stun

simple point to point tunnel
git clone git://git.2f30.org/stun
Log | Files | Refs | README

commit ed952c61cd79e4a49b75bea94e035111ae1a52a4
parent 92c5012bc36e097cc3a28c848c90fcf9b8ef1c6f
Author: sin <sin@2f30.org>
Date:   Wed, 23 Mar 2016 11:19:34 +0000

add primitive tap support for bsd

Diffstat:
Mstun.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 55 insertions(+), 12 deletions(-)

diff --git a/stun.c b/stun.c @@ -171,6 +171,10 @@ dummydec(EVP_CIPHER_CTX *ectx, unsigned char *plaintext, return len; } +int (*opendev)(char *); +int (*writedev)(int, unsigned char *, int); +int (*readdev)(int, unsigned char *, int); + #if defined(__linux__) int opentun(char *tundev) @@ -214,6 +218,35 @@ readtun(int fd, unsigned char *buf, int len) } #elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) int +opentap(char *tapdev) +{ + struct tuninfo ti; + int fd; + + fd = open(tapdev, O_RDWR); + if (fd < 0) + logerr("failed to open %s", tapdev); + if (ioctl(fd, TUNGIFINFO, &ti) < 0) + logerr("failed to set TUNGIFINFO on %s", tapdev); + ti.mtu = MTU - 14; + if (ioctl(fd, TUNSIFINFO, &ti) < 0) + logerr("failed to set TUNSIFINFO on %s", tapdev); + return fd; +} + +int +writetap(int fd, unsigned char *buf, int len) +{ + return write(fd, buf, len); +} + +int +readtap(int fd, unsigned char *buf, int len) +{ + return read(fd, buf, len); +} + +int opentun(char *tundev) { struct tuninfo ti; @@ -428,7 +461,7 @@ response(int netfd) } int -tunnel(int netfd, int tunfd) +tunnel(int netfd, int devfd) { unsigned char buf[MTU + AES_BLOCK_SIZE]; struct pollfd pfd[2]; @@ -436,7 +469,7 @@ tunnel(int netfd, int tunfd) pfd[0].fd = netfd; pfd[0].events = POLLIN; - pfd[1].fd = tunfd; + pfd[1].fd = devfd; pfd[1].events = POLLIN; for (;;) { ret = poll(pfd, 2, -1); @@ -447,10 +480,10 @@ tunnel(int netfd, int tunfd) logerr("bad fd in poll set"); if (pfd[0].revents & (POLLIN | POLLHUP)) if ((n = readnet(netfd, buf, MTU)) <= 0 || - (n = writetun(tunfd, buf, n)) <= 0) + (n = writedev(devfd, buf, n)) <= 0) return 1; if (pfd[1].revents & (POLLIN | POLLHUP)) - if ((n = readtun(tunfd, buf, MTU)) <= 0 || + if ((n = readdev(devfd, buf, MTU)) <= 0 || (n = writenet(netfd, buf, n)) <= 0) return 1; } @@ -458,7 +491,7 @@ tunnel(int netfd, int tunfd) } int -serversetup(int tunfd) +serversetup(int devfd) { struct addrinfo hints, *ai, *p; struct sockaddr_in remote; @@ -512,7 +545,7 @@ serversetup(int tunfd) continue; } - tunnel(netfd, tunfd); + tunnel(netfd, devfd); close(netfd); if (debug) logdbg("remote peer disconnected: %s", @@ -521,7 +554,7 @@ serversetup(int tunfd) } int -clientsetup(int tunfd) +clientsetup(int devfd) { struct addrinfo hints, *ai, *p; int ret, netfd; @@ -554,7 +587,7 @@ clientsetup(int tunfd) if (ret < 0) logerr("failed to respond to challenge"); - ret = tunnel(netfd, tunfd); + ret = tunnel(netfd, devfd); logwarn("connection to %s:%s dropped", host, port); close(netfd); return ret; @@ -601,7 +634,7 @@ int main(int argc, char *argv[]) { char *pw; - int tunfd; + int devfd; ARGBEGIN { case 'd': @@ -630,7 +663,17 @@ main(int argc, char *argv[]) daemonize(); openlog("stun", LOG_PID | LOG_NDELAY, LOG_DAEMON); - tunfd = opentun(argv[0]); + if (strstr(argv[0], "tun")) { + devfd = opentun(argv[0]); + opendev = opentun; + writedev = writetun; + readdev = readtun; + } else { + devfd = opentap(argv[0]); + opendev = opentap; + writedev = writetap; + readdev = readtap; + } pw = getenv("STUNPW"); if (!pw) @@ -640,10 +683,10 @@ main(int argc, char *argv[]) explicit_bzero(pw, strlen(pw)); if (sflag) - return serversetup(tunfd); + return serversetup(devfd); /* auto-reconnect client */ for (;;) { - clientsetup(tunfd); + clientsetup(devfd); sleep(1); } return 0;