]>
Commit | Line | Data |
---|---|---|
870a0fe4 AT |
1 | #ifdef HAVE_CONFIG_H |
2 | #include "config.h" | |
3 | #endif | |
ff6a1e7b BH |
4 | #include "dnsparser.hh" |
5 | #include "sstuff.hh" | |
6 | #include "misc.hh" | |
a0a276c2 BH |
7 | #include "dnswriter.hh" |
8 | #include "dnsrecords.hh" | |
b0d4fb45 | 9 | #include "statbag.hh" |
c5c4fbdc | 10 | #include <boost/array.hpp> |
b0d4fb45 | 11 | StatBag S; |
ff6a1e7b BH |
12 | |
13 | int main(int argc, char** argv) | |
14 | try | |
15 | { | |
ee6c3a6b | 16 | bool dnssec=false; |
b97043ee | 17 | bool recurse=false; |
c5c4fbdc | 18 | bool tcp=false; |
b8adb30d | 19 | bool showflags=false; |
b19ad29b | 20 | bool hidesoadetails=false; |
ee6c3a6b | 21 | |
b0d4fb45 | 22 | reportAllTypes(); |
a0a276c2 | 23 | |
ee6c3a6b | 24 | if(argc < 5) { |
b0d6eced | 25 | cerr<<"Syntax: sdig IP-address port question question-type [dnssec] [recurse] [showflags] [hidesoadetails] [tcp]\n"; |
a8ad4624 BH |
26 | exit(EXIT_FAILURE); |
27 | } | |
a0a276c2 | 28 | |
b19ad29b RA |
29 | if (argc > 5) { |
30 | for(int i=5; i<argc; i++) { | |
31 | if (strcmp(argv[i], "dnssec") == 0) | |
32 | dnssec=true; | |
33 | if (strcmp(argv[i], "recurse") == 0) | |
34 | recurse=true; | |
b0d6eced KM |
35 | if (strcmp(argv[i], "showflags") == 0) |
36 | showflags=true; | |
b19ad29b RA |
37 | if (strcmp(argv[i], "hidesoadetails") == 0) |
38 | hidesoadetails=true; | |
b0d6eced | 39 | if (strcmp(argv[i], "tcp") == 0) { |
b19ad29b RA |
40 | tcp=true; |
41 | } | |
42 | } | |
b97043ee PD |
43 | } |
44 | ||
a0a276c2 | 45 | vector<uint8_t> packet; |
bca6643b | 46 | |
eaedd091 | 47 | DNSPacketWriter pw(packet, DNSName(argv[3]), DNSRecordContent::TypeToNumber(argv[4])); |
a0a276c2 | 48 | |
794c2f92 | 49 | if(dnssec || getenv("SDIGBUFSIZE")) |
ee6c3a6b | 50 | { |
794c2f92 PD |
51 | char *sbuf=getenv("SDIGBUFSIZE"); |
52 | int bufsize; | |
53 | if(sbuf) | |
54 | bufsize=atoi(sbuf); | |
55 | else | |
56 | bufsize=2800; | |
57 | ||
a40a830c | 58 | pw.addOpt(bufsize, 0, dnssec ? EDNSOpts::DNSSECOK : 0); |
ee6c3a6b PD |
59 | pw.commit(); |
60 | } | |
b97043ee PD |
61 | |
62 | if(recurse) | |
63 | { | |
64 | pw.getHeader()->rd=true; | |
65 | } | |
bca6643b | 66 | // pw.setRD(true); |
bca6643b | 67 | |
d59b894d | 68 | /* |
bca6643b BH |
69 | pw.startRecord("powerdns.com", DNSRecordContent::TypeToNumber("NS")); |
70 | NSRecordContent nrc("ns1.powerdns.com"); | |
a0a276c2 | 71 | nrc.toPacket(pw); |
878435ce | 72 | |
bca6643b BH |
73 | pw.startRecord("powerdns.com", DNSRecordContent::TypeToNumber("NS")); |
74 | NSRecordContent nrc2("ns2.powerdns.com"); | |
75 | nrc2.toPacket(pw); | |
bca6643b | 76 | */ |
edb1c9ee | 77 | |
edb1c9ee | 78 | /* DNSPacketWriter::optvect_t opts; |
fdf05fd4 BH |
79 | |
80 | opts.push_back(make_pair(5, ping)); | |
a5d9f5f9 | 81 | |
0c70797e | 82 | pw.commit(); |
edb1c9ee | 83 | */ |
a5d9f5f9 BH |
84 | // pw.addOpt(5200, 0, 0); |
85 | // pw.commit(); | |
86 | ||
ff6a1e7b | 87 | string reply; |
4a549837 | 88 | ComboAddress dest(argv[1] + (*argv[1]=='@'), atoi(argv[2])); |
ff6a1e7b | 89 | |
c5c4fbdc | 90 | if(tcp) { |
4a549837 | 91 | Socket sock(dest.sin4.sin_family, SOCK_STREAM); |
c5c4fbdc PD |
92 | sock.connect(dest); |
93 | uint16_t len; | |
94 | len = htons(packet.size()); | |
95 | if(sock.write((char *) &len, 2) != 2) | |
3f81d239 | 96 | throw PDNSException("tcp write failed"); |
c5c4fbdc PD |
97 | |
98 | sock.writen(string((char*)&*packet.begin(), (char*)&*packet.end())); | |
99 | ||
100 | if(sock.read((char *) &len, 2) != 2) | |
3f81d239 | 101 | throw PDNSException("tcp read failed"); |
c5c4fbdc PD |
102 | |
103 | len=ntohs(len); | |
104 | char *creply = new char[len]; | |
105 | int n=0; | |
106 | int numread; | |
107 | while(n<len) { | |
108 | numread=sock.read(creply+n, len-n); | |
109 | if(numread<0) | |
3f81d239 | 110 | throw PDNSException("tcp read failed"); |
c5c4fbdc PD |
111 | n+=numread; |
112 | } | |
113 | ||
114 | reply=string(creply, len); | |
115 | delete[] creply; | |
116 | } | |
117 | else //udp | |
118 | { | |
4a549837 | 119 | Socket sock(dest.sin4.sin_family, SOCK_DGRAM); |
c5c4fbdc PD |
120 | sock.sendTo(string((char*)&*packet.begin(), (char*)&*packet.end()), dest); |
121 | ||
122 | sock.recvFrom(reply, dest); | |
123 | } | |
ff6a1e7b | 124 | MOADNSParser mdp(reply); |
9d7fa327 | 125 | cout<<"Reply to question for qname='"<<mdp.d_qname.toString()<<"', qtype="<<DNSRecordContent::NumberToType(mdp.d_qtype)<<endl; |
0c70797e | 126 | cout<<"Rcode: "<<mdp.d_header.rcode<<", RD: "<<mdp.d_header.rd<<", QR: "<<mdp.d_header.qr; |
7fc69fd0 | 127 | cout<<", TC: "<<mdp.d_header.tc<<", AA: "<<mdp.d_header.aa<<", opcode: "<<mdp.d_header.opcode<<endl; |
945a9ad4 | 128 | |
ff6a1e7b | 129 | for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) { |
f809c028 | 130 | cout<<i->first.d_place-1<<"\t"<<i->first.d_name.toString()<<"\tIN\t"<<DNSRecordContent::NumberToType(i->first.d_type); |
794c2f92 PD |
131 | if(i->first.d_type == QType::RRSIG) |
132 | { | |
133 | string zoneRep = i->first.d_content->getZoneRepresentation(); | |
134 | vector<string> parts; | |
135 | stringtok(parts, zoneRep); | |
136 | cout<<"\t"<<i->first.d_ttl<<"\t"<< parts[0]<<" "<<parts[1]<<" "<<parts[2]<<" "<<parts[3]<<" [expiry] [inception] [keytag] "<<parts[7]<<" ...\n"; | |
137 | } | |
b8adb30d KM |
138 | else if(!showflags && i->first.d_type == QType::NSEC3) |
139 | { | |
140 | string zoneRep = i->first.d_content->getZoneRepresentation(); | |
141 | vector<string> parts; | |
142 | stringtok(parts, zoneRep); | |
143 | cout<<"\t"<<i->first.d_ttl<<"\t"<< parts[0]<<" [flags] "<<parts[2]<<" "<<parts[3]<<" "<<parts[4]; | |
144 | for(vector<string>::iterator iter = parts.begin()+5; iter != parts.end(); ++iter) | |
145 | cout<<" "<<*iter; | |
146 | cout<<"\n"; | |
147 | } | |
794c2f92 PD |
148 | else if(i->first.d_type == QType::DNSKEY) |
149 | { | |
150 | string zoneRep = i->first.d_content->getZoneRepresentation(); | |
151 | vector<string> parts; | |
152 | stringtok(parts, zoneRep); | |
153 | cout<<"\t"<<i->first.d_ttl<<"\t"<< parts[0]<<" "<<parts[1]<<" "<<parts[2]<<" ...\n"; | |
154 | } | |
b19ad29b RA |
155 | else if (i->first.d_type == QType::SOA && hidesoadetails) |
156 | { | |
157 | string zoneRep = i->first.d_content->getZoneRepresentation(); | |
158 | vector<string> parts; | |
159 | stringtok(parts, zoneRep); | |
160 | cout<<"\t"<<i->first.d_ttl<<"\t"<<parts[0]<<" "<<parts[1]<<" [serial] "<<parts[3]<<" "<<parts[4]<<" "<<parts[5]<<" "<<parts[6]<<"\n"; | |
161 | } | |
794c2f92 PD |
162 | else |
163 | { | |
164 | cout<<"\t"<<i->first.d_ttl<<"\t"<< i->first.d_content->getZoneRepresentation()<<"\n"; | |
165 | } | |
166 | ||
ff6a1e7b | 167 | } |
fdf05fd4 | 168 | |
0c70797e BH |
169 | EDNSOpts edo; |
170 | if(getEDNSOpts(mdp, &edo)) { | |
a5d9f5f9 | 171 | // cerr<<"Have "<<edo.d_options.size()<<" options!"<<endl; |
0c70797e | 172 | for(vector<pair<uint16_t, string> >::const_iterator iter = edo.d_options.begin(); |
4957a608 BH |
173 | iter != edo.d_options.end(); |
174 | ++iter) { | |
fdf05fd4 | 175 | if(iter->first == 5) {// 'EDNS PING' |
4957a608 | 176 | cerr<<"Have ednsping: '"<<iter->second<<"'\n"; |
a5d9f5f9 BH |
177 | //if(iter->second == ping) |
178 | // cerr<<"It is correct!"<<endl; | |
0c70797e | 179 | } |
fdf05fd4 | 180 | else { |
4957a608 | 181 | cerr<<"Have unknown option "<<(int)iter->first<<endl; |
fdf05fd4 | 182 | } |
0c70797e BH |
183 | } |
184 | ||
185 | } | |
fdf05fd4 | 186 | |
ff6a1e7b | 187 | } |
0c70797e | 188 | catch(std::exception &e) |
ff6a1e7b BH |
189 | { |
190 | cerr<<"Fatal: "<<e.what()<<endl; | |
191 | } |