Commit | Line | Data |
---|---|---|
dc0d77d7 CE |
1 | #include "uint16.h" |
2 | #include "uint32.h" | |
3 | #include "error.h" | |
4 | #include "byte.h" | |
5 | #include "dns.h" | |
6 | #include "printrecord.h" | |
7 | #include "printpacket.h" | |
8 | ||
9 | static char *d; | |
10 | ||
11 | #define X(s) if (!stralloc_cats(out,s)) return 0; | |
12 | #define NUM(u) if (!stralloc_catulong0(out,u,0)) return 0; | |
13 | ||
14 | unsigned int printpacket_cat(stralloc *out,char *buf,unsigned int len) | |
15 | { | |
16 | uint16 numqueries; | |
17 | uint16 numanswers; | |
18 | uint16 numauthority; | |
19 | uint16 numglue; | |
20 | unsigned int pos; | |
21 | char data[12]; | |
22 | uint16 type; | |
23 | ||
24 | pos = dns_packet_copy(buf,len,0,data,12); if (!pos) return 0; | |
25 | ||
26 | uint16_unpack_big(data + 4,&numqueries); | |
27 | uint16_unpack_big(data + 6,&numanswers); | |
28 | uint16_unpack_big(data + 8,&numauthority); | |
29 | uint16_unpack_big(data + 10,&numglue); | |
30 | ||
31 | NUM(len) | |
32 | X(" bytes, ") | |
33 | NUM(numqueries) | |
34 | X("+") | |
35 | NUM(numanswers) | |
36 | X("+") | |
37 | NUM(numauthority) | |
38 | X("+") | |
39 | NUM(numglue) | |
40 | X(" records") | |
41 | ||
42 | if (data[2] & 128) X(", response") | |
43 | if (data[2] & 120) X(", weird op") | |
44 | if (data[2] & 4) X(", authoritative") | |
45 | if (data[2] & 2) X(", truncated") | |
46 | if (data[2] & 1) X(", weird rd") | |
47 | if (data[3] & 128) X(", weird ra") | |
48 | switch(data[3] & 15) { | |
49 | case 0: X(", noerror"); break; | |
50 | case 3: X(", nxdomain"); break; | |
51 | case 4: X(", notimp"); break; | |
52 | case 5: X(", refused"); break; | |
53 | default: X(", weird rcode"); | |
54 | } | |
55 | if (data[3] & 112) X(", weird z") | |
56 | ||
57 | X("\n") | |
58 | ||
59 | while (numqueries) { | |
60 | --numqueries; | |
61 | X("query: ") | |
62 | ||
63 | pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; | |
64 | pos = dns_packet_copy(buf,len,pos,data,4); if (!pos) return 0; | |
65 | ||
66 | if (byte_diff(data + 2,2,DNS_C_IN)) { | |
67 | X("weird class") | |
68 | } | |
69 | else { | |
70 | uint16_unpack_big(data,&type); | |
71 | NUM(type) | |
72 | X(" ") | |
73 | if (!dns_domain_todot_cat(out,d)) return 0; | |
74 | } | |
75 | X("\n") | |
76 | } | |
77 | ||
78 | for (;;) { | |
79 | if (numanswers) { --numanswers; X("answer: ") } | |
80 | else if (numauthority) { --numauthority; X("authority: ") } | |
81 | else if (numglue) { --numglue; X("additional: ") } | |
82 | else break; | |
83 | ||
84 | pos = printrecord_cat(out,buf,len,pos,0,0); | |
85 | if (!pos) return 0; | |
86 | } | |
87 | ||
88 | if (pos != len) { errno = error_proto; return 0; } | |
89 | return 1; | |
90 | } |