summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c58
1 files changed, 31 insertions, 27 deletions
diff --git a/misc.c b/misc.c
index 1c063ea42..5704fa6c4 100644
--- a/misc.c
+++ b/misc.c
@@ -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.101 2016/01/20 09:22:39 dtucker 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.
@@ -29,6 +29,7 @@
29#include <sys/types.h> 29#include <sys/types.h>
30#include <sys/ioctl.h> 30#include <sys/ioctl.h>
31#include <sys/socket.h> 31#include <sys/socket.h>
32#include <sys/time.h>
32#include <sys/un.h> 33#include <sys/un.h>
33 34
34#include <limits.h> 35#include <limits.h>
@@ -606,6 +607,8 @@ percent_expand(const char *string, ...)
606 /* %% case */ 607 /* %% case */
607 if (*string == '%') 608 if (*string == '%')
608 goto append; 609 goto append;
610 if (*string == '\0')
611 fatal("%s: invalid format", __func__);
609 for (j = 0; j < num_keys; j++) { 612 for (j = 0; j < num_keys; j++) {
610 if (strchr(keys[j].key, *string) != NULL) { 613 if (strchr(keys[j].key, *string) != NULL) {
611 i = strlcat(buf, keys[j].repl, sizeof(buf)); 614 i = strlcat(buf, keys[j].repl, sizeof(buf));
@@ -720,62 +723,63 @@ tun_open(int tun, int mode)
720 struct ifreq ifr; 723 struct ifreq ifr;
721 char name[100]; 724 char name[100];
722 int fd = -1, sock; 725 int fd = -1, sock;
726 const char *tunbase = "tun";
727
728 if (mode == SSH_TUNMODE_ETHERNET)
729 tunbase = "tap";
723 730
724 /* Open the tunnel device */ 731 /* Open the tunnel device */
725 if (tun <= SSH_TUNID_MAX) { 732 if (tun <= SSH_TUNID_MAX) {
726 snprintf(name, sizeof(name), "/dev/tun%d", tun); 733 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);
727 fd = open(name, O_RDWR); 734 fd = open(name, O_RDWR);
728 } else if (tun == SSH_TUNID_ANY) { 735 } else if (tun == SSH_TUNID_ANY) {
729 for (tun = 100; tun >= 0; tun--) { 736 for (tun = 100; tun >= 0; tun--) {
730 snprintf(name, sizeof(name), "/dev/tun%d", tun); 737 snprintf(name, sizeof(name), "/dev/%s%d",
738 tunbase, tun);
731 if ((fd = open(name, O_RDWR)) >= 0) 739 if ((fd = open(name, O_RDWR)) >= 0)
732 break; 740 break;
733 } 741 }
734 } else { 742 } else {
735 debug("%s: invalid tunnel %u", __func__, tun); 743 debug("%s: invalid tunnel %u", __func__, tun);
736 return (-1); 744 return -1;
737 } 745 }
738 746
739 if (fd < 0) { 747 if (fd < 0) {
740 debug("%s: %s open failed: %s", __func__, name, strerror(errno)); 748 debug("%s: %s open: %s", __func__, name, strerror(errno));
741 return (-1); 749 return -1;
742 } 750 }
743 751
744 debug("%s: %s mode %d fd %d", __func__, name, mode, fd); 752 debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
745 753
746 /* Set the tunnel device operation mode */ 754 /* Bring interface up if it is not already */
747 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); 755 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);
748 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 756 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
749 goto failed; 757 goto failed;
750 758
751 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) 759 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
752 goto failed; 760 debug("%s: get interface %s flags: %s", __func__,
753 761 ifr.ifr_name, strerror(errno));
754 /* Set interface mode */
755 ifr.ifr_flags &= ~IFF_UP;
756 if (mode == SSH_TUNMODE_ETHERNET)
757 ifr.ifr_flags |= IFF_LINK0;
758 else
759 ifr.ifr_flags &= ~IFF_LINK0;
760 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
761 goto failed; 762 goto failed;
763 }
762 764
763 /* Bring interface up */ 765 if (!(ifr.ifr_flags & IFF_UP)) {
764 ifr.ifr_flags |= IFF_UP; 766 ifr.ifr_flags |= IFF_UP;
765 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) 767 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
766 goto failed; 768 debug("%s: activate interface %s: %s", __func__,
769 ifr.ifr_name, strerror(errno));
770 goto failed;
771 }
772 }
767 773
768 close(sock); 774 close(sock);
769 return (fd); 775 return fd;
770 776
771 failed: 777 failed:
772 if (fd >= 0) 778 if (fd >= 0)
773 close(fd); 779 close(fd);
774 if (sock >= 0) 780 if (sock >= 0)
775 close(sock); 781 close(sock);
776 debug("%s: failed to set %s mode %d: %s", __func__, name, 782 return -1;
777 mode, strerror(errno));
778 return (-1);
779#else 783#else
780 error("Tunnel interfaces are not supported on this platform"); 784 error("Tunnel interfaces are not supported on this platform");
781 return (-1); 785 return (-1);
@@ -1174,7 +1178,7 @@ unix_listener(const char *path, int backlog, int unlink_first)
1174void 1178void
1175sock_set_v6only(int s) 1179sock_set_v6only(int s)
1176{ 1180{
1177#ifdef IPV6_V6ONLY 1181#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
1178 int on = 1; 1182 int on = 1;
1179 1183
1180 debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); 1184 debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);