diff options
-rw-r--r-- | misc.c | 55 |
1 files changed, 33 insertions, 22 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.97 2015/04/24 01:36:00 deraadt Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.98 2015/10/07 00:54:06 djm 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. |
@@ -666,49 +666,60 @@ tun_open(int tun, int mode) | |||
666 | } | 666 | } |
667 | } else { | 667 | } else { |
668 | debug("%s: invalid tunnel %u", __func__, tun); | 668 | debug("%s: invalid tunnel %u", __func__, tun); |
669 | return (-1); | 669 | return -1; |
670 | } | 670 | } |
671 | 671 | ||
672 | if (fd < 0) { | 672 | if (fd < 0) { |
673 | debug("%s: %s open failed: %s", __func__, name, strerror(errno)); | 673 | debug("%s: %s open: %s", __func__, name, strerror(errno)); |
674 | return (-1); | 674 | return -1; |
675 | } | 675 | } |
676 | 676 | ||
677 | debug("%s: %s mode %d fd %d", __func__, name, mode, fd); | 677 | debug("%s: %s mode %d fd %d", __func__, name, mode, fd); |
678 | 678 | ||
679 | /* Set the tunnel device operation mode */ | 679 | /* Set the tunnel device operation mode */ |
680 | snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); | 680 | snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); |
681 | if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) | 681 | if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { |
682 | error("%s: socket: %s", __func__, strerror(errno)); | ||
682 | goto failed; | 683 | goto failed; |
684 | } | ||
683 | 685 | ||
684 | if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) | 686 | if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { |
687 | debug("%s: get interface %s flags: %s", __func__, | ||
688 | ifr.ifr_name, strerror(errno)); | ||
685 | goto failed; | 689 | goto failed; |
690 | } | ||
686 | 691 | ||
687 | /* Set interface mode */ | 692 | /* Set interface mode if not already in correct mode */ |
688 | ifr.ifr_flags &= ~IFF_UP; | 693 | if ((mode == SSH_TUNMODE_ETHERNET && !(ifr.ifr_flags & IFF_LINK0)) || |
689 | if (mode == SSH_TUNMODE_ETHERNET) | 694 | (mode != SSH_TUNMODE_ETHERNET && (ifr.ifr_flags & IFF_LINK0))) { |
690 | ifr.ifr_flags |= IFF_LINK0; | 695 | ifr.ifr_flags &= ~IFF_UP; |
691 | else | 696 | ifr.ifr_flags ^= IFF_LINK0; |
692 | ifr.ifr_flags &= ~IFF_LINK0; | 697 | if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { |
693 | if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) | 698 | debug("%s: reset interface %s flags: %s", __func__, |
694 | goto failed; | 699 | ifr.ifr_name, strerror(errno)); |
700 | goto failed; | ||
701 | } | ||
702 | } | ||
695 | 703 | ||
696 | /* Bring interface up */ | 704 | /* Bring interface up if it is not already */ |
697 | ifr.ifr_flags |= IFF_UP; | 705 | if (!(ifr.ifr_flags & IFF_UP)) { |
698 | if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) | 706 | ifr.ifr_flags |= IFF_UP; |
699 | goto failed; | 707 | if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { |
708 | debug("%s: activate interface %s: %s", __func__, | ||
709 | ifr.ifr_name, strerror(errno)); | ||
710 | goto failed; | ||
711 | } | ||
712 | } | ||
700 | 713 | ||
701 | close(sock); | 714 | close(sock); |
702 | return (fd); | 715 | return fd; |
703 | 716 | ||
704 | failed: | 717 | failed: |
705 | if (fd >= 0) | 718 | if (fd >= 0) |
706 | close(fd); | 719 | close(fd); |
707 | if (sock >= 0) | 720 | if (sock >= 0) |
708 | close(sock); | 721 | close(sock); |
709 | debug("%s: failed to set %s mode %d: %s", __func__, name, | 722 | return -1; |
710 | mode, strerror(errno)); | ||
711 | return (-1); | ||
712 | #else | 723 | #else |
713 | error("Tunnel interfaces are not supported on this platform"); | 724 | error("Tunnel interfaces are not supported on this platform"); |
714 | return (-1); | 725 | return (-1); |