- (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.
This commit is contained in:
Damien Miller 2006-01-01 19:47:05 +11:00
parent c4bcc91751
commit 2dcddbfaf6
7 changed files with 119 additions and 11 deletions

View File

@ -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 $

View File

@ -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)

View File

@ -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

View File

@ -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>

2
misc.c
View File

@ -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;

View File

@ -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);
}

View File

@ -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