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