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
The following reply was made to PR bin/39233; it has been noted by GNATS.
From: Taylor R Campbell <campbell%mumble.net@localhost>
To: cube%cubidou.net@localhost
Cc: gnats-bugs%NetBSD.org@localhost
Subject: Re: bin/39233: OpenSSH fails to initialize tun(4) tunnels correctly
Date: Tue, 29 Jul 2008 10:36:31 -0400
This is a multi-part message in MIME format.
--=_CcgIGg4diOwClHzD+65up5YYtGiWa47p
Sorry, that was a terrible patch. Here's a better one (also actually
attached this time).
--=_CcgIGg4diOwClHzD+65up5YYtGiWa47p
Content-Type: text/plain; charset="iso-8859-1"; name="ssh-tun"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="ssh-tun.patch"
Index: misc.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/crypto/dist/ssh/misc.c,v
retrieving revision 1.21
diff -u -r1.21 misc.c
--- misc.c 6 Apr 2008 23:38:19 -0000 1.21
+++ misc.c 28 Jul 2008 23:36:35 -0000
@@ -35,6 +35,9 @@
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
+#ifdef __NetBSD__
+# include <net/if_tun.h>
+#endif
=20
#include <errno.h>
#include <fcntl.h>
@@ -636,20 +639,90 @@
return -1;
}
=20
+#if defined(__NetBSD__)
+
+static ssize_t
+tun_get_device_name(int tun, int mode, char *buf, size_t buflen)
+{
+ if (mode =3D=3D SSH_TUNMODE_POINTOPOINT)
+ return strlcpy(buf, "tun", buflen);
+ else if (mode =3D=3D SSH_TUNMODE_ETHERNET)
+ return strlcpy(buf, "tap", buflen);
+ else
+ return (-1);
+}
+
+static int
+tun_set_if_mode(int tun, int mode, int fd, int sock, struct ifreq *ifr)
+{
+ if (mode =3D=3D SSH_TUNMODE_POINTOPOINT) {
+ int one =3D 1;
+ /* Request the tun(4) interface to prepend four bytes
+ of address family to each packet delivered, which is
+ what OpenBSD's tun(4) expects. */
+ return ioctl(fd, TUNSIFHEAD, &one);
+ }
+ return 0;
+}
+
+#elif defined(__OpenBSD__) || defined(__FreeBSD__)
+
+static ssize_t
+tun_get_device_name(int tun, int mode, char *buf, size_t buflen)
+{
+ if (mode =3D=3D SSH_TUNMODE_POINTOPOINT ||
+ mode =3D=3D SSH_TUNMODE_ETHERNET)
+ return strlcpy(buf, "tun", buflen);
+ else
+ return (-1);
+}
+
+static int
+tun_set_if_mode(int tun, int mode, int fd, int sock, struct ifreq *ifr)
+{
+ ifr->ifr_flags &=3D ~IFF_IP;
+ if (mode =3D=3D SSH_TUNMODE_ETHERNET)
+ ifr->ifr_flags |=3D IFF_LINK0;
+ else
+ ifr->ifr_flags &=3D ~IFF_LINK0;
+ return ioctl(sock, SIOCSIFFLAGS, ifr);
+}
+
+#else
+
+static ssize_t
+tun_get_device_name(int tun, int mode, char *buf, size_t buflen)
+{
+ return (-1);
+}
+
+static int
+tun_set_if_mode(int tun, int mode, int fd, int sock, struct ifreq *ifr)
+{
+ return (-1);
+}
+
+#endif
+
int
tun_open(int tun, int mode)
{
struct ifreq ifr;
- char name[100];
+ char name[100], device[100];
int fd =3D -1, sock;
=20
+ if (tun_get_device_name(tun, mode, device, sizeof(device)) =3D=3D =
-1) {
+ debug("%s: no tunnel %d for mode %u", __func__, tun, mode);
+ return (-1);
+ }
+
/* Open the tunnel device */
if (tun <=3D SSH_TUNID_MAX) {
- snprintf(name, sizeof(name), "/dev/tun%d", tun);
+ snprintf(name, sizeof(name), "/dev/%s%d", device, tun);
fd =3D open(name, O_RDWR);
} else if (tun =3D=3D SSH_TUNID_ANY) {
for (tun =3D 100; tun >=3D 0; tun--) {
- snprintf(name, sizeof(name), "/dev/tun%d", tun);
+ snprintf(name, sizeof(name), "/dev/%s%d", device, tun);
if ((fd =3D open(name, O_RDWR)) >=3D 0)
break;
}
@@ -666,7 +739,7 @@
debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
=20
/* 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", device, tun);
if ((sock =3D socket(PF_UNIX, SOCK_STREAM, 0)) =3D=3D -1)
goto failed;
=20
@@ -674,12 +747,7 @@
goto failed;
=20
/* Set interface mode */
- ifr.ifr_flags &=3D ~IFF_UP;
- if (mode =3D=3D SSH_TUNMODE_ETHERNET)
- ifr.ifr_flags |=3D IFF_LINK0;
- else
- ifr.ifr_flags &=3D ~IFF_LINK0;
- if (ioctl(sock, SIOCSIFFLAGS, &ifr) =3D=3D -1)
+ if (tun_set_if_mode(tun, mode, fd, sock, &ifr) =3D=3D -1)
goto failed;
=20
/* Bring interface up */
--=_CcgIGg4diOwClHzD+65up5YYtGiWa47p--
Home |
Main Index |
Thread Index |
Old Index