root/trunk/pdns/pdns/dnswriter.hh @ 1359

Revision 1359, 3.9 KB (checked in by ahu, 4 years ago)

preliminary infrastructure for signing messages with TSIG in a clean way

Line 
1#ifndef PDNS_DNSWRITER_HH
2#define PDNS_DNSWRITER_HH
3
4#include <string>
5#include <vector>
6#include <map>
7#if !defined SOLARIS8 && !defined WIN32
8#include <stdint.h>
9#elif defined WIN32
10#include "utility.hh"
11#endif
12#include "dns.hh"
13using namespace std;
14
15/** this class can be used to write DNS packets. It knows about DNS in the sense that it makes
16    the packet header and record headers.
17
18    The model is:
19
20    packetheader (recordheader recordcontent)*
21
22    The packetheader needs to be updated with the amount of packets of each kind (answer, auth, additional)
23   
24    Each recordheader contains the length of a dns record.
25
26    Calling convention:
27
28    vector<uint8_t> content;
29    DNSPacketWriter dpw(content, const string& qname, uint16_t qtype, uint16_t qclass=1);  // sets the question
30    dpw.startrecord("this.is.an.ip.address.", ns_t_a);    // does nothing, except store qname and qtype
31    dpw.xfr32BitInt(0x01020304);                         // adds 4 bytes (0x01020304) to the record buffer
32    dpw.startrecord("this.is.an.ip.address.", ns_t_a);    // aha! writes out dnsrecord header containing qname and qtype and length 4, plus the recordbuffer, which gets emptied
33                                                         // new qname and qtype are stored
34    dpw.xfr32BitInt(0x04030201);                         // adds 4 bytes (0x04030201) to the record buffer
35    dpw.commit();                                        // writes out dnsrecord header containing qname and qtype and length 4, plus the recordbuffer
36
37    // content now contains the ready packet, with 1 question and 2 answers
38
39*/
40
41class DNSPacketWriter
42{
43
44public:
45  typedef vector<pair<string, uint16_t> > lmap_t;
46  enum Place {ANSWER=1, AUTHORITY=2, ADDITIONAL=3}; 
47
48  //! Start a DNS Packet in the vector passed, with question qname, qtype and qclass
49  DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t  qtype, uint16_t qclass=1, uint8_t opcode=0);
50 
51  /** Start a new DNS record within this packet for namq, qtype, ttl, class and in the requested place. Note that packets can only be written in natural order -
52      ANSWER, AUTHORITY, ADDITIONAL */
53  void startRecord(const string& name, uint16_t qtype, uint32_t ttl=3600, uint16_t qclass=1, Place place=ANSWER);
54
55  /** Shorthand way to add an Opt-record, for example for EDNS0 purposes */
56  typedef vector<pair<uint16_t,std::string> > optvect_t;
57  void addOpt(int udpsize, int extRCode, int Z, const optvect_t& options=optvect_t());
58
59  /** needs to be called after the last record is added, but can be called again and again later on. Is called internally by startRecord too.
60      The content of the vector<> passed to the constructor is inconsistent until commit is called.
61   */
62  void commit();
63
64  uint16_t size();
65
66  /** Should the packet have grown too big for the writer's liking, rollback removes the record currently being written */
67  void rollback();
68
69  void xfr48BitInt(uint64_t val);
70  void xfr32BitInt(uint32_t val);
71  void xfr16BitInt(uint16_t val);
72  void xfrType(uint16_t val)
73  {
74    xfr16BitInt(val);
75  }
76  void xfrIP(const uint32_t& val)
77  {
78    xfr32BitInt(htonl(val));
79  }
80  void xfrTime(const uint32_t& val)
81  {
82    xfr32BitInt(val);
83  }
84
85  void xfr8BitInt(uint8_t val);
86
87  void xfrLabel(const string& label, bool compress=false);
88  void xfrText(const string& text, bool multi=false);
89  void xfrBlob(const string& blob, int len=-1);
90  void xfrHexBlob(const string& blob);
91
92  uint16_t d_pos;
93 
94  dnsheader* getHeader();
95  void getRecords(string& records);
96  const vector<uint8_t>& getRecordBeingWritten() { return d_record; }
97
98private:
99  vector <uint8_t>& d_content;
100  vector <uint8_t> d_record;
101  string d_qname;
102  uint16_t d_qtype, d_qclass;
103  string d_recordqname;
104  uint16_t d_recordqtype, d_recordqclass;
105  uint32_t d_recordttl;
106  lmap_t d_labelmap;
107  uint16_t d_stuff;
108  uint16_t d_sor;
109  uint16_t d_rollbackmarker; // start of last complete packet, for rollback
110  Place d_recordplace;
111};
112#endif
Note: See TracBrowser for help on using the browser.