2 * Copyright (c) 2006-2007 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #include <sys/types.h>
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
32 #define TUN_MAX_TRY 50
38 #include <sys/ioctl.h>
40 #include <linux/if_tun.h>
43 open_tun(const char *tun_device)
48 char *tunnel = "/dev/net/tun";
50 if ((tun_fd = open(tunnel, O_RDWR)) < 0) {
51 warn("open_tun: %s: %s", tunnel, strerror(errno));
55 memset(&ifreq, 0, sizeof(ifreq));
57 ifreq.ifr_flags = IFF_TUN;
59 if (tun_device != NULL) {
60 strncpy(ifreq.ifr_name, tun_device, IFNAMSIZ);
61 strncpy(if_name, tun_device, sizeof(if_name));
63 if (ioctl(tun_fd, TUNSETIFF, (void *) &ifreq) != -1) {
64 printf("Opened %s\n", ifreq.ifr_name);
69 warn("open_tun: ioctl[TUNSETIFF]: %s", strerror(errno));
73 for (i = 0; i < TUN_MAX_TRY; i++) {
74 snprintf(ifreq.ifr_name, IFNAMSIZ, "dns%d", i);
76 if (ioctl(tun_fd, TUNSETIFF, (void *) &ifreq) != -1) {
77 printf("Opened %s\n", ifreq.ifr_name);
78 snprintf(if_name, sizeof(if_name), "dns%d", i);
83 warn("open_tun: ioctl[TUNSETIFF]: %s", strerror(errno));
88 warn("open_tun: Couldn't set interface name");
96 open_tun(const char *tun_device)
102 if (tun_device != NULL) {
103 snprintf(tun_name, sizeof(tun_name), "/dev/%s", tun_device);
104 strncpy(if_name, tun_device, sizeof(if_name));
106 if ((tun_fd = open(tun_name, O_RDWR)) < 0) {
107 warn("open_tun: %s: %s", tun_name, strerror(errno));
111 printf("Opened %s\n", tun_name);
114 for (i = 0; i < TUN_MAX_TRY; i++) {
115 snprintf(tun_name, sizeof(tun_name), "/dev/tun%d", i);
117 if ((tun_fd = open(tun_name, O_RDWR)) >= 0) {
118 printf("Opened %s\n", tun_name);
119 snprintf(if_name, sizeof(if_name), "tun%d", i);
127 warn("open_tun: Failed to open tunneling device");
136 close_tun(int tun_fd)
143 write_tun(int tun_fd, char *data, int len)
145 #if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD)
148 #else /* !FREEBSD/DARWIN */
162 if (write(tun_fd, data, len) != len) {
170 read_tun(int tun_fd, char *buf, int len)
172 #if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD)
173 /* FreeBSD/Darwin/NetBSD has no header */
174 return read(tun_fd, buf + 4, len - 4) + 4;
176 return read(tun_fd, buf, len);
177 #endif /* !FREEBSD */
181 tun_setip(const char *ip)
185 if (inet_addr(ip) != INADDR_NONE) {
186 snprintf(cmdline, sizeof(cmdline),
187 "/sbin/ifconfig %s %s %s netmask 255.255.255.0",
192 printf("Setting IP of %s to %s\n", if_name, ip);
200 snprintf(cmdline, sizeof(cmdline),
201 "/sbin/route add %s/24 %s",
204 printf("Adding route %s/24 to %s\n", ip, ip);
206 return system(cmdline);
208 printf("Invalid IP: %s!\n", ip);
215 tun_setmtu(const int mtu)
219 if (mtu > 200 && mtu < 1500) {
220 snprintf(cmdline, sizeof(cmdline),
221 "/sbin/ifconfig %s mtu %d",
225 printf("Setting MTU of %s to %d\n", if_name, mtu);
226 return system(cmdline);
228 warn("MTU out of range: %d\n", mtu);