diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 32 |
1 files changed, 11 insertions, 21 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.98 2015/10/07 00:54:06 djm Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.99 2015/10/24 08:34:09 sthen Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. |
@@ -653,14 +653,19 @@ tun_open(int tun, int mode) | |||
653 | struct ifreq ifr; | 653 | struct ifreq ifr; |
654 | char name[100]; | 654 | char name[100]; |
655 | int fd = -1, sock; | 655 | int fd = -1, sock; |
656 | const char *tunbase = "tun"; | ||
657 | |||
658 | if (mode == SSH_TUNMODE_ETHERNET) | ||
659 | tunbase = "tap"; | ||
656 | 660 | ||
657 | /* Open the tunnel device */ | 661 | /* Open the tunnel device */ |
658 | if (tun <= SSH_TUNID_MAX) { | 662 | if (tun <= SSH_TUNID_MAX) { |
659 | snprintf(name, sizeof(name), "/dev/tun%d", tun); | 663 | snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); |
660 | fd = open(name, O_RDWR); | 664 | fd = open(name, O_RDWR); |
661 | } else if (tun == SSH_TUNID_ANY) { | 665 | } else if (tun == SSH_TUNID_ANY) { |
662 | for (tun = 100; tun >= 0; tun--) { | 666 | for (tun = 100; tun >= 0; tun--) { |
663 | snprintf(name, sizeof(name), "/dev/tun%d", tun); | 667 | snprintf(name, sizeof(name), "/dev/%s%d", |
668 | tunbase, tun); | ||
664 | if ((fd = open(name, O_RDWR)) >= 0) | 669 | if ((fd = open(name, O_RDWR)) >= 0) |
665 | break; | 670 | break; |
666 | } | 671 | } |
@@ -676,12 +681,10 @@ tun_open(int tun, int mode) | |||
676 | 681 | ||
677 | debug("%s: %s mode %d fd %d", __func__, name, mode, fd); | 682 | debug("%s: %s mode %d fd %d", __func__, name, mode, fd); |
678 | 683 | ||
679 | /* Set the tunnel device operation mode */ | 684 | /* Bring interface up if it is not already */ |
680 | snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); | 685 | snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); |
681 | if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { | 686 | if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) |
682 | error("%s: socket: %s", __func__, strerror(errno)); | ||
683 | goto failed; | 687 | goto failed; |
684 | } | ||
685 | 688 | ||
686 | if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { | 689 | if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { |
687 | debug("%s: get interface %s flags: %s", __func__, | 690 | debug("%s: get interface %s flags: %s", __func__, |
@@ -689,19 +692,6 @@ tun_open(int tun, int mode) | |||
689 | goto failed; | 692 | goto failed; |
690 | } | 693 | } |
691 | 694 | ||
692 | /* Set interface mode if not already in correct mode */ | ||
693 | if ((mode == SSH_TUNMODE_ETHERNET && !(ifr.ifr_flags & IFF_LINK0)) || | ||
694 | (mode != SSH_TUNMODE_ETHERNET && (ifr.ifr_flags & IFF_LINK0))) { | ||
695 | ifr.ifr_flags &= ~IFF_UP; | ||
696 | ifr.ifr_flags ^= IFF_LINK0; | ||
697 | if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { | ||
698 | debug("%s: reset interface %s flags: %s", __func__, | ||
699 | ifr.ifr_name, strerror(errno)); | ||
700 | goto failed; | ||
701 | } | ||
702 | } | ||
703 | |||
704 | /* Bring interface up if it is not already */ | ||
705 | if (!(ifr.ifr_flags & IFF_UP)) { | 695 | if (!(ifr.ifr_flags & IFF_UP)) { |
706 | ifr.ifr_flags |= IFF_UP; | 696 | ifr.ifr_flags |= IFF_UP; |
707 | if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { | 697 | if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { |