tdns
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
dnsmessages.hh
Go to the documentation of this file.
1 #pragma once
2 #include "dns-storage.hh"
3 #include "record-types.hh"
4 #include <arpa/inet.h>
5 #include <vector>
6 
12 class DNSMessageReader
14 {
15 public:
16  DNSMessageReader(const char* input, uint16_t length);
17  DNSMessageReader(const std::string& str) : DNSMessageReader(str.c_str(), str.size()) {}
18  struct dnsheader dh=dnsheader{};
19  std::vector<uint8_t> payload;
20  uint16_t payloadpos{0};
21  uint16_t rrpos{0};
22  uint16_t d_endofrecord;
24  bool eor() const { return payloadpos == d_endofrecord; }
25 
27  void getQuestion(DNSName& name, DNSType& type) const;
29  bool getEDNS(uint16_t* newsize, bool* doBit) const;
30 
32  bool getRR(DNSSection& section, DNSName& name, DNSType& type, uint32_t& ttl, std::unique_ptr<RRGen>& content);
33  void skipRRs(int n);
34 
35  uint8_t d_ednsVersion{0};
36 
37  void xfrName(DNSName& ret, uint16_t* pos=0);
38  DNSName getName(uint16_t* pos=0) { DNSName res; xfrName(res, pos); return res;}
41  void xfrUInt8(uint8_t&res, uint16_t* pos = 0)
42  {
43  if(!pos) pos = &payloadpos;
44  res=payload.at((*pos)++);
45  }
47  uint8_t getUInt8(uint16_t* pos=0)
48  { uint8_t ret; xfrUInt8(ret, pos); return ret; }
49 
51  void xfrUInt16(uint16_t& res)
52  {
53  memcpy(&res, &payload.at(payloadpos+1)-1, 2);
54  payloadpos+=2;
55  res=htons(res);
56  }
57 
59  void xfrType(DNSType& type)
60  {
61  xfrUInt16((uint16_t&)type);
62  }
63 
65  uint16_t getUInt16()
66  { uint16_t ret; xfrUInt16(ret); return ret; }
67 
69  void xfrUInt32(uint32_t& res)
70  {
71  memcpy(&res, &payload.at(payloadpos+3)-3, 4);
72  payloadpos+=4;
73  res=ntohl(res);
74  }
75 
76  void xfrTxt(std::string& blob)
77  {
78  auto len = getUInt8();
79  xfrBlob(blob, len);
80  }
82  void xfrBlob(std::string& blob, int size, uint16_t* pos = 0)
83  {
84  if(!pos) pos = &payloadpos;
85  if(!size) {
86  blob.clear();
87  return;
88  }
89  blob.assign(&payload.at(*pos), &payload.at(*pos+size-1)+1);
90  (*pos) += size;
91  }
92 
94  std::string getBlob(int size, uint16_t* pos = 0)
95  {
96  std::string res;
97  xfrBlob(res, size, pos);
98  return res;
99  }
100 
104  uint16_t d_bufsize;
105  bool d_doBit{false};
106 
107  bool d_haveEDNS{false};
108 };
109 
112 {
113 public:
115  std::vector<uint8_t> payload;
116  uint16_t payloadpos=0;
120  bool haveEDNS{false};
121  bool d_doBit;
122  bool d_nocompress{false}; // if set, never compress. For AXFR/IXFR
123  RCode d_ercode{(RCode)0};
124 
125  DNSMessageWriter(const DNSName& name, DNSType type, DNSClass qclass=DNSClass::IN, int maxsize=500);
126  ~DNSMessageWriter();
127  DNSMessageWriter(const DNSMessageWriter&) = delete;
128  DNSMessageWriter& operator=(const DNSMessageWriter&) = delete;
129  void randomizeID();
130  void clearRRs();
131  void putRR(DNSSection section, const DNSName& name, uint32_t ttl, const std::unique_ptr<RRGen>& rr, DNSClass dclass = DNSClass::IN);
132  void setEDNS(uint16_t bufsize, bool doBit, RCode ercode = (RCode)0);
133  std::string serialize();
134 
135  void xfrUInt8(uint8_t val)
136  {
137  payload.at(payloadpos++)=val;
138  }
139 
140  void xfrType(DNSType val)
141  {
142  xfrUInt16((uint16_t)val);
143  }
144 
145  uint16_t xfrUInt16(uint16_t val)
146  {
147  val = htons(val);
148  memcpy(&payload.at(payloadpos+2)-2, &val, 2);
149  payloadpos+=2;
150  return payloadpos - 2;
151  }
152 
153  void xfrUInt16At(uint16_t pos, uint16_t val)
154  {
155  val = htons(val);
156  memcpy(&payload.at(pos+2)-2, &val, 2);
157  }
158 
159  void xfrUInt32(uint32_t val)
160  {
161  val = htonl(val);
162  memcpy(&payload.at(payloadpos+sizeof(val)) - sizeof(val), &val, sizeof(val));
163  payloadpos += sizeof(val);
164  }
165 
166  void xfrTxt(const std::string& blob)
167  {
168  if(blob.size() > 255)
169  throw std::runtime_error("Overly large TXT segment");
170  xfrUInt8(blob.size());
171  xfrBlob(blob);
172  }
173 
174  void xfrBlob(const std::string& blob)
175  {
176  memcpy(&payload.at(payloadpos+blob.size()) - blob.size(), blob.c_str(), blob.size());
177  payloadpos += blob.size();;
178  }
179 
180  void xfrBlob(const unsigned char* blob, int size)
181  {
182  memcpy(&payload.at(payloadpos+size) - size, blob, size);
183  payloadpos += size;
184  }
185 
186  void xfrName(const DNSName& name, bool compress=true);
187 private:
188  std::unique_ptr<DNSNode> d_comptree;
189  void putEDNS(uint16_t bufsize, RCode ercode, bool doBit);
190  bool d_serialized{false}; // needed to make serialize() idempotent
191 };
192 
DNSName d_qname
Definition: dnsmessages.hh:117
uint16_t d_endofrecord
Definition: dnsmessages.hh:22
void xfrType(DNSType &type)
For symmetry, this reads a type.
Definition: dnsmessages.hh:59
struct dnsheader dh
the DNS header
Definition: dnsmessages.hh:18
uint8_t d_ednsVersion
Definition: dnsmessages.hh:35
uint16_t xfrUInt16(uint16_t val)
Definition: dnsmessages.hh:145
bool d_haveEDNS
Definition: dnsmessages.hh:107
DNSClass
Stores the class of a DNS query or resource record.
Definition: dns-storage.hh:85
DNS header struct.
Definition: dns-storage.hh:23
std::vector< uint8_t > payload
The payload.
Definition: dnsmessages.hh:19
void xfrTxt(const std::string &blob)
Definition: dnsmessages.hh:166
uint16_t rrpos
Used in getRR to set section correctly.
Definition: dnsmessages.hh:21
void xfrType(DNSType val)
Definition: dnsmessages.hh:140
bool eor() const
are we at the end of a record?
Definition: dnsmessages.hh:24
uint8_t getUInt8(uint16_t *pos=0)
Convenience form that returns the next 8 bit integer, or from pos.
Definition: dnsmessages.hh:47
uint16_t payloadpos
Current position of processing.
Definition: dnsmessages.hh:20
void xfrUInt32(uint32_t val)
Definition: dnsmessages.hh:159
Defines DNSLabel, DNSType, DNSClass and DNSNode, which together store DNS details.
void xfrUInt16(uint16_t &res)
Gets the next 16 bit unsigned integer from the message.
Definition: dnsmessages.hh:51
bool getEDNS(uint16_t *newsize, bool *doBit) const
Returns true if there was an EDNS record, plus copies details.
Definition: dnsmessages.cc:66
DNSClass d_qclass
Definition: dnsmessages.hh:103
std::vector< uint8_t > payload
Definition: dnsmessages.hh:115
A class that parses a DNS Message.
Definition: dnsmessages.hh:13
bool getRR(DNSSection &section, DNSName &name, DNSType &type, uint32_t &ttl, std::unique_ptr< RRGen > &content)
Puts the next RR in content, unless at 'end of message', in which case it returns false...
Definition: dnsmessages.cc:87
uint16_t d_bufsize
Definition: dnsmessages.hh:104
DNSType d_qtype
Definition: dnsmessages.hh:102
DNSType d_qtype
Definition: dnsmessages.hh:118
void xfrBlob(std::string &blob, int size, uint16_t *pos=0)
Gets the next size bytes from the message, of from pos.
Definition: dnsmessages.hh:82
void xfrName(DNSName &ret, uint16_t *pos=0)
Definition: dnsmessages.cc:35
DNSName getName(uint16_t *pos=0)
Convenience form of xfrName that returns its result.
Definition: dnsmessages.hh:39
A DNS Message writer.
Definition: dnsmessages.hh:111
bool d_doBit
Definition: dnsmessages.hh:121
Defines all Resource Record Generators.
void xfrUInt16At(uint16_t pos, uint16_t val)
Definition: dnsmessages.hh:153
void xfrTxt(std::string &blob)
Definition: dnsmessages.hh:76
RCode
Definition: dns-storage.hh:62
void xfrUInt32(uint32_t &res)
Gets the next 32 bit unsigned integer from the message.
Definition: dnsmessages.hh:69
A DNS Name with helpful methods. Inherits case insensitivity from DNSLabel.
Definition: dns-storage.hh:133
DNSMessageReader(const char *input, uint16_t length)
Definition: dnsmessages.cc:5
DNSMessageReader(const std::string &str)
Definition: dnsmessages.hh:17
bool d_doBit
Definition: dnsmessages.hh:105
void getQuestion(DNSName &name, DNSType &type) const
Copies the qname and type to you.
Definition: dnsmessages.cc:61
DNSName d_qname
Definition: dnsmessages.hh:101
void skipRRs(int n)
Skip over n RRs.
Definition: dnsmessages.cc:75
DNSType
Stores the type of a DNS query or resource record.
Definition: dns-storage.hh:73
void xfrUInt8(uint8_t val)
Definition: dnsmessages.hh:135
void xfrBlob(const unsigned char *blob, int size)
Definition: dnsmessages.hh:180
void xfrUInt8(uint8_t &res, uint16_t *pos=0)
Gets the next 8 bit unsigned integer from the message, or the one from 'pos'.
Definition: dnsmessages.hh:41
std::string getBlob(int size, uint16_t *pos=0)
Convenience function that returns next size bytes of the message, or from pos.
Definition: dnsmessages.hh:94
uint16_t getUInt16()
Convenience form that returns the next 16 bit integer.
Definition: dnsmessages.hh:65
void xfrBlob(const std::string &blob)
Definition: dnsmessages.hh:174