aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilipp Tölke <toelke@in.tum.de>2010-06-28 12:37:44 +0000
committerPhilipp Tölke <toelke@in.tum.de>2010-06-28 12:37:44 +0000
commita5cff0a0a73df5c9155e90c93dd59a92da705c95 (patch)
tree6493e5ad5638509db626136a661edd1199dbb518 /src
parent7a2378763af1b240ac943a3d499f792bde48d02a (diff)
downloadgnunet-a5cff0a0a73df5c9155e90c93dd59a92da705c95.tar.gz
gnunet-a5cff0a0a73df5c9155e90c93dd59a92da705c95.zip
vpn: a better way to parse the packets using bitfields
Diffstat (limited to 'src')
-rw-r--r--src/vpn/packet.c117
-rw-r--r--src/vpn/packet.h51
-rw-r--r--src/vpn/pretty-print.c23
-rw-r--r--src/vpn/test.c12
4 files changed, 67 insertions, 136 deletions
diff --git a/src/vpn/packet.c b/src/vpn/packet.c
index 2d52dbc81..4e96fb5f1 100644
--- a/src/vpn/packet.c
+++ b/src/vpn/packet.c
@@ -8,31 +8,16 @@
8 8
9#include "debug.h" 9#include "debug.h"
10#include "packet.h" 10#include "packet.h"
11#include "arpa/inet.h"
11 12
12long payload(struct ip6_hdr* hdr) {{{ 13short payload(struct ip6_hdr* hdr) {{{
13 return (hdr->paylgth[0] << 8) + hdr->paylgth[1]; 14 return ntohs(hdr->paylgth);
14}}} 15}}}
15 16
16void send_pkt(int fd, struct ip6_pkt* pkt) {{{ 17void send_pkt(int fd, struct ip6_pkt* pkt) {{{
17 int sz = payload(&(pkt->hdr)); 18 int sz = payload(&(pkt->hdr));
18 int w = 0; 19 int w = 0;
19 char* buf = (char*)malloc(sz+40); 20 char* buf = (char*)pkt;
20
21 buf[0] = (6 << 4) | (pkt->hdr.tclass >> 4);
22 buf[1] = (pkt->hdr.tclass << 4) | (pkt->hdr.flowlbl[0] >> 4);
23 buf[2] = pkt->hdr.flowlbl[1];
24 buf[3] = pkt->hdr.flowlbl[2];
25 buf[4] = pkt->hdr.paylgth[0];
26 buf[5] = pkt->hdr.paylgth[1];
27 buf[6] = pkt->hdr.nxthdr;
28 buf[7] = pkt->hdr.hoplmt;
29
30 for (w = 0; w < 16; w++) {
31 buf[8+w] = pkt->hdr.sadr[w];
32 buf[24+w] = pkt->hdr.dadr[w];
33 }
34
35 memcpy(buf+40, pkt->data, sz);
36 21
37 w = 0; 22 w = 0;
38 while ( w > 0) { 23 while ( w > 0) {
@@ -46,48 +31,31 @@ void send_pkt(int fd, struct ip6_pkt* pkt) {{{
46 free(buf); 31 free(buf);
47}}} 32}}}
48 33
49int recv_ipv6pkt(int fd, struct pkt_tun** pkt, unsigned char* data) {{{ 34int recv_ipv6pkt(int fd, struct pkt_tun** pkt) {{{
50 int size = (data[4] << 8) + data[5] + 40;
51
52 debug(1, 0, "read the size: %d\n", size);
53
54 (*pkt)->data = (unsigned char*)malloc(size);
55
56 memcpy((*pkt)->data, data, size);
57
58 return size;
59}}} 35}}}
60 36
61int recv_pkt(int fd, struct pkt_tun** pkt) {{{ 37int recv_pkt(int fd, struct pkt_tun** pkt) {{{
62 struct pkt_tun* _pkt = (struct pkt_tun*)malloc(sizeof(struct pkt_tun)); 38 // TODO: länge lesen?
63 *pkt = _pkt; 39 *pkt = (struct pkt_tun*)malloc(1504);
40 struct pkt_tun* _pkt = *pkt;
64 41
65 unsigned char data[1500]; 42 unsigned char *data = (unsigned char*)_pkt;
66 unsigned char buf[4];
67
68 struct iovec vect[2];
69 vect[0].iov_len = sizeof(struct tun_pi);
70 vect[0].iov_base = &buf;
71 vect[1].iov_len = 1500;
72 vect[1].iov_base = data;
73
74 int r = 0;
75 43
76 debug(1, 0, "beginning to read...\n"); 44 debug(1, 0, "beginning to read...\n");
77 45
78 r = readv(fd, vect, 2); 46 int r = read(fd, data, 1504);
79 47 debug(1, 0, "read %d bytes\n", r);
80 _pkt->flags[0] = buf[0];
81 _pkt->flags[1] = buf[1];
82 _pkt->type[0] = buf[2];
83 _pkt->type[1] = buf[3];
84 48
85 debug(1, 0, "read the flags: %02x%02x\n", _pkt->flags[0], _pkt->flags[1]); 49 debug(1, 0, "read the flags: %04x\n", ntohs(_pkt->flags));
86 debug(1, 0, "read the type: %02x%02x\n", _pkt->type[0], _pkt->type[1]); 50 debug(1, 0, "read the type: %04x\n", ntohs(_pkt->type));
87 51
88 switch((_pkt->type[0] << 8) + _pkt->type[1]) { 52 switch(ntohs(_pkt->type)) {
89 case 0x86dd: 53 case 0x86dd:
90 return recv_ipv6pkt(fd, pkt, data); 54 debug(1, 0, "reading an ipv6-packet\n");
55 struct ip6_pkt * pkt6 = (struct ip6_pkt*) *pkt;
56 int size = payload(&(pkt6->hdr));
57 debug(1, 0, "read the size: %d\n", size);
58 return size;
91 break; 59 break;
92 case 0x0800: 60 case 0x0800:
93 debug(1, 0, "unknown pkt-type: IPv4\n"); 61 debug(1, 0, "unknown pkt-type: IPv4\n");
@@ -102,56 +70,13 @@ int recv_pkt(int fd, struct pkt_tun** pkt) {{{
102}}} 70}}}
103 71
104struct ip6_pkt* parse_ip6(struct pkt_tun* pkt) {{{ 72struct ip6_pkt* parse_ip6(struct pkt_tun* pkt) {{{
105 struct ip6_pkt* pkt6 = (struct ip6_pkt*)malloc(sizeof(struct ip6_pkt)); 73 struct ip6_pkt* pkt6 = (struct ip6_pkt*)pkt;
106
107 pkt6->hdr.tclass = pkt->data[0] << 4 | pkt->data[1] >> 4;
108 pkt6->hdr.flowlbl[0] = pkt->data[1]>>4;
109 pkt6->hdr.flowlbl[1] = pkt->data[2];
110 pkt6->hdr.flowlbl[2] = pkt->data[3];
111
112 pkt6->hdr.paylgth[0] = pkt->data[4];
113 pkt6->hdr.paylgth[1] = pkt->data[5];
114
115 pkt6->hdr.nxthdr = pkt->data[6];
116 pkt6->hdr.hoplmt = pkt->data[7];
117
118 for (int w = 0; w < 16; w++) {
119 pkt6->hdr.sadr[w] = pkt->data[8+w];
120 pkt6->hdr.dadr[w] = pkt->data[24+w];
121 }
122
123 pkt6->data = (unsigned char*)malloc(payload(&(pkt6->hdr)));
124 memcpy(pkt6->data, pkt->data+40, payload(&(pkt6->hdr)));
125 74
126 return pkt6; 75 return pkt6;
127}}} 76}}}
128 77
129struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt* pkt) {{{ 78struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt* pkt) {{{
130 struct ip6_tcp* res = (struct ip6_tcp*) malloc(sizeof(struct ip6_tcp)); 79 struct ip6_tcp* res = (struct ip6_tcp*) pkt;
131 memcpy(&(res->hdr), &(pkt->hdr), sizeof(struct ip6_hdr));
132
133 res->data.spt = (pkt->data[0] << 8) | pkt->data[1];
134 res->data.dpt = (pkt->data[2] << 8) | pkt->data[3];
135
136 res->data.seq = (pkt->data[4] << 24) | (pkt->data[5] << 16) | (pkt->data[6] << 8) | pkt->data[7];
137 res->data.ack = (pkt->data[8] << 24) | (pkt->data[9] << 16) | (pkt->data[10] << 8) | pkt->data[11];
138
139 res->data.off = pkt->data[12] >> 4;
140 res->data.rsv = pkt->data[12] & 0xF;
141
142 res->data.flg = pkt->data[13];
143
144 res->data.wsz = (pkt->data[14] << 8) | pkt->data[15];
145
146 res->data.crc = (pkt->data[16] << 8) | pkt->data[17];
147
148 res->data.urg = (pkt->data[18] << 8) | pkt->data[19];
149
150 res->data.opt = (unsigned char*) malloc((res->data.off - 5)*4);
151 memcpy(res->data.opt, pkt->data+20, (res->data.off - 5)*4);
152
153 res->data.data = (unsigned char*) malloc(payload(&(pkt->hdr)) - 4*(res->data.off));
154 memcpy(res->data.data, pkt->data+4*(res->data.off), payload(&(pkt->hdr)) - 4*(res->data.off));
155 80
156 return res; 81 return res;
157}}} 82}}}
diff --git a/src/vpn/packet.h b/src/vpn/packet.h
index 4044eecb0..fa3c8f38c 100644
--- a/src/vpn/packet.h
+++ b/src/vpn/packet.h
@@ -2,49 +2,54 @@
2#define _GNTUN_PACKET_H_ 2#define _GNTUN_PACKET_H_
3 3
4struct pkt_tun { 4struct pkt_tun {
5 unsigned char flags[2]; 5 unsigned flags:16;
6 unsigned char type[2]; 6 unsigned type:16;
7
8 unsigned char* data;
9}; 7};
10 8
11struct ip6_hdr { 9struct ip6_hdr {
12 unsigned char tclass; 10 unsigned version:4;
13 unsigned char flowlbl[3]; 11 unsigned tclass:8;
14 unsigned char paylgth[2]; 12 unsigned flowlbl:20;
15 unsigned char nxthdr; 13 unsigned paylgth:16;
16 unsigned char hoplmt; 14 unsigned nxthdr:8;
15 unsigned hoplmt:8;
17 unsigned char sadr[16]; 16 unsigned char sadr[16];
18 unsigned char dadr[16]; 17 unsigned char dadr[16];
19}; 18};
20 19
21struct ip6_pkt { 20struct tcp_pkt {
22 struct ip6_hdr hdr; 21 unsigned spt:16;
23 unsigned char* data; 22 unsigned dpt:16;
23 unsigned seq:32;
24 unsigned ack:32;
25 unsigned off:4;
26 unsigned rsv:4;
27 unsigned flg:8;
28 unsigned wsz:16;
29 unsigned crc:16;
30 unsigned urg:16;
31 unsigned char data[1];
24}; 32};
25 33
26struct tcp_pkt { 34struct ip6_pkt {
27 unsigned short spt, dpt; 35 struct pkt_tun tun;
28 unsigned int seq, ack; 36 struct ip6_hdr hdr;
29 unsigned char off, rsv, flg; 37 unsigned char data[1];
30 unsigned short wsz;
31 unsigned short crc, urg;
32 unsigned char* opt;
33 unsigned char* data;
34}; 38};
35 39
36struct ip6_tcp { 40struct ip6_tcp {
41 struct pkt_tun tun;
37 struct ip6_hdr hdr; 42 struct ip6_hdr hdr;
38 struct tcp_pkt data; 43 struct tcp_pkt data;
39}; 44};
40 45
41extern void send_pkt(int fd, struct ip6_pkt* pkt); 46extern void send_pkt(int fd, struct ip6_pkt* pkt);
42extern int recv_ipv6pkt(int fd, struct pkt_tun** pkt, unsigned char*); 47extern int recv_ipv6pkt(int fd, struct pkt_tun** pkt);
43extern int recv_pkt(int fd, struct pkt_tun** pkt); 48extern int recv_pkt(int fd, struct pkt_tun** pkt);
44extern struct ip6_pkt* parse_ip6(struct pkt_tun* pkt); 49extern struct ip6_pkt* parse_ip6(struct pkt_tun* pkt);
45 50
46struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*); 51extern struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*);
47 52
48extern long payload(struct ip6_hdr* pkt); 53extern short payload(struct ip6_hdr* pkt);
49 54
50#endif 55#endif
diff --git a/src/vpn/pretty-print.c b/src/vpn/pretty-print.c
index c9878461d..96e435d2d 100644
--- a/src/vpn/pretty-print.c
+++ b/src/vpn/pretty-print.c
@@ -2,6 +2,7 @@
2#include <stdio.h> 2#include <stdio.h>
3#include <string.h> 3#include <string.h>
4#include <ctype.h> 4#include <ctype.h>
5#include <arpa/inet.h>
5 6
6#include "packet.h" 7#include "packet.h"
7 8
@@ -112,13 +113,13 @@ void pkt_printf(struct ip6_pkt* pkt) {{{
112 pp_ip6adr(pkt->hdr.sadr, buf+16); 113 pp_ip6adr(pkt->hdr.sadr, buf+16);
113 pp_ip6adr(pkt->hdr.dadr, buf+76); 114 pp_ip6adr(pkt->hdr.dadr, buf+76);
114 115
115 int flow = (pkt->hdr.flowlbl[0] << 16) + (pkt->hdr.flowlbl[1] << 8) + (pkt->hdr.flowlbl[2]); 116 int flow = (ntohl(pkt->hdr.flowlbl));
116 sprintf(tmp, "%03x", flow); 117 sprintf(tmp, "%03x", flow);
117 memcpy(buf+138, tmp, 3); 118 memcpy(buf+138, tmp, 3);
118 sprintf(tmp, "%-8d", flow); 119 sprintf(tmp, "%-8d", flow);
119 memcpy(buf+143, tmp, 8); 120 memcpy(buf+143, tmp, 8);
120 121
121 int length = (pkt->hdr.paylgth[0] << 8) + (pkt->hdr.paylgth[1]); 122 int length = ntohs(pkt->hdr.paylgth);
122 sprintf(tmp, "%02x", length); 123 sprintf(tmp, "%02x", length);
123 memcpy(buf+198, tmp, 2); 124 memcpy(buf+198, tmp, 2);
124 sprintf(tmp, "%-3d", length); 125 sprintf(tmp, "%-3d", length);
@@ -133,7 +134,7 @@ void pkt_printf(struct ip6_pkt* pkt) {{{
133 sprintf(tmp, "%-3d", pkt->hdr.hoplmt); 134 sprintf(tmp, "%-3d", pkt->hdr.hoplmt);
134 memcpy(buf+323, tmp, 3); 135 memcpy(buf+323, tmp, 3);
135 136
136 int size = payload(pkt); 137 int size = payload(&pkt->hdr);
137 for(int i = 0; i < 8; i++) { 138 for(int i = 0; i < 8; i++) {
138 if (16*i > size) break; 139 if (16*i > size) break;
139 pp_hexdump(pkt->data + (16*i), buf + 420 + (i*70), size - 16*i); 140 pp_hexdump(pkt->data + (16*i), buf + 420 + (i*70), size - 16*i);
@@ -144,14 +145,14 @@ void pkt_printf(struct ip6_pkt* pkt) {{{
144}}} 145}}}
145 146
146void pkt_printf_ip6tcp(struct ip6_tcp* pkt) {{{ 147void pkt_printf_ip6tcp(struct ip6_tcp* pkt) {{{
147 printf("spt: %u\n", pkt->data.spt); 148 printf("spt: %u\n", ntohs(pkt->data.spt));
148 printf("dpt: %u\n", pkt->data.dpt); 149 printf("dpt: %u\n", ntohs(pkt->data.dpt));
149 printf("seq: %u\n", pkt->data.seq); 150 printf("seq: %u\n", ntohs(pkt->data.seq));
150 printf("ack: %u\n", pkt->data.ack); 151 printf("ack: %u\n", ntohs(pkt->data.ack));
151 printf("off: %u\n", pkt->data.off); 152 printf("off: %u\n", ntohs(pkt->data.off));
152 printf("wsz: %u\n", pkt->data.wsz); 153 printf("wsz: %u\n", ntohs(pkt->data.wsz));
153 printf("crc: %u\n", pkt->data.crc); 154 printf("crc: %u\n", ntohs(pkt->data.crc));
154 printf("urg: %u\n", pkt->data.urg); 155 printf("urg: %u\n", ntohs(pkt->data.urg));
155 printf("flags: %c%c%c%c%c%c%c%c\n", 156 printf("flags: %c%c%c%c%c%c%c%c\n",
156 pkt->data.flg & 0x80 ? 'C' : '.', 157 pkt->data.flg & 0x80 ? 'C' : '.',
157 pkt->data.flg & 0x40 ? 'E' : '.', 158 pkt->data.flg & 0x40 ? 'E' : '.',
diff --git a/src/vpn/test.c b/src/vpn/test.c
index 3672b9df2..87ad9b10d 100644
--- a/src/vpn/test.c
+++ b/src/vpn/test.c
@@ -10,6 +10,8 @@
10#include "debug.h" 10#include "debug.h"
11#include "pretty-print.h" 11#include "pretty-print.h"
12#include "tcp.h" 12#include "tcp.h"
13#include <arpa/inet.h>
14
13 15
14int main(int c, char** v) { 16int main(int c, char** v) {
15 char dev[IFNAMSIZ]; 17 char dev[IFNAMSIZ];
@@ -22,17 +24,15 @@ int main(int c, char** v) {
22 24
23 for(;;) { 25 for(;;) {
24 printf("read %d bytes from socket, ", recv_pkt(fd, &pkt)); 26 printf("read %d bytes from socket, ", recv_pkt(fd, &pkt));
25 switch (pkt->type[0] << 8 | pkt->type[1]) { 27 switch (ntohs(pkt->type)) {
26 case 0x86dd: 28 case 0x86dd:
27 printf("parsing ipv6:\n"); 29 printf("parsing ipv6:\n");
28 struct ip6_pkt* pkt6 = parse_ip6(pkt); 30 struct ip6_pkt* pkt6 = parse_ip6(pkt);
31 pkt_printf(pkt6);
32 struct ip6_tcp* pkt6_tcp;
29 switch(pkt6->hdr.nxthdr) { 33 switch(pkt6->hdr.nxthdr) {
30 case 0x3a:
31 pkt_printf(pkt6);
32 break;
33 case 0x06: 34 case 0x06:
34 pkt_printf(pkt6); 35 pkt6_tcp = parse_ip6_tcp(pkt6);
35 struct ip6_tcp* pkt6_tcp = parse_ip6_tcp(pkt6);
36 pkt_printf_ip6tcp(pkt6_tcp); 36 pkt_printf_ip6tcp(pkt6_tcp);
37 handle_tcp(pkt6_tcp); 37 handle_tcp(pkt6_tcp);
38 break; 38 break;