4 * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
5 * featured implementation uAnytun has no support for multiple connections
6 * or synchronisation. It is a small single threaded implementation intended
7 * to act as a client on small platforms.
8 * The secure anycast tunneling protocol (satp) defines a protocol used
9 * for communication between any combination of unicast and anycast
10 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
11 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
12 * ethernet, ip, arp ...). satp directly includes cryptography and
13 * message authentication based on the methodes used by SRTP. It is
14 * intended to deliver a generic, scaleable and secure solution for
15 * tunneling and relaying of packets of any protocol.
18 * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org>
20 * This file is part of uAnytun.
22 * uAnytun is free software: you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 3 as
24 * published by the Free Software Foundation.
26 * uAnytun is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
37 #include "datatypes.h"
41 #include "tun_helper.h"
47 #include <sys/ioctl.h>
48 #include <arpa/inet.h>
52 #include <linux/if_ether.h>
53 #include <linux/if_tun.h>
54 #define DEFAULT_DEVICE "/dev/net/tun"
58 int tun_init(tun_device_t* dev, const char* dev_name, const char* dev_type, const char* ifcfg_addr, u_int16_t ifcfg_prefix){
62 tun_conf(dev, dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400);
63 dev->actual_name_ = NULL;
65 dev->fd_ = open(DEFAULT_DEVICE, O_RDWR);
67 log_printf(ERROR, "can't open device file (%s): %s", DEFAULT_DEVICE, strerror(errno));
73 memset(&ifr, 0, sizeof(ifr));
75 if(dev->type_ == TYPE_TUN) {
76 ifr.ifr_flags = IFF_TUN;
79 else if(dev->type_ == TYPE_TAP) {
80 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
84 log_printf(ERROR, "unable to recognize type of device (tun or tap)");
90 strncpy(ifr.ifr_name, dev_name, IFNAMSIZ);
92 if(!ioctl(dev->fd_, TUNSETIFF, &ifr)) {
93 dev->actual_name_ = strdup(ifr.ifr_name);
94 } else if(!ioctl(dev->fd_, (('T' << 8) | 202), &ifr)) {
95 dev->actual_name_ = strdup(ifr.ifr_name);
97 log_printf(ERROR, "tun/tap device ioctl failed: %s", strerror(errno));
102 if(!dev->actual_name_) {
103 log_printf(ERROR, "can't open device file: memory error");
109 tun_do_ifconfig(dev);
114 int tun_init_post(tun_device_t* dev)
119 void tun_close(tun_device_t* dev)
127 if(dev->actual_name_)
128 free(dev->actual_name_);
131 free(dev->net_addr_);
134 free(dev->net_mask_);
137 int tun_read(tun_device_t* dev, u_int8_t* buf, u_int32_t len)
139 if(!dev || dev->fd_ < 0)
147 iov[0].iov_base = &tpi;
148 iov[0].iov_len = sizeof(tpi);
149 iov[1].iov_base = buf;
150 iov[1].iov_len = len;
151 return(tun_fix_return(readv(dev->fd_, iov, 2), sizeof(tpi)));
154 return(read(dev->fd_, buf, len));
157 int tun_write(tun_device_t* dev, u_int8_t* buf, u_int32_t len)
159 if(!dev || dev->fd_ < 0)
169 struct iphdr *hdr = (struct iphdr *)buf;
172 if(hdr->version == 4)
173 tpi.proto = htons(ETH_P_IP);
175 tpi.proto = htons(ETH_P_IPV6);
177 iov[0].iov_base = &tpi;
178 iov[0].iov_len = sizeof(tpi);
179 iov[1].iov_base = buf;
180 iov[1].iov_len = len;
181 return(tun_fix_return(writev(dev->fd_, iov, 2), sizeof(tpi)));
184 return(write(dev->fd_, buf, len));
187 void tun_do_ifconfig(tun_device_t* dev)
189 if(!dev || !dev->actual_name_ || !dev->net_addr_ || !dev->net_mask_)
192 char* command = NULL;
193 asprintf(&command, "/sbin/ifconfig %s %s netmask %s mtu %d", dev->actual_name_, dev->net_addr_, dev->net_mask_, dev->mtu_);
195 log_printf(ERROR, "Execution of ifconfig failed");
199 int result = system(command);
201 log_printf(ERROR, "Execution of ifconfig failed");
203 log_printf(NOTICE, "ifconfig returned %d", WEXITSTATUS(result));