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 ddd2b2db4..de7e1facd 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>
@@ -604,6 +605,8 @@ percent_expand(const char *string, ...)
604 /* %% case */ 605 /* %% case */
605 if (*string == '%') 606 if (*string == '%')
606 goto append; 607 goto append;
608 if (*string == '\0')
609 fatal("%s: invalid format", __func__);
607 for (j = 0; j < num_keys; j++) { 610 for (j = 0; j < num_keys; j++) {
608 if (strchr(keys[j].key, *string) != NULL) { 611 if (strchr(keys[j].key, *string) != NULL) {
609 i = strlcat(buf, keys[j].repl, sizeof(buf)); 612 i = strlcat(buf, keys[j].repl, sizeof(buf));
@@ -653,62 +656,63 @@ tun_open(int tun, int mode)
653 struct ifreq ifr; 656 struct ifreq ifr;
654 char name[100]; 657 char name[100];
655 int fd = -1, sock; 658 int fd = -1, sock;
659 const char *tunbase = "tun";
660
661 if (mode == SSH_TUNMODE_ETHERNET)
662 tunbase = "tap";
656 663
657 /* Open the tunnel device */ 664 /* Open the tunnel device */
658 if (tun <= SSH_TUNID_MAX) { 665 if (tun <= SSH_TUNID_MAX) {
659 snprintf(name, sizeof(name), "/dev/tun%d", tun); 666 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);
660 fd = open(name, O_RDWR); 667 fd = open(name, O_RDWR);
661 } else if (tun == SSH_TUNID_ANY) { 668 } else if (tun == SSH_TUNID_ANY) {
662 for (tun = 100; tun >= 0; tun--) { 669 for (tun = 100; tun >= 0; tun--) {
663 snprintf(name, sizeof(name), "/dev/tun%d", tun); 670 snprintf(name, sizeof(name), "/dev/%s%d",
671 tunbase, tun);
664 if ((fd = open(name, O_RDWR)) >= 0) 672 if ((fd = open(name, O_RDWR)) >= 0)
665 break; 673 break;
666 } 674 }
667 } else { 675 } else {
668 debug("%s: invalid tunnel %u", __func__, tun); 676 debug("%s: invalid tunnel %u", __func__, tun);
669 return (-1); 677 return -1;
670 } 678 }
671 679
672 if (fd < 0) { 680 if (fd < 0) {
673 debug("%s: %s open failed: %s", __func__, name, strerror(errno)); 681 debug("%s: %s open: %s", __func__, name, strerror(errno));
674 return (-1); 682 return -1;
675 } 683 }
676 684
677 debug("%s: %s mode %d fd %d", __func__, name, mode, fd); 685 debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
678 686
679 /* Set the tunnel device operation mode */ 687 /* Bring interface up if it is not already */
680 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); 688 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);
681 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 689 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
682 goto failed; 690 goto failed;
683 691
684 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) 692 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
685 goto failed; 693 debug("%s: get interface %s flags: %s", __func__,
686 694 ifr.ifr_name, strerror(errno));
687 /* Set interface mode */
688 ifr.ifr_flags &= ~IFF_UP;
689 if (mode == SSH_TUNMODE_ETHERNET)
690 ifr.ifr_flags |= IFF_LINK0;
691 else
692 ifr.ifr_flags &= ~IFF_LINK0;
693 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
694 goto failed; 695 goto failed;
696 }
695 697
696 /* Bring interface up */ 698 if (!(ifr.ifr_flags & IFF_UP)) {
697 ifr.ifr_flags |= IFF_UP; 699 ifr.ifr_flags |= IFF_UP;
698 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) 700 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
699 goto failed; 701 debug("%s: activate interface %s: %s", __func__,
702 ifr.ifr_name, strerror(errno));
703 goto failed;
704 }
705 }
700 706
701 close(sock); 707 close(sock);
702 return (fd); 708 return fd;
703 709
704 failed: 710 failed:
705 if (fd >= 0) 711 if (fd >= 0)
706 close(fd); 712 close(fd);
707 if (sock >= 0) 713 if (sock >= 0)
708 close(sock); 714 close(sock);
709 debug("%s: failed to set %s mode %d: %s", __func__, name, 715 return -1;
710 mode, strerror(errno));
711 return (-1);
712#else 716#else
713 error("Tunnel interfaces are not supported on this platform"); 717 error("Tunnel interfaces are not supported on this platform");
714 return (-1); 718 return (-1);
@@ -1107,7 +1111,7 @@ unix_listener(const char *path, int backlog, int unlink_first)
1107void 1111void
1108sock_set_v6only(int s) 1112sock_set_v6only(int s)
1109{ 1113{
1110#ifdef IPV6_V6ONLY 1114#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
1111 int on = 1; 1115 int on = 1;
1112 1116
1113 debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); 1117 debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);