Changeset 505

Show
Ignore:
Timestamp:
10/02/05 15:28:51 (8 years ago)
Author:
ahu
Message:

add support for blobs and 8 bit ints to the magical symmetrical transfer machinery
add support for DNSSEC records to MOADNSParser! Tested except for DS, can't find a live DS record.
add support for RP and other odd records to MOADNSParser
except for LOC we are complete now

Location:
trunk/pdns/pdns
Files:
8 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/dnsparser.cc

    r501 r505  
    154154  ah.d_clen=ntohs(ah.d_clen); 
    155155  ah.d_ttl=ntohl(ah.d_ttl); 
     156 
     157  d_startrecordpos=d_pos; // needed for getBlob later on 
     158  d_recordlen=ah.d_clen; 
    156159} 
    157160 
     
    259262  } 
    260263} 
     264 
     265void PacketReader::xfrBlob(string& blob) 
     266{ 
     267  blob.assign(&d_content.at(d_pos), &d_content.at(d_startrecordpos + d_recordlen - 1 ) + 1); 
     268 
     269  d_pos = d_startrecordpos + d_recordlen; 
     270} 
  • trunk/pdns/pdns/dnsparser.hh

    r502 r505  
    7676 
    7777  uint32_t get32BitInt(); 
    78  
    7978  uint16_t get16BitInt(); 
    8079  uint8_t get8BitInt(); 
     
    9594  } 
    9695 
     96  void xfr8BitInt(uint8_t& val) 
     97  { 
     98    val=get8BitInt(); 
     99  } 
     100 
     101 
    97102  void xfrLabel(string &label) 
    98103  { 
     
    104109    text=getText(); 
    105110  } 
     111 
     112  void xfrBlob(string& blob); 
    106113 
    107114  static uint16_t get16BitInt(const vector<unsigned char>&content, uint16_t& pos); 
     
    118125 
    119126private: 
     127  uint16_t d_startrecordpos; // needed for getBlob later on 
     128  uint16_t d_recordlen;      // dito 
    120129  const vector<uint8_t>& d_content; 
    121130}; 
  • trunk/pdns/pdns/dnsrecords.cc

    r502 r505  
    1919#include "dnsrecords.hh" 
    2020 
    21 #define boilerplate(RNAME, RTYPE)                                                                         \ 
    22 RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \ 
    23 {                                                                                                  \ 
    24   return new RNAME##RecordContent(dr, pr);                                                         \ 
    25 }                                                                                                  \ 
    26                                                                                                    \ 
    27 RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr)                  \ 
    28 {                                                                                                  \ 
    29   doRecordCheck(dr);                                                                               \ 
    30   xfrPacket(pr);                                                                                   \ 
    31 }                                                                                                  \ 
    32                                                                                                    \ 
    33 RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const string& zonedata)         \ 
    34 {                                                                                                  \ 
    35   return new RNAME##RecordContent(zonedata);                                                       \ 
    36 }                                                                                                  \ 
    37                                                                                                    \ 
    38 void RNAME##RecordContent::toPacket(DNSPacketWriter& pw)                                           \ 
    39 {                                                                                                  \ 
    40   this->xfrPacket(pw);                                                                             \ 
    41 }                                                                                                  \ 
    42                                                                                                    \ 
    43 void RNAME##RecordContent::report(void)                                                            \ 
    44 {                                                                                                  \ 
    45   regist(1, RTYPE, &RNAME##RecordContent::make, #RNAME);                                           \ 
    46 }                                                                                                  \ 
    47                                                                                                    \ 
    48 RNAME##RecordContent::RNAME##RecordContent(const string& zoneData)                                 \ 
    49 {                                                                                                  \ 
    50   RecordTextReader rtr(zoneData);                                                                  \ 
    51   xfrPacket(rtr);                                                                                  \ 
    52 }                                                                                                  \ 
    53                                                                                                    \ 
    54 string RNAME##RecordContent::getZoneRepresentation() const                                         \ 
    55 {                                                                                                  \ 
    56   string ret;                                                                                      \ 
    57   RecordTextWriter rtw(ret);                                                                       \ 
    58   const_cast<RNAME##RecordContent*>(this)->xfrPacket(rtw);                                         \ 
    59   return ret;                                                                                      \ 
    60 }                                                                                                   
    61                                                                                             
    62  
    63 #define boilerplate_conv(RNAME, CONV)                             \ 
    64 template<class Convertor>                                         \ 
    65 void RNAME##RecordContent::xfrPacket(Convertor& conv)             \ 
    66 {                                                                 \ 
    67   CONV;                                                           \ 
    68 }                                                                 \ 
    69  
    70  
    71 boilerplate(A, ns_t_a) 
    72  
    73 template<class Convertor> 
    74 void ARecordContent::xfrPacket(Convertor& conv) 
    75 { 
    76   conv.xfrIP(d_ip); 
    77 } 
    78    
     21boilerplate_conv(A, ns_t_a, conv.xfrIP(d_ip)); 
     22 
    7923void ARecordContent::doRecordCheck(const DNSRecord& dr) 
    8024 
     
    12266}; 
    12367 
    124  
    125 boilerplate(NS, ns_t_ns) 
    126 boilerplate_conv(NS, conv.xfrLabel(d_content)) 
    127  
    128 boilerplate(PTR, ns_t_ptr) 
    129 boilerplate_conv(PTR, conv.xfrLabel(d_content)) 
    130  
    131 boilerplate(CNAME, ns_t_cname) 
    132 boilerplate_conv(CNAME, conv.xfrLabel(d_content)) 
    133  
    134 boilerplate(TXT, ns_t_txt) 
    135 boilerplate_conv(TXT, conv.xfrText(d_text)) 
    136  
    137  
    138 boilerplate(HINFO, ns_t_hinfo) 
    139 boilerplate_conv(HINFO,   conv.xfrText(d_cpu);   conv.xfrText(d_host)) 
    140  
    141 boilerplate(RP, ns_t_rp) 
    142 boilerplate_conv(RP,   conv.xfrLabel(d_mbox);   conv.xfrLabel(d_info)) 
    143  
    144  
    145 boilerplate(MX, ns_t_mx) 
     68class NSECRecordContent : public DNSRecordContent 
     69{ 
     70public: 
     71  static void report(void) 
     72  { 
     73    regist(1,47 ,&make,"NSEC"); 
     74  } 
     75 
     76  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr)  
     77  { 
     78    NSECRecordContent* ret=new NSECRecordContent(); 
     79    pr.xfrLabel(ret->d_next); 
     80    string bitmap; 
     81    pr.xfrBlob(bitmap); 
     82 
     83    cout<<"get bitmap: "<<makeHexDump(bitmap)<<endl; 
     84 
     85    // 00 06 20 00 00 00 00 03  -> NS RRSIG NSEC  ( 2, 46, 47 ) counts from left 
     86 
     87    if(bitmap.size() < 2) 
     88      throw MOADNSException("NSEC record with impossibly small bitmap"); 
     89 
     90    if(bitmap[0]) 
     91      throw MOADNSException("Can't deal with NSEC mappings > 255 yet"); 
     92     
     93    int len=bitmap[1]; 
     94    if(bitmap.size()!=2+len) 
     95      throw MOADNSException("Can't deal with multi-part NSEC mappings yet"); 
     96 
     97    for(int n=0 ; n < len ; ++n) { 
     98      uint8_t val=bitmap[2+n]; 
     99      for(int bit = 0; bit < 8 ; ++bit , val>>=1) 
     100        if(val & 1) { 
     101          ret->d_set.insert((7-bit) + 8*(n)); 
     102        } 
     103    } 
     104 
     105    return ret; 
     106  } 
     107   
     108  string getZoneRepresentation() const 
     109  { 
     110    string ret; 
     111    RecordTextWriter rtw(ret); 
     112    rtw.xfrLabel(d_next); 
     113 
     114    for(set<uint16_t>::const_iterator i=d_set.begin(); i!=d_set.end(); ++i) { 
     115      ret+=" "; 
     116      ret+=NumberToType(*i); 
     117    } 
     118 
     119    return ret; 
     120  } 
     121 
     122private: 
     123  string d_next; 
     124  set<uint16_t> d_set; 
     125}; 
     126 
     127 
     128 
     129 
     130boilerplate_conv(NS, ns_t_ns, conv.xfrLabel(d_content)); 
     131boilerplate_conv(PTR, ns_t_ptr, conv.xfrLabel(d_content)); 
     132boilerplate_conv(CNAME, ns_t_cname, conv.xfrLabel(d_content)); 
     133boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text)); 
     134boilerplate_conv(SPF, 99, conv.xfrText(d_text)); 
     135boilerplate_conv(HINFO, ns_t_hinfo,  conv.xfrText(d_cpu);   conv.xfrText(d_host)); 
     136 
     137boilerplate_conv(RP, ns_t_rp, 
     138                 conv.xfrLabel(d_mbox);    
     139                 conv.xfrLabel(d_info) 
     140                 ); 
     141 
    146142 
    147143MXRecordContent::MXRecordContent(uint16_t preference, const string& mxname) : d_preference(preference), d_mxname(mxname) 
     
    149145} 
    150146 
    151 template<class Convertor> 
    152 void MXRecordContent::xfrPacket(Convertor& conv) 
    153 { 
    154   conv.xfr16BitInt(d_preference); 
    155   conv.xfrLabel(d_mxname); 
    156 } 
    157  
    158 boilerplate(NAPTR, ns_t_naptr) 
    159  
    160 template<class Convertor> 
    161 void NAPTRRecordContent::xfrPacket(Convertor& conv) 
    162 { 
    163   conv.xfr16BitInt(d_order);    conv.xfr16BitInt(d_preference); 
    164   conv.xfrText(d_flags);        conv.xfrText(d_services);         conv.xfrText(d_regexp); 
    165   conv.xfrLabel(d_replacement); 
    166 } 
    167  
    168  
    169 boilerplate(SRV, ns_t_srv) 
     147boilerplate_conv(MX, ns_t_mx,  
     148                 conv.xfr16BitInt(d_preference); 
     149                 conv.xfrLabel(d_mxname); 
     150                 ) 
     151 
     152 
     153boilerplate_conv(NAPTR, ns_t_naptr, 
     154                 conv.xfr16BitInt(d_order);    conv.xfr16BitInt(d_preference); 
     155                 conv.xfrText(d_flags);        conv.xfrText(d_services);         conv.xfrText(d_regexp); 
     156                 conv.xfrLabel(d_replacement); 
     157                 ) 
     158 
     159 
     160 
    170161SRVRecordContent::SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, const string& target)  
    171162  : d_preference(preference), d_weight(weight), d_port(port), d_target(target) 
    172163{} 
    173164 
    174 template<class Convertor> void SRVRecordContent::xfrPacket(Convertor& conv) 
    175 { 
    176   conv.xfr16BitInt(d_preference);   conv.xfr16BitInt(d_weight);   conv.xfr16BitInt(d_port); 
    177   conv.xfrLabel(d_target); 
    178 } 
    179  
    180  
    181 boilerplate(SOA, ns_t_soa) 
     165boilerplate_conv(SRV, ns_t_srv,  
     166                 conv.xfr16BitInt(d_preference);   conv.xfr16BitInt(d_weight);   conv.xfr16BitInt(d_port); 
     167                 conv.xfrLabel(d_target); 
     168                 ) 
     169 
     170 
    182171 
    183172SOARecordContent::SOARecordContent(const string& mname, const string& rname, const struct soatimes& st)  
     
    187176} 
    188177 
    189 template<class Convertor> 
    190 void SOARecordContent::xfrPacket(Convertor& conv) 
    191 { 
    192   conv.xfrLabel(d_mname); 
    193   conv.xfrLabel(d_rname); 
    194    
    195   conv.xfr32BitInt(d_st.serial); 
    196   conv.xfr32BitInt(d_st.refresh); 
    197   conv.xfr32BitInt(d_st.retry); 
    198   conv.xfr32BitInt(d_st.expire); 
    199   conv.xfr32BitInt(d_st.minimum); 
    200 } 
    201  
     178boilerplate_conv(SOA, ns_t_soa,  
     179                 conv.xfrLabel(d_mname); 
     180                 conv.xfrLabel(d_rname); 
     181                 conv.xfr32BitInt(d_st.serial); 
     182                 conv.xfr32BitInt(d_st.refresh); 
     183                 conv.xfr32BitInt(d_st.retry); 
     184                 conv.xfr32BitInt(d_st.expire); 
     185                 conv.xfr32BitInt(d_st.minimum); 
     186                 ); 
     187 
     188 
     189boilerplate_conv(DS, 43,  
     190                 conv.xfr16BitInt(d_tag);  
     191                 conv.xfr8BitInt(d_algorithm);  
     192                 conv.xfr8BitInt(d_digesttype);  
     193                 conv.xfrBlob(d_digest); 
     194                 ) 
     195 
     196 
     197 
     198boilerplate_conv(RRSIG, 46,  
     199                 conv.xfr16BitInt(d_type);  
     200                 conv.xfr8BitInt(d_algorithm);  
     201                 conv.xfr8BitInt(d_labels);  
     202 
     203                 conv.xfr32BitInt(d_originalttl);  
     204                 conv.xfr32BitInt(d_sigexpire);  
     205                 conv.xfr32BitInt(d_siginception);  
     206                 conv.xfr16BitInt(d_tag);  
     207                 conv.xfrLabel(d_signer); 
     208                 conv.xfrBlob(d_signature); 
     209                 ) 
     210                  
     211 
     212 
     213boilerplate_conv(DNSKEY, 48,  
     214                 conv.xfr16BitInt(d_flags);  
     215                 conv.xfr8BitInt(d_protocol);  
     216                 conv.xfr8BitInt(d_algorithm);  
     217                 conv.xfrBlob(d_key); 
     218                 ) 
     219 
     220 
     221 
     222                  
    202223 
    203224static struct Reporter 
     
    212233    PTRRecordContent::report(); 
    213234    TXTRecordContent::report(); 
     235    SPFRecordContent::report(); 
    214236    SOARecordContent::report(); 
    215237    MXRecordContent::report(); 
     
    217239    SRVRecordContent::report(); 
    218240    RPRecordContent::report(); 
     241    DNSKEYRecordContent::report(); 
     242    RRSIGRecordContent::report(); 
     243    DSRecordContent::report(); 
     244    NSECRecordContent::report(); 
    219245    DNSRecordContent::regist(1,255,0,"ANY"); 
    220246  } 
  • trunk/pdns/pdns/dnsrecords.hh

    r502 r505  
    2424#include "rcpgenerator.hh" 
    2525#include <boost/lexical_cast.hpp> 
     26#include <set> 
     27 
    2628using namespace std; 
    2729using namespace boost; 
     
    9496}; 
    9597 
     98class SPFRecordContent : public DNSRecordContent 
     99{ 
     100public: 
     101  includeboilerplate(SPF) 
     102 
     103private: 
     104  string d_text; 
     105}; 
     106 
     107 
    96108class NSRecordContent : public DNSRecordContent 
    97109{ 
     
    139151  string d_mbox, d_info; 
    140152}; 
     153 
     154 
     155class DNSKEYRecordContent : public DNSRecordContent 
     156{ 
     157public: 
     158  includeboilerplate(DNSKEY) 
     159 
     160private: 
     161  uint16_t d_flags; 
     162  uint8_t d_protocol; 
     163  uint8_t d_algorithm; 
     164  string d_key; 
     165}; 
     166 
     167class DSRecordContent : public DNSRecordContent 
     168{ 
     169public: 
     170  includeboilerplate(DS) 
     171 
     172private: 
     173  uint16_t d_tag; 
     174  uint8_t d_algorithm, d_digesttype; 
     175  string d_digest; 
     176}; 
     177 
     178 
     179class RRSIGRecordContent : public DNSRecordContent 
     180{ 
     181public: 
     182  includeboilerplate(RRSIG) 
     183 
     184private: 
     185  uint16_t d_type; 
     186  uint8_t d_algorithm, d_labels; 
     187  uint32_t d_originalttl, d_sigexpire, d_siginception; 
     188  uint16_t d_tag; 
     189  string d_signer, d_signature; 
     190}; 
     191 
    141192 
    142193 
     
    165216}; 
    166217 
     218 
     219#define boilerplate(RNAME, RTYPE)                                                                         \ 
     220RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \ 
     221{                                                                                                  \ 
     222  return new RNAME##RecordContent(dr, pr);                                                         \ 
     223}                                                                                                  \ 
     224                                                                                                   \ 
     225RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr)                  \ 
     226{                                                                                                  \ 
     227  doRecordCheck(dr);                                                                               \ 
     228  xfrPacket(pr);                                                                                   \ 
     229}                                                                                                  \ 
     230                                                                                                   \ 
     231RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const string& zonedata)         \ 
     232{                                                                                                  \ 
     233  return new RNAME##RecordContent(zonedata);                                                       \ 
     234}                                                                                                  \ 
     235                                                                                                   \ 
     236void RNAME##RecordContent::toPacket(DNSPacketWriter& pw)                                           \ 
     237{                                                                                                  \ 
     238  this->xfrPacket(pw);                                                                             \ 
     239}                                                                                                  \ 
     240                                                                                                   \ 
     241void RNAME##RecordContent::report(void)                                                            \ 
     242{                                                                                                  \ 
     243  regist(1, RTYPE, &RNAME##RecordContent::make, #RNAME);                                           \ 
     244}                                                                                                  \ 
     245                                                                                                   \ 
     246RNAME##RecordContent::RNAME##RecordContent(const string& zoneData)                                 \ 
     247{                                                                                                  \ 
     248  RecordTextReader rtr(zoneData);                                                                  \ 
     249  xfrPacket(rtr);                                                                                  \ 
     250}                                                                                                  \ 
     251                                                                                                   \ 
     252string RNAME##RecordContent::getZoneRepresentation() const                                         \ 
     253{                                                                                                  \ 
     254  string ret;                                                                                      \ 
     255  RecordTextWriter rtw(ret);                                                                       \ 
     256  const_cast<RNAME##RecordContent*>(this)->xfrPacket(rtw);                                         \ 
     257  return ret;                                                                                      \ 
     258}                                                                                                   
     259                                                                                            
     260 
     261#define boilerplate_conv(RNAME, TYPE, CONV)                       \ 
     262boilerplate(RNAME, TYPE)                                          \ 
     263template<class Convertor>                                         \ 
     264void RNAME##RecordContent::xfrPacket(Convertor& conv)             \ 
     265{                                                                 \ 
     266  CONV;                                                           \ 
     267}                                                                 \ 
     268 
    167269#endif  
  • trunk/pdns/pdns/dnswriter.cc

    r497 r505  
    8888} 
    8989 
     90void DNSPacketWriter::xfrBlob(const string& blob) 
     91{ 
     92  const uint8_t* ptr=reinterpret_cast<const uint8_t*>(blob.c_str()); 
     93 
     94  d_record.insert(d_record.end(), ptr, ptr+blob.size()); 
     95} 
     96 
    9097 
    9198void DNSPacketWriter::commit() 
  • trunk/pdns/pdns/dnswriter.hh

    r502 r505  
    5151  void xfrLabel(const string& label); 
    5252  void xfrText(const string& text); 
    53  
     53  void xfrBlob(const string& blob); 
    5454  void commit(); 
    5555   
  • trunk/pdns/pdns/rcpgenerator.cc

    r502 r505  
    2121#include <boost/lexical_cast.hpp> 
    2222#include <iostream> 
     23#include "base64.hh" 
    2324using namespace boost; 
    2425 
     
    6364  if(val!=tmp) 
    6465    throw RecordTextException("Overflow reading 16 bit integer from record content"); // fixme improve 
     66} 
     67 
     68void RecordTextReader::xfr8BitInt(uint8_t &val) 
     69{ 
     70  uint32_t tmp; 
     71  xfr32BitInt(tmp); 
     72  val=tmp; 
     73  if(val!=tmp) 
     74    throw RecordTextException("Overflow reading 8 bit integer from record content"); // fixme improve 
    6575} 
    6676 
     
    8494} 
    8595 
     96void RecordTextReader::xfrBlob(string& val) 
     97{ 
     98  skipSpaces(); 
     99  int pos=d_pos; 
     100  while(d_pos < d_end && !isspace(d_string[d_pos])) 
     101    d_pos++; 
     102 
     103  val.assign(d_string.c_str()+pos, d_string.c_str() + d_pos); 
     104   
     105  // XXX FIXME add base-64 decode here! 
     106 
     107} 
     108 
    86109void RecordTextReader::xfrText(string& val) 
    87110{ 
     
    102125    throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'"); 
    103126  d_pos++; 
    104  
    105 } 
     127} 
     128 
    106129 
    107130 
     
    149172} 
    150173 
     174void RecordTextWriter::xfr8BitInt(const uint8_t& val) 
     175{ 
     176  xfr32BitInt(val); 
     177} 
     178 
    151179 
    152180void RecordTextWriter::xfrLabel(const string& val) 
     
    155183    d_string.append(1,' '); 
    156184  d_string+=val; 
     185} 
     186 
     187void RecordTextWriter::xfrBlob(const string& val) 
     188{ 
     189  if(!d_string.empty()) 
     190    d_string.append(1,' '); 
     191 
     192  d_string+=Base64Encode(val); 
    157193} 
    158194 
  • trunk/pdns/pdns/rcpgenerator.hh

    r502 r505  
    4040  void xfr32BitInt(uint32_t& val); 
    4141  void xfr16BitInt(uint16_t& val); 
     42  void xfr8BitInt(uint8_t& val); 
    4243 
    4344  void xfrIP(uint32_t& val); 
    4445  void xfrLabel(string& val); 
    4546  void xfrText(string& val); 
     47  void xfrBlob(string& val); 
    4648 
    4749private: 
     
    5961  void xfr32BitInt(const uint32_t& val); 
    6062  void xfr16BitInt(const uint16_t& val); 
     63  void xfr8BitInt(const uint8_t& val); 
    6164  void xfrIP(const uint32_t& val); 
    6265  void xfrLabel(const string& val); 
    6366  void xfrText(const string& val); 
     67  void xfrBlob(const string& val); 
    6468 
    6569private: