11 #include "gnunet-vpn-packet.h"
13 static char* pretty = /*{{{*/
15 0123456789012345678901234567890123456789012345678901234567890123456789 */
16 "IPv6-Paket from xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx \n" //60
17 " to xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx \n" //120
19 0123456789012345678901234567890123456789012345678901234567890123456789 */
20 " flow 0xXXX ( ) \n" //180
21 " length 0xXX ( ) \n" //240
22 " nexthdr 0xXX ( \n" //300
23 " hoplmt 0xXX ( ) \n" //360
24 "first 128 bytes of payload: \n" //420
26 0123456789012345678901234567890123456789012345678901234567890123456789 */
27 "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //490
28 "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //560
29 "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //630
30 "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //700
31 "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //770
32 "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //840
33 "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n" //910
34 "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ \n";//980
37 static void pp_ip6adr(unsigned char* adr, char* dest) {{{
40 sprintf(tmp, "%02X", adr[0]);
41 memcpy(dest+0, tmp, 2);
42 sprintf(tmp, "%02X", adr[1]);
43 memcpy(dest+2, tmp, 2);
45 sprintf(tmp, "%02X", adr[2]);
46 memcpy(dest+5, tmp, 2);
47 sprintf(tmp, "%02X", adr[3]);
48 memcpy(dest+7, tmp, 2);
50 sprintf(tmp, "%02X", adr[4]);
51 memcpy(dest+10, tmp, 2);
52 sprintf(tmp, "%02X", adr[5]);
53 memcpy(dest+12, tmp, 2);
55 sprintf(tmp, "%02X", adr[6]);
56 memcpy(dest+15, tmp, 2);
57 sprintf(tmp, "%02X", adr[7]);
58 memcpy(dest+17, tmp, 2);
60 sprintf(tmp, "%02X", adr[8]);
61 memcpy(dest+20, tmp, 2);
62 sprintf(tmp, "%02X", adr[9]);
63 memcpy(dest+22, tmp, 2);
65 sprintf(tmp, "%02X", adr[10]);
66 memcpy(dest+25, tmp, 2);
67 sprintf(tmp, "%02X", adr[11]);
68 memcpy(dest+27, tmp, 2);
70 sprintf(tmp, "%02X", adr[12]);
71 memcpy(dest+30, tmp, 2);
72 sprintf(tmp, "%02X", adr[13]);
73 memcpy(dest+32, tmp, 2);
75 sprintf(tmp, "%02X", adr[14]);
76 memcpy(dest+35, tmp, 2);
77 sprintf(tmp, "%02X", adr[15]);
78 memcpy(dest+37, tmp, 2);
81 void pp_hexdump(unsigned char* data, char* dest, int max) {{{
86 int to = max > 16 ? 16 : max;
87 for (i = 0; i < to; i++) {
89 sprintf(tmp, "%02x", data[i]);
90 memcpy(dest+(3*i)+off, tmp, 2);
91 if (isprint(data[i])) {
92 sprintf(tmp2, "%c", data[i]);
93 memcpy(dest+51+i, tmp2, 1);
98 void pp_write_header(char* dest, struct ip6_pkt* pkt) {{{
99 switch (pkt->ip6_hdr.nxthdr) {
101 memcpy(dest, "ICMPv6)", 7);
104 memcpy(dest, "TCP)", 4);
107 memcpy(dest, "UDP)", 4);
110 memcpy(dest, "unknown)", 8);
115 void pkt_printf(struct ip6_pkt* pkt) {{{
116 char* buf = alloca(strlen(pretty)+1);
119 memcpy(buf, pretty, strlen(pretty)+1);
121 pp_ip6adr(pkt->ip6_hdr.sadr, buf+16);
122 pp_ip6adr(pkt->ip6_hdr.dadr, buf+76);
124 int flow = (ntohl(pkt->ip6_hdr.flowlbl));
125 sprintf(tmp, "%03x", flow);
126 memcpy(buf+138, tmp, 3);
127 sprintf(tmp, "%-8d", flow);
128 memcpy(buf+143, tmp, 8);
130 int length = ntohs(pkt->ip6_hdr.paylgth);
131 sprintf(tmp, "%02x", length);
132 memcpy(buf+198, tmp, 2);
133 sprintf(tmp, "%-3d", length);
134 memcpy(buf+203, tmp, 3);
136 sprintf(tmp, "%02x", pkt->ip6_hdr.nxthdr);
137 memcpy(buf+258, tmp, 2);
138 pp_write_header(buf+263, pkt);
140 sprintf(tmp, "%02x", pkt->ip6_hdr.hoplmt);
141 memcpy(buf+318, tmp, 2);
142 sprintf(tmp, "%-3d", pkt->ip6_hdr.hoplmt);
143 memcpy(buf+323, tmp, 3);
145 int size = ntohs(pkt->ip6_hdr.paylgth);
147 for(i = 0; i < 8; i++) {
148 if (16*i > size) break;
149 pp_hexdump(pkt->data + (16*i), buf + 420 + (i*70), size - 16*i);
155 void pkt_printf_ip6tcp(struct ip6_tcp* pkt) {{{
156 printf("spt: %u\n", ntohs(pkt->tcp_hdr.spt));
157 printf("dpt: %u\n", ntohs(pkt->tcp_hdr.dpt));
158 printf("seq: %u\n", ntohs(pkt->tcp_hdr.seq));
159 printf("ack: %u\n", ntohs(pkt->tcp_hdr.ack));
160 printf("off: %u\n", ntohs(pkt->tcp_hdr.off));
161 printf("wsz: %u\n", ntohs(pkt->tcp_hdr.wsz));
162 printf("crc: 0x%x\n", ntohs(pkt->tcp_hdr.crc));
163 printf("urg: %u\n", ntohs(pkt->tcp_hdr.urg));
164 printf("flags: %c%c%c%c%c%c%c%c\n",
165 pkt->tcp_hdr.flg & 0x80 ? 'C' : '.',
166 pkt->tcp_hdr.flg & 0x40 ? 'E' : '.',
167 pkt->tcp_hdr.flg & 0x20 ? 'U' : '.',
168 pkt->tcp_hdr.flg & 0x10 ? 'A' : '.',
169 pkt->tcp_hdr.flg & 0x08 ? 'P' : '.',
170 pkt->tcp_hdr.flg & 0x04 ? 'R' : '.',
171 pkt->tcp_hdr.flg & 0x02 ? 'S' : '.',
172 pkt->tcp_hdr.flg & 0x01 ? 'F' : '.'
176 void pkt_printf_ip6udp(struct ip6_udp* pkt) {{{
177 printf("spt: %u\n", ntohs(pkt->udp_hdr.spt));
178 printf("dpt: %u\n", ntohs(pkt->udp_hdr.dpt));
179 printf("len: %u\n", ntohs(pkt->udp_hdr.len));
180 printf("crc: 0x%x\n", ntohs(pkt->udp_hdr.crc));
183 static char* dns_types(unsigned short type) {{{
184 static char* types[] = { /*{{{*/
186 "A", // 1 a host address
187 "NS", // 2 an authoritative name server
188 "MD", // 3 a mail destination (Obsolete - use MX)
189 "MF", // 4 a mail forwarder (Obsolete - use MX)
190 "CNAME", // 5 the canonical name for an alias
191 "SOA", // 6 marks the start of a zone of authority
192 "MB", // 7 a mailbox domain name (EXPERIMENTAL)
193 "MG", // 8 a mail group member (EXPERIMENTAL)
194 "MR", // 9 a mail rename domain name (EXPERIMENTAL)
195 "NULL", // 10 a null RR (EXPERIMENTAL)
196 "WKS", // 11 a well known service description
197 "PTR", // 12 a domain name pointer
198 "HINFO", // 13 host information
199 "MINFO", // 14 mailbox or mail list information
200 "MX", // 15 mail exchange
201 "TXT", // 16 text strings
206 static char* qtypes[] = { /* + 252! {{{ */
207 "AXFR", // 252 A request for a transfer of an entire zone
208 "MAILB", // 253 A request for mailbox-related records (MB, MG or MR)
209 "MAILA", // 254 A request for mail agent RRs (Obsolete - see MX)
210 "*", // 255 A request for all records
213 if (type <= 18) return types[type];
214 if (type >= 252 && type <= 255) return qtypes[type-252];
217 case 24: return "SIG";
218 case 25: return "KEY";
219 case 28: return "AAAA";
220 case 29: return "LOC";
221 case 33: return "SRV";
222 case 35: return "NAPTR";
223 case 36: return "KX";
224 case 37: return "CERT";
225 case 39: return "DNAME";
226 case 42: return "APL";
227 case 43: return "DS";
228 case 44: return "SSHFP";
229 case 45: return "IPSECKEY";
230 case 46: return "RRSIG";
231 case 47: return "NSEC";
232 case 48: return "DNSKEY";
233 case 49: return "DHCID";
234 case 50: return "NSEC3";
235 case 51: return "NSEC3PARAM";
236 case 55: return "HIP";
237 case 99: return "SPF";
238 case 249: return "TKEY";
239 case 250: return "TSIG";
240 case 32768: return "TA";
241 case 32769: return "DLV";
248 static char* dns_classes(short class) {{{
249 static char* classes[] = { /*{{{*/
251 "IN", // 1 the Internet
252 "CS", // 2 the CSNET class (Obsolete - used only for examples in some obsolete RFCs)
253 "CH", // 3 the CHAOS class
254 "HS", // 4 Hesiod [Dyer 87]
257 if (class <= 4) return classes[class];
261 unsigned int parse_dns_name(unsigned char* d, const unsigned char* src, unsigned short idx) {/*{{{*/
262 unsigned char* dest = d;
264 int len = src[idx++];
266 if (len & 0xC0) { /* Compressed name, offset in this and the next octet */
267 unsigned short offset = ((len & 0x3F) << 8) | src[idx++];
268 parse_dns_name(dest, src, offset - 12);
271 memcpy(dest, src+idx, len);
284 void pkt_printf_dns(struct dns_pkt* pkt) {{{
285 printf("DNS-Packet:\n");
286 printf("\tid: %d\n", ntohs(pkt->id));
287 printf("\t%d: %s\n", pkt->qr, pkt->qr == 0 ? "query" : "response");
288 printf("\top: %s\n", (char*[]){"query", "inverse q.", "status", "inval"}[pkt->op]);
289 printf("\trecursion is%s desired\n", pkt->rd == 0 ? " not" : "");
290 unsigned short qdcount = ntohs(pkt->qdcount);
291 unsigned short ancount = ntohs(pkt->ancount);
292 unsigned short nscount = ntohs(pkt->nscount);
293 unsigned short arcount = ntohs(pkt->arcount);
294 printf("\t#qd: %d\n", qdcount);
295 printf("\t#an: %d\n", ancount);
296 printf("\t#ns: %d\n", nscount);
297 printf("\t#ar: %d\n", arcount);
299 struct dns_query** queries = alloca(qdcount*sizeof(struct dns_query*));
300 struct dns_record** answers = alloca(ancount*sizeof(struct dns_record*));
301 struct dns_record** nameserver = alloca(nscount*sizeof(struct dns_record*));
302 struct dns_record** additional = alloca(arcount*sizeof(struct dns_record*));
303 unsigned short idx = 0;
306 for (i = 0; i < qdcount; i++) { /*{{{*/
307 queries[i] = alloca(sizeof(struct dns_query));
308 queries[i]->name = alloca(255); // see RFC1035
309 unsigned char* name = queries[i]->name;
311 idx = parse_dns_name(name, pkt->data, idx);
314 queries[i]->qtype = *((unsigned short*)(pkt->data+idx));
316 queries[i]->qclass = *((unsigned short*)(pkt->data+idx));
318 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)));
321 for (i = 0; i < ancount; i++) { /*{{{*/
322 answers[i] = alloca(sizeof(struct dns_record));
323 answers[i]->name = alloca(255); // see RFC1035
324 unsigned char* name = answers[i]->name;
326 idx = parse_dns_name(name, pkt->data, idx);
329 answers[i]->type = *((unsigned short*)(pkt->data+idx));
331 answers[i]->class = *((unsigned short*)(pkt->data+idx));
333 answers[i]->ttl = *((unsigned int*)(pkt->data+idx));
335 answers[i]->data_len = *((unsigned short*)(pkt->data+idx));
337 answers[i]->data = alloca(ntohs(answers[i]->data_len));
338 memcpy(answers[i]->data, pkt->data+idx, ntohs(answers[i]->data_len));
339 idx += ntohs(answers[i]->data_len);
341 printf("answer for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", answers[i]->name, ntohs(answers[i]->type), dns_types(ntohs(answers[i]->type)), ntohs(answers[i]->class), dns_classes(ntohs(answers[i]->class)), ntohl(answers[i]->ttl), ntohs(answers[i]->data_len));
344 for (i = 0; i < nscount; i++) { /*{{{*/
345 nameserver[i] = alloca(sizeof(struct dns_record));
346 nameserver[i]->name = alloca(255); // see RFC1035
347 unsigned char* name = nameserver[i]->name;
349 idx = parse_dns_name(name, pkt->data, idx);
352 nameserver[i]->type = *((unsigned short*)(pkt->data+idx));
354 nameserver[i]->class = *((unsigned short*)(pkt->data+idx));
356 nameserver[i]->ttl = *((unsigned int*)(pkt->data+idx));
358 nameserver[i]->data_len = *((unsigned short*)(pkt->data+idx));
360 nameserver[i]->data = alloca(ntohs(nameserver[i]->data_len));
361 memcpy(nameserver[i]->data, pkt->data+idx, ntohs(nameserver[i]->data_len));
362 idx += ntohs(nameserver[i]->data_len);
364 printf("nameserver for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", nameserver[i]->name, ntohs(nameserver[i]->type), dns_types(ntohs(nameserver[i]->type)), ntohs(nameserver[i]->class), dns_classes(ntohs(nameserver[i]->class)), ntohl(nameserver[i]->ttl), ntohs(nameserver[i]->data_len));
367 for (i = 0; i < arcount; i++) { /*{{{*/
368 additional[i] = alloca(sizeof(struct dns_query));
369 additional[i]->name = alloca(255); // see RFC1035
370 unsigned char* name = additional[i]->name;
372 idx = parse_dns_name(name, pkt->data, idx);
375 additional[i]->type = *((unsigned short*)(pkt->data+idx));
377 additional[i]->class = *((unsigned short*)(pkt->data+idx));
379 additional[i]->ttl = *((unsigned int*)(pkt->data+idx));
381 additional[i]->data_len = *((unsigned short*)(pkt->data+idx));
383 additional[i]->data = alloca(ntohs(additional[i]->data_len));
384 memcpy(additional[i]->data, pkt->data+idx, ntohs(additional[i]->data_len));
385 idx += ntohs(additional[i]->data_len);
387 printf("additional record for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", additional[i]->name, ntohs(additional[i]->type), dns_types(ntohs(additional[i]->type)), ntohs(additional[i]->class), dns_classes(ntohs(additional[i]->class)), ntohl(additional[i]->ttl), ntohs(additional[i]->data_len));
392 void pkt_printf_udp_dns(struct udp_dns* pkt) {{{
393 pkt_printf_dns(&pkt->data);
396 void pkt_printf_ip6dns(struct ip6_udp_dns* pkt) {{{
397 pkt_printf_udp_dns(&pkt->udp_dns);
400 void pkt_printf_ipdns(struct ip_udp_dns* pkt) {{{
401 pkt_printf_udp_dns(&pkt->udp_dns);