51#include <sys/socket.h>
56#define LOG_MODULE "Tun6"
57#define LOG_LEVEL LOG_LEVEL_WARN
61#include <linux/if_tun.h>
68static const char *config_ipaddr =
"fd00::1/64";
70static char config_tundev[IFNAMSIZ + 1] =
"tun0";
75static int set_fd(fd_set *rset, fd_set *wset);
76static void handle_fd(fd_set *rset, fd_set *wset);
77static const struct select_callback tun_select_callback = {
82static int ssystem(
const char *fmt, ...)
83 __attribute__((__format__ (__printf__, 1, 2)));
86static ssystem(const
char *fmt, ...)
91 vsnprintf(cmd,
sizeof(cmd), fmt, ap);
93 LOG_INFO(
"%s\n", cmd);
102#define TMPBUFSIZE 128
104 char buf[TMPBUFSIZE];
105 strcpy(buf,
"ifconfig ");
107 buf[TMPBUFSIZE - 1] =
'\0';
108 strncat(buf, config_tundev, TMPBUFSIZE - strlen(buf) - 1);
109 strncat(buf,
" down", TMPBUFSIZE - strlen(buf) - 1);
112 system(
"sysctl -w net.ipv6.conf.all.forwarding=1");
114 strcpy(buf,
"netstat -nr"
115 " | awk '{ if ($2 == \"");
116 buf[TMPBUFSIZE - 1] =
'\0';
117 strncat(buf, config_tundev, TMPBUFSIZE - strlen(buf) - 1);
118 strncat(buf,
"\") print \"route delete -net \"$1; }'"
119 " | sh", TMPBUFSIZE - strlen(buf) - 1);
127 const char *prefix =
"signal ";
129 signo == SIGHUP ?
"HUP\n" : signo == SIGTERM ?
"TERM\n" :
"INT\n";
130 write(fileno(stderr), prefix, strlen(prefix));
131 write(fileno(stderr), sig, strlen(sig));
138ifconf(
const char *tundev,
const char *
ipaddr)
141 ssystem(
"ifconfig %s inet `hostname` up", tundev);
142 ssystem(
"ifconfig %s add %s", tundev,
ipaddr);
143#elif defined(__APPLE__)
144 ssystem(
"ifconfig %s inet6 %s up", tundev,
ipaddr);
145 ssystem(
"sysctl -w net.inet.ip.forwarding=1");
147 ssystem(
"ifconfig %s inet `hostname` %s up", tundev,
ipaddr);
148 ssystem(
"sysctl -w net.inet.ip.forwarding=1");
152 ssystem(
"ifconfig %s\n", tundev);
157tun_alloc(
char *dev, uint16_t devsize)
161 LOG_INFO(
"Opening: %s\n", dev);
162 if( (fd = open(
"/dev/net/tun", O_RDWR)) < 0 ) {
167 memset(&ifr, 0,
sizeof(ifr));
172 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
174 memcpy(ifr.ifr_name, dev, MIN(
sizeof(ifr.ifr_name), devsize));
176 if((err = ioctl(fd, TUNSETIFF, (
void *) &ifr)) < 0 ) {
182 LOG_INFO(
"Using '%s' vs '%s'\n", dev, ifr.ifr_name);
183 strncpy(dev, ifr.ifr_name, MIN(devsize - 1,
sizeof(ifr.ifr_name)));
184 dev[devsize - 1] =
'\0';
185 LOG_INFO(
"Using %s\n", dev);
190devopen(
const char *dev,
int flags)
194 strncat(t, dev,
sizeof(t) - 5);
195 return open(t, flags);
199tun_alloc(
char *dev, uint16_t devsize)
201 LOG_INFO(
"Opening: %s\n", dev);
202 return devopen(dev, O_RDWR);
209 setvbuf(stdout, NULL, _IOLBF, 0);
211 LOG_INFO(
"Initializing tun interface\n");
213 tunfd = tun_alloc(config_tundev,
sizeof(config_tundev));
215 LOG_WARN(
"Failed to open tun device (you may be lacking permission). Running without network.\n");
220 LOG_INFO(
"Tun open:%d\n", tunfd);
222 select_set_callback(tunfd, &tun_select_callback);
224 fprintf(stderr,
"opened %s device ``/dev/%s''\n",
225 "tun", config_tundev);
228 signal(SIGHUP, sigcleanup);
229 signal(SIGTERM, sigcleanup);
230 signal(SIGINT, sigcleanup);
231 ifconf(config_tundev, config_ipaddr);
236tun_output(uint8_t *data,
int len)
239 if(tunfd != -1 && write(tunfd, data, len) != len) {
240 err(1,
"serial_to_tun: write");
246tun_input(
unsigned char *data,
int maxlen)
255 if((size = read(tunfd, data, maxlen)) == -1) {
256 err(1,
"tun_input: read");
263output(
const linkaddr_t *localdest)
276set_fd(fd_set *rset, fd_set *wset)
289handle_fd(fd_set *rset, fd_set *wset)
298 LOG_INFO(
"Tun6-handle FD\n");
300 if(FD_ISSET(tunfd, rset)) {
302 LOG_DBG(
"TUN data incoming read:%d\n", size);
308static void input(
void)
311 LOG_DBG(
"Tun6 - input\n");
#define CC_NORETURN
Configure if the C compiler supports functions that are not meant to return e.g.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
Header file for the logging system.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
The structure of a network driver in Contiki.
void(* input)(void)
Callback for getting notified of incoming packet in packetbuf.
uint8_t(* output)(const linkaddr_t *localdest)
Output funtion, sends from uipbuf.
Header file for IPv6-related data structures.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Header file for the uIP TCP/IP stack.