| 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 | } |