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 | ||
8 | static char *d; | |
9 | ||
10 | unsigned int printrecord_cat(stralloc *out,const char *buf,unsigned int len,unsigned int pos,const char *q,const char qtype[2]) | |
11 | { | |
12 | const char *x; | |
13 | char misc[20]; | |
14 | uint16 datalen; | |
15 | uint16 u16; | |
16 | uint32 u32; | |
17 | unsigned int newpos; | |
18 | int i; | |
19 | unsigned char ch; | |
20 | ||
21 | pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; | |
22 | pos = dns_packet_copy(buf,len,pos,misc,10); if (!pos) return 0; | |
23 | uint16_unpack_big(misc + 8,&datalen); | |
24 | newpos = pos + datalen; | |
25 | ||
26 | if (q) { | |
27 | if (!dns_domain_equal(d,q)) | |
28 | return newpos; | |
29 | if (byte_diff(qtype,2,misc) && byte_diff(qtype,2,DNS_T_ANY)) | |
30 | return newpos; | |
31 | } | |
32 | ||
33 | if (!dns_domain_todot_cat(out,d)) return 0; | |
34 | if (!stralloc_cats(out," ")) return 0; | |
35 | uint32_unpack_big(misc + 4,&u32); | |
36 | if (!stralloc_catulong0(out,u32,0)) return 0; | |
37 | ||
38 | if (byte_diff(misc + 2,2,DNS_C_IN)) { | |
39 | if (!stralloc_cats(out," weird class\n")) return 0; | |
40 | return newpos; | |
41 | } | |
42 | ||
43 | x = 0; | |
44 | if (byte_equal(misc,2,DNS_T_NS)) x = " NS "; | |
45 | if (byte_equal(misc,2,DNS_T_PTR)) x = " PTR "; | |
46 | if (byte_equal(misc,2,DNS_T_CNAME)) x = " CNAME "; | |
47 | if (x) { | |
48 | pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; | |
49 | if (!stralloc_cats(out,x)) return 0; | |
50 | if (!dns_domain_todot_cat(out,d)) return 0; | |
51 | } | |
52 | else if (byte_equal(misc,2,DNS_T_MX)) { | |
53 | if (!stralloc_cats(out," MX ")) return 0; | |
54 | pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; | |
55 | pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; | |
56 | uint16_unpack_big(misc,&u16); | |
57 | if (!stralloc_catulong0(out,u16,0)) return 0; | |
58 | if (!stralloc_cats(out," ")) return 0; | |
59 | if (!dns_domain_todot_cat(out,d)) return 0; | |
60 | } | |
61 | else if (byte_equal(misc,2,DNS_T_SOA)) { | |
62 | if (!stralloc_cats(out," SOA ")) return 0; | |
63 | pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; | |
64 | if (!dns_domain_todot_cat(out,d)) return 0; | |
65 | if (!stralloc_cats(out," ")) return 0; | |
66 | pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; | |
67 | if (!dns_domain_todot_cat(out,d)) return 0; | |
68 | pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) return 0; | |
69 | for (i = 0;i < 5;++i) { | |
70 | if (!stralloc_cats(out," ")) return 0; | |
71 | uint32_unpack_big(misc + 4 * i,&u32); | |
72 | if (!stralloc_catulong0(out,u32,0)) return 0; | |
73 | } | |
74 | } | |
75 | else if (byte_equal(misc,2,DNS_T_A)) { | |
76 | if (datalen != 4) { errno = error_proto; return 0; } | |
77 | if (!stralloc_cats(out," A ")) return 0; | |
78 | pos = dns_packet_copy(buf,len,pos,misc,4); if (!pos) return 0; | |
79 | for (i = 0;i < 4;++i) { | |
80 | ch = misc[i]; | |
81 | if (i) if (!stralloc_cats(out,".")) return 0; | |
82 | if (!stralloc_catulong0(out,ch,0)) return 0; | |
83 | } | |
84 | } | |
85 | else { | |
86 | if (!stralloc_cats(out," ")) return 0; | |
87 | uint16_unpack_big(misc,&u16); | |
88 | if (!stralloc_catulong0(out,u16,0)) return 0; | |
89 | if (!stralloc_cats(out," ")) return 0; | |
90 | while (datalen--) { | |
91 | pos = dns_packet_copy(buf,len,pos,misc,1); if (!pos) return 0; | |
92 | if ((misc[0] >= 33) && (misc[0] <= 126) && (misc[0] != '\\')) { | |
93 | if (!stralloc_catb(out,misc,1)) return 0; | |
94 | } | |
95 | else { | |
96 | ch = misc[0]; | |
97 | misc[3] = '0' + (7 & ch); ch >>= 3; | |
98 | misc[2] = '0' + (7 & ch); ch >>= 3; | |
99 | misc[1] = '0' + (7 & ch); | |
100 | misc[0] = '\\'; | |
101 | if (!stralloc_catb(out,misc,4)) return 0; | |
102 | } | |
103 | } | |
104 | } | |
105 | ||
106 | if (!stralloc_cats(out,"\n")) return 0; | |
107 | if (pos != newpos) { errno = error_proto; return 0; } | |
108 | return newpos; | |
109 | } | |
110 | ||
111 | unsigned int printrecord(stralloc *out,const char *buf,unsigned int len,unsigned int pos,const char *q,const char qtype[2]) | |
112 | { | |
113 | if (!stralloc_copys(out,"")) return 0; | |
114 | return printrecord_cat(out,buf,len,pos,q,qtype); | |
115 | } |