stun

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

dev_bsd.c (1822B)


      1 #include <sys/types.h>
      2 #include <sys/uio.h>
      3 #include <sys/ioctl.h>
      4 #include <sys/socket.h>
      5 
      6 #include <net/if.h>
      7 #if defined(__OpenBSD__) || defined(__FreeBSD__)
      8 #include <net/if_tun.h>
      9 #elif defined(__DragonFly__)
     10 #include <net/tun/if_tun.h>
     11 #endif
     12 #include <netinet/in.h>
     13 
     14 #include <fcntl.h>
     15 #include <libgen.h>
     16 #include <limits.h>
     17 #include <stdio.h>
     18 #include <unistd.h>
     19 
     20 #include "warp.h"
     21 
     22 int
     23 devopen(char *ifname)
     24 {
     25 	char dev[PATH_MAX];
     26 	struct tuninfo ti;
     27 	int fd;
     28 
     29 	snprintf(dev, sizeof(dev), "/dev/%s", basename(ifname));
     30 	if ((fd = open(dev, O_RDWR)) < 0)
     31 		fatal("open %s", dev);
     32 	if (ioctl(fd, TUNGIFINFO, &ti) < 0)
     33 		fatal("TUNGIFINFO %s", dev);
     34 	if (devtype == TUNDEV)
     35 		ti.mtu = MAXPAYLOADLEN;
     36 	else
     37 		ti.mtu = MAXPAYLOADLEN - 14; /* make room for ethernet header */
     38 	if (ioctl(fd, TUNSIFINFO, &ti) < 0)
     39 		fatal("TUNSIFINFO %s", dev);
     40 	if (devtype == TUNDEV) {
     41 #if defined(TUNSIFHEAD)
     42 		int one = 1;
     43 		if (ioctl(fd, TUNSIFHEAD, &one) < 0)
     44 			fatal("TUNSIFHEAD %s", dev);
     45 #endif
     46 	}
     47 	return fd;
     48 }
     49 
     50 int
     51 devwrite(int fd, unsigned char *buf, int len)
     52 {
     53 	struct iovec iov[2];
     54 	uint32_t type;
     55 	int n, af;
     56 
     57 	switch (devtype) {
     58 	case TAPDEV:
     59 		return write(fd, buf, len);
     60 	case TUNDEV:
     61 		if ((af = ipversion(buf)) < 0)
     62 			return -1;
     63 		type = htonl(af);
     64 		iov[0].iov_base = &type;
     65 		iov[0].iov_len = sizeof(type);
     66 		iov[1].iov_base = buf;
     67 		iov[1].iov_len = len;
     68 		n = writev(fd, iov, 2);
     69 		if (n > 0)
     70 			n -= sizeof(type);
     71 		break;
     72 	}
     73 	return n;
     74 }
     75 
     76 int
     77 devread(int fd, unsigned char *buf, int len)
     78 {
     79 	struct iovec iov[2];
     80 	uint32_t type;
     81 	int n;
     82 
     83 	switch (devtype) {
     84 	case TAPDEV:
     85 		return read(fd, buf, len);
     86 	case TUNDEV:
     87 		iov[0].iov_base = &type;
     88 		iov[0].iov_len = sizeof(type);
     89 		iov[1].iov_base = buf;
     90 		iov[1].iov_len = len;
     91 		n = readv(fd, iov, 2);
     92 		if (n > 0)
     93 			n -= sizeof(type);
     94 		break;
     95 	}
     96 	return n;
     97 }