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:
M | stun.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;