1 #include "uint16_unpack_big.h"
2 #include "uint32_unpack_big.h"
3 #include "e.h"
4 #include "byte.h"
5 #include "dns.h"
6 #include "printrecord.h"
7 #include "iptostr.h"
8
9 static unsigned char *d = 0;
10
printrecord_cat(stralloc * out,const unsigned char * buf,long long len,long long pos,const unsigned char * q,const unsigned char qtype[2])11 long long printrecord_cat(stralloc *out,const unsigned char *buf,long long len,long long pos,const unsigned char *q,const unsigned char qtype[2])
12 {
13 const unsigned char *x;
14 unsigned char misc[20];
15 crypto_uint16 datalen;
16 crypto_uint16 u16;
17 crypto_uint32 u32;
18 long long newpos;
19 long long i;
20 unsigned char ch;
21 long long txtlen;
22
23 pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
24 pos = dns_packet_copy(buf,len,pos,misc,10); if (!pos) return 0;
25 datalen = uint16_unpack_big(misc + 8);
26 newpos = pos + datalen;
27
28 if (q) {
29 if (!dns_domain_equal(d,q))
30 return newpos;
31 if (!byte_isequal(qtype,2,misc) && !byte_isequal(qtype,2,DNS_T_ANY))
32 return newpos;
33 }
34
35 if (!dns_domain_todot_cat(out,d)) return 0;
36 if (!stralloc_cats(out," ")) return 0;
37 u32 = uint32_unpack_big(misc + 4);
38 if (!stralloc_catnum(out,u32)) return 0;
39
40 if (!byte_isequal(misc + 2,2,DNS_C_IN)) {
41 if (!stralloc_cats(out," weird class\n")) return 0;
42 return newpos;
43 }
44
45 x = 0;
46 if (byte_isequal(misc,2,DNS_T_NS)) x = (unsigned char *)" NS ";
47 if (byte_isequal(misc,2,DNS_T_PTR)) x = (unsigned char *)" PTR ";
48 if (byte_isequal(misc,2,DNS_T_CNAME)) x = (unsigned char *)" CNAME ";
49 if (x) {
50 pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
51 if (!stralloc_cats(out,x)) return 0;
52 if (!dns_domain_todot_cat(out,d)) return 0;
53 }
54 else if (byte_isequal(misc,2,DNS_T_MX)) {
55 if (!stralloc_cats(out," MX ")) return 0;
56 pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0;
57 pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
58 u16 = uint16_unpack_big(misc);
59 if (!stralloc_catnum(out,u16)) return 0;
60 if (!stralloc_cats(out," ")) return 0;
61 if (!dns_domain_todot_cat(out,d)) return 0;
62 }
63 else if (byte_isequal(misc,2,DNS_T_SOA)) {
64 if (!stralloc_cats(out," SOA ")) return 0;
65 pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
66 if (!dns_domain_todot_cat(out,d)) return 0;
67 if (!stralloc_cats(out," ")) return 0;
68 pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
69 if (!dns_domain_todot_cat(out,d)) return 0;
70 pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) return 0;
71 for (i = 0;i < 5;++i) {
72 if (!stralloc_cats(out," ")) return 0;
73 u32 = uint32_unpack_big(misc + 4 * i);
74 if (!stralloc_catnum(out,u32)) return 0;
75 }
76 }
77 else if (byte_isequal(misc,2,DNS_T_AAAA)) {
78 if (datalen != 16) { errno = EPROTO; return 0; }
79 if (!stralloc_cats(out," AAAA ")) return 0;
80 pos = dns_packet_copy(buf,len,pos,misc,16); if (!pos) return 0;
81 if (!stralloc_cats(out,iptostr(0, misc))) return 0;
82 }
83 else if (byte_isequal(misc,2,DNS_T_TXT)) {
84 if (pos + datalen > len) return -1;
85 if (!stralloc_cats(out," TXT ")) return 0;
86 txtlen = 0;
87 for (i = 0;i < datalen;++i) {
88 ch = buf[pos + i];
89 if (!txtlen)
90 txtlen = ch;
91 else {
92 --txtlen;
93 if (ch < 32 || ch > 126) {
94 misc[3] = '0' + (7 & ch); ch >>= 3;
95 misc[2] = '0' + (7 & ch); ch >>= 3;
96 misc[1] = '0' + (7 & ch);
97 misc[0] = '\\';
98 if (!stralloc_catb(out,misc,4)) return 0;
99 }
100 else {
101 if (!stralloc_append(out,&ch)) return -1;
102 }
103 }
104 }
105 pos += datalen;
106 }
107 else if (byte_isequal(misc,2,DNS_T_SRV)) {
108 if (!stralloc_cats(out," SRV ")) return 0;
109 pos = dns_packet_copy(buf,len,pos,misc,6); if (!pos) return 0;
110 u16 = uint16_unpack_big(misc);
111 if (!stralloc_catnum(out,u16)) return 0;
112 if (!stralloc_cats(out," ")) return 0;
113 u16 = uint16_unpack_big(misc + 2);
114 if (!stralloc_catnum(out,u16)) return 0;
115 if (!stralloc_cats(out," ")) return 0;
116 u16 = uint16_unpack_big(misc + 4);
117 if (!stralloc_catnum(out,u16)) return 0;
118 if (!stralloc_cats(out," ")) return 0;
119 pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
120 if (!dns_domain_todot_cat(out,d)) return 0;
121 }
122 else if (byte_isequal(misc,2,DNS_T_A)) {
123 if (datalen != 4) { errno = EPROTO; return 0; }
124 if (!stralloc_cats(out," A ")) return 0;
125 pos = dns_packet_copy(buf,len,pos,misc,4); if (!pos) return 0;
126 for (i = 0;i < 4;++i) {
127 ch = misc[i];
128 if (i) if (!stralloc_cats(out,".")) return 0;
129 if (!stralloc_catnum(out,ch)) return 0;
130 }
131 }
132 else {
133 if (!stralloc_cats(out," ")) return 0;
134 u16 = uint16_unpack_big(misc);
135 if (!stralloc_catnum(out,u16)) return 0;
136 if (!stralloc_cats(out," ")) return 0;
137 while (datalen--) {
138 pos = dns_packet_copy(buf,len,pos,misc,1); if (!pos) return 0;
139 if ((misc[0] >= 33) && (misc[0] <= 126) && (misc[0] != '\\')) {
140 if (!stralloc_catb(out,misc,1)) return 0;
141 }
142 else {
143 ch = misc[0];
144 misc[3] = '0' + (7 & ch); ch >>= 3;
145 misc[2] = '0' + (7 & ch); ch >>= 3;
146 misc[1] = '0' + (7 & ch);
147 misc[0] = '\\';
148 if (!stralloc_catb(out,misc,4)) return 0;
149 }
150 }
151 }
152
153 if (!stralloc_cats(out,"\n")) return 0;
154 if (pos != newpos) { errno = EPROTO; return 0; }
155 return newpos;
156 }
157
printrecord(stralloc * out,const unsigned char * buf,long long len,long long pos,const unsigned char * q,const unsigned char qtype[2])158 long long printrecord(stralloc *out,const unsigned char *buf,long long len,long long pos,const unsigned char *q,const unsigned char qtype[2])
159 {
160 if (!stralloc_copys(out,"")) return 0;
161 return printrecord_cat(out,buf,len,pos,q,qtype);
162 }
163