root/trunk/pdns/pdns/dnswriter.cc @ 497

Revision 497, 2.9 KB (checked in by ahu, 8 years ago)

the magic 'turn the parser into a generator' work

Line 
1#include "dnswriter.hh"
2#include "misc.hh"
3#include "dnsparser.hh"
4
5static const string EncodeDNSLabel(const string& input)
6{
7  typedef vector<string> parts_t;
8  parts_t parts;
9  stringtok(parts,input,".");
10
11  string ret;
12  for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
13    ret.append(1, (char)i->length());
14    ret.append(*i);
15  }
16  ret.append(1,(char)0);
17  return ret;
18}
19
20DNSPacketWriter::DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t  qtype, uint16_t qclass)
21  : d_pos(0), d_content(content), d_qname(qname), d_qtype(qtype), d_qclass(qclass)
22{
23  d_content.clear();
24  dnsheader dnsheader;
25 
26  memset(&dnsheader, 0, sizeof(dnsheader));
27  dnsheader.id=random();
28  dnsheader.qdcount=htons(1);
29 
30  const uint8_t* ptr=(const uint8_t*)&dnsheader;
31  d_content.insert(d_content.end(), ptr, ptr + sizeof(dnsheader));   
32 
33  string label=EncodeDNSLabel(d_qname);
34  ptr=(const uint8_t*) label.c_str();
35  d_content.insert(d_content.end(), ptr, ptr + label.length());   
36 
37  qtype=htons(qtype);
38  ptr=(const uint8_t*)&qtype;
39  d_content.insert(d_content.end(), ptr, ptr+2);
40 
41  qclass=htons(qclass);
42  ptr=(const uint8_t*)&qclass;
43  d_content.insert(d_content.end(), ptr, ptr+2);
44}
45
46void DNSPacketWriter::startRecord(const string& name, uint16_t qtype, uint16_t qclass)
47{
48  if(!d_record.empty()) 
49    commit();
50  d_recordqname=name;
51  d_recordqtype=qtype;
52  d_recordqclass=qclass;
53
54  dnsheader* dh=(dnsheader*) &*d_content.begin();
55  dh->ancount = htons(ntohs(dh->ancount) + 1);
56}
57
58void DNSPacketWriter::xfr32BitInt(uint32_t val)
59{
60  uint8_t* ptr=reinterpret_cast<uint8_t*>(&val);
61  d_record.insert(d_record.end(), ptr, ptr+4);
62}
63
64void DNSPacketWriter::xfr16BitInt(uint16_t val)
65{
66  uint8_t* ptr=reinterpret_cast<uint8_t*>(&val);
67  d_record.insert(d_record.end(), ptr, ptr+2);
68}
69
70void DNSPacketWriter::xfr8BitInt(uint8_t val)
71{
72  d_record.push_back(val);
73}
74
75void DNSPacketWriter::xfrText(const string& text)
76{
77  d_record.push_back(text.length());
78  const uint8_t* ptr=(uint8_t*)(text.c_str());
79  d_record.insert(d_record.end(), ptr, ptr+text.size());
80}
81
82void DNSPacketWriter::xfrLabel(const string& label)
83{
84  string encoded=EncodeDNSLabel(label);
85  const uint8_t* ptr=reinterpret_cast<const uint8_t*>(encoded.c_str());
86
87  d_record.insert(d_record.end(), ptr, ptr+encoded.size());
88}
89
90
91void DNSPacketWriter::commit()
92{
93  string label=EncodeDNSLabel(d_qname); // write out qname
94
95  const uint8_t* ptr=(const uint8_t*) label.c_str();
96  d_content.insert(d_content.end(), ptr, ptr + label.length());
97
98  // write out dnsrecordheader
99  struct dnsrecordheader drh;
100  drh.d_type=htons(d_recordqtype);
101  drh.d_class=htons(d_recordqclass);
102  drh.d_ttl=htonl(3600);
103  drh.d_clen=htons(d_record.size());
104
105  ptr=(const uint8_t*)&drh;
106  d_content.insert(d_content.end(), ptr, ptr+sizeof(drh));
107
108  // write out d_record
109  d_content.insert(d_content.end(), d_record.begin(), d_record.end());
110
111  d_record.clear();   // clear d_record
112}
113
114
115
116
117
118
Note: See TracBrowser for help on using the browser.