about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2019-12-15 16:20:15 +0000
committerAlyssa Ross <hi@alyssa.is>2019-12-15 16:21:19 +0000
commitd2bdbc297ce4bd3f2c58f90157aebf7313efec3f (patch)
tree0b49285dd339e22d1e23169bebdac600b5a55d17
parente7dd74d559686919b6234a9b0d98c4b1df07579d (diff)
downloadmktuntap-d2bdbc297ce4bd3f2c58f90157aebf7313efec3f.tar
mktuntap-d2bdbc297ce4bd3f2c58f90157aebf7313efec3f.tar.gz
mktuntap-d2bdbc297ce4bd3f2c58f90157aebf7313efec3f.tar.bz2
mktuntap-d2bdbc297ce4bd3f2c58f90157aebf7313efec3f.tar.lz
mktuntap-d2bdbc297ce4bd3f2c58f90157aebf7313efec3f.tar.xz
mktuntap-d2bdbc297ce4bd3f2c58f90157aebf7313efec3f.tar.zst
mktuntap-d2bdbc297ce4bd3f2c58f90157aebf7313efec3f.zip
Support both TUN and TAP devices
-rw-r--r--.gitignore2
-rw-r--r--Makefile8
-rw-r--r--README12
-rw-r--r--TODO2
-rw-r--r--mktuntap.8 (renamed from mktap.8)20
-rw-r--r--mktuntap.c (renamed from mktap.c)49
6 files changed, 51 insertions, 42 deletions
diff --git a/.gitignore b/.gitignore
index 39ca1ef..7e27746 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
 result
 result-*
 *.o
-/mktap
\ No newline at end of file
+/mktuntap
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 054b56f..ff52ac4 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
-all: mktap
+all: mktuntap
 .PHONY: all
 
 prefix = /usr/local
@@ -36,7 +36,7 @@ install-dirs:
 	$(MKDIR_P) $(DESTDIR)$(bindir) $(DESTDIR)$(man8dir)
 .PHONY: install-dirs
 
-install: mktap install-dirs
-	$(INSTALL_PROGRAM) mktap $(DESTDIR)$(bindir)/
-	$(INSTALL_DATA) mktap.8 $(DESTDIR)$(man8dir)/
+install: mktuntap install-dirs
+	$(INSTALL_PROGRAM) mktuntap $(DESTDIR)$(bindir)/
+	$(INSTALL_DATA) mktuntap.8 $(DESTDIR)$(man8dir)/
 .PHONY: install
diff --git a/README b/README
index 8b71fee..84769aa 100644
--- a/README
+++ b/README
@@ -1,13 +1,13 @@
-mktap
------
+mktuntap
+--------
 
-creates a tap device on a specified file descriptor, and then execs
-into the rest of argv.
+creates a tun or tap device on a specified file descriptor, and then
+execs into the rest of argv.
 
-mktap makes use of example code from the Linux kernel, and as such is
+mktuntap makes use of example code from the Linux kernel, and as such is
 licensed under (only) version 2 of the GNU General Public License as
 published by the Free Software Foundation.
 
 Other source files are licensed under the GNU General Public License,
 either version 2 of the License, or (at your option) any later
-version.
\ No newline at end of file
+version.
diff --git a/TODO b/TODO
index 3cc51c7..7c9b18a 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,2 @@
-* Give choice between tun/tap with -n | -p (like tunctl), and rename
-  to mktuntap
 * Reimplement tap_alloc for compatibility with newer GPLs
 * Refer to % formats available for ifr_name
diff --git a/mktap.8 b/mktuntap.8
index 6e7815e..7e6414d 100644
--- a/mktap.8
+++ b/mktuntap.8
@@ -15,19 +15,20 @@
 .\" You should have received a copy of the GNU General Public License
 .\" along with this program.  If not, see <https://www.gnu.org/licenses/>.
 .Dd December 15, 2019
-.Dt MKTAP 8
+.Dt MKTUNTAP 8
 .Os Linux
 .Sh NAME
-.Nm mktap
-.Nd create and open a tap device on a file descriptor, then exec
+.Nm mktuntap
+.Nd create and open a TUN or TAP device on a file descriptor, then exec
 .Sh SYNOPSIS
 .Nm
+.Fl ( n | p )
 .Op Fl E
 .Op Fl i Ar ifr_name
 .Ar fd
 .Ar prog...
 .Sh DESCRIPTION
-Create a tap device named with format
+Create a TUN or TAP device named with format
 .Ar ifr_name ,
 open it on file descriptor
 .Ar fd ,
@@ -37,6 +38,12 @@ opened device, and then exec into
 .Pp
 The arguments are as follows:
 .Bl -tag -width Ds
+.It Fl p
+Create a TAP device.  Mutually exclusive with
+.Fl n .
+.It Fl n
+Create a TUN device.  Mutually exclusive with
+.Fl p .
 .It Fl E
 Don't set the TUNTAP_NAME environment variable.  Caution: if you use
 this without using
@@ -47,7 +54,10 @@ device name later.
 Set the name for the device.  If present, the character sequence
 .Dq %d
 will be replaced with a number to create a unique name.  Default:
-.Dq tap%d .
+.Dq tap%d
+or
+.Dq tun%d ,
+as appropriate.
 .El
 .Sh EXIT STATUS
 .Ex -std
diff --git a/mktap.c b/mktuntap.c
index 8e0b5bf..cae3f5a 100644
--- a/mktap.c
+++ b/mktuntap.c
@@ -29,8 +29,8 @@
 #include <linux/if.h>
 #include <linux/if_tun.h>
 
-// Adapted 2019-12-14 from Documentation/networking/tuntap.txt in Linux.
-int tap_alloc(char *dev)
+// Adapted 2019-12-14 from Documentation/networking/tuntuntap.txt in Linux.
+int tuntap_alloc(char *dev, short flags)
 {
 	struct ifreq ifr;
 	int fd, err;
@@ -40,12 +40,7 @@ int tap_alloc(char *dev)
 
 	memset(&ifr, 0, sizeof(ifr));
 
-	/* Flags: IFF_TUN   - TUN device (no Ethernet headers)
-	 *        IFF_TAP   - TAP device
-	 *
-	 *        IFF_NO_PI - Do not provide packet information
-	 */
-	ifr.ifr_flags = IFF_TAP;
+	ifr.ifr_flags = flags;
 	if (*dev)
 		strncpy(ifr.ifr_name, dev, IFNAMSIZ);
 
@@ -59,18 +54,24 @@ int tap_alloc(char *dev)
 
 void ex_usage()
 {
-	fputs("mktap: usage: mktap [-E] [-i ifr_name] fd prog...\n", stderr);
+	fputs("mktuntap: usage: mktuntap (-n | -p) [-E] [-i ifr_name] fd prog...\n", stderr);
 	exit(EX_USAGE);
 }
 
 int main(int argc, char **argv)
 {
 	char *ifr_name_in = NULL;
-	bool name_env = true;
+	bool name_env = true, tap = false, tun = false;
 
 	int c;
-	while ((c = getopt(argc, argv, "+Ei:")) != -1) {
+	while ((c = getopt(argc, argv, "+npEi:")) != -1) {
 		switch (c) {
+		case 'n':
+			tun = true;
+			break;
+		case 'p':
+			tap = true;
+			break;
 		case 'E':
 			name_env = false;
 			break;
@@ -82,14 +83,14 @@ int main(int argc, char **argv)
 		}
 	}
 
-	if (argc - optind < 2)
+	if (argc - optind < 2 || !(tap ^ tun))
 		ex_usage();
 
 	// ifr_name is a macro, so add a trailing _.
 	char *ifr_name_ = calloc(IFNAMSIZ, sizeof(char));
 	if (ifr_name_in) {
 		if (strlen(ifr_name_in) > IFNAMSIZ - 1) {
-			fprintf(stderr, "mktap: ifr_name too long (max %i)\n", IFNAMSIZ - 1);
+			fprintf(stderr, "mktuntap: ifr_name too long (max %i)\n", IFNAMSIZ - 1);
 			return EX_USAGE;
 		}
 		strcpy(ifr_name_, ifr_name_in);
@@ -99,37 +100,37 @@ int main(int argc, char **argv)
 	char *target_fd_end;
 	long int target_fd_l = strtol(argv[optind], &target_fd_end, 10);
 	if (errno) {
-		fprintf(stderr, "mktap: %s\n", strerror(errno));
+		fprintf(stderr, "mktuntap: %s\n", strerror(errno));
 		return EX_USAGE;
 	}
 	if (argv[optind][0] == '\0' || target_fd_end[0] != '\0') {
-		fprintf(stderr, "mktap: invalid integer: `%s'\n", argv[optind]);
+		fprintf(stderr, "mktuntap: invalid integer: `%s'\n", argv[optind]);
 		return EX_USAGE;
 	}
 	if (target_fd_l < INT_MIN || target_fd_l > INT_MAX) {
-		fprintf(stderr, "mktap: out of range for file descriptor: `%li'\n", target_fd_l);
+		fprintf(stderr, "mktuntap: out of range for file descriptor: `%li'\n", target_fd_l);
 		return EX_USAGE;
 	}
 	int target_fd = (int)target_fd_l;
 
-	int tap_fd = tap_alloc(ifr_name_);
-	if (tap_fd < 0) {
-		fprintf(stderr, "mktap: failed to open tap device: %s\n", strerror(errno));
+	int tuntap_fd = tuntap_alloc(ifr_name_, tap ? IFF_TAP : IFF_TUN);
+	if (tuntap_fd < 0) {
+		fprintf(stderr, "mktuntap: failed to open tuntap device: %s\n", strerror(errno));
 		return EX_IOERR;
 	}
 
-	if (dup2(tap_fd, target_fd) == -1) {
-		fprintf(stderr, "mktap: %s\n", strerror(errno));
+	if (dup2(tuntap_fd, target_fd) == -1) {
+		fprintf(stderr, "mktuntap: %s\n", strerror(errno));
 		return EX_IOERR;
 	}
-	if (close(tap_fd) == -1) {
-		fprintf(stderr, "mktap: %s\n", strerror(errno));
+	if (close(tuntap_fd) == -1) {
+		fprintf(stderr, "mktuntap: %s\n", strerror(errno));
 		return EX_IOERR;
 	}
 
 	if (name_env) {
 		if (setenv("TUNTAP_NAME", ifr_name_, 1) == -1) {
-			fprintf(stderr, "mktap: %s\n", strerror(errno));
+			fprintf(stderr, "mktuntap: %s\n", strerror(errno));
 			return EX_OSERR;
 		}
 	}