]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/sdig.cc
4 #include "dnsparser.hh"
7 #include "dnswriter.hh"
8 #include "dnsrecords.hh"
10 #include <boost/array.hpp>
11 #include "ednssubnet.hh"
16 string
ttl(uint32_t ttl
)
21 return std::to_string(ttl
);
26 cerr
<<"Syntax: sdig IP-ADDRESS PORT QUESTION QUESTION-TYPE [dnssec] [recurse] [showflags] [hidesoadetails] [hidettl] [tcp] [ednssubnet SUBNET/MASK]"<<endl
;
29 int main(int argc
, char** argv
)
36 bool hidesoadetails
=false;
37 boost::optional
<Netmask
> ednsnm
;
40 for(int i
=1; i
<argc
; i
++) {
41 if ((string
) argv
[i
] == "--help") {
46 if ((string
) argv
[i
] == "--version") {
47 cerr
<<"sdig "<<VERSION
<<endl
;
60 for(int i
=5; i
<argc
; i
++) {
61 if (strcmp(argv
[i
], "dnssec") == 0)
63 if (strcmp(argv
[i
], "recurse") == 0)
65 if (strcmp(argv
[i
], "showflags") == 0)
67 if (strcmp(argv
[i
], "hidesoadetails") == 0)
69 if (strcmp(argv
[i
], "hidettl") == 0)
71 if (strcmp(argv
[i
], "tcp") == 0)
73 if (strcmp(argv
[i
], "ednssubnet") == 0) {
74 ednsnm
=Netmask(argv
[++i
]);
79 vector
<uint8_t> packet
;
81 DNSPacketWriter
pw(packet
, DNSName(argv
[3]), DNSRecordContent::TypeToNumber(argv
[4]));
83 if(dnssec
|| ednsnm
|| getenv("SDIGBUFSIZE"))
85 char *sbuf
=getenv("SDIGBUFSIZE");
91 DNSPacketWriter::optvect_t opts
;
95 opts
.push_back(make_pair(8, makeEDNSSubnetOptsString(eo
)));
98 pw
.addOpt(bufsize
, 0, dnssec
? EDNSOpts::DNSSECOK
: 0, opts
);
104 pw
.getHeader()->rd
=true;
108 ComboAddress
dest(argv
[1] + (*argv
[1]=='@'), atoi(argv
[2]));
111 Socket
sock(dest
.sin4
.sin_family
, SOCK_STREAM
);
114 len
= htons(packet
.size());
115 if(sock
.write((char *) &len
, 2) != 2)
116 throw PDNSException("tcp write failed");
118 sock
.writen(string((char*)&*packet
.begin(), (char*)&*packet
.end()));
120 if(sock
.read((char *) &len
, 2) != 2)
121 throw PDNSException("tcp read failed");
124 char *creply
= new char[len
];
128 numread
=sock
.read(creply
+n
, len
-n
);
130 throw PDNSException("tcp read failed");
134 reply
=string(creply
, len
);
139 Socket
sock(dest
.sin4
.sin_family
, SOCK_DGRAM
);
140 sock
.sendTo(string((char*)&*packet
.begin(), (char*)&*packet
.end()), dest
);
141 int result
=waitForData(sock
.getHandle(), 10);
143 throw std::runtime_error("Error waiting for data: "+string(strerror(errno
)));
145 throw std::runtime_error("Timeout waiting for data");
146 sock
.recvFrom(reply
, dest
);
148 MOADNSParser
mdp(false, reply
);
149 cout
<<"Reply to question for qname='"<<mdp
.d_qname
.toString()<<"', qtype="<<DNSRecordContent::NumberToType(mdp
.d_qtype
)<<endl
;
150 cout
<<"Rcode: "<<mdp
.d_header
.rcode
<<" ("<<RCode::to_s(mdp
.d_header
.rcode
)<<"), RD: "<<mdp
.d_header
.rd
<<", QR: "<<mdp
.d_header
.qr
;
151 cout
<<", TC: "<<mdp
.d_header
.tc
<<", AA: "<<mdp
.d_header
.aa
<<", opcode: "<<mdp
.d_header
.opcode
<<endl
;
153 for(MOADNSParser::answers_t::const_iterator i
=mdp
.d_answers
.begin(); i
!=mdp
.d_answers
.end(); ++i
) {
154 cout
<<i
->first
.d_place
-1<<"\t"<<i
->first
.d_name
.toString()<<"\tIN\t"<<DNSRecordContent::NumberToType(i
->first
.d_type
);
155 if(i
->first
.d_type
== QType::RRSIG
)
157 string zoneRep
= i
->first
.d_content
->getZoneRepresentation();
158 vector
<string
> parts
;
159 stringtok(parts
, zoneRep
);
160 cout
<<"\t"<<ttl(i
->first
.d_ttl
)<<"\t"<< parts
[0]<<" "<<parts
[1]<<" "<<parts
[2]<<" "<<parts
[3]<<" [expiry] [inception] [keytag] "<<parts
[7]<<" ...\n";
162 else if(!showflags
&& i
->first
.d_type
== QType::NSEC3
)
164 string zoneRep
= i
->first
.d_content
->getZoneRepresentation();
165 vector
<string
> parts
;
166 stringtok(parts
, zoneRep
);
167 cout
<<"\t"<<ttl(i
->first
.d_ttl
)<<"\t"<< parts
[0]<<" [flags] "<<parts
[2]<<" "<<parts
[3]<<" "<<parts
[4];
168 for(vector
<string
>::iterator iter
= parts
.begin()+5; iter
!= parts
.end(); ++iter
)
172 else if(i
->first
.d_type
== QType::DNSKEY
)
174 string zoneRep
= i
->first
.d_content
->getZoneRepresentation();
175 vector
<string
> parts
;
176 stringtok(parts
, zoneRep
);
177 cout
<<"\t"<<ttl(i
->first
.d_ttl
)<<"\t"<< parts
[0]<<" "<<parts
[1]<<" "<<parts
[2]<<" ...\n";
179 else if (i
->first
.d_type
== QType::SOA
&& hidesoadetails
)
181 string zoneRep
= i
->first
.d_content
->getZoneRepresentation();
182 vector
<string
> parts
;
183 stringtok(parts
, zoneRep
);
184 cout
<<"\t"<<ttl(i
->first
.d_ttl
)<<"\t"<<parts
[0]<<" "<<parts
[1]<<" [serial] "<<parts
[3]<<" "<<parts
[4]<<" "<<parts
[5]<<" "<<parts
[6]<<"\n";
188 cout
<<"\t"<<ttl(i
->first
.d_ttl
)<<"\t"<< i
->first
.d_content
->getZoneRepresentation()<<"\n";
194 if(getEDNSOpts(mdp
, &edo
)) {
195 // cerr<<"Have "<<edo.d_options.size()<<" options!"<<endl;
196 for(vector
<pair
<uint16_t, string
> >::const_iterator iter
= edo
.d_options
.begin();
197 iter
!= edo
.d_options
.end();
199 if(iter
->first
== 5) {// 'EDNS PING'
200 cerr
<<"Have ednsping: '"<<iter
->second
<<"'\n";
201 //if(iter->second == ping)
202 // cerr<<"It is correct!"<<endl;
204 if(iter
->first
== 8) {// 'EDNS subnet'
206 if(getEDNSSubnetOptsFromString(iter
->second
, &reso
)) {
207 cerr
<<"EDNS Subnet response: "<<reso
.source
.toString()<<", scope: "<<reso
.scope
.toString()<<", family = "<<reso
.scope
.getNetwork().sin4
.sin_family
<<endl
;
212 cerr
<<"Have unknown option "<<(int)iter
->first
<<endl
;
218 catch(std::exception
&e
)
220 cerr
<<"Fatal: "<<e
.what()<<endl
;
222 catch(PDNSException
&e
)
224 cerr
<<"Fatal: "<<e
.reason
<<endl
;