commit 46117277d3218ec780839f7cb036ff4024eefb14
parent 8ea6d7e3d19a6d3f52ec3e801f2485118c51f8fa
Author: sin <sin@2f30.org>
Date: Tue, 12 Apr 2016 10:44:33 +0100
reorg
Diffstat:
M | Makefile | | | 7 | ++++--- |
M | config.mk | | | 2 | ++ |
A | dev_bsd.c | | | 88 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | dev_linux.c | | | 53 | +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | log.c | | | 57 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | stun.c | | | 291 | +------------------------------------------------------------------------------ |
A | stun.h | | | 41 | +++++++++++++++++++++++++++++++++++++++++ |
A | util.c | | | 99 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
8 files changed, 347 insertions(+), 291 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,8 +1,9 @@
include config.mk
DISTFILES = Makefile README WHATSNEW UNLICENSE arg.h \
- config.mk stun.8 stun.c
-OBJ = stun.o
+ config.mk dev_bsd.c dev_linux.c log.c stun.8 stun.c \
+ stun.h util.c
+OBJ = $(EXTRAOBJ) log.o stun.o util.o
BIN = stun
all: $(BIN)
@@ -10,7 +11,7 @@ all: $(BIN)
$(BIN): $(OBJ)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(OBJ) $(LDLIBS)
-stun.o: arg.h
+$(OBJ): stun.h
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
diff --git a/config.mk b/config.mk
@@ -9,8 +9,10 @@ LIB = /usr/local/lib
# BSD
CFLAGS = -std=c99 -Wall -I$(INC)
LDLIBS = -L$(LIB) -lcrypto
+EXTRAOBJ = dev_bsd.o
# Linux
#CFLAGS = -std=c99 -Wall -I$(INC)
#CPPFLAGS = -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
#LDLIBS = -L$(LIB) -lcrypto -lbsd
+#EXTRAOBJ = dev_linux.o
diff --git a/dev_bsd.c b/dev_bsd.c
@@ -0,0 +1,88 @@
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#include <net/if_tun.h>
+#elif defined(__DragonFly__)
+#include <net/tun/if_tun.h>
+#endif
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "stun.h"
+
+int
+opendev(char *dev)
+{
+ struct tuninfo ti;
+ int fd;
+
+ if ((fd = open(dev, O_RDWR)) < 0)
+ logerr("failed to open %s", dev);
+ if (ioctl(fd, TUNGIFINFO, &ti) < 0)
+ logerr("failed to set TUNGIFINFO on %s", dev);
+ if (devtype == TUNDEV)
+ ti.mtu = MAXPAYLOADLEN;
+ else
+ ti.mtu = MAXPAYLOADLEN - 14; /* make some room for ethernet header */
+ if (ioctl(fd, TUNSIFINFO, &ti) < 0)
+ logerr("failed to set TUNSIFINFO on %s", dev);
+ if (devtype == TUNDEV) {
+#if defined(TUNSIFHEAD)
+ int one = 1;
+ if (ioctl(fd, TUNSIFHEAD, &one) < 0)
+ logerr("failed to set TUNSIFHEAD on %s", dev);
+#endif
+ }
+ return fd;
+}
+
+int
+writedev(int fd, unsigned char *buf, int len)
+{
+ struct iovec iov[2];
+ uint32_t type = htonl(AF_INET);
+ int n;
+
+ switch (devtype) {
+ case TAPDEV:
+ return write(fd, buf, len);
+ case TUNDEV:
+ iov[0].iov_base = &type;
+ iov[0].iov_len = sizeof(type);
+ iov[1].iov_base = buf;
+ iov[1].iov_len = len;
+ n = writev(fd, iov, 2);
+ if (n > 0)
+ n -= sizeof(type);
+ break;
+ }
+ return n;
+}
+
+int
+readdev(int fd, unsigned char *buf, int len)
+{
+ struct iovec iov[2];
+ uint32_t type;
+ int n;
+
+ switch (devtype) {
+ case TAPDEV:
+ return read(fd, buf, len);
+ case TUNDEV:
+ iov[0].iov_base = &type;
+ iov[0].iov_len = sizeof(type);
+ iov[1].iov_base = buf;
+ iov[1].iov_len = len;
+ n = readv(fd, iov, 2);
+ if (n > 0)
+ n -= sizeof(type);
+ break;
+ }
+ return n;
+}
diff --git a/dev_linux.c b/dev_linux.c
@@ -0,0 +1,53 @@
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <linux/if_tun.h>
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "stun.h"
+
+int
+opendev(char *dev)
+{
+ struct ifreq ifr;
+ int fd, s;
+
+ if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
+ logerr("failed to open %s", "/dev/net/tun");
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = (devtype == TUNDEV ? IFF_TUN : IFF_TAP) | IFF_NO_PI;
+ strncpy(ifr.ifr_name, dev, IF_NAMESIZE);
+ ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
+ if (ioctl(fd, TUNSETIFF, &ifr) < 0)
+ logerr("failed to set TUNSETIFF on %s", dev);
+
+ /* dummy socket so we can manipulate the params */
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ logerr("failed to create socket");
+ if (devtype == TUNDEV)
+ ifr.ifr_mtu = MAXPAYLOADLEN;
+ else
+ ifr.ifr_mtu = MAXPAYLOADLEN - 14; /* make some room for ethernet header */
+ if (ioctl(s, SIOCSIFMTU, &ifr) < 0)
+ logerr("failed to set MTU on %s", dev);
+ close(s);
+
+ return fd;
+}
+
+int
+writedev(int fd, unsigned char *buf, int len)
+{
+ return write(fd, buf, len);
+}
+
+int
+readdev(int fd, unsigned char *buf, int len)
+{
+ return read(fd, buf, len);
+}
diff --git a/log.c b/log.c
@@ -0,0 +1,57 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+
+#include "stun.h"
+
+static void
+logmsg(int priority, char *msg, va_list ap)
+{
+ if (foreground) {
+ fputs("stun: ", stderr);
+ vfprintf(stderr, msg, ap);
+ fputc('\n', stderr);
+ } else {
+ vsyslog(priority, msg, ap);
+ }
+}
+
+void
+loginit(char *prog)
+{
+ openlog(prog, LOG_PID | LOG_NDELAY, LOG_DAEMON);
+}
+
+void
+logdbg(char *msg, ...)
+{
+ va_list ap;
+
+ if (debug) {
+ va_start(ap, msg);
+ logmsg(LOG_DAEMON | LOG_DEBUG, msg, ap);
+ va_end(ap);
+ }
+}
+
+void
+logwarn(char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ logmsg(LOG_DAEMON | LOG_WARNING, msg, ap);
+ va_end(ap);
+}
+
+void
+logerr(char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ logmsg(LOG_DAEMON | LOG_ERR, msg, ap);
+ va_end(ap);
+ exit(1);
+}
diff --git a/stun.c b/stun.c
@@ -42,20 +42,9 @@
*/
#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/socket.h>
-#include <net/if.h>
-#if defined(__linux__)
-#include <linux/if_tun.h>
-#include <bsd/stdlib.h>
-#elif defined(__OpenBSD__) || defined(__FreeBSD__)
-#include <net/if_tun.h>
-#elif defined(__DragonFly__)
-#include <net/tun/if_tun.h>
-#endif
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
@@ -63,41 +52,19 @@
#include <errno.h>
#include <fcntl.h>
-#include <grp.h>
#include <poll.h>
-#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <openssl/evp.h>
-#include "arg.h"
-
-#if defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__)
-#undef explicit_bzero
-#define explicit_bzero bzero
-#endif
-
-#define NOPRIVUSER "nobody"
-#define RCVTIMEO 250 /* in milliseconds */
-#define RECONNECTTIMEO 60 /* in seconds */
-#define HDRLEN 2
-#define MAXPAYLOADLEN 1424
-#define BADPKT 0x1000
-#define NROUNDS 100000
-#define DEFCIPHER "chacha20-poly1305"
-
-enum {
- TUNDEV,
- TAPDEV
-};
+#include "stun.h"
EVP_AEAD_CTX ectx, dctx;
const EVP_AEAD *aead;
@@ -112,258 +79,6 @@ int debug;
int foreground;
int sflag;
-void
-logmsg(int priority, char *msg, va_list ap)
-{
- if (foreground) {
- fputs("stun: ", stderr);
- vfprintf(stderr, msg, ap);
- fputc('\n', stderr);
- } else {
- vsyslog(priority, msg, ap);
- }
-}
-
-void
-logdbg(char *msg, ...)
-{
- va_list ap;
-
- if (debug) {
- va_start(ap, msg);
- logmsg(LOG_DAEMON | LOG_DEBUG, msg, ap);
- va_end(ap);
- }
-}
-
-void
-logwarn(char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- logmsg(LOG_DAEMON | LOG_WARNING, msg, ap);
- va_end(ap);
-}
-
-void
-logerr(char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- logmsg(LOG_DAEMON | LOG_ERR, msg, ap);
- va_end(ap);
- exit(1);
-}
-
-void
-pack16(unsigned char *buf, uint16_t n)
-{
- buf[0] = n >> 8 & 0xff;
- buf[1] = n & 0xff;
-}
-
-uint16_t
-unpack16(unsigned char *buf)
-{
- return buf[0] << 8 | buf[1];
-}
-
-void
-pack64(unsigned char *buf, uint64_t n)
-{
- buf[0] = n >> 56 & 0xff;
- buf[1] = n >> 48 & 0xff;
- buf[2] = n >> 40 & 0xff;
- buf[3] = n >> 32 & 0xff;
- buf[4] = n >> 24 & 0xff;
- buf[5] = n >> 16 & 0xff;
- buf[6] = n >> 8 & 0xff;
- buf[7] = n & 0xff;
-}
-
-uint64_t
-unpack64(unsigned char *buf)
-{
- return (uint64_t)buf[0] << 56 |
- (uint64_t)buf[1] << 48 |
- (uint64_t)buf[2] << 40 |
- (uint64_t)buf[3] << 32 |
- (uint64_t)buf[4] << 24 |
- (uint64_t)buf[5] << 16 |
- (uint64_t)buf[6] << 8 |
- (uint64_t)buf[7];
-}
-
-int
-writeall(int fd, void *buf, int len)
-{
- unsigned char *p = buf;
- int n, total = 0;
-
- while (len > 0) {
- n = write(fd, p + total, len);
- if (n <= 0)
- break;
- total += n;
- len -= n;
- }
- return total;
-}
-
-int
-readall(int fd, void *buf, int len)
-{
- unsigned char *p = buf;
- int n, total = 0;
-
- while (len > 0) {
- n = read(fd, p + total, len);
- if (n <= 0)
- break;
- total += n;
- len -= n;
- }
- return total;
-}
-
-void
-ms2tv(struct timeval *tv, long ms)
-{
- tv->tv_sec = ms / 1000;
- tv->tv_usec = (ms % 1000) * 1000;
-}
-
-void
-revokeprivs(void)
-{
- struct passwd *pw;
-
- if (!(pw = getpwnam(NOPRIVUSER)))
- logerr("no %s user", NOPRIVUSER);
- if (setgroups(1, &pw->pw_gid) < 0 ||
- setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0 ||
- setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)
- logerr("failed to revoke privs");
-}
-
-#if defined(__linux__)
-int
-opendev(char *dev)
-{
- struct ifreq ifr;
- int fd, s;
-
- if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
- logerr("failed to open %s", "/dev/net/tun");
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = (devtype == TUNDEV ? IFF_TUN : IFF_TAP) | IFF_NO_PI;
- strncpy(ifr.ifr_name, dev, IF_NAMESIZE);
- ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
- if (ioctl(fd, TUNSETIFF, &ifr) < 0)
- logerr("failed to set TUNSETIFF on %s", dev);
-
- /* dummy socket so we can manipulate the params */
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- logerr("failed to create socket");
- if (devtype == TUNDEV)
- ifr.ifr_mtu = MAXPAYLOADLEN;
- else
- ifr.ifr_mtu = MAXPAYLOADLEN - 14; /* make some room for ethernet header */
- if (ioctl(s, SIOCSIFMTU, &ifr) < 0)
- logerr("failed to set MTU on %s", dev);
- close(s);
-
- return fd;
-}
-
-int
-writedev(int fd, unsigned char *buf, int len)
-{
- return write(fd, buf, len);
-}
-
-int
-readdev(int fd, unsigned char *buf, int len)
-{
- return read(fd, buf, len);
-}
-#elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__)
-int
-opendev(char *dev)
-{
- struct tuninfo ti;
- int fd;
-
- if ((fd = open(dev, O_RDWR)) < 0)
- logerr("failed to open %s", dev);
- if (ioctl(fd, TUNGIFINFO, &ti) < 0)
- logerr("failed to set TUNGIFINFO on %s", dev);
- if (devtype == TUNDEV)
- ti.mtu = MAXPAYLOADLEN;
- else
- ti.mtu = MAXPAYLOADLEN - 14; /* make some room for ethernet header */
- if (ioctl(fd, TUNSIFINFO, &ti) < 0)
- logerr("failed to set TUNSIFINFO on %s", dev);
- if (devtype == TUNDEV) {
-#if defined(TUNSIFHEAD)
- int one = 1;
- if (ioctl(fd, TUNSIFHEAD, &one) < 0)
- logerr("failed to set TUNSIFHEAD on %s", dev);
-#endif
- }
- return fd;
-}
-
-int
-writedev(int fd, unsigned char *buf, int len)
-{
- struct iovec iov[2];
- uint32_t type = htonl(AF_INET);
- int n;
-
- switch (devtype) {
- case TAPDEV:
- return write(fd, buf, len);
- case TUNDEV:
- iov[0].iov_base = &type;
- iov[0].iov_len = sizeof(type);
- iov[1].iov_base = buf;
- iov[1].iov_len = len;
- n = writev(fd, iov, 2);
- if (n > 0)
- n -= sizeof(type);
- break;
- }
- return n;
-}
-
-int
-readdev(int fd, unsigned char *buf, int len)
-{
- struct iovec iov[2];
- uint32_t type;
- int n;
-
- switch (devtype) {
- case TAPDEV:
- return read(fd, buf, len);
- case TUNDEV:
- iov[0].iov_base = &type;
- iov[0].iov_len = sizeof(type);
- iov[1].iov_base = buf;
- iov[1].iov_len = len;
- n = readv(fd, iov, 2);
- if (n > 0)
- n -= sizeof(type);
- break;
- }
- return n;
-}
-#endif
-
int
writenet(int fd, unsigned char *pt, int ptlen)
{
@@ -755,7 +470,7 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
if (!foreground) {
daemon(0, 0);
- openlog("stun", LOG_PID | LOG_NDELAY, LOG_DAEMON);
+ loginit("stun");
}
devfd = opendev(argv[0]);
@@ -767,7 +482,7 @@ main(int argc, char *argv[])
if (!(pw = getenv("STUNPW")))
logerr("STUNPW is not set");
aeadinit(pw);
- explicit_bzero(pw, strlen(pw));
+ bzero(pw, strlen(pw));
if (sflag)
return serversetup(devfd);
diff --git a/stun.h b/stun.h
@@ -0,0 +1,41 @@
+#include "arg.h"
+
+#define NOPRIVUSER "nobody"
+#define RCVTIMEO 250 /* in milliseconds */
+#define RECONNECTTIMEO 60 /* in seconds */
+#define HDRLEN 2
+#define MAXPAYLOADLEN 1424
+#define BADPKT 0x1000
+#define NROUNDS 100000
+#define DEFCIPHER "chacha20-poly1305"
+
+enum {
+ TUNDEV,
+ TAPDEV
+};
+
+/* stun.c */
+extern int devtype;
+extern int debug;
+extern int foreground;
+
+/* dev_*.c */
+int opendev(char *);
+int writedev(int, unsigned char *, int);
+int readdev(int, unsigned char *, int);
+
+/* log.c */
+void loginit(char *);
+void logdbg(char *, ...);
+void logwarn(char *, ...);
+void logerr(char *, ...);
+
+/* util.c */
+void pack16(unsigned char *, uint16_t);
+uint16_t unpack16(unsigned char *);
+void pack64(unsigned char *, uint64_t);
+uint64_t unpack64(unsigned char *);
+int writeall(int, void *, int);
+int readall(int, void *, int);
+void ms2tv(struct timeval *, long);
+void revokeprivs(void);
diff --git a/util.c b/util.c
@@ -0,0 +1,99 @@
+#include <sys/types.h>
+
+#include <grp.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "stun.h"
+
+void
+pack16(unsigned char *buf, uint16_t n)
+{
+ buf[0] = n >> 8 & 0xff;
+ buf[1] = n & 0xff;
+}
+
+uint16_t
+unpack16(unsigned char *buf)
+{
+ return buf[0] << 8 | buf[1];
+}
+
+void
+pack64(unsigned char *buf, uint64_t n)
+{
+ buf[0] = n >> 56 & 0xff;
+ buf[1] = n >> 48 & 0xff;
+ buf[2] = n >> 40 & 0xff;
+ buf[3] = n >> 32 & 0xff;
+ buf[4] = n >> 24 & 0xff;
+ buf[5] = n >> 16 & 0xff;
+ buf[6] = n >> 8 & 0xff;
+ buf[7] = n & 0xff;
+}
+
+uint64_t
+unpack64(unsigned char *buf)
+{
+ return (uint64_t)buf[0] << 56 |
+ (uint64_t)buf[1] << 48 |
+ (uint64_t)buf[2] << 40 |
+ (uint64_t)buf[3] << 32 |
+ (uint64_t)buf[4] << 24 |
+ (uint64_t)buf[5] << 16 |
+ (uint64_t)buf[6] << 8 |
+ (uint64_t)buf[7];
+}
+
+int
+writeall(int fd, void *buf, int len)
+{
+ unsigned char *p = buf;
+ int n, total = 0;
+
+ while (len > 0) {
+ n = write(fd, p + total, len);
+ if (n <= 0)
+ break;
+ total += n;
+ len -= n;
+ }
+ return total;
+}
+
+int
+readall(int fd, void *buf, int len)
+{
+ unsigned char *p = buf;
+ int n, total = 0;
+
+ while (len > 0) {
+ n = read(fd, p + total, len);
+ if (n <= 0)
+ break;
+ total += n;
+ len -= n;
+ }
+ return total;
+}
+
+void
+ms2tv(struct timeval *tv, long ms)
+{
+ tv->tv_sec = ms / 1000;
+ tv->tv_usec = (ms % 1000) * 1000;
+}
+
+void
+revokeprivs(void)
+{
+ struct passwd *pw;
+
+ if (!(pw = getpwnam(NOPRIVUSER)))
+ logerr("no %s user", NOPRIVUSER);
+ if (setgroups(1, &pw->pw_gid) < 0 ||
+ setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0 ||
+ setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)
+ logerr("failed to revoke privs");
+}