From 2c0849c8a93f381cf3e4d52654dd9480d6280310 Mon Sep 17 00:00:00 2001 From: Stuart Henderson Date: Fri, 13 Feb 2015 16:39:57 +0000 Subject: [PATCH] BSD patches for ocserv Iterate over tunXX devices, for BSDs that can't just open /dev/tun to retrieve the "next available tun". This is just copied with minor changes from openconnect/src/tun.c, Signed-off-by: Stuart Henderson --- src/tun.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/tun.c b/src/tun.c index 51a2c970..46b833cd 100644 --- a/src/tun.c +++ b/src/tun.c @@ -321,9 +321,39 @@ static int set_network_info(main_server_st * s, struct proc_st *proc) #include +#ifndef __linux__ +# ifdef SIOCIFCREATE +static int bsd_open_tun(char *tun_name) +{ + int fd; + int s; + struct ifreq ifr; + + fd = open(tun_name, O_RDWR); + if (fd == -1) { + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + return -1; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, tun_name + 5, sizeof(ifr.ifr_name) - 1); + if (!ioctl(s, SIOCIFCREATE, &ifr)) + fd = open(tun_name, O_RDWR); + + close(s); + } + return fd; +} +# else +# define bsd_open_tun(tun_name) open(tun_name, O_RDWR) +# endif +#endif + int open_tun(main_server_st * s, struct proc_st *proc) { int tunfd, ret, e; + static char tun_name[80]; + int unit_nr = 0; struct ifreq ifr; unsigned int t; @@ -394,12 +424,20 @@ int open_tun(main_server_st * s, struct proc_st *proc) } #endif #else /* freebsd */ - tunfd = open("/dev/tun", O_RDWR); + tunfd = bsd_open_tun("/dev/tun"); if (tunfd < 0) { - int e = errno; - mslog(s, NULL, LOG_ERR, "Can't open /dev/tun: %s\n", - strerror(e)); - return -1; + for (unit_nr = 0; unit_nr < 255; unit_nr++) { + sprintf(tun_name, "/dev/tun%d", unit_nr); + tunfd = bsd_open_tun(tun_name); + if (tunfd >= 0) + break; + } + if (tunfd < 0) { + int e = errno; + mslog(s, NULL, LOG_ERR, "Can't open /dev/tun: %s\n", + strerror(e)); + return -1; + } } /* find device name */