- reyk@cvs.openbsd.org 2005/12/06 22:38:28
[auth-options.c auth-options.h channels.c channels.h clientloop.c]
[misc.c misc.h readconf.c readconf.h scp.c servconf.c servconf.h]
[serverloop.c sftp.c ssh.1 ssh.c ssh_config ssh_config.5 sshconnect.c]
[sshconnect.h sshd.8 sshd_config sshd_config.5]
Add support for tun(4) forwarding over OpenSSH, based on an idea and
initial channel code bits by markus@. This is a simple and easy way to
use OpenSSH for ad hoc virtual private network connections, e.g.
administrative tunnels or secure wireless access. It's based on a new
ssh channel and works similar to the existing TCP forwarding support,
except that it depends on the tun(4) network interface on both ends of
the connection for layer 2 or layer 3 tunneling. This diff also adds
support for LocalCommand in the ssh(1) client.
ok djm@, markus@, jmc@ (manpages), tested and discussed with others
diff --git a/misc.c b/misc.c
index 27b947f..9b23e2c 100644
--- a/misc.c
+++ b/misc.c
@@ -24,7 +24,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.35 2005/09/13 23:40:07 djm Exp $");
+RCSID("$OpenBSD: misc.c,v 1.36 2005/12/06 22:38:27 reyk Exp $");
#include "misc.h"
#include "log.h"
@@ -194,6 +194,37 @@
return port;
}
+int
+a2tun(const char *s, int *remote)
+{
+ const char *errstr = NULL;
+ char *sp, *ep;
+ int tun;
+
+ if (remote != NULL) {
+ *remote = -1;
+ sp = xstrdup(s);
+ if ((ep = strchr(sp, ':')) == NULL) {
+ xfree(sp);
+ return (a2tun(s, NULL));
+ }
+ ep[0] = '\0'; ep++;
+ *remote = a2tun(ep, NULL);
+ tun = a2tun(sp, NULL);
+ xfree(sp);
+ return (tun);
+ }
+
+ if (strcasecmp(s, "any") == 0)
+ return (-1);
+
+ tun = strtonum(s, 0, INT_MAX, &errstr);
+ if (errstr != NULL || tun < -1)
+ return (-2);
+
+ return (tun);
+}
+
#define SECONDS 1
#define MINUTES (SECONDS * 60)
#define HOURS (MINUTES * 60)
@@ -507,6 +538,31 @@
return -1;
}
+int
+tun_open(int tun)
+{
+ char name[100];
+ int i, fd;
+
+ if (tun > -1) {
+ snprintf(name, sizeof(name), "/dev/tun%d", tun);
+ if ((fd = open(name, O_RDWR)) >= 0) {
+ debug("%s: %s: %d", __func__, name, fd);
+ return (fd);
+ }
+ } else {
+ for (i = 100; i >= 0; i--) {
+ snprintf(name, sizeof(name), "/dev/tun%d", i);
+ if ((fd = open(name, O_RDWR)) >= 0) {
+ debug("%s: %s: %d", __func__, name, fd);
+ return (fd);
+ }
+ }
+ }
+ debug("%s: %s failed: %s", __func__, name, strerror(errno));
+ return (-1);
+}
+
void
sanitise_stdfd(void)
{