aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorPhilipp Tölke <toelke@in.tum.de>2010-07-20 05:45:21 +0000
committerPhilipp Tölke <toelke@in.tum.de>2010-07-20 05:45:21 +0000
commit6f26625f6a432f75ff339adf7b3330d5f32855ba (patch)
tree24a900522a9698e2bc225ae9aad8017a18ce6324 /src/vpn
parent425e80a6d25faa505513cacd10a3667a48c62d1e (diff)
downloadgnunet-6f26625f6a432f75ff339adf7b3330d5f32855ba.tar.gz
gnunet-6f26625f6a432f75ff339adf7b3330d5f32855ba.zip
Parse and pretty-print dns
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/packet.h46
-rw-r--r--src/vpn/pretty-print.c117
-rw-r--r--src/vpn/pretty-print.h1
-rw-r--r--src/vpn/test.c2
-rw-r--r--src/vpn/tun.h2
-rw-r--r--src/vpn/udp.c22
-rw-r--r--src/vpn/udp.h8
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
41struct dns_pkt { 41struct 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
66struct dns_query {
67 unsigned char* name;
68 unsigned short qtype;
69 unsigned short qclass;
70};
71
72struct 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
64struct ip6_pkt { 81struct 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);
84int recv_pkt(int fd, struct pkt_tun** pkt); 101int recv_pkt(int fd, struct pkt_tun** pkt);
85struct ip6_pkt* parse_ip6(struct pkt_tun* pkt); 102struct ip6_pkt* parse_ip6(struct pkt_tun* pkt);
86 103
104struct ip6_udp_dns {
105 struct ip6_udp hdr;
106 struct dns_pkt data;
107};
108
87struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*); 109struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*);
88struct ip6_udp* parse_ip6_udp(struct ip6_pkt*); 110struct 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
180static 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
245static 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
258void 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
10void pkt_printf_ip6tcp(struct ip6_tcp* pkt); 10void pkt_printf_ip6tcp(struct ip6_tcp* pkt);
11void pkt_printf_ip6udp(struct ip6_udp* pkt); 11void pkt_printf_ip6udp(struct ip6_udp* pkt);
12void 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 */
9extern int init_tun(char *dev); 9int 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
17void 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
6extern void handle_udp(struct ip6_udp*);
7
8#endif