NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/39233: OpenSSH fails to initialize tun(4) tunnels correctly



Attached is a patch that slightly adapts of the code one finds in
portable OpenSSH's openbsd-compat/port-tun.c into misc.c.  I have
lightly tested both point-to-point and bridge tunnels on a machine
running NetBSD 4.0_STABLE talking with a machine running OpenBSD 4.3,
and the patch applies to both netbsd-4 and HEAD.  The only difference
from my last patch, really, is that there are no confused cpp feature
conditionals and no auxiliary routines.
--- misc.c      15 Jun 2008 01:35:37 +0000      1.21
+++ misc.c      16 Sep 2008 22:25:22 +0000      
@@ -33,6 +33,7 @@
 #include <sys/param.h>
 
 #include <net/if.h>
+#include <net/if_tun.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 
@@ -641,15 +642,20 @@
 {
        struct ifreq ifr;
        char name[100];
-       int fd = -1, sock;
+       int fd = -1, sock, flag;
+       const char *tunbase = "tun";
+
+       if (mode == SSH_TUNMODE_ETHERNET)
+               tunbase = "tap";
 
        /* Open the tunnel device */
        if (tun <= SSH_TUNID_MAX) {
-               snprintf(name, sizeof(name), "/dev/tun%d", tun);
+               snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);
                fd = open(name, O_RDWR);
        } else if (tun == SSH_TUNID_ANY) {
                for (tun = 100; tun >= 0; tun--) {
-                       snprintf(name, sizeof(name), "/dev/tun%d", tun);
+                       snprintf(name, sizeof(name), "/dev/%s%d",
+                           tunbase, tun);
                        if ((fd = open(name, O_RDWR)) >= 0)
                                break;
                }
@@ -663,26 +669,24 @@
                return (-1);
        }
 
+       /* Turn on tunnel headers */
+       flag = 1;
+       if (mode != SSH_TUNMODE_ETHERNET &&
+           ioctl(fd, TUNSIFHEAD, &flag) == -1) {
+               debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd,
+                   strerror(errno));
+               close(fd);
+       }
+
        debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
 
        /* Set the tunnel device operation mode */
-       snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun);
+       snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);
        if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
                goto failed;
 
        if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
                goto failed;
-
-       /* Set interface mode */
-       ifr.ifr_flags &= ~IFF_UP;
-       if (mode == SSH_TUNMODE_ETHERNET)
-               ifr.ifr_flags |= IFF_LINK0;
-       else
-               ifr.ifr_flags &= ~IFF_LINK0;
-       if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
-               goto failed;
-
-       /* Bring interface up */
        ifr.ifr_flags |= IFF_UP;
        if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
                goto failed;


Home | Main Index | Thread Index | Old Index