From 7fc69fd06c0db55f816e53eb3b66a549f241d86b Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Sat, 12 Feb 2005 19:42:44 +0000 Subject: [PATCH] make sdig useable, remove warts from dnsparser git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@308 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- pdns/dnsparser.cc | 34 ++++++++++------------- pdns/dnsparser.hh | 42 +++++++++++++++++++++++++--- pdns/dnsrecords.cc | 68 ++++++++++++---------------------------------- pdns/sdig.cc | 13 +++++---- 4 files changed, 77 insertions(+), 80 deletions(-) diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 4e5100e54..9f71228d3 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -6,30 +6,23 @@ using namespace boost; class UnknownRecordContent : public DNSRecordContent { public: - UnknownRecordContent(const struct dnsrecordheader& ah, PacketReader& pr) - : d_ah(ah) + UnknownRecordContent(const DNSRecord& dr, PacketReader& pr) + : d_dr(dr) { - pr.copyRecord(d_record, ah.d_clen); + pr.copyRecord(d_record, dr.d_clen); } - string getType() const - { - return "#"+lexical_cast(d_ah.d_type); - } - - - string getZoneRepresentation() const { ostringstream str; - if(d_ah.d_class==1) + if(d_dr.d_class==1) str<<"IN"; else - str<<"CLASS"< d_record; }; -DNSRecordContent* DNSRecordContent::mastermake(const struct dnsrecordheader& ah, +DNSRecordContent* DNSRecordContent::mastermake(const DNSRecord &dr, PacketReader& pr) { - typemap_t::const_iterator i=typemap.find(make_pair(ah.d_class, ah.d_type)); + typemap_t::const_iterator i=typemap.find(make_pair(dr.d_class, dr.d_type)); if(i==typemap.end()) { - return new UnknownRecordContent(ah, pr); + return new UnknownRecordContent(dr, pr); } - return i->second(ah, pr); + return i->second(dr, pr); } DNSRecordContent::typemap_t DNSRecordContent::typemap __attribute__((init_priority(1000))); +DNSRecordContent::namemap_t DNSRecordContent::namemap __attribute__((init_priority(1000))); void MOADNSParser::init(const char *packet, unsigned int len) { @@ -111,10 +105,10 @@ void MOADNSParser::init(const char *packet, unsigned int len) dr.d_class=ah.d_class; dr.d_label=label; - dr.d_ah=ah; + dr.d_clen=ah.d_clen; d_answers.push_back(make_pair(dr, pr.d_pos)); - dr.d_content=boost::shared_ptr(DNSRecordContent::mastermake(ah, pr)); + dr.d_content=boost::shared_ptr(DNSRecordContent::mastermake(dr, pr)); if(dr.d_content) { // cout<getZoneRepresentation(); } diff --git a/pdns/dnsparser.hh b/pdns/dnsparser.hh index 0beea764c..fff4ba542 100644 --- a/pdns/dnsparser.hh +++ b/pdns/dnsparser.hh @@ -11,6 +11,7 @@ #include #include #include +#include namespace { typedef HEADER dnsheader; @@ -31,6 +32,8 @@ struct dnsrecordheader class MOADNSParser; + + class PacketReader { public: @@ -54,20 +57,49 @@ private: }; +class DNSRecord; + class DNSRecordContent { public: - static DNSRecordContent* mastermake(const struct dnsrecordheader& ah, PacketReader& pr); + static DNSRecordContent* mastermake(const DNSRecord &dr, PacketReader& pr); virtual std::string getZoneRepresentation() const = 0; - virtual std::string getType() const=0; virtual ~DNSRecordContent() {} std::string label; struct dnsrecordheader header; + + typedef DNSRecordContent* makerfunc_t(const struct DNSRecord& dr, PacketReader& pr); + static void regist(uint16_t cl, uint16_t ty, makerfunc_t* f, const char* name) + { + typemap[make_pair(cl,ty)]=f; + namemap[make_pair(cl,ty)]=name; + } + + static uint16_t TypeToNumber(const string& name) + { + for(namemap_t::const_iterator i=namemap.begin(); i!=namemap.end();++i) + if(i->second==name) + return i->first.second; + + throw runtime_error("Unknown DNS type '"+name+"'"); + + } + + static const string NumberToType(uint16_t num) + { + if(!namemap.count(make_pair(1,num))) + throw runtime_error("Unknown DNS type with numerical id "+lexical_cast(num)); + return namemap[make_pair(1,num)]; + } + + protected: - typedef DNSRecordContent* makerfunc_t(const struct dnsrecordheader& ah, PacketReader& pr); + typedef std::map, makerfunc_t* > typemap_t; static typemap_t typemap; + typedef std::map, string > namemap_t; + static namemap_t namemap; }; struct DNSRecord @@ -76,11 +108,12 @@ struct DNSRecord u_int16_t d_type; u_int16_t d_class; u_int32_t d_ttl; + u_int16_t d_clen; enum {Answer, Nameserver, Additional} d_place; boost::shared_ptr d_content; - struct dnsrecordheader d_ah; }; + class MOADNSParser { public: @@ -96,6 +129,7 @@ public: dnsheader d_header; string d_qname; u_int16_t d_qclass, d_qtype; + uint8_t d_rcode; typedef vector > answers_t; answers_t d_answers; diff --git a/pdns/dnsrecords.cc b/pdns/dnsrecords.cc index dca3114bf..1a85e82f0 100644 --- a/pdns/dnsrecords.cc +++ b/pdns/dnsrecords.cc @@ -3,18 +3,17 @@ using namespace std; using namespace boost; - class ARecordContent : public DNSRecordContent { public: static void report(void) { - typemap[make_pair(1,1)]=&make; - } + regist(1,1,&make,"A"); + } - static DNSRecordContent* make(const struct dnsrecordheader& ah, PacketReader& pr) + static DNSRecordContent* make(const DNSRecord& dr, PacketReader& pr) { - if(ah.d_clen!=4) + if(dr.d_clen!=4) throw MOADNSException("Wrong size for A record"); ARecordContent* ret=new ARecordContent(); @@ -27,10 +26,6 @@ public: return d_ip; } - string getType() const - { - return "A"; - } string getZoneRepresentation() const { @@ -56,15 +51,9 @@ public: typemap[make_pair(1,ns_t_aaaa)]=&make; } - string getType() const - { - return "AAAA"; - } - - - static DNSRecordContent* make(const struct dnsrecordheader& ah, PacketReader& pr) + static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr) { - if(ah.d_clen!=16) + if(dr.d_clen!=16) throw MOADNSException("Wrong size for AAAA record"); AAAARecordContent* ret=new AAAARecordContent(); @@ -110,28 +99,18 @@ class OneLabelRecordContent : public DNSRecordContent { public: - OneLabelRecordContent(const struct dnsrecordheader& ah, const string& nsname) : d_type(ah.d_type), d_nsname(nsname) {} + OneLabelRecordContent(const DNSRecord &dr, const string& nsname) : d_type(dr.d_type), d_nsname(nsname) {} static void report(void) { - typemap[make_pair(1,ns_t_ns)]=&make; - typemap[make_pair(1,ns_t_cname)]=&make; - typemap[make_pair(1,ns_t_ptr)]=&make; + regist(1, ns_t_ns, &make, "NS"); + regist(1, ns_t_cname, &make, "CNAME"); + regist(1, ns_t_ptr, &make, "PTR"); } - static DNSRecordContent* make(const struct dnsrecordheader& ah, PacketReader &pr) + static DNSRecordContent* make(const DNSRecord &dr, PacketReader &pr) { - return new OneLabelRecordContent(ah, pr.getLabel()); - } - - string getType() const - { - if(d_type==ns_t_ns) - return "NS"; - else if(d_type==ns_t_cname) - return "CNAME"; - if(d_type==ns_t_ptr) - return "PTR"; + return new OneLabelRecordContent(dr, pr.getLabel()); } string getZoneRepresentation() const @@ -165,22 +144,16 @@ public: static void report(void) { - typemap[make_pair(1,6)]=&make; + regist(1,ns_t_soa,&make,"SOA"); } - string getType() const - { - return "SOA"; - } - - - static DNSRecordContent* make(const struct dnsrecordheader& ah, PacketReader& pr) + static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr) { u_int16_t nowpos(pr.d_pos); string mname=pr.getLabel(); string rname=pr.getLabel(); - u_int16_t left=ah.d_clen - (pr.d_pos-nowpos); + u_int16_t left=dr.d_clen - (pr.d_pos-nowpos); if(left!=sizeof(struct soatimes)) throw MOADNSException("SOA RDATA has wrong size: "+lexical_cast(left)+ ", should be "+lexical_cast(sizeof(struct soatimes))); @@ -223,18 +196,12 @@ public: { } - string getType() const - { - return "MX"; - } - - static void report(void) { - typemap[make_pair(1,ns_t_mx)]=&make; + regist(1,ns_t_mx,&make,"MX"); } - static DNSRecordContent* make(const struct dnsrecordheader& ah, PacketReader& pr) + static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr) { u_int16_t preference=pr.get16BitInt(); string mxname=pr.getLabel(); @@ -264,5 +231,6 @@ static struct Reporter OneLabelRecordContent::report(); SOARecordContent::report(); MXRecordContent::report(); + MXRecordContent::regist(1,255,0,"ANY"); } } reporter __attribute__((init_priority(65535))); diff --git a/pdns/sdig.cc b/pdns/sdig.cc index cb75462cd..73826a93a 100644 --- a/pdns/sdig.cc +++ b/pdns/sdig.cc @@ -50,22 +50,23 @@ const string DNSPacketGenerator::getPacket() int main(int argc, char** argv) try { - DNSPacketGenerator dpg(argv[3], atoi(argv[4])); + DNSPacketGenerator dpg(argv[3], DNSRecordContent::TypeToNumber(argv[4])); Socket sock(InterNetwork, Datagram); - IPEndpoint dest(argv[1], atoi(argv[2])); + IPEndpoint dest(argv[1] + (*argv[1]=='@'), atoi(argv[2])); sock.sendTo(dpg.getPacket(), dest); string reply; sock.recvFrom(reply, dest); MOADNSParser mdp(reply); - cout<<"Reply to question for qname='"< pr=mdp.getPacketReader(i->second); - DNSRecordContent* drc=DNSRecordContent::mastermake(i->first.d_ah, *pr); - cout<first.d_place<<"\t"<first.d_label<<"\tIN\t"<getType()<<"\t"<first.d_ttl<<"\t"<getZoneRepresentation()<first, *pr); + cout<first.d_place<<"\t"<first.d_label<<"\tIN\t"<first.d_type)<<"\t"<first.d_ttl<<"\t"<getZoneRepresentation()<