libtins 4.5
Loading...
Searching...
No Matches
dns.h
1/*
2 * Copyright (c) 2017, Matias Fontanini
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef TINS_DNS_H
31#define TINS_DNS_H
32
33#include <stdint.h>
34#include <vector>
35#include <cstring>
36#include <string>
37#include <map>
38#include <tins/macros.h>
39#include <tins/pdu.h>
40#include <tins/endianness.h>
41
42// Undefining some macros that conflict with some symbols here.
43// Eventually, the conflicting names will be removed, but until then
44// this is the best we can do.
45// - IN is defined by winsock2.h
46// - CERT is defined by openssl
47#undef IN
48#undef CERT
49
50namespace Tins {
51namespace Memory {
52
53class InputMemoryStream;
54
55} // Memory
56
57class IPv4Address;
58class IPv6Address;
59
85class TINS_API DNS : public PDU {
86public:
90 static const PDU::PDUType pdu_flag = PDU::DNS;
91
95 enum QRType {
96 QUERY = 0,
97 RESPONSE = 1
98 };
99
104 A = 1,
105 NS,
106 MD,
107 MF,
108 CNAME,
109 SOA,
110 MB,
111 MG,
112 MR,
113 NULL_R,
114 WKS,
115 PTR,
116 HINFO,
117 MINFO,
118 MX,
119 TXT,
120 RP,
121 AFSDB,
122 X25,
123 ISDN,
124 RT,
125 NSAP,
126 NSAP_PTR,
127 SIG,
128 KEY,
129 PX,
130 GPOS,
131 AAAA,
132 LOC,
133 NXT,
134 EID,
135 NIMLOC,
136 SRV,
137 ATMA,
138 NAPTR,
139 KX,
140 CERTIFICATE,
141 A6,
142 DNAM,
143 SINK,
144 OPT,
145 APL,
146 DS,
147 SSHFP,
148 IPSECKEY,
149 RRSIG,
150 NSEC,
151 DNSKEY,
152 DHCID,
153 NSEC3,
154 NSEC3PARAM,
155 CERT = CERTIFICATE
156 };
157
158 enum QueryClass {
159 INTERNET = 1,
160 CHAOS = 3,
161 HESIOD = 4,
165 IN = INTERNET,
166 CH = CHAOS,
167 HS = HESIOD,
171 ANY = 255
172 };
173
177 class query {
178 public:
186 #if TINS_IS_CXX11
187 query(std::string nm, QueryType tp, QueryClass cl)
188 : name_(std::move(nm)), type_(tp), qclass_(cl) {}
189 #else
190 query(const std::string& nm, QueryType tp, QueryClass cl)
191 : name_(nm), type_(tp), qclass_(cl) {}
192 #endif
193
197 query() : type_(), qclass_() {}
198
204 void dname(const std::string& nm) {
205 name_ = nm;
206 }
207
214 type_ = tp;
215 }
216
225 TINS_DEPRECATED(void type(QueryType tp)) {
226 type_ = tp;
227 }
228
234 void query_class(QueryClass cl) {
235 qclass_ = cl;
236 }
237
241 const std::string& dname() const {
242 return name_;
243 }
244
249 return type_;
250 }
251
261 return type_;
262 }
263
267 QueryClass query_class() const {
268 return qclass_;
269 }
270 private:
271 std::string name_;
272 QueryType type_;
273 QueryClass qclass_;
274 };
275
276 class resource;
277
282 public:
286 soa_record();
287
293
299 soa_record(const uint8_t* buffer, uint32_t total_sz);
300
312 soa_record(const std::string& mname,
313 const std::string& rname,
314 uint32_t serial,
315 uint32_t refresh,
316 uint32_t retry,
317 uint32_t expire,
318 uint32_t minimum_ttl);
319
327 const std::string& mname() const {
328 return mname_;
329 }
330
338 const std::string& rname() const {
339 return rname_;
340 }
341
346 uint32_t serial() const {
347 return serial_;
348 }
349
354 uint32_t refresh() const {
355 return refresh_;
356 }
357
362 uint32_t retry() const {
363 return retry_;
364 }
365
370 uint32_t expire() const {
371 return expire_;
372 }
373
378 uint32_t minimum_ttl() const {
379 return minimum_ttl_;
380 }
381
386 void mname(const std::string& value);
387
392 void rname(const std::string& value);
393
398 void serial(uint32_t value);
399
404 void refresh(uint32_t value);
405
410 void retry(uint32_t value);
411
416 void expire(uint32_t value);
417
422 void minimum_ttl(uint32_t value);
423
428 PDU::serialization_type serialize() const;
429 private:
430 void init(const uint8_t* buffer, uint32_t total_sz);
431
432 std::string mname_;
433 std::string rname_;
434 uint32_t serial_;
435 uint32_t refresh_;
436 uint32_t retry_;
437 uint32_t expire_;
438 uint32_t minimum_ttl_;
439 };
440
444 class resource {
445 public:
456 #if TINS_IS_CXX11
457 resource(std::string dname,
458 std::string data,
459 uint16_t type,
460 uint16_t rclass,
461 uint32_t ttl,
462 uint16_t preference = 0)
463 : dname_(std::move(dname)), data_(std::move(data)), type_(type),
464 qclass_(rclass), ttl_(ttl), preference_(preference) {}
465 #else
466 resource(const std::string& dname,
467 const std::string& data,
468 uint16_t type,
469 uint16_t rclass,
470 uint32_t ttl,
471 uint16_t preference = 0)
472 : dname_(dname), data_(data), type_(type), qclass_(rclass),
473 ttl_(ttl), preference_(preference) {}
474 #endif
475
476 resource() : type_(), qclass_(), ttl_(), preference_() {}
477
484 const std::string& dname() const {
485 return dname_;
486 }
487
491 const std::string& data() const {
492 return data_;
493 }
494
498 uint16_t query_type() const {
499 return type_;
500 }
501
510 TINS_DEPRECATED(uint16_t type() const) {
511 return type_;
512 }
513
517 uint16_t query_class() const {
518 return qclass_;
519 }
520
524 uint32_t ttl() const {
525 return ttl_;
526 }
527
533 uint16_t preference() const {
534 return preference_;
535 }
536
540 void dname(const std::string& data) {
541 dname_ = data;
542 }
543
556 void data(const std::string& data) {
557 data_ = data;
558 }
559
564 void data(const soa_record& data) {
565 serialization_type buffer = data.serialize();
566 data_.assign(buffer.begin(), buffer.end());
567 }
568
572 void query_type(uint16_t data) {
573 type_ = data;
574 }
575
584 TINS_DEPRECATED(void type(uint16_t data)) {
585 type_ = data;
586 }
587
591 void query_class(uint16_t data) {
592 qclass_ = data;
593 }
594
598 void ttl(uint32_t data) {
599 ttl_ = data;
600 }
601
607 void preference(uint16_t data) {
608 preference_ = data;
609 }
610 private:
611 std::string dname_, data_;
612 uint16_t type_, qclass_;
613 uint32_t ttl_;
614 uint16_t preference_;
615 };
616
617 TINS_DEPRECATED(typedef query Query);
618 TINS_DEPRECATED(typedef resource Resource);
619
620 typedef std::vector<query> queries_type;
621 typedef std::vector<resource> resources_type;
622 typedef IPv4Address address_type;
623 typedef IPv6Address address_v6_type;
624
631 static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
632
638 DNS();
639
650 DNS(const uint8_t* buffer, uint32_t total_sz);
651
652 // Getters
653
659 uint16_t id() const {
660 return Endian::be_to_host(header_.id);
661 }
662
669 QRType type() const {
670 return static_cast<QRType>(header_.qr);
671 }
672
678 uint8_t opcode() const {
679 return header_.opcode;
680 }
681
688 uint8_t authoritative_answer() const {
689 return header_.aa;
690 }
691
697 uint8_t truncated() const {
698 return header_.tc;
699 }
700
707 uint8_t recursion_desired() const {
708 return header_.rd;
709 }
710
717 uint8_t recursion_available() const {
718 return header_.ra;
719 }
720
726 uint8_t z() const {
727 return header_.z;
728 }
729
736 uint8_t authenticated_data() const {
737 return header_.ad;
738 }
739
746 uint8_t checking_disabled() const {
747 return header_.cd;
748 }
749
755 uint8_t rcode() const {
756 return header_.rcode;
757 }
758
764 uint16_t questions_count() const {
765 return Endian::be_to_host(header_.questions);
766 }
767
773 uint16_t answers_count() const {
774 return Endian::be_to_host(header_.answers);
775 }
776
782 uint16_t authority_count() const {
783 return Endian::be_to_host(header_.authority);
784 }
785
791 uint16_t additional_count() const {
792 return Endian::be_to_host(header_.additional);
793 }
794
801 return pdu_flag;
802 }
803
807 uint32_t header_size() const;
808
809 // Setters
810
816 void id(uint16_t new_id);
817
823 void type(QRType new_qr);
824
830 void opcode(uint8_t new_opcode);
831
838 void authoritative_answer(uint8_t new_aa);
839
846 void truncated(uint8_t new_tc);
847
854 void recursion_desired(uint8_t new_rd);
855
862 void recursion_available(uint8_t new_ra);
863
869 void z(uint8_t new_z);
870
877 void authenticated_data(uint8_t new_ad);
878
884 void checking_disabled(uint8_t new_cd);
885
891 void rcode(uint8_t new_rcode);
892
893 // Methods
894
900 void add_query(const query& query);
901
907 void add_answer(const resource& resource);
908
914 void add_authority(const resource& resource);
915
921 void add_additional(const resource& resource);
922
928 queries_type queries() const;
929
935 resources_type answers() const;
936
942 resources_type authority() const;
943
949 resources_type additional() const;
950
966 static std::string encode_domain_name(const std::string& domain_name);
967
980 static std::string decode_domain_name(const std::string& domain_name);
981
989 bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
990
994 DNS* clone() const {
995 return new DNS(*this);
996 }
997private:
998 friend class soa_record;
999
1000 TINS_BEGIN_PACK
1001 struct dns_header {
1002 uint16_t id;
1003 #if TINS_IS_LITTLE_ENDIAN
1004 uint16_t
1005 rd:1,
1006 tc:1,
1007 aa:1,
1008 opcode:4,
1009 qr:1,
1010 rcode:4,
1011 cd:1,
1012 ad:1,
1013 z:1,
1014 ra:1;
1015 #elif TINS_IS_BIG_ENDIAN
1016 uint16_t
1017 qr:1,
1018 opcode:4,
1019 aa:1,
1020 tc:1,
1021 rd:1,
1022 ra:1,
1023 z:1,
1024 ad:1,
1025 cd:1,
1026 rcode:4;
1027 #endif
1028 uint16_t questions, answers,
1029 authority, additional;
1030 } TINS_END_PACK;
1031
1032 typedef std::vector<std::pair<uint32_t*, uint32_t> > sections_type;
1033
1034 uint32_t compose_name(const uint8_t* ptr, char* out_ptr) const;
1035 void convert_records(const uint8_t* ptr,
1036 const uint8_t* end,
1037 resources_type& res,
1038 const uint16_t rr_count) const;
1039 void skip_to_section_end(Memory::InputMemoryStream& stream,
1040 const uint32_t num_records) const;
1041 void skip_to_dname_end(Memory::InputMemoryStream& stream) const;
1042 void update_records(uint32_t& section_start,
1043 uint32_t num_records,
1044 uint32_t threshold,
1045 uint32_t offset);
1046 uint8_t* update_dname(uint8_t* ptr, uint32_t threshold, uint32_t offset);
1047 static void inline_convert_v4(uint32_t value, char* output);
1048 static bool contains_dname(uint16_t type);
1049 void write_serialization(uint8_t* buffer, uint32_t total_sz);
1050 void add_record(const resource& resource, const sections_type& sections);
1051
1052 dns_header header_;
1053 byte_array records_data_;
1054 uint32_t answers_idx_, authority_idx_, additional_idx_;
1055};
1056
1057} // Tins
1058
1059#endif // TINS_DNS_H
Struct that represent DNS queries.
Definition dns.h:177
void dname(const std::string &nm)
Setter for the name field.
Definition dns.h:204
TINS_DEPRECATED(QueryType type() const)
Getter for the query type field.
Definition dns.h:260
const std::string & dname() const
Getter for the name field.
Definition dns.h:241
void query_class(QueryClass cl)
Setter for the query class field.
Definition dns.h:234
QueryType query_type() const
Getter for the query type field.
Definition dns.h:248
TINS_DEPRECATED(void type(QueryType tp))
Setter for the query type field.
Definition dns.h:225
void query_type(QueryType tp)
Setter for the query type field.
Definition dns.h:213
query(std::string nm, QueryType tp, QueryClass cl)
Constructs a DNS query.
Definition dns.h:187
QueryClass query_class() const
Getter for the query class field.
Definition dns.h:267
query()
Default constructs this Query.
Definition dns.h:197
Class that represent DNS resource records.
Definition dns.h:444
uint16_t preference() const
Getter for the preferece field.
Definition dns.h:533
uint32_t ttl() const
Definition dns.h:524
const std::string & data() const
Definition dns.h:491
TINS_DEPRECATED(void type(uint16_t data))
Setter for the query type field.
Definition dns.h:584
uint16_t query_class() const
Definition dns.h:517
void data(const std::string &data)
Setter for the data field.
Definition dns.h:556
resource(std::string dname, std::string data, uint16_t type, uint16_t rclass, uint32_t ttl, uint16_t preference=0)
Definition dns.h:457
void query_type(uint16_t data)
Definition dns.h:572
uint16_t query_type() const
Definition dns.h:498
const std::string & dname() const
Getter for the domain name field.
Definition dns.h:484
void dname(const std::string &data)
Definition dns.h:540
void ttl(uint32_t data)
Definition dns.h:598
TINS_DEPRECATED(uint16_t type() const)
Getter for the query type field.
Definition dns.h:510
void preference(uint16_t data)
Setter for the preference field.
Definition dns.h:607
void data(const soa_record &data)
Sets the contents of this resource to the provided SOA record.
Definition dns.h:564
void query_class(uint16_t data)
Definition dns.h:591
Class that represents a Start Of Authority record.
Definition dns.h:281
void rname(const std::string &value)
Getter for the responsible person name field.
const std::string & mname() const
Getter for the primary source name field.
Definition dns.h:327
const std::string & rname() const
Getter for the responsible person name field.
Definition dns.h:338
uint32_t expire() const
Getter for the expire field.
Definition dns.h:370
soa_record(const std::string &mname, const std::string &rname, uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum_ttl)
Constructs a SOA record.
uint32_t refresh() const
Getter for the refresh field.
Definition dns.h:354
uint32_t minimum_ttl() const
Getter for the minimum TTL field.
Definition dns.h:378
uint32_t retry() const
Getter for the retry field.
Definition dns.h:362
void mname(const std::string &value)
Getter for the primary source name field.
PDU::serialization_type serialize() const
Serialize this SOA record.
Definition dns.cpp:681
uint32_t serial() const
Getter for the serial number field.
Definition dns.h:346
Represents a DNS PDU.
Definition dns.h:85
uint8_t authenticated_data() const
Getter for the authenticated data field.
Definition dns.h:736
uint16_t id() const
Getter for the id field.
Definition dns.h:659
QRType
Definition dns.h:95
uint16_t answers_count() const
Getter for the answers field.
Definition dns.h:773
QRType type() const
Getter for the query response field.
Definition dns.h:669
uint8_t rcode() const
Getter for the rcode field.
Definition dns.h:755
uint16_t additional_count() const
Getter for the additional field.
Definition dns.h:791
DNS * clone() const
Definition dns.h:994
QueryType
Query types enum.
Definition dns.h:103
uint8_t recursion_available() const
Getter for the recursion available field.
Definition dns.h:717
uint8_t authoritative_answer() const
Getter for the authoritative answer field.
Definition dns.h:688
PDUType pdu_type() const
Getter for the PDU's type.
Definition dns.h:800
uint8_t z() const
Getter for the z desired field.
Definition dns.h:726
uint8_t recursion_desired() const
Getter for the recursion desired field.
Definition dns.h:707
uint8_t opcode() const
Getter for the opcode field.
Definition dns.h:678
uint8_t truncated() const
Getter for the truncated field.
Definition dns.h:697
uint16_t authority_count() const
Getter for the authority field.
Definition dns.h:782
uint16_t questions_count() const
Getter for the questions field.
Definition dns.h:764
uint8_t checking_disabled() const
Getter for the checking disabled field.
Definition dns.h:746
Abstraction of an IPv4 address.
Definition ip_address.h:45
Definition ipv6_address.h:45
Base class for protocol data units.
Definition pdu.h:107
PDUType
Enum which identifies each type of PDU.
Definition pdu.h:127
byte_array serialization_type
Definition pdu.h:112
The Tins namespace.
Definition address_range.h:38