Hi,

Solaris buildslave failed to test, because "--dev tun" did not work
if tun0 was already in use (didn't hunt to tun1).

Fixed, tested on OpenSolaris 10 / i386 - but the code is straightforward, 
so it should work on "standard Solaris" and "sparc" as well.  Managed to
get it to hunt to tun2 just fine, and then ran out of possible OpenVPN
targets :-) but if it works for tun0, tun1, tun2 there is no reason why
it shouldn't work for tun63. 

The moving around of the open() calls is purely cosmetic - I wanted to
have all code that relates to tun device unit number in one block, not
"first parse device name, then open unrelated stuff, then try to use
that just-parsed device and the resulting 'ptr' variable".

gert
-- 
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             g...@greenie.muc.de
fax: +49-89-35655025                        g...@net.informatik.tu-muenchen.de
From 606e5c98ba25381b8396eb8a12d923af55ed6385 Mon Sep 17 00:00:00 2001
From: Gert Doering <g...@greenie.muc.de>
List-Post: openvpn-devel@lists.sourceforge.net
Date: Thu, 7 Jun 2012 17:38:17 +0200
Subject: [PATCH] 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 <g...@greenie.muc.de>
---
 src/openvpn/tun.c |   40 ++++++++++++++++++++++++++++++++--------
 1 files 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);
-- 
1.5.6.5

Attachment: pgpH5MEl6F9xU.pgp
Description: PGP signature

Reply via email to