diff options
author | Philipp Tölke <toelke@in.tum.de> | 2010-06-28 12:37:44 +0000 |
---|---|---|
committer | Philipp Tölke <toelke@in.tum.de> | 2010-06-28 12:37:44 +0000 |
commit | a5cff0a0a73df5c9155e90c93dd59a92da705c95 (patch) | |
tree | 6493e5ad5638509db626136a661edd1199dbb518 /src | |
parent | 7a2378763af1b240ac943a3d499f792bde48d02a (diff) | |
download | gnunet-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.c | 117 | ||||
-rw-r--r-- | src/vpn/packet.h | 51 | ||||
-rw-r--r-- | src/vpn/pretty-print.c | 23 | ||||
-rw-r--r-- | src/vpn/test.c | 12 |
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 | ||
12 | long payload(struct ip6_hdr* hdr) {{{ | 13 | short payload(struct ip6_hdr* hdr) {{{ |
13 | return (hdr->paylgth[0] << 8) + hdr->paylgth[1]; | 14 | return ntohs(hdr->paylgth); |
14 | }}} | 15 | }}} |
15 | 16 | ||
16 | void send_pkt(int fd, struct ip6_pkt* pkt) {{{ | 17 | void 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 | ||
49 | int recv_ipv6pkt(int fd, struct pkt_tun** pkt, unsigned char* data) {{{ | 34 | int 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 | ||
61 | int recv_pkt(int fd, struct pkt_tun** pkt) {{{ | 37 | int 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 | ||
104 | struct ip6_pkt* parse_ip6(struct pkt_tun* pkt) {{{ | 72 | struct 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 | ||
129 | struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt* pkt) {{{ | 78 | struct 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 | ||
4 | struct pkt_tun { | 4 | struct 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 | ||
11 | struct ip6_hdr { | 9 | struct 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 | ||
21 | struct ip6_pkt { | 20 | struct 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 | ||
26 | struct tcp_pkt { | 34 | struct 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 | ||
36 | struct ip6_tcp { | 40 | struct 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 | ||
41 | extern void send_pkt(int fd, struct ip6_pkt* pkt); | 46 | extern void send_pkt(int fd, struct ip6_pkt* pkt); |
42 | extern int recv_ipv6pkt(int fd, struct pkt_tun** pkt, unsigned char*); | 47 | extern int recv_ipv6pkt(int fd, struct pkt_tun** pkt); |
43 | extern int recv_pkt(int fd, struct pkt_tun** pkt); | 48 | extern int recv_pkt(int fd, struct pkt_tun** pkt); |
44 | extern struct ip6_pkt* parse_ip6(struct pkt_tun* pkt); | 49 | extern struct ip6_pkt* parse_ip6(struct pkt_tun* pkt); |
45 | 50 | ||
46 | struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*); | 51 | extern struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*); |
47 | 52 | ||
48 | extern long payload(struct ip6_hdr* pkt); | 53 | extern 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 | ||
146 | void pkt_printf_ip6tcp(struct ip6_tcp* pkt) {{{ | 147 | void 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 | ||
14 | int main(int c, char** v) { | 16 | int 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; |