From 21ae2ec2b963e33e1b48b6cf9069e774b3f656b1 Mon Sep 17 00:00:00 2001 From: Gert Doering Date: Thu, 7 Jun 2012 17:38:17 +0200 Subject: Implement search for "first free" tun/tap device on Solaris Without this patch, Solaris will do "--dev tun3" just fine, but "--dev tun" will either use "tun0" if that is available, or fail. With the patch, the first available device is searched if "--dev tun" or "--dev tap" (without a number) is specified. Signed-off-by: Gert Doering Acked-by: David Sommerseth Message-Id: 20120607174638.GW1059@greenie.muc.de URL: http://article.gmane.org/gmane.network.openvpn.devel/6705 Signed-off-by: David Sommerseth --- src/openvpn/tun.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 633150f..c9edbb8 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -1711,6 +1711,12 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu msg (M_FATAL, "I don't recognize device %s as a tun or tap device", dev); } + + if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0) + msg (M_ERR, "Can't open %s", ip_node); + + if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0) + msg (M_ERR, "Can't open %s", dev_node); /* get unit number */ if (*dev) @@ -1721,19 +1727,37 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu ppa = atoi (ptr); } - if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0) - msg (M_ERR, "Can't open %s", ip_node); - - if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0) - msg (M_ERR, "Can't open %s", dev_node); - /* Assign a new PPA and get its unit number. */ strioc_ppa.ic_cmd = TUNNEWPPA; strioc_ppa.ic_timout = 0; strioc_ppa.ic_len = sizeof(ppa); strioc_ppa.ic_dp = (char *)&ppa; - if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0) - msg (M_ERR, "Can't assign new interface"); + + if ( *ptr == '\0' ) /* no number given, try dynamic */ + { + bool found_one = false; + while( ! found_one && ppa < 64 ) + { + int new_ppa = ioctl (tt->fd, I_STR, &strioc_ppa); + if ( new_ppa >= 0 ) + { + msg( M_INFO, "open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa ); + ppa = new_ppa; + found_one = true; + break; + } + if ( errno != EEXIST ) + msg (M_ERR, "open_tun: unexpected error trying to find free %s interface", dev_tuntap_type ); + ppa++; + } + if ( !found_one ) + msg (M_ERR, "open_tun: could not find free %s interface, give up.", dev_tuntap_type ); + } + else /* try this particular one */ + { + if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0) + msg (M_ERR, "Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa ); + } if ((if_fd = open (dev_node, O_RDWR, 0)) < 0) msg (M_ERR, "Can't open %s (2)", dev_node); -- cgit