From f45fcb661ef5586656c2a3af787166e2bceab61d Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sun, 15 Dec 2019 20:22:47 +0000 Subject: 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. --- mktuntap.8 | 5 +++++ 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) { -- cgit 1.4.1