diff options
author | Philipp Tölke <toelke@in.tum.de> | 2010-07-20 05:45:21 +0000 |
---|---|---|
committer | Philipp Tölke <toelke@in.tum.de> | 2010-07-20 05:45:21 +0000 |
commit | 6f26625f6a432f75ff339adf7b3330d5f32855ba (patch) | |
tree | 24a900522a9698e2bc225ae9aad8017a18ce6324 /src/vpn | |
parent | 425e80a6d25faa505513cacd10a3667a48c62d1e (diff) | |
download | gnunet-6f26625f6a432f75ff339adf7b3330d5f32855ba.tar.gz gnunet-6f26625f6a432f75ff339adf7b3330d5f32855ba.zip |
Parse and pretty-print dns
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/packet.h | 46 | ||||
-rw-r--r-- | src/vpn/pretty-print.c | 117 | ||||
-rw-r--r-- | src/vpn/pretty-print.h | 1 | ||||
-rw-r--r-- | src/vpn/test.c | 2 | ||||
-rw-r--r-- | src/vpn/tun.h | 2 | ||||
-rw-r--r-- | src/vpn/udp.c | 22 | ||||
-rw-r--r-- | src/vpn/udp.h | 8 |
7 files changed, 185 insertions, 13 deletions
diff --git a/src/vpn/packet.h b/src/vpn/packet.h index ccf3cb7fc..c19e7a101 100644 --- a/src/vpn/packet.h +++ b/src/vpn/packet.h | |||
@@ -39,28 +39,45 @@ struct udp_pkt { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | struct dns_pkt { | 41 | struct dns_pkt { |
42 | unsigned id:16; | 42 | unsigned short id; |
43 | unsigned qr:1; // query:0, response:1 | 43 | |
44 | unsigned op:4; // query:0, inverse q.:1, status: 2 | ||
45 | unsigned aa:1; // authoritative answer | ||
46 | unsigned tc:1; // message is truncated | ||
47 | unsigned rd:1; // recursion desired (client -> server) | 44 | unsigned rd:1; // recursion desired (client -> server) |
48 | unsigned ra:1; // recursion available (server -> client) | 45 | unsigned tc:1; // message is truncated |
49 | unsigned z:2; // reserved | 46 | unsigned aa:1; // authoritative answer |
50 | unsigned a:1; // answer is signed by server | 47 | unsigned op:4; // query:0, inverse q.:1, status: 2 |
48 | unsigned qr:1; // query:0, response:1 | ||
49 | |||
51 | unsigned rcode:4; // 0 No error | 50 | unsigned rcode:4; // 0 No error |
52 | // 1 Format error | 51 | // 1 Format error |
53 | // 2 Server failure | 52 | // 2 Server failure |
54 | // 3 Name Error | 53 | // 3 Name Error |
55 | // 4 Not Implemented | 54 | // 4 Not Implemented |
56 | // 5 Refused | 55 | // 5 Refused |
57 | unsigned qdcount:16; // number of questions | 56 | unsigned z:3; // reserved |
58 | unsigned ancount:16; // number of answers | 57 | unsigned ra:1; // recursion available (server -> client) |
59 | unsigned nscount:16; // number of authority-records | 58 | |
60 | unsigned arcount:16; // number of additional records | 59 | unsigned short qdcount; // number of questions |
60 | unsigned short ancount; // number of answers | ||
61 | unsigned short nscount; // number of authority-records | ||
62 | unsigned short arcount; // number of additional records | ||
61 | unsigned char data[1]; | 63 | unsigned char data[1]; |
62 | }; | 64 | }; |
63 | 65 | ||
66 | struct dns_query { | ||
67 | unsigned char* name; | ||
68 | unsigned short qtype; | ||
69 | unsigned short qclass; | ||
70 | }; | ||
71 | |||
72 | struct dns_record { | ||
73 | unsigned char* name; | ||
74 | unsigned short type; | ||
75 | unsigned short class; | ||
76 | unsigned int ttl; | ||
77 | unsigned short data_len; | ||
78 | unsigned char* data; | ||
79 | }; | ||
80 | |||
64 | struct ip6_pkt { | 81 | struct ip6_pkt { |
65 | struct pkt_tun tun; | 82 | struct pkt_tun tun; |
66 | struct ip6_hdr hdr; | 83 | struct ip6_hdr hdr; |
@@ -84,6 +101,11 @@ int recv_ipv6pkt(int fd, struct pkt_tun** pkt); | |||
84 | int recv_pkt(int fd, struct pkt_tun** pkt); | 101 | int recv_pkt(int fd, struct pkt_tun** pkt); |
85 | struct ip6_pkt* parse_ip6(struct pkt_tun* pkt); | 102 | struct ip6_pkt* parse_ip6(struct pkt_tun* pkt); |
86 | 103 | ||
104 | struct ip6_udp_dns { | ||
105 | struct ip6_udp hdr; | ||
106 | struct dns_pkt data; | ||
107 | }; | ||
108 | |||
87 | struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*); | 109 | struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*); |
88 | struct ip6_udp* parse_ip6_udp(struct ip6_pkt*); | 110 | struct ip6_udp* parse_ip6_udp(struct ip6_pkt*); |
89 | 111 | ||
diff --git a/src/vpn/pretty-print.c b/src/vpn/pretty-print.c index 096afbf96..90bbe7bea 100644 --- a/src/vpn/pretty-print.c +++ b/src/vpn/pretty-print.c | |||
@@ -176,3 +176,120 @@ void pkt_printf_ip6udp(struct ip6_udp* pkt) {{{ | |||
176 | printf("len: %u\n", ntohs(pkt->data.len)); | 176 | printf("len: %u\n", ntohs(pkt->data.len)); |
177 | printf("crc: 0x%x\n", ntohs(pkt->data.crc)); | 177 | printf("crc: 0x%x\n", ntohs(pkt->data.crc)); |
178 | }}} | 178 | }}} |
179 | |||
180 | static char* dns_types(unsigned short type) {{{ | ||
181 | static char* types[] = { /*{{{*/ | ||
182 | "", | ||
183 | "A", // 1 a host address | ||
184 | "NS", // 2 an authoritative name server | ||
185 | "MD", // 3 a mail destination (Obsolete - use MX) | ||
186 | "MF", // 4 a mail forwarder (Obsolete - use MX) | ||
187 | "CNAME", // 5 the canonical name for an alias | ||
188 | "SOA", // 6 marks the start of a zone of authority | ||
189 | "MB", // 7 a mailbox domain name (EXPERIMENTAL) | ||
190 | "MG", // 8 a mail group member (EXPERIMENTAL) | ||
191 | "MR", // 9 a mail rename domain name (EXPERIMENTAL) | ||
192 | "NULL", // 10 a null RR (EXPERIMENTAL) | ||
193 | "WKS", // 11 a well known service description | ||
194 | "PTR", // 12 a domain name pointer | ||
195 | "HINFO", // 13 host information | ||
196 | "MINFO", // 14 mailbox or mail list information | ||
197 | "MX", // 15 mail exchange | ||
198 | "TXT", // 16 text strings | ||
199 | "RP", | ||
200 | "AFSDB" | ||
201 | }; /*}}}*/ | ||
202 | |||
203 | static char* qtypes[] = { /* + 252! {{{ */ | ||
204 | "AXFR", // 252 A request for a transfer of an entire zone | ||
205 | "MAILB", // 253 A request for mailbox-related records (MB, MG or MR) | ||
206 | "MAILA", // 254 A request for mail agent RRs (Obsolete - see MX) | ||
207 | "*", // 255 A request for all records | ||
208 | }; /*}}}*/ | ||
209 | |||
210 | if (type <= 18) return types[type]; | ||
211 | if (type >= 252 && type <= 255) return qtypes[type-252]; | ||
212 | |||
213 | switch(type) { | ||
214 | case 24: return "SIG"; | ||
215 | case 25: return "KEY"; | ||
216 | case 28: return "AAAA"; | ||
217 | case 29: return "LOC"; | ||
218 | case 33: return "SRV"; | ||
219 | case 35: return "NAPTR"; | ||
220 | case 36: return "KX"; | ||
221 | case 37: return "CERT"; | ||
222 | case 39: return "DNAME"; | ||
223 | case 42: return "APL"; | ||
224 | case 43: return "DS"; | ||
225 | case 44: return "SSHFP"; | ||
226 | case 45: return "IPSECKEY"; | ||
227 | case 46: return "RRSIG"; | ||
228 | case 47: return "NSEC"; | ||
229 | case 48: return "DNSKEY"; | ||
230 | case 49: return "DHCID"; | ||
231 | case 50: return "NSEC3"; | ||
232 | case 51: return "NSEC3PARAM"; | ||
233 | case 55: return "HIP"; | ||
234 | case 99: return "SPF"; | ||
235 | case 249: return "TKEY"; | ||
236 | case 250: return "TSIG"; | ||
237 | case 32768: return "TA"; | ||
238 | case 32769: return "DLV"; | ||
239 | } | ||
240 | |||
241 | return 0; | ||
242 | |||
243 | }}} | ||
244 | |||
245 | static char* dns_classes(short class) {{{ | ||
246 | static char* classes[] = { /*{{{*/ | ||
247 | "", | ||
248 | "IN", // 1 the Internet | ||
249 | "CS", // 2 the CSNET class (Obsolete - used only for examples in some obsolete RFCs) | ||
250 | "CH", // 3 the CHAOS class | ||
251 | "HS", // 4 Hesiod [Dyer 87] | ||
252 | }; /*}}}*/ | ||
253 | |||
254 | if (class <= 4) return classes[class]; | ||
255 | return 0; | ||
256 | }}} | ||
257 | |||
258 | void pkt_printf_ip6dns(struct ip6_udp_dns* pkt) {{{ | ||
259 | printf("DNS-Packet:\n"); | ||
260 | printf("\tid: %d\n", ntohs(pkt->data.id)); | ||
261 | printf("\t%d: %s\n", pkt->data.qr, pkt->data.qr == 0 ? "query" : "response"); | ||
262 | printf("\top: %s\n", (char*[]){"query", "inverse q.", "status", "inval"}[pkt->data.op]); | ||
263 | printf("\trecursion is%s desired\n", pkt->data.rd == 0 ? " not" : ""); | ||
264 | unsigned short qdcount = ntohs(pkt->data.qdcount); | ||
265 | printf("\t#qd: %d\n", qdcount); | ||
266 | printf("\t#an: %d\n", ntohs(pkt->data.ancount)); | ||
267 | printf("\t#ns: %d\n", ntohs(pkt->data.nscount)); | ||
268 | printf("\t#ar: %d\n", ntohs(pkt->data.arcount)); | ||
269 | |||
270 | struct dns_query** queries = (struct dns_query**)malloc(qdcount*sizeof(struct dns_query*)); | ||
271 | unsigned int idx = 0; | ||
272 | |||
273 | int i; | ||
274 | for (i = 0; i < qdcount; i++) { | ||
275 | queries[i] = (struct dns_query*)malloc(sizeof(struct dns_query)); | ||
276 | queries[i]->name = (unsigned char*)malloc(255); // see RFC1035 | ||
277 | unsigned char* name = queries[i]->name; | ||
278 | int len = pkt->data.data[idx++]; | ||
279 | while (len != 0) { | ||
280 | memcpy(name, pkt->data.data+idx, len); | ||
281 | idx += len; | ||
282 | name += len; | ||
283 | *name = '.'; | ||
284 | name++; | ||
285 | len = pkt->data.data[idx++]; | ||
286 | }; | ||
287 | printf("%d\n", idx); | ||
288 | *name = 0; | ||
289 | queries[i]->qtype = *((unsigned short*)(pkt->data.data+idx)); | ||
290 | idx += 2; | ||
291 | queries[i]->qclass = *((unsigned short*)(pkt->data.data+idx)); | ||
292 | idx += 2; | ||
293 | printf("query for %s type=%d (%s) class=%d (%s)\n", queries[i]->name, ntohs(queries[i]->qtype), dns_types(ntohs(queries[i]->qtype)), ntohs(queries[i]->qclass), dns_classes(ntohs(queries[i]->qclass))); | ||
294 | } | ||
295 | }}} | ||
diff --git a/src/vpn/pretty-print.h b/src/vpn/pretty-print.h index f2aa5b795..57b1825b4 100644 --- a/src/vpn/pretty-print.h +++ b/src/vpn/pretty-print.h | |||
@@ -9,5 +9,6 @@ extern void pkt_printf(struct ip6_pkt* pkt); | |||
9 | 9 | ||
10 | void pkt_printf_ip6tcp(struct ip6_tcp* pkt); | 10 | void pkt_printf_ip6tcp(struct ip6_tcp* pkt); |
11 | void pkt_printf_ip6udp(struct ip6_udp* pkt); | 11 | void pkt_printf_ip6udp(struct ip6_udp* pkt); |
12 | void pkt_printf_ip6dns(struct ip6_udp_dns* pkt); | ||
12 | 13 | ||
13 | #endif | 14 | #endif |
diff --git a/src/vpn/test.c b/src/vpn/test.c index 959c56b23..b24397c71 100644 --- a/src/vpn/test.c +++ b/src/vpn/test.c | |||
@@ -10,6 +10,7 @@ | |||
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 "udp.h" | ||
13 | #include <arpa/inet.h> | 14 | #include <arpa/inet.h> |
14 | 15 | ||
15 | 16 | ||
@@ -40,6 +41,7 @@ int main(int c, char** v) { | |||
40 | case 0x11: | 41 | case 0x11: |
41 | pkt6_udp = parse_ip6_udp(pkt6); | 42 | pkt6_udp = parse_ip6_udp(pkt6); |
42 | pkt_printf_ip6udp(pkt6_udp); | 43 | pkt_printf_ip6udp(pkt6_udp); |
44 | handle_udp(pkt6_udp); | ||
43 | break; | 45 | break; |
44 | } | 46 | } |
45 | break; | 47 | break; |
diff --git a/src/vpn/tun.h b/src/vpn/tun.h index ebd92199a..3ba61771a 100644 --- a/src/vpn/tun.h +++ b/src/vpn/tun.h | |||
@@ -6,6 +6,6 @@ | |||
6 | * if *dev == 0, uses the name supplied by the kernel | 6 | * if *dev == 0, uses the name supplied by the kernel |
7 | * returns the fd to the tun or -1 | 7 | * returns the fd to the tun or -1 |
8 | */ | 8 | */ |
9 | extern int init_tun(char *dev); | 9 | int init_tun(char *dev); |
10 | 10 | ||
11 | #endif | 11 | #endif |
diff --git a/src/vpn/udp.c b/src/vpn/udp.c new file mode 100644 index 000000000..4a7cb94ed --- /dev/null +++ b/src/vpn/udp.c | |||
@@ -0,0 +1,22 @@ | |||
1 | #include "debug.h" | ||
2 | #include "packet.h" | ||
3 | #include "udp.h" | ||
4 | |||
5 | #include "pretty-print.h" | ||
6 | |||
7 | #include <errno.h> | ||
8 | #include <netinet/in.h> | ||
9 | #include <netinet/ip.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <arpa/inet.h> | ||
12 | #include <string.h> | ||
13 | #include <sys/socket.h> | ||
14 | #include <sys/types.h> | ||
15 | #include <unistd.h> | ||
16 | |||
17 | void handle_udp(struct ip6_udp* pkt) { | ||
18 | if (ntohs(pkt->data.dpt) == 53) { //TODO check for dadr, too | ||
19 | pkt_printf_ip6dns((struct ip6_udp_dns*)pkt); | ||
20 | return; | ||
21 | } | ||
22 | } | ||
diff --git a/src/vpn/udp.h b/src/vpn/udp.h new file mode 100644 index 000000000..ab285d6c8 --- /dev/null +++ b/src/vpn/udp.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _GNTUN_UDP_H_ | ||
2 | #define _GNTUN_UDP_H_ | ||
3 | |||
4 | #include "packet.h" | ||
5 | |||
6 | extern void handle_udp(struct ip6_udp*); | ||
7 | |||
8 | #endif | ||