diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | configure.ac | 12 | ||||
-rw-r--r-- | includes.h | 3 | ||||
-rw-r--r-- | misc.c | 2 | ||||
-rw-r--r-- | openbsd-compat/port-tun.c | 98 | ||||
-rw-r--r-- | openbsd-compat/port-tun.h | 2 |
7 files changed, 119 insertions, 11 deletions
@@ -1,3 +1,10 @@ +20060101 + - (djm) [Makefile.in configure.ac includes.h misc.c] + [openbsd-compat/port-tun.c openbsd-compat/port-tun.h] Add support + for tunnel forwarding for FreeBSD and NetBSD. NetBSD's support is + limited to IPv4 tunnels only, and most versions don't support the + tap(4) device at all. + 20051229 - (djm) OpenBSD CVS Sync - stevesk@cvs.openbsd.org 2005/12/28 22:46:06 @@ -3578,4 +3585,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4059 2005/12/31 06:05:58 djm Exp $ +$Id: ChangeLog,v 1.4060 2006/01/01 08:47:05 djm Exp $ diff --git a/Makefile.in b/Makefile.in index fcbc522f..af881c52 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.273 2005/05/29 07:22:29 dtucker Exp $ +# $Id: Makefile.in,v 1.274 2006/01/01 08:47:05 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -139,7 +139,7 @@ sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBS) scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o - $(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff --git a/configure.ac b/configure.ac index 26ed218d..2f590666 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.319 2005/12/31 06:05:58 djm Exp $ +# $Id: configure.ac,v 1.320 2006/01/01 08:47:05 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -346,10 +346,18 @@ mips-sony-bsd|mips-sony-newsos4) if test "x$withval" != "xno" ; then need_dash_r=1 fi + AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way]) + AC_CHECK_HEADER([net/if_tap.h], , + AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support])) + AC_DEFINE(SSH_TUN_PREPEND_AF, 1, + [Prepend the address family to IP tunnel traffic]) ;; *-*-freebsd*) check_for_libcrypt_later=1 AC_DEFINE(LOCKED_PASSWD_PREFIX, "*LOCKED*", [Account locked with pw(1)]) + AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way]) + AC_CHECK_HEADER([net/if_tap.h], , + AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support])) ;; *-*-bsdi*) AC_DEFINE(SETEUID_BREAKS_SETUID) @@ -369,7 +377,7 @@ mips-sony-bsd|mips-sony-newsos4) *-*-openbsd*) AC_DEFINE(HAVE_ATTRIBUTE__SENTINEL__, 1, [OpenBSD's gcc has sentinel]) AC_DEFINE(HAVE_ATTRIBUTE__BOUNDED__, 1, [OpenBSD's gcc has bounded]) - AC_DEFINE(SSH_TUN_BSD, 1, [Open tunnel devices the BSD way]) + AC_DEFINE(SSH_TUN_OPENBSD, 1, [Open tunnel devices the OpenBSD way]) ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -148,9 +148,6 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg } #include <netinet/in.h> /* For IPv6 macros */ #include <netinet/ip.h> /* For IPTOS macros */ #include <netinet/tcp.h> -#ifdef HAVE_NET_IF_H -# include <net/if.h> -#endif #include <arpa/inet.h> #if defined(HAVE_NETDB_H) # include <netdb.h> @@ -543,7 +543,7 @@ tun_open(int tun, int mode) { #if defined(CUSTOM_SYS_TUN_OPEN) return (sys_tun_open(tun, mode)); -#elif defined(SSH_TUN_BSD) +#elif defined(SSH_TUN_OPENBSD) struct ifreq ifr; char name[100]; int fd = -1, sock; diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-tun.c index 479b46b7..00a0442b 100644 --- a/openbsd-compat/port-tun.c +++ b/openbsd-compat/port-tun.c @@ -89,6 +89,88 @@ sys_tun_open(int tun, int mode) } #endif /* SSH_TUN_LINUX */ +#ifdef SSH_TUN_FREEBSD +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_tun.h> + +int +sys_tun_open(int tun, int mode) +{ + struct ifreq ifr; + char name[100]; + int fd = -1, sock, flag; + const char *tunbase = "tun"; + + if (mode == SSH_TUNMODE_ETHERNET) { +#ifdef SSH_TUN_NO_L2 + debug("%s: no layer 2 tunnelling support", __func__); + return (-1); +#else + tunbase = "tap"; +#endif + } + + /* Open the tunnel device */ + if (tun <= SSH_TUNID_MAX) { + 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/%s%d", + tunbase, tun); + if ((fd = open(name, O_RDWR)) >= 0) + break; + } + } else { + debug("%s: invalid tunnel %u\n", __func__, tun); + return (-1); + } + + if (fd < 0) { + debug("%s: %s open failed: %s", __func__, name, + strerror(errno)); + return (-1); + } + + /* Turn on tunnel headers */ + flag = 1; +#if defined(TUNSIFHEAD) && !defined(SSH_TUN_PREPEND_AF) + if (mode != SSH_TUNMODE_ETHERNET && + ioctl(fd, TUNSIFHEAD, &flag) == -1) { + debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd, + strerror(errno)); + close(fd); + } +#endif + + 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), "%s%d", tunbase, tun); + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) + goto failed; + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) + goto failed; + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) + goto failed; + + close(sock); + return (fd); + + failed: + if (fd >= 0) + close(fd); + if (sock >= 0) + close(sock); + debug("%s: failed to set %s mode %d: %s", __func__, name, + mode, strerror(errno)); + return (-1); +} +#endif /* SSH_TUN_FREEBSD */ + /* * System-specific channel filters */ @@ -102,16 +184,29 @@ sys_tun_infilter(struct Channel *c, char *buf, int len) { #if defined(SSH_TUN_PREPEND_AF) char rbuf[CHAN_RBUF]; + struct ip *iph; #endif u_int32_t *af; char *ptr = buf; #if defined(SSH_TUN_PREPEND_AF) - if (len > (int)(sizeof(rbuf) - sizeof(*af))) + if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af))) return (-1); ptr = (char *)&rbuf[0]; bcopy(buf, ptr + sizeof(u_int32_t), len); len += sizeof(u_int32_t); + af = (u_int32_t *)ptr; + + iph = (struct ip *)(ptr + sizeof(u_int32_t)); + switch (iph->ip_v) { + case 6: + *af = AF_INET6; + break; + case 4: + default: + *af = AF_INET; + break; + } #endif #if defined(SSH_TUN_COMPAT_AF) @@ -124,6 +219,7 @@ sys_tun_infilter(struct Channel *c, char *buf, int len) else *af = htonl(OPENBSD_AF_INET); #endif + buffer_put_string(&c->input, ptr, len); return (0); } diff --git a/openbsd-compat/port-tun.h b/openbsd-compat/port-tun.h index 942610c6..86d9272b 100644 --- a/openbsd-compat/port-tun.h +++ b/openbsd-compat/port-tun.h @@ -19,7 +19,7 @@ #include "channels.h" -#if defined(SSH_TUN_LINUX) +#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) # define CUSTOM_SYS_TUN_OPEN int sys_tun_open(int, int); #endif |