E-MailRelay

gdnsmessage.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gdnsmessage.h
19///
20
21#ifndef G_NET_DNS_MESSAGE_H
22#define G_NET_DNS_MESSAGE_H
23
24#include "gdef.h"
25#include "gexception.h"
26#include "gaddress.h"
27#include <vector>
28#include <utility>
29#include <string>
30#include <map>
31
32 namespace GNet
33{
34 class DnsMessage ;
35 class DnsMessageRR ;
36 class DnsMessageRecordType ;
37 class DnsMessageQuestion ;
38 class DnsMessageNameParser ;
39 class DnsMessageRequest ;
40 class DnsMessageDumper ;
41}
42
43//| \class GNet::DnsMessage
44/// A DNS message parser, with static factory functions for message composition.
45/// A DnsMessage contains a Header and four sections: Question, Answer, Authority
46/// and Additional. The Question section contains Question records (DnsMessageQuestion)
47/// while the Answer, Authority and Additional sections contain RR records
48/// (DnsMessageRR). Each RR has a standard header followed by RDATA.
49/// \see RFC-1035
50///
51 class GNet::DnsMessage
52{
53 public:
54 G_EXCEPTION( Error , "dns message error" ) ;
55 using Question = DnsMessageQuestion ;
56 using RR = DnsMessageRR ;
57
58 explicit DnsMessage( const std::vector<char> & buffer ) ;
59 ///< Constructor.
60
61 DnsMessage( const char * , std::size_t ) ;
62 ///< Constructor.
63
64 std::vector<Address> addresses() const ;
65 ///< Returns the Answer addresses.
66
67 unsigned int ID() const ;
68 ///< Returns the header ID.
69
70 bool QR() const ;
71 ///< Returns the header QR (query/response).
72
73 unsigned int OPCODE() const ;
74 ///< Returns the header OPCODE.
75
76 bool AA() const ;
77 ///< Returns the header AA flag (authorative).
78
79 bool TC() const ;
80 ///< Returns the header TC flag (truncated).
81
82 bool RD() const ;
83 ///< Returns the header RD (recursion desired).
84
85 bool RA() const ;
86 ///< Returns the header RA (recursion available).
87
88 unsigned int Z() const ;
89 ///< Returns the header Z value (zero).
90
91 unsigned int RCODE() const ;
92 ///< Returns the header RCODE.
93
94 unsigned int QDCOUNT() const ;
95 ///< Returns the header QDCOUNT field, ie. the number of
96 ///< records in the Question section.
97
98 unsigned int ANCOUNT() const ;
99 ///< Returns the header ANCOUNT field, ie. the number of
100 ///< RR records in the Answer section.
101
102 unsigned int NSCOUNT() const ;
103 ///< Returns the header NSCOUNT field, ie. the number of
104 ///< RR records in the Authority section.
105
106 unsigned int ARCOUNT() const ;
107 ///< Returns the header ARCOUNT field, ie. the number of
108 ///< RR records in the Additional section.
109
110 Question question( unsigned int n ) const ;
111 ///< Returns the n'th record as a Question record.
112 ///< Precondition: n < QDCOUNT()
113
114 RR rr( unsigned int n ) const ;
115 ///< Returns the n'th record as a RR record. The returned
116 ///< object retains a reference to this DnsMessage, so
117 ///< prefer rrAddress().
118 ///< Precondition: n >= QDCOUNT() && n < (QDCOUNT()+ANCOUNT()+NSCOUNT()+ARCOUNT())
119
120 Address rrAddress( unsigned int n ) const ;
121 ///< Returns the address in the n'th record treated as a RR record.
122
123 const char * p() const ;
124 ///< Returns the raw data.
125
126 std::size_t n() const ;
127 ///< Returns the raw data size.
128
129 unsigned int byte( unsigned int byte_index ) const ;
130 ///< Returns byte at the given offset.
131
132 unsigned int word( unsigned int byte_index ) const ;
133 ///< Returns word at the given byte offset.
134
135 std::string span( unsigned int begin , unsigned int end ) const ;
136 ///< Returns the data in the given half-open byte range.
137
138 static DnsMessage request( const std::string & type , const std::string & hostname , unsigned int id = 0U ) ;
139 ///< Factory function for a request message of the give type
140 ///< ("A", "AAAA", etc). The type name is interpreted by
141 ///< DnsMessageRecordType::value().
142
143 static DnsMessage rejection( const DnsMessage & request , unsigned int rcode ) ;
144 ///< Factory function for a failure response based on the given
145 ///< request message.
146
147 static DnsMessage empty() ;
148 ///< Factory function for an unusable object. Most methods will
149 ///< throw, except n() will return zero.
150
151 private:
152 friend class DnsMessageDumper ;
153 DnsMessage() ;
154 void reject( unsigned int rcode ) ;
155
156 private:
157 std::vector<char> m_buffer ;
158} ;
159
160//| \class GNet::DnsMessageRecordType
161/// A static class for mapping between a RR type name, such as "AAAA",
162/// and its corresponding numeric value.
163///
164 class GNet::DnsMessageRecordType
165{
166 public:
167 static unsigned int value( const std::string & type_name ) ;
168 ///< Returns the type value for the given type name.
169
170 static std::string name( unsigned int type_value ) ;
171 ///< Returns the type name for the given type value.
172
173 public:
174 DnsMessageRecordType() = delete ;
175} ;
176
177//| \class GNet::DnsMessageRR
178/// Represents DNS response record.
179///
180 class GNet::DnsMessageRR
181{
182 public:
183 using RR = DnsMessageRR ;
184
185 public:
186 DnsMessageRR( const DnsMessage & , unsigned int offset ) ;
187 ///< Constructor. Keeps the reference, which is then passed
188 ///< to copies.
189
190 bool isa( const std::string & ) const ;
191 ///< Returns true if the type() has the given name().
192
193 unsigned int type() const ;
194 ///< Returns the type value().
195
196 unsigned int size() const ;
197 ///< Returns the size.
198
199 std::string name() const ;
200 ///< Returns the NAME.
201
202 Address address() const ;
203 ///< Returns the Address if isa(A) or isa(AAAA).
204
205 private:
206 friend class DnsMessageDumper ;
207 std::string rdata_dname( unsigned int rdata_offset ) const ;
208 std::string rdata_dname( unsigned int * rdata_offset_p ) const ;
209 std::string rdata_span( unsigned int begin ) const ;
210 std::string rdata_span( unsigned int begin , unsigned int end ) const ;
211 unsigned int rdata_offset() const ;
212 unsigned int rdata_size() const ;
213 unsigned int rdata_byte( unsigned int offset ) const ;
214 unsigned int rdata_word( unsigned int offset ) const ;
215
216 private:
217 const DnsMessage & m_msg ;
218 unsigned int m_offset ;
219 unsigned int m_size ;
220 unsigned int m_type ;
221 unsigned int m_class ;
222 unsigned int m_rdata_offset ;
223 unsigned int m_rdata_size ;
224 std::string m_name ;
225} ;
226
227//| \class GNet::DnsMessageQuestion
228/// Represents DNS question record.
229///
230 class GNet::DnsMessageQuestion
231{
232 public:
233 DnsMessageQuestion( const DnsMessage & , unsigned int offset ) ;
234 ///< Constructor.
235
236 unsigned int size() const ;
237 ///< Returns the record size.
238
239 std::string qname() const ;
240 ///< Returns the subject of the question.
241
242 private:
243 unsigned int m_size ;
244 std::string m_qname ;
245} ;
246
247//| \class GNet::DnsMessageNameParser
248/// An implementation class used by GNet::DnsMessage to parse
249/// compressed domain names.
250///
251 class GNet::DnsMessageNameParser
252{
253 public:
254 static unsigned int size( const DnsMessage & msg , unsigned int ) ;
255 ///< Returns the size of the compressed name.
256
257 static std::string read( const DnsMessage & msg , unsigned int ) ;
258 ///< Returns the decompressed name, made up of the
259 ///< labels with dots inbetween.
260
261 public:
262 DnsMessageNameParser() = delete ;
263} ;
264
265//| \class GNet::DnsMessageRequest
266/// Represents a DNS query message.
267///
268 class GNet::DnsMessageRequest
269{
270 public:
271 using RR = DnsMessageRR ;
272
273 DnsMessageRequest( const std::string & type , const std::string & hostname , unsigned int id = 0U ) ;
274 ///< Constructor.
275
276 const char * p() const ;
277 ///< Returns a pointer to the message data.
278
279 std::size_t n() const ;
280 ///< Returns message size.
281
282 private:
283 void q( const std::string & domain , char ) ;
284 void q( const std::string & ) ;
285 void q( unsigned int ) ;
286 void q( int ) ;
287
288 private:
289 std::string m_data ;
290} ;
291
292#endif
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
GNet::DnsMessageNameParser
An implementation class used by GNet::DnsMessage to parse compressed domain names.
Definition: gdnsmessage.h:252
GNet::DnsMessageNameParser::size
static unsigned int size(const DnsMessage &msg, unsigned int)
Returns the size of the compressed name.
Definition: gdnsmessage.cpp:293
GNet::DnsMessageNameParser::read
static std::string read(const DnsMessage &msg, unsigned int)
Returns the decompressed name, made up of the labels with dots inbetween.
Definition: gdnsmessage.cpp:311
GNet::DnsMessageQuestion
Represents DNS question record.
Definition: gdnsmessage.h:231
GNet::DnsMessageQuestion::DnsMessageQuestion
DnsMessageQuestion(const DnsMessage &, unsigned int offset)
Constructor.
Definition: gdnsmessage.cpp:274
GNet::DnsMessageQuestion::qname
std::string qname() const
Returns the subject of the question.
Definition: gdnsmessage.cpp:286
GNet::DnsMessageQuestion::size
unsigned int size() const
Returns the record size.
Definition: gdnsmessage.cpp:281
GNet::DnsMessageRR
Represents DNS response record.
Definition: gdnsmessage.h:181
GNet::DnsMessageRR::type
unsigned int type() const
Returns the type value().
Definition: gdnsmessage.cpp:369
GNet::DnsMessageRR::DnsMessageRR
DnsMessageRR(const DnsMessage &, unsigned int offset)
Constructor.
Definition: gdnsmessage.cpp:345
GNet::DnsMessageRR::address
Address address() const
Returns the Address if isa(A) or isa(AAAA).
Definition: gdnsmessage.cpp:431
GNet::DnsMessageRR::size
unsigned int size() const
Returns the size.
Definition: gdnsmessage.cpp:379
GNet::DnsMessageRR::isa
bool isa(const std::string &) const
Returns true if the type() has the given name().
Definition: gdnsmessage.cpp:374
GNet::DnsMessageRR::name
std::string name() const
Returns the NAME.
Definition: gdnsmessage.cpp:384
GNet::DnsMessageRecordType
A static class for mapping between a RR type name, such as "AAAA", and its corresponding numeric valu...
Definition: gdnsmessage.h:165
GNet::DnsMessageRecordType::name
static std::string name(unsigned int type_value)
Returns the type name for the given type value.
Definition: gdnsmessage.cpp:504
GNet::DnsMessageRecordType::value
static unsigned int value(const std::string &type_name)
Returns the type value for the given type name.
Definition: gdnsmessage.cpp:493
GNet::DnsMessageRequest
Represents a DNS query message.
Definition: gdnsmessage.h:269
GNet::DnsMessageRequest::n
std::size_t n() const
Returns message size.
Definition: gdnsmessage.cpp:83
GNet::DnsMessageRequest::p
const char * p() const
Returns a pointer to the message data.
Definition: gdnsmessage.cpp:78
GNet::DnsMessageRequest::DnsMessageRequest
DnsMessageRequest(const std::string &type, const std::string &hostname, unsigned int id=0U)
Constructor.
Definition: gdnsmessage.cpp:32
GNet::DnsMessage
A DNS message parser, with static factory functions for message composition.
Definition: gdnsmessage.h:52
GNet::DnsMessage::rrAddress
Address rrAddress(unsigned int n) const
Returns the address in the n'th record treated as a RR record.
Definition: gdnsmessage.cpp:267
GNet::DnsMessage::ANCOUNT
unsigned int ANCOUNT() const
Returns the header ANCOUNT field, ie.
Definition: gdnsmessage.cpp:204
GNet::DnsMessage::question
Question question(unsigned int n) const
Returns the n'th record as a Question record.
Definition: gdnsmessage.cpp:244
GNet::DnsMessage::RCODE
unsigned int RCODE() const
Returns the header RCODE.
Definition: gdnsmessage.cpp:194
GNet::DnsMessage::QR
bool QR() const
Returns the header QR (query/response).
Definition: gdnsmessage.cpp:159
GNet::DnsMessage::Z
unsigned int Z() const
Returns the header Z value (zero).
Definition: gdnsmessage.cpp:189
GNet::DnsMessage::QDCOUNT
unsigned int QDCOUNT() const
Returns the header QDCOUNT field, ie.
Definition: gdnsmessage.cpp:199
GNet::DnsMessage::n
std::size_t n() const
Returns the raw data size.
Definition: gdnsmessage.cpp:110
GNet::DnsMessage::NSCOUNT
unsigned int NSCOUNT() const
Returns the header NSCOUNT field, ie.
Definition: gdnsmessage.cpp:209
GNet::DnsMessage::ARCOUNT
unsigned int ARCOUNT() const
Returns the header ARCOUNT field, ie.
Definition: gdnsmessage.cpp:214
GNet::DnsMessage::AA
bool AA() const
Returns the header AA flag (authorative).
Definition: gdnsmessage.cpp:169
GNet::DnsMessage::p
const char * p() const
Returns the raw data.
Definition: gdnsmessage.cpp:105
GNet::DnsMessage::OPCODE
unsigned int OPCODE() const
Returns the header OPCODE.
Definition: gdnsmessage.cpp:164
GNet::DnsMessage::rejection
static DnsMessage rejection(const DnsMessage &request, unsigned int rcode)
Factory function for a failure response based on the given request message.
Definition: gdnsmessage.cpp:219
GNet::DnsMessage::TC
bool TC() const
Returns the header TC flag (truncated).
Definition: gdnsmessage.cpp:174
GNet::DnsMessage::request
static DnsMessage request(const std::string &type, const std::string &hostname, unsigned int id=0U)
Factory function for a request message of the give type ("A", "AAAA", etc).
Definition: gdnsmessage.cpp:120
GNet::DnsMessage::span
std::string span(unsigned int begin, unsigned int end) const
Returns the data in the given half-open byte range.
Definition: gdnsmessage.cpp:147
GNet::DnsMessage::byte
unsigned int byte(unsigned int byte_index) const
Returns byte at the given offset.
Definition: gdnsmessage.cpp:136
GNet::DnsMessage::addresses
std::vector< Address > addresses() const
Returns the Answer addresses.
Definition: gdnsmessage.cpp:126
GNet::DnsMessage::RD
bool RD() const
Returns the header RD (recursion desired).
Definition: gdnsmessage.cpp:179
GNet::DnsMessage::empty
static DnsMessage empty()
Factory function for an unusable object.
Definition: gdnsmessage.cpp:115
GNet::DnsMessage::ID
unsigned int ID() const
Returns the header ID.
Definition: gdnsmessage.cpp:154
GNet::DnsMessage::RA
bool RA() const
Returns the header RA (recursion available).
Definition: gdnsmessage.cpp:184
GNet::DnsMessage::rr
RR rr(unsigned int n) const
Returns the n'th record as a RR record.
Definition: gdnsmessage.cpp:253
GNet::DnsMessage::word
unsigned int word(unsigned int byte_index) const
Returns word at the given byte offset.
Definition: gdnsmessage.cpp:142
gaddress.h
gexception.h
GNet
Network classes.
Definition: gdef.h:1115
G::hostname
std::string hostname()
Returns the hostname.
Definition: ghostname_unix.cpp:27