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
32namespace 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///
52{
53public:
54 G_EXCEPTION( Error , "dns message error" ) ;
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
151private:
152 friend class DnsMessageDumper ;
153 DnsMessage() ;
154 void reject( unsigned int rcode ) ;
155
156private:
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///
165{
166public:
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
173public:
174 DnsMessageRecordType() = delete ;
175} ;
176
177//| \class GNet::DnsMessageRR
178/// Represents DNS response record.
179///
181{
182public:
183 using RR = DnsMessageRR ;
184
185public:
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
205private:
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
216private:
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///
231{
232public:
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
242private:
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///
252{
253public:
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
261public:
262 DnsMessageNameParser() = delete ;
263} ;
264
265//| \class GNet::DnsMessageRequest
266/// Represents a DNS query message.
267///
269{
270public:
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
282private:
283 void q( const std::string & domain , char ) ;
284 void q( const std::string & ) ;
285 void q( unsigned int ) ;
286 void q( int ) ;
287
288private:
289 std::string m_data ;
290} ;
291
292#endif
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
An implementation class used by GNet::DnsMessage to parse compressed domain names.
Definition: gdnsmessage.h:252
static unsigned int size(const DnsMessage &msg, unsigned int)
Returns the size of the compressed name.
static std::string read(const DnsMessage &msg, unsigned int)
Returns the decompressed name, made up of the labels with dots inbetween.
Represents DNS question record.
Definition: gdnsmessage.h:231
DnsMessageQuestion(const DnsMessage &, unsigned int offset)
Constructor.
std::string qname() const
Returns the subject of the question.
unsigned int size() const
Returns the record size.
Represents DNS response record.
Definition: gdnsmessage.h:181
unsigned int type() const
Returns the type value().
DnsMessageRR(const DnsMessage &, unsigned int offset)
Constructor.
Address address() const
Returns the Address if isa(A) or isa(AAAA).
unsigned int size() const
Returns the size.
bool isa(const std::string &) const
Returns true if the type() has the given name().
std::string name() const
Returns the NAME.
A static class for mapping between a RR type name, such as "AAAA", and its corresponding numeric valu...
Definition: gdnsmessage.h:165
static std::string name(unsigned int type_value)
Returns the type name for the given type value.
static unsigned int value(const std::string &type_name)
Returns the type value for the given type name.
Represents a DNS query message.
Definition: gdnsmessage.h:269
std::size_t n() const
Returns message size.
Definition: gdnsmessage.cpp:83
const char * p() const
Returns a pointer to the message data.
Definition: gdnsmessage.cpp:78
DnsMessageRequest(const std::string &type, const std::string &hostname, unsigned int id=0U)
Constructor.
Definition: gdnsmessage.cpp:32
A DNS message parser, with static factory functions for message composition.
Definition: gdnsmessage.h:52
Address rrAddress(unsigned int n) const
Returns the address in the n'th record treated as a RR record.
unsigned int ANCOUNT() const
Returns the header ANCOUNT field, ie.
Question question(unsigned int n) const
Returns the n'th record as a Question record.
unsigned int RCODE() const
Returns the header RCODE.
bool QR() const
Returns the header QR (query/response).
unsigned int Z() const
Returns the header Z value (zero).
unsigned int QDCOUNT() const
Returns the header QDCOUNT field, ie.
std::size_t n() const
Returns the raw data size.
unsigned int NSCOUNT() const
Returns the header NSCOUNT field, ie.
unsigned int ARCOUNT() const
Returns the header ARCOUNT field, ie.
bool AA() const
Returns the header AA flag (authorative).
const char * p() const
Returns the raw data.
unsigned int OPCODE() const
Returns the header OPCODE.
static DnsMessage rejection(const DnsMessage &request, unsigned int rcode)
Factory function for a failure response based on the given request message.
bool TC() const
Returns the header TC flag (truncated).
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).
std::string span(unsigned int begin, unsigned int end) const
Returns the data in the given half-open byte range.
unsigned int byte(unsigned int byte_index) const
Returns byte at the given offset.
std::vector< Address > addresses() const
Returns the Answer addresses.
bool RD() const
Returns the header RD (recursion desired).
static DnsMessage empty()
Factory function for an unusable object.
unsigned int ID() const
Returns the header ID.
bool RA() const
Returns the header RA (recursion available).
RR rr(unsigned int n) const
Returns the n'th record as a RR record.
unsigned int word(unsigned int byte_index) const
Returns word at the given byte offset.
Network classes.
Definition: gdef.h:1115
std::string hostname()
Returns the hostname.