diff options
author | Alyssa Ross <hi@alyssa.is> | 2019-12-15 20:22:47 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2019-12-15 23:00:57 +0000 |
commit | f45fcb661ef5586656c2a3af787166e2bceab61d (patch) | |
tree | c9d7f1b4aa961f95d6bc660f1d08acdec0f6cf49 | |
parent | 89990f7ae1b8b26f4d6915914e1ede95156e1a95 (diff) | |
download | mktuntap-f45fcb661ef5586656c2a3af787166e2bceab61d.tar mktuntap-f45fcb661ef5586656c2a3af787166e2bceab61d.tar.gz mktuntap-f45fcb661ef5586656c2a3af787166e2bceab61d.tar.bz2 mktuntap-f45fcb661ef5586656c2a3af787166e2bceab61d.tar.lz mktuntap-f45fcb661ef5586656c2a3af787166e2bceab61d.tar.xz mktuntap-f45fcb661ef5586656c2a3af787166e2bceab61d.tar.zst mktuntap-f45fcb661ef5586656c2a3af787166e2bceab61d.zip |
Don't close fd if it's the target
Without this, if the fd assigned by open(2) happened to be the one we wanted, we would dup it to itself, and then close it, leaving no copy of the fd. I'm surprised duping an fd over itself doesn't cause an error, but here we are.
-rw-r--r-- | mktuntap.8 | 5 | ||||
-rw-r--r-- | mktuntap.c | 28 |
2 files changed, 23 insertions, 10 deletions
diff --git a/mktuntap.8 b/mktuntap.8 index 7e6414d..6f2a32f 100644 --- a/mktuntap.8 +++ b/mktuntap.8 @@ -23,6 +23,7 @@ .Sh SYNOPSIS .Nm .Fl ( n | p ) +.Op Fl v .Op Fl E .Op Fl i Ar ifr_name .Ar fd @@ -44,6 +45,10 @@ Create a TAP device. Mutually exclusive with .It Fl n Create a TUN device. Mutually exclusive with .Fl p . +.It Fl v +Set the +.Dv IFF_VNET_HDR +flag on the device. .It Fl E Don't set the TUNTAP_NAME environment variable. Caution: if you use this without using diff --git a/mktuntap.c b/mktuntap.c index cae3f5a..8cbc335 100644 --- a/mktuntap.c +++ b/mktuntap.c @@ -61,10 +61,10 @@ void ex_usage() int main(int argc, char **argv) { char *ifr_name_in = NULL; - bool name_env = true, tap = false, tun = false; + bool name_env = true, tap = false, tun = false, vnet_hdr = false; int c; - while ((c = getopt(argc, argv, "+npEi:")) != -1) { + while ((c = getopt(argc, argv, "+npvEi:")) != -1) { switch (c) { case 'n': tun = true; @@ -72,6 +72,9 @@ int main(int argc, char **argv) case 'p': tap = true; break; + case 'v': + vnet_hdr = true; + break; case 'E': name_env = false; break; @@ -113,19 +116,24 @@ int main(int argc, char **argv) } int target_fd = (int)target_fd_l; - int tuntap_fd = tuntap_alloc(ifr_name_, tap ? IFF_TAP : IFF_TUN); + short flags = tap ? IFF_TAP : IFF_TUN; + if (vnet_hdr) + flags |= IFF_VNET_HDR; + int tuntap_fd = tuntap_alloc(ifr_name_, flags); if (tuntap_fd < 0) { fprintf(stderr, "mktuntap: failed to open tuntap device: %s\n", strerror(errno)); return EX_IOERR; } - if (dup2(tuntap_fd, target_fd) == -1) { - fprintf(stderr, "mktuntap: %s\n", strerror(errno)); - return EX_IOERR; - } - if (close(tuntap_fd) == -1) { - fprintf(stderr, "mktuntap: %s\n", strerror(errno)); - return EX_IOERR; + if (tuntap_fd != target_fd) { + if (dup2(tuntap_fd, target_fd) == -1) { + fprintf(stderr, "mktuntap: %s\n", strerror(errno)); + return EX_IOERR; + } + if (close(tuntap_fd) == -1) { + fprintf(stderr, "mktuntap: %s\n", strerror(errno)); + return EX_IOERR; + } } if (name_env) { |