New revision of the Tunnel6 client with improvements and routed prefix support
[tunnel6.git] / client / src / tun / linux.c
blob00058206ff4cede2edaa9f1e21fa488878bd1ad5
1 /*
2 * tunnel6
3 * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef __linux__
21 #include <net/if.h>
22 #include <linux/if_tun.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <sys/ioctl.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <arpa/inet.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <stdio.h>
34 #include "ipv6.h"
35 #include "tunnel.h"
36 #include "packet.h"
37 #include "defaults.h"
39 static int fd; /* FD of the TUN/TAP device */
40 static char data[DEFAULT_MTU+1];
41 static char dev[IFNAMSIZ+1];
43 extern int fd_tun; /* polling FD of the TUN/TAP device */
45 extern ipv6_addr_t tunip; /* IPv6 address obtained from tunnel server */
46 extern ipv6_addr_t tungw; /* IPv6 gateway obtained from tunnel server */
47 extern ipv6_prefix_t tunpr; /* IPv6 prefix obtained from tunnel server */
49 static int tundev_arch_alloc (int flags)
51 /* try to load tun module / we dont know when its module or built-in */
52 int r = system ("modprobe -q tun 2>/dev/null >/dev/null");
54 r = 0;
56 struct ifreq ifr;
57 int err;
58 char *clonedev = DEFAULT_TUNTAP_DEV;
60 if( (fd = open (clonedev, O_RDWR)) < 0 ) {
61 perror ("Opening " DEFAULT_TUNTAP_DEV);
62 return fd;
65 memset (&ifr, 0x0, sizeof (ifr));
67 ifr.ifr_flags = flags;
69 if (*dev)
70 strncpy (ifr.ifr_name, dev, IFNAMSIZ);
72 if ((err = ioctl (fd, TUNSETIFF, (void *) &ifr)) < 0) {
73 perror ("ioctl (TUNSETIFF)");
74 close (fd);
75 return err;
78 strcpy (dev, ifr.ifr_name);
80 return fd;
83 int tundev_arch_recv ()
85 int ret = read (fd, data, DEFAULT_MTU);
87 if (ret < 1) {
88 return 0;
91 data[ret] = '\0';
93 return ret;
96 int tundev_arch_poll ()
98 int ret = tundev_arch_recv ();
100 if (!ret)
101 return 0;
103 struct proto_ipv6_t *ip = (struct proto_ipv6_t *) &data;
105 if (!ipv6_cmp (ip->src, tunip) && !ipv6_cmp_prefix (tunpr, (unsigned char *) ip->src)) {
106 printf ("WARNING -> This is not our packet\n");
107 return 0;
110 return tunnel_send (data, ret);
113 int tundev_arch_send (char *packet, unsigned len)
115 if (write (fd, packet, len) == -1) {
116 printf ("ERROR -> tap_send ()\n");
117 return -1;
120 return 0;
123 int tundev_arch_setup ()
125 sprintf (data, "ip link set %s up", dev);
126 int r = system (data);
128 sprintf (data, "ip link set mtu %u dev %s", DEFAULT_MTU - 40, dev);
129 r = system (data);
131 char ipv6[64];
132 inet_ntop (AF_INET6, &tunip, ipv6, 64);
134 sprintf (data, "ip -6 addr add %s/%u dev %s", ipv6, 64, dev);
135 r = system (data);
137 inet_ntop (AF_INET6, &tungw, ipv6, 64);
139 sprintf (data, "ip -6 ro add default via %s dev %s", ipv6, dev);
140 r = system (data);
142 return 0;
145 int tundev_arch_init ()
147 strncpy (dev, DEFAULT_TUNNEL6_DEV, IFNAMSIZ);
149 /* initialize TUN interface, which operates on 3rd network layer (IP) */
150 fd_tun = tundev_arch_alloc (IFF_TUN | IFF_NO_PI | IFF_POINTOPOINT);
152 if (fd_tun < 0) {
153 printf ("ERROR -> TUN/TAP interface '%s' failed\n", DEFAULT_TUNNEL6_DEV);
154 return -1;
157 printf ("> Tunnel device '%s' was created\n", dev);
159 return 0;
161 #endif