increase timeout to give sparc buildbot a chance
[oweals/gnunet.git] / src / vpn / gnunet-vpn-pretty-print.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <malloc.h>
6 #ifndef _WIN32
7  #include <arpa/inet.h>
8 #else
9 #include <ws2tcpip.h>
10 #endif
11
12 #include "gnunet-vpn-packet.h"
13
14 static char* pretty = /*{{{*/
15 /*     0       1         2         3         4        5          6
16  0123456789012345678901234567890123456789012345678901234567890123456789 */
17 "IPv6-Paket from xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx    \n" //60
18 "             to xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx    \n" //120
19 /*     0       1         2         3         4        5          6
20  0123456789012345678901234567890123456789012345678901234567890123456789 */
21 "        flow    0xXXX (        )                           \n" //180
22 "        length  0xXX  (   )                                \n" //240
23 "        nexthdr 0xXX  (                                    \n" //300
24 "        hoplmt  0xXX  (   )                                \n" //360
25 "first 128 bytes of payload:                                \n" //420
26 /*     0       1         2         3         4        5          6
27  0123456789012345678901234567890123456789012345678901234567890123456789 */
28 "XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX | ................  \n" //490
29 "XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX | ................  \n" //560
30 "XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX | ................  \n" //630
31 "XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX | ................  \n" //700
32 "XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX | ................  \n" //770
33 "XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX | ................  \n" //840
34 "XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX | ................  \n" //910
35 "XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX | ................  \n";//980
36 /*}}}*/
37
38 static void pp_ip6adr(unsigned char* adr, char* dest) {{{
39         char tmp[3];
40
41         sprintf(tmp, "%02X", adr[0]);
42         memcpy(dest+0, tmp, 2);
43         sprintf(tmp, "%02X", adr[1]);
44         memcpy(dest+2, tmp, 2);
45
46         sprintf(tmp, "%02X", adr[2]);
47         memcpy(dest+5, tmp, 2);
48         sprintf(tmp, "%02X", adr[3]);
49         memcpy(dest+7, tmp, 2);
50
51         sprintf(tmp, "%02X", adr[4]);
52         memcpy(dest+10, tmp, 2);
53         sprintf(tmp, "%02X", adr[5]);
54         memcpy(dest+12, tmp, 2);
55
56         sprintf(tmp, "%02X", adr[6]);
57         memcpy(dest+15, tmp, 2);
58         sprintf(tmp, "%02X", adr[7]);
59         memcpy(dest+17, tmp, 2);
60
61         sprintf(tmp, "%02X", adr[8]);
62         memcpy(dest+20, tmp, 2);
63         sprintf(tmp, "%02X", adr[9]);
64         memcpy(dest+22, tmp, 2);
65
66         sprintf(tmp, "%02X", adr[10]);
67         memcpy(dest+25, tmp, 2);
68         sprintf(tmp, "%02X", adr[11]);
69         memcpy(dest+27, tmp, 2);
70
71         sprintf(tmp, "%02X", adr[12]);
72         memcpy(dest+30, tmp, 2);
73         sprintf(tmp, "%02X", adr[13]);
74         memcpy(dest+32, tmp, 2);
75
76         sprintf(tmp, "%02X", adr[14]);
77         memcpy(dest+35, tmp, 2);
78         sprintf(tmp, "%02X", adr[15]);
79         memcpy(dest+37, tmp, 2);
80 }}}
81
82 void pp_hexdump(unsigned char* data, char* dest, int max) {{{
83         int i;
84         char tmp[3];
85         char tmp2[2];
86         int off = 0;
87         int to = max > 16 ? 16 : max;
88         for (i = 0; i < to; i++) {
89                 if (i == 8) off = 1;
90                 sprintf(tmp, "%02x", data[i]);
91                 memcpy(dest+(3*i)+off, tmp, 2);
92                 if (isprint(data[i])) {
93                         sprintf(tmp2, "%c", data[i]);
94                         memcpy(dest+51+i, tmp2, 1);
95                 }
96         }
97 }}}
98
99 void pp_write_header(char* dest, struct ip6_pkt* pkt) {{{
100         switch (pkt->ip6_hdr.nxthdr) {
101                 case 0x3a:
102                         memcpy(dest, "ICMPv6)", 7);
103                         break;
104                 case 0x06:
105                         memcpy(dest, "TCP)", 4);
106                         break;
107                 case 0x11:
108                         memcpy(dest, "UDP)", 4);
109                         break;
110                 default:
111                         memcpy(dest, "unknown)", 8);
112                         break;
113         }
114 }}}
115
116 void pkt_printf(struct ip6_pkt* pkt) {{{
117         char* buf = alloca(strlen(pretty)+1);
118         char tmp[9];
119
120         memcpy(buf, pretty, strlen(pretty)+1);
121
122         pp_ip6adr(pkt->ip6_hdr.sadr, buf+16);
123         pp_ip6adr(pkt->ip6_hdr.dadr, buf+76);
124
125         int flow = (ntohl(pkt->ip6_hdr.flowlbl));
126         sprintf(tmp, "%03x", flow);
127         memcpy(buf+138, tmp, 3);
128         sprintf(tmp, "%-8d", flow);
129         memcpy(buf+143, tmp, 8);
130
131         int length = ntohs(pkt->ip6_hdr.paylgth);
132         sprintf(tmp, "%02x", length);
133         memcpy(buf+198, tmp, 2);
134         sprintf(tmp, "%-3d", length);
135         memcpy(buf+203, tmp, 3);
136
137         sprintf(tmp, "%02x", pkt->ip6_hdr.nxthdr);
138         memcpy(buf+258, tmp, 2);
139         pp_write_header(buf+263, pkt);
140
141         sprintf(tmp, "%02x", pkt->ip6_hdr.hoplmt);
142         memcpy(buf+318, tmp, 2);
143         sprintf(tmp, "%-3d", pkt->ip6_hdr.hoplmt);
144         memcpy(buf+323, tmp, 3);
145
146         int size = ntohs(pkt->ip6_hdr.paylgth);
147         int i;
148         for(i = 0; i < 8; i++) {
149                 if (16*i > size) break;
150                 pp_hexdump(pkt->data + (16*i), buf + 420 + (i*70), size - 16*i);
151         }
152
153         printf("%s", buf);
154 }}}
155
156 void pkt_printf_ip6tcp(struct ip6_tcp* pkt) {{{
157         printf("spt: %u\n", ntohs(pkt->tcp_hdr.spt));
158         printf("dpt: %u\n", ntohs(pkt->tcp_hdr.dpt));
159         printf("seq: %u\n", ntohs(pkt->tcp_hdr.seq));
160         printf("ack: %u\n", ntohs(pkt->tcp_hdr.ack));
161         printf("off: %u\n", ntohs(pkt->tcp_hdr.off));
162         printf("wsz: %u\n", ntohs(pkt->tcp_hdr.wsz));
163         printf("crc: 0x%x\n", ntohs(pkt->tcp_hdr.crc));
164         printf("urg: %u\n", ntohs(pkt->tcp_hdr.urg));
165         printf("flags: %c%c%c%c%c%c%c%c\n",
166                         pkt->tcp_hdr.flg & 0x80 ? 'C' : '.',
167                         pkt->tcp_hdr.flg & 0x40 ? 'E' : '.',
168                         pkt->tcp_hdr.flg & 0x20 ? 'U' : '.',
169                         pkt->tcp_hdr.flg & 0x10 ? 'A' : '.',
170                         pkt->tcp_hdr.flg & 0x08 ? 'P' : '.',
171                         pkt->tcp_hdr.flg & 0x04 ? 'R' : '.',
172                         pkt->tcp_hdr.flg & 0x02 ? 'S' : '.',
173                         pkt->tcp_hdr.flg & 0x01 ? 'F' : '.'
174                         );
175 }}}
176
177 void pkt_printf_ip6udp(struct ip6_udp* pkt) {{{
178         printf("spt: %u\n", ntohs(pkt->udp_hdr.spt));
179         printf("dpt: %u\n", ntohs(pkt->udp_hdr.dpt));
180         printf("len: %u\n", ntohs(pkt->udp_hdr.len));
181         printf("crc: 0x%x\n", ntohs(pkt->udp_hdr.crc));
182 }}}
183
184 static char* dns_types(unsigned short type) {{{
185         static char* types[] = { /*{{{*/
186                 "",
187                 "A",              // 1 a host address
188                 "NS",             // 2 an authoritative name server
189                 "MD",             // 3 a mail destination (Obsolete - use MX)
190                 "MF",             // 4 a mail forwarder (Obsolete - use MX)
191                 "CNAME",          // 5 the canonical name for an alias
192                 "SOA",            // 6 marks the start of a zone of authority
193                 "MB",             // 7 a mailbox domain name (EXPERIMENTAL)
194                 "MG",             // 8 a mail group member (EXPERIMENTAL)
195                 "MR",             // 9 a mail rename domain name (EXPERIMENTAL)
196                 "NULL",           // 10 a null RR (EXPERIMENTAL)
197                 "WKS",            // 11 a well known service description
198                 "PTR",            // 12 a domain name pointer
199                 "HINFO",          // 13 host information
200                 "MINFO",          // 14 mailbox or mail list information
201                 "MX",             // 15 mail exchange
202                 "TXT",            // 16 text strings
203                 "RP",
204                 "AFSDB"
205         }; /*}}}*/
206
207         static char* qtypes[] = { /* + 252! {{{ */
208                 "AXFR",           // 252 A request for a transfer of an entire zone
209                 "MAILB",          // 253 A request for mailbox-related records (MB, MG or MR)
210                 "MAILA",          // 254 A request for mail agent RRs (Obsolete - see MX)
211                 "*",              // 255 A request for all records
212         }; /*}}}*/
213
214         if (type <= 18) return types[type];
215         if (type >= 252 && type <= 255) return qtypes[type-252];
216         
217         switch(type) {
218                 case 24: return "SIG";
219                 case 25: return "KEY";
220                 case 28: return "AAAA";
221                 case 29: return "LOC";
222                 case 33: return "SRV";
223                 case 35: return "NAPTR";
224                 case 36: return "KX";
225                 case 37: return "CERT";
226                 case 39: return "DNAME";
227                 case 42: return "APL";
228                 case 43: return "DS";
229                 case 44: return "SSHFP";
230                 case 45: return "IPSECKEY";
231                 case 46: return "RRSIG";
232                 case 47: return "NSEC";
233                 case 48: return "DNSKEY";
234                 case 49: return "DHCID";
235                 case 50: return "NSEC3";
236                 case 51: return "NSEC3PARAM";
237                 case 55: return "HIP";
238                 case 99: return "SPF";
239                 case 249: return "TKEY";
240                 case 250: return "TSIG";
241                 case 32768: return "TA";
242                 case 32769: return "DLV";
243         }
244
245         return 0;
246
247 }}}
248
249 static char* dns_classes(short class) {{{
250         static char* classes[] = { /*{{{*/
251                 "",
252                 "IN", // 1 the Internet
253                 "CS", // 2 the CSNET class (Obsolete - used only for examples in some obsolete RFCs)
254                 "CH", // 3 the CHAOS class
255                 "HS", // 4 Hesiod [Dyer 87]
256         }; /*}}}*/
257
258         if (class <= 4) return classes[class];
259         return 0;
260 }}}
261
262 unsigned int parse_dns_name(unsigned char* d, const unsigned char* src, unsigned short idx) {/*{{{*/
263         unsigned char* dest = d;
264
265         int len = src[idx++];
266         while (len != 0) {
267                 if (len & 0xC0) { /* Compressed name, offset in this and the next octet */
268                         unsigned short offset = ((len & 0x3F) << 8) | src[idx++];
269                         parse_dns_name(dest, src, offset - 12);
270                         return idx;
271                 }
272                 memcpy(dest, src+idx, len);
273                 idx += len;
274                 dest += len;
275                 *dest = '.';
276                 dest++;
277                 len = src[idx++];
278         };
279         *dest = 0;
280
281         return idx;
282 }
283 /*}}}*/
284
285 void pkt_printf_dns(struct dns_pkt* pkt) {{{
286         printf("DNS-Packet:\n");
287         printf("\tid: %d\n", ntohs(pkt->id));
288         printf("\t%d: %s\n", pkt->qr, pkt->qr == 0 ? "query" : "response");
289         printf("\top: %s\n", (char*[]){"query", "inverse q.", "status", "inval"}[pkt->op]);
290         printf("\trecursion is%s desired\n", pkt->rd == 0 ? " not" : "");
291         unsigned short qdcount = ntohs(pkt->qdcount);
292         unsigned short ancount = ntohs(pkt->ancount);
293         unsigned short nscount = ntohs(pkt->nscount);
294         unsigned short arcount = ntohs(pkt->arcount);
295         printf("\t#qd: %d\n", qdcount);
296         printf("\t#an: %d\n", ancount);
297         printf("\t#ns: %d\n", nscount);
298         printf("\t#ar: %d\n", arcount);
299         
300         struct dns_query** queries = alloca(qdcount*sizeof(struct dns_query*));
301         struct dns_record** answers = alloca(ancount*sizeof(struct dns_record*));
302         struct dns_record** nameserver = alloca(nscount*sizeof(struct dns_record*));
303         struct dns_record** additional = alloca(arcount*sizeof(struct dns_record*));
304         unsigned short idx = 0;
305
306         int i;
307         for (i = 0; i < qdcount; i++) { /*{{{*/
308                 queries[i] = alloca(sizeof(struct dns_query));
309                 queries[i]->name = alloca(255); // see RFC1035
310                 unsigned char* name = queries[i]->name;
311
312                 idx = parse_dns_name(name, pkt->data, idx);
313
314                 printf("%d\n", idx);
315                 queries[i]->qtype = *((unsigned short*)(pkt->data+idx));
316                 idx += 2;
317                 queries[i]->qclass = *((unsigned short*)(pkt->data+idx));
318                 idx += 2;
319                 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)));
320         }
321         /*}}}*/
322         for (i = 0; i < ancount; i++) { /*{{{*/
323                 answers[i] = alloca(sizeof(struct dns_record));
324                 answers[i]->name = alloca(255); // see RFC1035
325                 unsigned char* name = answers[i]->name;
326
327                 idx = parse_dns_name(name, pkt->data, idx);
328
329                 printf("%d\n", idx);
330                 answers[i]->type = *((unsigned short*)(pkt->data+idx));
331                 idx += 2;
332                 answers[i]->class = *((unsigned short*)(pkt->data+idx));
333                 idx += 2;
334                 answers[i]->ttl = *((unsigned int*)(pkt->data+idx));
335                 idx += 4;
336                 answers[i]->data_len = *((unsigned short*)(pkt->data+idx));
337                 idx += 2;
338                 answers[i]->data = alloca(ntohs(answers[i]->data_len));
339                 memcpy(answers[i]->data, pkt->data+idx, ntohs(answers[i]->data_len));
340                 idx += ntohs(answers[i]->data_len);
341
342                 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));
343         }
344         /*}}}*/
345         for (i = 0; i < nscount; i++) { /*{{{*/
346                 nameserver[i] = alloca(sizeof(struct dns_record));
347                 nameserver[i]->name = alloca(255); // see RFC1035
348                 unsigned char* name = nameserver[i]->name;
349
350                 idx = parse_dns_name(name, pkt->data, idx);
351
352                 printf("%d\n", idx);
353                 nameserver[i]->type = *((unsigned short*)(pkt->data+idx));
354                 idx += 2;
355                 nameserver[i]->class = *((unsigned short*)(pkt->data+idx));
356                 idx += 2;
357                 nameserver[i]->ttl = *((unsigned int*)(pkt->data+idx));
358                 idx += 4;
359                 nameserver[i]->data_len = *((unsigned short*)(pkt->data+idx));
360                 idx += 2;
361                 nameserver[i]->data = alloca(ntohs(nameserver[i]->data_len));
362                 memcpy(nameserver[i]->data, pkt->data+idx, ntohs(nameserver[i]->data_len));
363                 idx += ntohs(nameserver[i]->data_len);
364
365                 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));
366         }
367         /*}}}*/
368         for (i = 0; i < arcount; i++) { /*{{{*/
369                 additional[i] = alloca(sizeof(struct dns_query));
370                 additional[i]->name = alloca(255); // see RFC1035
371                 unsigned char* name = additional[i]->name;
372
373                 idx = parse_dns_name(name, pkt->data, idx);
374
375                 printf("%d\n", idx);
376                 additional[i]->type = *((unsigned short*)(pkt->data+idx));
377                 idx += 2;
378                 additional[i]->class = *((unsigned short*)(pkt->data+idx));
379                 idx += 2;
380                 additional[i]->ttl = *((unsigned int*)(pkt->data+idx));
381                 idx += 4;
382                 additional[i]->data_len = *((unsigned short*)(pkt->data+idx));
383                 idx += 2;
384                 additional[i]->data = alloca(ntohs(additional[i]->data_len));
385                 memcpy(additional[i]->data, pkt->data+idx, ntohs(additional[i]->data_len));
386                 idx += ntohs(additional[i]->data_len);
387
388                 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));
389         }
390         /*}}}*/
391 }}}
392
393 void pkt_printf_udp_dns(struct udp_dns* pkt) {{{
394         pkt_printf_dns(&pkt->data);
395 }}}
396
397 void pkt_printf_ip6dns(struct ip6_udp_dns* pkt) {{{
398         pkt_printf_udp_dns(&pkt->udp_dns);
399 }}}
400
401 void pkt_printf_ipdns(struct ip_udp_dns* pkt) {{{
402         pkt_printf_udp_dns(&pkt->udp_dns);
403 }}}