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