PR/39233: Taylor R Campbeel: OpenSSH fails to initialize tun(4) tunnels
correctly.
This commit is contained in:
parent
ab6abfafd3
commit
7a75c9a543
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: misc.c,v 1.21 2008/04/06 23:38:19 christos Exp $ */
|
||||
/* $NetBSD: misc.c,v 1.22 2008/09/17 15:45:50 christos Exp $ */
|
||||
/* $OpenBSD: misc.c,v 1.67 2008/01/01 08:47:04 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
|
@ -26,13 +26,14 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
__RCSID("$NetBSD: misc.c,v 1.21 2008/04/06 23:38:19 christos Exp $");
|
||||
__RCSID("$NetBSD: misc.c,v 1.22 2008/09/17 15:45:50 christos Exp $");
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_tun.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
|
@ -640,17 +641,19 @@ int
|
|||
tun_open(int tun, int mode)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
char name[100];
|
||||
int fd = -1, sock;
|
||||
int fd = -1, sock, flag;
|
||||
const char *tunbase = mode == SSH_TUNMODE_ETHERNET ? "tap" : "tun";
|
||||
|
||||
/* Open the tunnel device */
|
||||
if (tun <= SSH_TUNID_MAX) {
|
||||
snprintf(name, sizeof(name), "/dev/tun%d", tun);
|
||||
fd = open(name, O_RDWR);
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name),
|
||||
"/dev/%s%d", tunbase, tun);
|
||||
fd = open(ifr.ifr_name, O_RDWR);
|
||||
} else if (tun == SSH_TUNID_ANY) {
|
||||
for (tun = 100; tun >= 0; tun--) {
|
||||
snprintf(name, sizeof(name), "/dev/tun%d", tun);
|
||||
if ((fd = open(name, O_RDWR)) >= 0)
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name),
|
||||
"/dev/%s%d", tunbase, tun);
|
||||
if ((fd = open(ifr.ifr_name, O_RDWR)) >= 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -659,20 +662,31 @@ tun_open(int tun, int mode)
|
|||
}
|
||||
|
||||
if (fd < 0) {
|
||||
debug("%s: %s open failed: %s", __func__, name, strerror(errno));
|
||||
debug("%s: %s open failed: %s", __func__, ifr.ifr_name,
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
|
||||
/* 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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd);
|
||||
|
||||
/* Set the tunnel device operation mode */
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun);
|
||||
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
goto failed;
|
||||
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
|
||||
goto failed;
|
||||
|
||||
#if 0
|
||||
/* Set interface mode */
|
||||
ifr.ifr_flags &= ~IFF_UP;
|
||||
if (mode == SSH_TUNMODE_ETHERNET)
|
||||
|
@ -681,6 +695,7 @@ tun_open(int tun, int mode)
|
|||
ifr.ifr_flags &= ~IFF_LINK0;
|
||||
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
|
||||
goto failed;
|
||||
#endif
|
||||
|
||||
/* Bring interface up */
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
|
@ -695,7 +710,7 @@ tun_open(int tun, int mode)
|
|||
close(fd);
|
||||
if (sock >= 0)
|
||||
close(sock);
|
||||
debug("%s: failed to set %s mode %d: %s", __func__, name,
|
||||
debug("%s: failed to set %s mode %d: %s", __func__, ifr.ifr_name,
|
||||
mode, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue