summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorsthen@openbsd.org <sthen@openbsd.org>2015-10-24 08:34:09 +0000
committerDamien Miller <djm@mindrot.org>2015-10-25 11:42:05 +1100
commita820a8618ec44735dabc688fab96fba38ad66bb2 (patch)
treeefb864a70778d67c9c5d4ccac4f64a2ccfda6558 /misc.c
parent66d2e229baa9fe57b868c373b05f7ff3bb20055b (diff)
upstream commit
Handle the split of tun(4) "link0" into tap(4) in ssh tun-forwarding. Adapted from portable (using separate devices for this is the normal case in most OS). ok djm@ Upstream-ID: 90facf4c59ce73d6741db1bc926e578ef465cd39
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c32
1 files changed, 11 insertions, 21 deletions
diff --git a/misc.c b/misc.c
index b6503abbb..b358a035e 100644
--- a/misc.c
+++ b/misc.c
@@ -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) {