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