version 1.98, 2015/10/07 00:54:06 |
version 1.99, 2015/10/24 08:34:09 |
|
|
struct ifreq ifr; |
struct ifreq ifr; |
char name[100]; |
char name[100]; |
int fd = -1, sock; |
int fd = -1, sock; |
|
const char *tunbase = "tun"; |
|
|
|
if (mode == SSH_TUNMODE_ETHERNET) |
|
tunbase = "tap"; |
|
|
/* Open the tunnel device */ |
/* Open the tunnel device */ |
if (tun <= SSH_TUNID_MAX) { |
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); |
fd = open(name, O_RDWR); |
} else if (tun == SSH_TUNID_ANY) { |
} else if (tun == SSH_TUNID_ANY) { |
for (tun = 100; tun >= 0; tun--) { |
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) |
if ((fd = open(name, O_RDWR)) >= 0) |
break; |
break; |
} |
} |
|
|
|
|
debug("%s: %s mode %d fd %d", __func__, name, mode, fd); |
debug("%s: %s mode %d fd %d", __func__, name, mode, fd); |
|
|
/* Set the tunnel device operation mode */ |
/* Bring interface up if it is not already */ |
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) { |
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) |
error("%s: socket: %s", __func__, strerror(errno)); |
|
goto failed; |
goto failed; |
} |
|
|
|
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { |
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { |
debug("%s: get interface %s flags: %s", __func__, |
debug("%s: get interface %s flags: %s", __func__, |
|
|
goto failed; |
goto failed; |
} |
} |
|
|
/* Set interface mode if not already in correct mode */ |
|
if ((mode == SSH_TUNMODE_ETHERNET && !(ifr.ifr_flags & IFF_LINK0)) || |
|
(mode != SSH_TUNMODE_ETHERNET && (ifr.ifr_flags & IFF_LINK0))) { |
|
ifr.ifr_flags &= ~IFF_UP; |
|
ifr.ifr_flags ^= IFF_LINK0; |
|
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { |
|
debug("%s: reset interface %s flags: %s", __func__, |
|
ifr.ifr_name, strerror(errno)); |
|
goto failed; |
|
} |
|
} |
|
|
|
/* Bring interface up if it is not already */ |
|
if (!(ifr.ifr_flags & IFF_UP)) { |
if (!(ifr.ifr_flags & IFF_UP)) { |
ifr.ifr_flags |= IFF_UP; |
ifr.ifr_flags |= IFF_UP; |
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { |
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { |