about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mktuntap.85
-rw-r--r--mktuntap.c28
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) {