diff options
Diffstat (limited to 'src/vpn/gnunet-vpn-pretty-print.c')
-rw-r--r-- | src/vpn/gnunet-vpn-pretty-print.c | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/src/vpn/gnunet-vpn-pretty-print.c b/src/vpn/gnunet-vpn-pretty-print.c new file mode 100644 index 000000000..90bbe7bea --- /dev/null +++ b/src/vpn/gnunet-vpn-pretty-print.c | |||
@@ -0,0 +1,295 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <stdio.h> | ||
3 | #include <string.h> | ||
4 | #include <ctype.h> | ||
5 | #include <arpa/inet.h> | ||
6 | |||
7 | #include "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->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 = (char*)malloc(strlen(pretty)+1); | ||
113 | char tmp[9]; | ||
114 | |||
115 | memcpy(buf, pretty, strlen(pretty)+1); | ||
116 | |||
117 | pp_ip6adr(pkt->hdr.sadr, buf+16); | ||
118 | pp_ip6adr(pkt->hdr.dadr, buf+76); | ||
119 | |||
120 | int flow = (ntohl(pkt->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->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->hdr.nxthdr); | ||
133 | memcpy(buf+258, tmp, 2); | ||
134 | pp_write_header(buf+263, pkt); | ||
135 | |||
136 | sprintf(tmp, "%02x", pkt->hdr.hoplmt); | ||
137 | memcpy(buf+318, tmp, 2); | ||
138 | sprintf(tmp, "%-3d", pkt->hdr.hoplmt); | ||
139 | memcpy(buf+323, tmp, 3); | ||
140 | |||
141 | int size = payload(&pkt->hdr); | ||
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 | free(buf); | ||
150 | }}} | ||
151 | |||
152 | void pkt_printf_ip6tcp(struct ip6_tcp* pkt) {{{ | ||
153 | printf("spt: %u\n", ntohs(pkt->data.spt)); | ||
154 | printf("dpt: %u\n", ntohs(pkt->data.dpt)); | ||
155 | printf("seq: %u\n", ntohs(pkt->data.seq)); | ||
156 | printf("ack: %u\n", ntohs(pkt->data.ack)); | ||
157 | printf("off: %u\n", ntohs(pkt->data.off)); | ||
158 | printf("wsz: %u\n", ntohs(pkt->data.wsz)); | ||
159 | printf("crc: 0x%x\n", ntohs(pkt->data.crc)); | ||
160 | printf("urg: %u\n", ntohs(pkt->data.urg)); | ||
161 | printf("flags: %c%c%c%c%c%c%c%c\n", | ||
162 | pkt->data.flg & 0x80 ? 'C' : '.', | ||
163 | pkt->data.flg & 0x40 ? 'E' : '.', | ||
164 | pkt->data.flg & 0x20 ? 'U' : '.', | ||
165 | pkt->data.flg & 0x10 ? 'A' : '.', | ||
166 | pkt->data.flg & 0x08 ? 'P' : '.', | ||
167 | pkt->data.flg & 0x04 ? 'R' : '.', | ||
168 | pkt->data.flg & 0x02 ? 'S' : '.', | ||
169 | pkt->data.flg & 0x01 ? 'F' : '.' | ||
170 | ); | ||
171 | }}} | ||
172 | |||
173 | void pkt_printf_ip6udp(struct ip6_udp* pkt) {{{ | ||
174 | printf("spt: %u\n", ntohs(pkt->data.spt)); | ||
175 | printf("dpt: %u\n", ntohs(pkt->data.dpt)); | ||
176 | printf("len: %u\n", ntohs(pkt->data.len)); | ||
177 | printf("crc: 0x%x\n", ntohs(pkt->data.crc)); | ||
178 | }}} | ||
179 | |||
180 | static 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 | |||
245 | static 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 | |||
258 | void 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 | }}} | ||