release
[hcoop/zz_old/debian/djbdns.git] / printrecord.c
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 }