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 }