summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-12-13 19:33:19 +1100
committerDamien Miller <djm@mindrot.org>2005-12-13 19:33:19 +1100
commit7b58e800364870d05630514945687d2f26e3c065 (patch)
treef8b436c13a767fcb014125513fe53b6bc0bde9a2 /misc.c
parent957d4e430ed40265cffc483abdc5b0e6a58c69ed (diff)
- reyk@cvs.openbsd.org 2005/12/08 18:34:11
[auth-options.c includes.h misc.c misc.h readconf.c servconf.c] [serverloop.c ssh.c ssh_config.5 sshd_config.5 configure.ac] two changes to the new ssh tunnel support. this breaks compatibility with the initial commit but is required for a portable approach. - make the tunnel id u_int and platform friendly, use predefined types. - support configuration of layer 2 (ethernet) or layer 3 (point-to-point, default) modes. configuration is done using the Tunnel (yes|point-to-point|ethernet|no) option is ssh_config(5) and restricted by the PermitTunnel (yes|point-to-point|ethernet|no) option in sshd_config(5). ok djm@, man page bits by jmc@
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c75
1 files changed, 54 insertions, 21 deletions
diff --git a/misc.c b/misc.c
index 9b23e2c37..4f41332f9 100644
--- a/misc.c
+++ b/misc.c
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26#include "includes.h" 26#include "includes.h"
27RCSID("$OpenBSD: misc.c,v 1.36 2005/12/06 22:38:27 reyk Exp $"); 27RCSID("$OpenBSD: misc.c,v 1.37 2005/12/08 18:34:11 reyk Exp $");
28 28
29#include "misc.h" 29#include "misc.h"
30#include "log.h" 30#include "log.h"
@@ -202,7 +202,7 @@ a2tun(const char *s, int *remote)
202 int tun; 202 int tun;
203 203
204 if (remote != NULL) { 204 if (remote != NULL) {
205 *remote = -1; 205 *remote = SSH_TUNID_ANY;
206 sp = xstrdup(s); 206 sp = xstrdup(s);
207 if ((ep = strchr(sp, ':')) == NULL) { 207 if ((ep = strchr(sp, ':')) == NULL) {
208 xfree(sp); 208 xfree(sp);
@@ -212,15 +212,15 @@ a2tun(const char *s, int *remote)
212 *remote = a2tun(ep, NULL); 212 *remote = a2tun(ep, NULL);
213 tun = a2tun(sp, NULL); 213 tun = a2tun(sp, NULL);
214 xfree(sp); 214 xfree(sp);
215 return (tun); 215 return (*remote == SSH_TUNID_ERR ? *remote : tun);
216 } 216 }
217 217
218 if (strcasecmp(s, "any") == 0) 218 if (strcasecmp(s, "any") == 0)
219 return (-1); 219 return (SSH_TUNID_ANY);
220 220
221 tun = strtonum(s, 0, INT_MAX, &errstr); 221 tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);
222 if (errstr != NULL || tun < -1) 222 if (errstr != NULL)
223 return (-2); 223 return (SSH_TUNID_ERR);
224 224
225 return (tun); 225 return (tun);
226} 226}
@@ -539,27 +539,60 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
539} 539}
540 540
541int 541int
542tun_open(int tun) 542tun_open(int tun, int mode)
543{ 543{
544 struct ifreq ifr;
544 char name[100]; 545 char name[100];
545 int i, fd; 546 int fd = -1, sock;
546 547
547 if (tun > -1) { 548 /* Open the tunnel device */
549 if (tun <= SSH_TUNID_MAX) {
548 snprintf(name, sizeof(name), "/dev/tun%d", tun); 550 snprintf(name, sizeof(name), "/dev/tun%d", tun);
549 if ((fd = open(name, O_RDWR)) >= 0) { 551 fd = open(name, O_RDWR);
550 debug("%s: %s: %d", __func__, name, fd); 552 } else if (tun == SSH_TUNID_ANY) {
551 return (fd); 553 for (tun = 100; tun >= 0; tun--) {
554 snprintf(name, sizeof(name), "/dev/tun%d", tun);
555 if ((fd = open(name, O_RDWR)) >= 0)
556 break;
552 } 557 }
553 } else { 558 } else {
554 for (i = 100; i >= 0; i--) { 559 debug("%s: invalid tunnel %u\n", __func__, tun);
555 snprintf(name, sizeof(name), "/dev/tun%d", i); 560 return (-1);
556 if ((fd = open(name, O_RDWR)) >= 0) { 561 }
557 debug("%s: %s: %d", __func__, name, fd); 562
558 return (fd); 563 if (fd < 0) {
559 } 564 debug("%s: %s open failed: %s", __func__, name, strerror(errno));
560 } 565 return (-1);
566 }
567
568 debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
569
570 /* Set the tunnel device operation mode */
571 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun);
572 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
573 goto failed;
574
575 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
576 goto failed;
577 if (mode == SSH_TUNMODE_ETHERNET) {
578 ifr.ifr_flags |= IFF_LINK0;
579 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
580 goto failed;
561 } 581 }
562 debug("%s: %s failed: %s", __func__, name, strerror(errno)); 582 ifr.ifr_flags |= IFF_UP;
583 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
584 goto failed;
585
586 close(sock);
587 return (fd);
588
589 failed:
590 if (fd >= 0)
591 close(fd);
592 if (sock >= 0)
593 close(sock);
594 debug("%s: failed to set %s mode %d: %s", __func__, name,
595 mode, strerror(errno));
563 return (-1); 596 return (-1);
564} 597}
565 598