aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Tölke <toelke@in.tum.de>2010-06-28 12:37:36 +0000
committerPhilipp Tölke <toelke@in.tum.de>2010-06-28 12:37:36 +0000
commit09c43b4598f40f2bf3ebfe7593f9ed10502b3574 (patch)
treec0262ef13a33b9f8ae3e0e39d65a67b5610781ec
parent9be3670e6dcfa44b52156506d59ec05028540bfe (diff)
downloadgnunet-09c43b4598f40f2bf3ebfe7593f9ed10502b3574.tar.gz
gnunet-09c43b4598f40f2bf3ebfe7593f9ed10502b3574.zip
parse ipv6-packets for the vpn-functionality
-rw-r--r--src/vpn/Makefile10
-rw-r--r--src/vpn/debug.c13
-rw-r--r--src/vpn/debug.h7
-rw-r--r--src/vpn/packet.c235
-rw-r--r--src/vpn/packet.h29
-rw-r--r--src/vpn/test.c25
-rw-r--r--src/vpn/tun.c39
-rw-r--r--src/vpn/tun.h11
8 files changed, 339 insertions, 30 deletions
diff --git a/src/vpn/Makefile b/src/vpn/Makefile
index ac8633c65..848faf24d 100644
--- a/src/vpn/Makefile
+++ b/src/vpn/Makefile
@@ -1,16 +1,14 @@
1CFLAGS=-Wall -pedantic 1CFLAGS=-Wall -pedantic --std=c99 -g
2CXXFLAGS = ${CFLAGS} 2CXXFLAGS = ${CFLAGS}
3 3
4LDFLAGS = 4LDFLAGS =
5 5
6all:default 6all:default
7 7
8default: tun 8default: test
9 9
10tun.o: tun.c 10test: test.o tun.o packet.o debug.o
11
12tun: tun.o
13 11
14clean: 12clean:
15 rm -f *.o 13 rm -f *.o
16 rm -f tun 14 rm -f test
diff --git a/src/vpn/debug.c b/src/vpn/debug.c
new file mode 100644
index 000000000..900a4bd00
--- /dev/null
+++ b/src/vpn/debug.c
@@ -0,0 +1,13 @@
1#include <stdio.h>
2#include <stdarg.h>
3#include <stdlib.h>
4
5#include "debug.h"
6
7void debug(int lvl, int es, char* msg, ...) {
8 va_list ap;
9 va_start(ap, msg);
10 vprintf(msg, ap);
11 va_end(ap);
12 if (es != 0) exit(es);
13}
diff --git a/src/vpn/debug.h b/src/vpn/debug.h
new file mode 100644
index 000000000..8f3e71813
--- /dev/null
+++ b/src/vpn/debug.h
@@ -0,0 +1,7 @@
1#ifndef _GNTUN_DEBUG_H_
2#define _GNTUN_DEBUG_H_
3
4/* exits with status exit if != 0; */
5extern void debug(int lvl, int exit, char* msg, ...);
6
7#endif
diff --git a/src/vpn/packet.c b/src/vpn/packet.c
new file mode 100644
index 000000000..c4c7dc290
--- /dev/null
+++ b/src/vpn/packet.c
@@ -0,0 +1,235 @@
1#include <errno.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5#include <unistd.h>
6#include <sys/uio.h>
7
8#include <linux/if_tun.h>
9
10#include "debug.h"
11#include "packet.h"
12
13static long payload(struct ip6_pkt* pkt) {
14 return (pkt->paylgth[0] << 8) + pkt->paylgth[1];
15}
16
17static char* pretty = /*{{{*/
18/* 0 1 2 3 4 5 6
19 0123456789012345678901234567890123456789012345678901234567890123456789 */
20"IPv6-Paket from xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx \n" //60
21" to xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx \n" //120
22" flow 0xXXX ( ) \n" //180
23" length 0xXX ( ) \n" //240
24" nexthdr 0xXX ( \n" //300
25" hoplmt 0xXX ( ) \n" //360
26"first 128 bytes of payload: \n" //420
27/* 0 1 2 3 4 5 6
28 0123456789012345678901234567890123456789012345678901234567890123456789 */
29"XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //490
30"XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //560
31"XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //630
32"XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //700
33"XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //770
34"XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //840
35"XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //910
36"XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n";//980
37/*}}}*/
38
39void send_pkt(int fd, struct ip6_pkt* pkt) {{{
40 int sz = payload(pkt);
41 int w = 0;
42 char* buf = (char*)malloc(sz+40);
43
44 buf[0] = (6 << 4) | (pkt->tclass >> 4);
45 buf[1] = (pkt->tclass << 4) | (pkt->flowlbl[0] >> 4);
46 buf[2] = pkt->flowlbl[1];
47 buf[3] = pkt->flowlbl[2];
48 buf[4] = pkt->paylgth[0];
49 buf[5] = pkt->paylgth[1];
50 buf[6] = pkt->nxthdr;
51 buf[7] = pkt->hoplmt;
52
53 for (w = 0; w < 16; w++) {
54 buf[8+w] = pkt->sadr[w];
55 buf[24+w] = pkt->dadr[w];
56 }
57
58 memcpy(buf+40, pkt->data, sz);
59
60 w = 0;
61 while ( w > 0) {
62 int t = write(fd, buf+w, (sz + 40) - w);
63 if (t < 0)
64 debug(1, 0, "packet: write : %s\n", strerror(errno));
65 else
66 w+=t;
67 }
68
69 free(buf);
70}}}
71
72int recv_ipv6pkt(int fd, struct pkt_tun** pkt, unsigned char* data) {{{
73 int size = (data[4] << 8) + data[5] + 40;
74
75 debug(1, 0, "read the size: %d\n", size);
76
77 (*pkt)->data = (unsigned char*)malloc(size);
78
79 memcpy((*pkt)->data, data, size);
80
81 return size;
82}}}
83
84int recv_pkt(int fd, struct pkt_tun** pkt) {{{
85 struct pkt_tun* _pkt = (struct pkt_tun*)malloc(sizeof(struct pkt_tun));
86 *pkt = _pkt;
87
88 unsigned char data[1500];
89 unsigned char buf[4];
90
91 struct iovec vect[2];
92 vect[0].iov_len = sizeof(struct tun_pi);
93 vect[0].iov_base = &buf;
94 vect[1].iov_len = 1500;
95 vect[1].iov_base = data;
96
97 int r = 0;
98
99 debug(1, 0, "beginning to read...\n");
100
101 r = readv(fd, vect, 2);
102
103 _pkt->flags[0] = buf[0];
104 _pkt->flags[1] = buf[1];
105 _pkt->type[0] = buf[2];
106 _pkt->type[1] = buf[3];
107
108 debug(1, 0, "read the flags: %02x%02x\n", _pkt->flags[0], _pkt->flags[1]);
109 debug(1, 0, "read the type: %02x%02x\n", _pkt->type[0], _pkt->type[1]);
110
111 switch((_pkt->type[0] << 8) + _pkt->type[1]) {
112 case 0x86dd:
113 return recv_ipv6pkt(fd, pkt, data);
114 break;
115 case 0x0800:
116 debug(1, 0, "unknown pkt-type: IPv4\n");
117 //IPv4 TODO
118 break;
119 default:
120 debug(1, 0, "unknown pkt-type: 0x%02x\n", 0x800);
121 //Whatever TODO
122 break;
123 }
124 return -1;
125}}}
126
127struct ip6_pkt* parse_ip6(struct pkt_tun* pkt) {{{
128 struct ip6_pkt* pkt6 = (struct ip6_pkt*)malloc(sizeof(struct ip6_pkt));
129
130 pkt6->tclass = pkt->data[0] << 4 | pkt->data[1] >> 4;
131 pkt6->flowlbl[0] = pkt->data[1]>>4;
132 pkt6->flowlbl[1] = pkt->data[2];
133 pkt6->flowlbl[2] = pkt->data[3];
134
135 pkt6->paylgth[0] = pkt->data[4];
136 pkt6->paylgth[1] = pkt->data[5];
137
138 pkt6->nxthdr = pkt->data[6];
139 pkt6->hoplmt = pkt->data[7];
140
141 for (int w = 0; w < 16; w++) {
142 pkt6->sadr[w] = pkt->data[8+w];
143 pkt6->dadr[w] = pkt->data[24+w];
144 }
145
146 pkt6->data = (unsigned char*)malloc(payload(pkt6));
147 memcpy(pkt6->data, pkt->data+40, payload(pkt6));
148
149 return pkt6;
150}}}
151
152static void pp_ip6adr(unsigned char* adr, char* dest) {{{
153 char tmp[3];
154
155 sprintf(tmp, "%02X", adr[0]);
156 memcpy(dest+0, tmp, 2);
157 sprintf(tmp, "%02X", adr[1]);
158 memcpy(dest+2, tmp, 2);
159
160 sprintf(tmp, "%02X", adr[2]);
161 memcpy(dest+5, tmp, 2);
162 sprintf(tmp, "%02X", adr[3]);
163 memcpy(dest+7, tmp, 2);
164
165 sprintf(tmp, "%02X", adr[4]);
166 memcpy(dest+10, tmp, 2);
167 sprintf(tmp, "%02X", adr[5]);
168 memcpy(dest+12, tmp, 2);
169
170 sprintf(tmp, "%02X", adr[6]);
171 memcpy(dest+15, tmp, 2);
172 sprintf(tmp, "%02X", adr[7]);
173 memcpy(dest+17, tmp, 2);
174
175 sprintf(tmp, "%02X", adr[8]);
176 memcpy(dest+20, tmp, 2);
177 sprintf(tmp, "%02X", adr[9]);
178 memcpy(dest+22, tmp, 2);
179
180 sprintf(tmp, "%02X", adr[10]);
181 memcpy(dest+25, tmp, 2);
182 sprintf(tmp, "%02X", adr[11]);
183 memcpy(dest+27, tmp, 2);
184
185 sprintf(tmp, "%02X", adr[12]);
186 memcpy(dest+30, tmp, 2);
187 sprintf(tmp, "%02X", adr[13]);
188 memcpy(dest+32, tmp, 2);
189
190 sprintf(tmp, "%02X", adr[14]);
191 memcpy(dest+35, tmp, 2);
192 sprintf(tmp, "%02X", adr[15]);
193 memcpy(dest+37, tmp, 2);
194}}}
195
196void pp_hexdump(unsigned char* data, char* dest, int max) {
197 char tmp[3];
198 int to = max > 8 ? 8 : max;
199 for (int i = 0; i < to; i++) {
200 sprintf(tmp, "%02x", data[i]);
201 memcpy(dest+(3*i), tmp, 2);
202 }
203}
204
205void pkt_printf(struct ip6_pkt* pkt) {
206 char* buf = (char*)malloc(strlen(pretty)+1);
207 char tmp[4];
208
209 memcpy(buf, pretty, strlen(pretty)+1);
210
211 pp_ip6adr(pkt->sadr, buf+16);
212 pp_ip6adr(pkt->dadr, buf+76);
213
214 sprintf(tmp, "%03x", (pkt->flowlbl[0] << 16) + (pkt->flowlbl[1] << 8) + (pkt->flowlbl[2]));
215 memcpy(buf+138, tmp, 3);
216
217 sprintf(tmp, "%02x", (pkt->paylgth[0] << 8) + (pkt->paylgth[1]));
218 memcpy(buf+198, tmp, 2);
219
220 sprintf(tmp, "%02x", pkt->nxthdr);
221 memcpy(buf+258, tmp, 2);
222
223 sprintf(tmp, "%02x", pkt->hoplmt);
224 memcpy(buf+318, tmp, 2);
225
226 int size = payload(pkt);
227 for(int i = 0; i < 8; i++) {
228 if (16*i > size) break;
229 pp_hexdump(pkt->data + (16*i), buf + 420 + (i*70), size - 16*i);
230 pp_hexdump(pkt->data + (16*i) + 8, buf + 445 + (i*70), size - (16*i + 8));
231 }
232
233 printf(buf);
234 free(buf);
235}
diff --git a/src/vpn/packet.h b/src/vpn/packet.h
new file mode 100644
index 000000000..9d5153f13
--- /dev/null
+++ b/src/vpn/packet.h
@@ -0,0 +1,29 @@
1#ifndef _GNTUN_PACKET_H_
2#define _GNTUN_PACKET_H_
3
4struct pkt_tun {
5 unsigned char flags[2];
6 unsigned char type[2];
7
8 unsigned char* data;
9};
10
11struct ip6_pkt {
12 unsigned char tclass;
13 unsigned char flowlbl[3];
14 unsigned char paylgth[2];
15 unsigned char nxthdr;
16 unsigned char hoplmt;
17 unsigned char sadr[16];
18 unsigned char dadr[16];
19
20 unsigned char* data;
21};
22
23extern void send_pkt(int fd, struct ip6_pkt* pkt);
24extern int recv_ipv6pkt(int fd, struct pkt_tun** pkt, unsigned char*);
25extern int recv_pkt(int fd, struct pkt_tun** pkt);
26extern struct ip6_pkt* parse_ip6(struct pkt_tun* pkt);
27extern void pkt_printf(struct ip6_pkt* pkt);
28
29#endif
diff --git a/src/vpn/test.c b/src/vpn/test.c
new file mode 100644
index 000000000..7b1182126
--- /dev/null
+++ b/src/vpn/test.c
@@ -0,0 +1,25 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/socket.h>
4
5#include <linux/if.h>
6
7#include "packet.h"
8#include "tun.h"
9#include "debug.h"
10
11int main(int c, char** v) {
12 //char* dev = (char*) malloc(IFNAMSIZ);
13 char dev[IFNAMSIZ];
14 int fd = init_tun(dev);
15
16 debug(1, 0, "Initialized the interface %s.\n", dev);
17
18 struct pkt_tun* pkt;
19
20 printf("read %d bytes from socket, now to parse'em\n", recv_pkt(fd, &pkt));
21
22 struct ip6_pkt* pkt6 = parse_ip6(pkt);
23
24 pkt_printf(pkt6);
25}
diff --git a/src/vpn/tun.c b/src/vpn/tun.c
index 6e184b079..d3c38bb4d 100644
--- a/src/vpn/tun.c
+++ b/src/vpn/tun.c
@@ -11,32 +11,40 @@
11#include <stdio.h> 11#include <stdio.h>
12#include <string.h> 12#include <string.h>
13#include <errno.h> 13#include <errno.h>
14#include <stdlib.h>
14 15
15int tun_alloc(char *dev) { 16#include "debug.h"
17
18/**
19 * Creates a tun-interface called dev;
20 * if *dev == 0, uses the name supplied by the kernel
21 * returns the fd to the tun or -1
22 */
23int init_tun(char *dev) { /*{{{*/
16 struct ifreq ifr; 24 struct ifreq ifr;
17 int fd, err; 25 int fd, err;
18 26
19 if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { 27 if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
20 fprintf(stderr, "open: %s\n", strerror(errno)); 28 debug(1, 0, "opening /dev/net/tun: %s\n", strerror(errno));
21 return -1; 29 return -1;
22 } 30 }
23 31
24 memset(&ifr, 0, sizeof(ifr)); 32 memset(&ifr, 0, sizeof(ifr));
25 33
26 ifr.ifr_flags = IFF_TUN; 34 ifr.ifr_flags = IFF_TUN;
27 if(*dev) 35 if(dev)
28 strncpy(ifr.ifr_name, dev, IFNAMSIZ); 36 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
29 37
30 if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ 38 if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
31 close(fd); 39 close(fd);
32 fprintf(stderr, "ioctl: %s\n", strerror(errno)); 40 debug(1, 0, "ioctl'ing /dev/net/tun: %s\n", strerror(errno));
33 return err; 41 return err;
34 } 42 }
35 strcpy(dev, ifr.ifr_name); 43 strcpy(dev, ifr.ifr_name);
36 return fd; 44 return fd;
37} 45} /*}}}*/
38 46
39void n2o(fd) { 47void n2o(int fd) {
40 char buf[1024]; 48 char buf[1024];
41 int r, w; 49 int r, w;
42 for(;;) { 50 for(;;) {
@@ -61,7 +69,7 @@ void n2o(fd) {
61 } 69 }
62} 70}
63 71
64void o2n(fd) { 72void o2n(int fd) {
65 char buf[1024]; 73 char buf[1024];
66 int r, w; 74 int r, w;
67 for(;;) { 75 for(;;) {
@@ -85,20 +93,3 @@ void o2n(fd) {
85 } 93 }
86 } 94 }
87} 95}
88
89int main(int argc, char** argv) {
90 char name[IFNAMSIZ];
91 int fd;
92
93 memset(name, 0, IFNAMSIZ);
94
95 strncpy(name, "mynet", IFNAMSIZ);
96 fprintf(stderr, "fd = %d, name = %s\n", fd = tun_alloc(name), name);
97
98 if (fork() == 0)
99 n2o(fd);
100
101 o2n(fd);
102
103 return 0;
104}
diff --git a/src/vpn/tun.h b/src/vpn/tun.h
new file mode 100644
index 000000000..ebd92199a
--- /dev/null
+++ b/src/vpn/tun.h
@@ -0,0 +1,11 @@
1#ifndef _GNTUN_TUN_H_
2#define _GNTUN_TUN_H_
3
4/**
5 * Creates a tun-interface called dev;
6 * if *dev == 0, uses the name supplied by the kernel
7 * returns the fd to the tun or -1
8 */
9extern int init_tun(char *dev);
10
11#endif