libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
dns.h
1 /*
2  * Copyright (c) 2016, 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 <list>
35 #include <vector>
36 #include <cstring>
37 #include <string>
38 #include <map>
39 #include "macros.h"
40 #include "pdu.h"
41 #include "endianness.h"
42 
43 namespace Tins {
44 namespace Memory {
45 
46 class InputMemoryStream;
47 
48 } // Memory
49 
50 class IPv4Address;
51 class IPv6Address;
52 
78 class TINS_API DNS : public PDU {
79 public:
83  static const PDU::PDUType pdu_flag = PDU::DNS;
84 
88  enum QRType {
89  QUERY = 0,
90  RESPONSE = 1
91  };
92 
96  enum QueryType {
97  A = 1,
98  NS,
99  MD,
100  MF,
101  CNAME,
102  SOA,
103  MB,
104  MG,
105  MR,
106  NULL_R,
107  WKS,
108  PTR,
109  HINFO,
110  MINFO,
111  MX,
112  TXT,
113  RP,
114  AFSDB,
115  X25,
116  ISDN,
117  RT,
118  NSAP,
119  NSAP_PTR,
120  SIG,
121  KEY,
122  PX,
123  GPOS,
124  AAAA,
125  LOC,
126  NXT,
127  EID,
128  NIMLOC,
129  SRV,
130  ATMA,
131  NAPTR,
132  KX,
133  CERT,
134  A6,
135  DNAM,
136  SINK,
137  OPT,
138  APL,
139  DS,
140  SSHFP,
141  IPSECKEY,
142  RRSIG,
143  NSEC,
144  DNSKEY,
145  DHCID,
146  NSEC3,
147  NSEC3PARAM
148  };
149 
150  enum QueryClass {
151  IN = 1,
152  CH = 3,
153  HS = 4,
154  ANY = 255
155  };
156 
160  class query {
161  public:
169  query(const std::string& nm, QueryType tp, QueryClass cl)
170  : name_(nm), type_(tp), qclass_(cl) {}
171 
175  query() : type_(), qclass_() {}
176 
182  void dname(const std::string& nm) {
183  name_ = nm;
184  }
185 
192  type_ = tp;
193  }
194 
203  TINS_DEPRECATED(void type(QueryType tp)) {
204  type_ = tp;
205  }
206 
212  void query_class(QueryClass cl) {
213  qclass_ = cl;
214  }
215 
219  const std::string& dname() const {
220  return name_;
221  }
222 
227  return type_;
228  }
229 
238  TINS_DEPRECATED(QueryType type() const) {
239  return type_;
240  }
241 
245  QueryClass query_class() const {
246  return qclass_;
247  }
248  private:
249  std::string name_;
250  QueryType type_;
251  QueryClass qclass_;
252  };
253 
254  class resource;
255 
259  class soa_record {
260  public:
264  soa_record();
265 
271 
277  soa_record(const uint8_t* buffer, uint32_t total_sz);
278 
290  soa_record(const std::string& mname,
291  const std::string& rname,
292  uint32_t serial,
293  uint32_t refresh,
294  uint32_t retry,
295  uint32_t expire,
296  uint32_t minimum_ttl);
297 
305  const std::string& mname() const {
306  return mname_;
307  }
308 
316  const std::string& rname() const {
317  return rname_;
318  }
319 
324  uint32_t serial() const {
325  return serial_;
326  }
327 
332  uint32_t refresh() const {
333  return refresh_;
334  }
335 
340  uint32_t retry() const {
341  return retry_;
342  }
343 
348  uint32_t expire() const {
349  return expire_;
350  }
351 
356  uint32_t minimum_ttl() const {
357  return minimum_ttl_;
358  }
359 
364  void mname(const std::string& value);
365 
370  void rname(const std::string& value);
371 
376  void serial(uint32_t value);
377 
382  void refresh(uint32_t value);
383 
388  void retry(uint32_t value);
389 
394  void expire(uint32_t value);
395 
400  void minimum_ttl(uint32_t value);
401 
406  PDU::serialization_type serialize() const;
407  private:
408  void init(const uint8_t* buffer, uint32_t total_sz);
409 
410  std::string mname_;
411  std::string rname_;
412  uint32_t serial_;
413  uint32_t refresh_;
414  uint32_t retry_;
415  uint32_t expire_;
416  uint32_t minimum_ttl_;
417  };
418 
422  class resource {
423  public:
434  resource(const std::string& dname,
435  const std::string& data,
436  uint16_t type,
437  uint16_t rclass,
438  uint32_t ttl,
439  uint16_t preference = 0)
440  : dname_(dname), data_(data), type_(type), qclass_(rclass),
441  ttl_(ttl), preference_(preference) {}
442 
443  resource() : type_(), qclass_(), ttl_(), preference_() {}
444 
451  const std::string& dname() const {
452  return dname_;
453  }
454 
458  const std::string& data() const {
459  return data_;
460  }
461 
465  uint16_t query_type() const {
466  return type_;
467  }
468 
477  TINS_DEPRECATED(uint16_t type() const) {
478  return type_;
479  }
480 
484  uint16_t query_class() const {
485  return qclass_;
486  }
487 
491  uint32_t ttl() const {
492  return ttl_;
493  }
494 
500  uint16_t preference() const {
501  return preference_;
502  }
503 
507  void dname(const std::string& data) {
508  dname_ = data;
509  }
510 
523  void data(const std::string& data) {
524  data_ = data;
525  }
526 
531  void data(const soa_record& data) {
532  serialization_type buffer = data.serialize();
533  data_.assign(buffer.begin(), buffer.end());
534  }
535 
539  void query_type(uint16_t data) {
540  type_ = data;
541  }
542 
551  TINS_DEPRECATED(void type(uint16_t data)) {
552  type_ = data;
553  }
554 
558  void query_class(uint16_t data) {
559  qclass_ = data;
560  }
561 
565  void ttl(uint32_t data) {
566  ttl_ = data;
567  }
568 
574  void preference(uint16_t data) {
575  preference_ = data;
576  }
577  private:
578  std::string dname_, data_;
579  uint16_t type_, qclass_;
580  uint32_t ttl_;
581  uint16_t preference_;
582  };
583 
584  TINS_DEPRECATED(typedef query Query);
585  TINS_DEPRECATED(typedef resource Resource);
586 
587  typedef std::list<query> queries_type;
588  typedef std::list<resource> resources_type;
589  typedef IPv4Address address_type;
590  typedef IPv6Address address_v6_type;
591 
598  static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
599 
605  DNS();
606 
617  DNS(const uint8_t* buffer, uint32_t total_sz);
618 
619  // Getters
620 
626  uint16_t id() const {
627  return Endian::be_to_host(header_.id);
628  }
629 
636  QRType type() const {
637  return static_cast<QRType>(header_.qr);
638  }
639 
645  uint8_t opcode() const {
646  return header_.opcode;
647  }
648 
655  uint8_t authoritative_answer() const {
656  return header_.aa;
657  }
658 
664  uint8_t truncated() const {
665  return header_.tc;
666  }
667 
674  uint8_t recursion_desired() const {
675  return header_.rd;
676  }
677 
684  uint8_t recursion_available() const {
685  return header_.ra;
686  }
687 
693  uint8_t z() const {
694  return header_.z;
695  }
696 
703  uint8_t authenticated_data() const {
704  return header_.ad;
705  }
706 
713  uint8_t checking_disabled() const {
714  return header_.cd;
715  }
716 
722  uint8_t rcode() const {
723  return header_.rcode;
724  }
725 
731  uint16_t questions_count() const {
732  return Endian::be_to_host(header_.questions);
733  }
734 
740  uint16_t answers_count() const {
741  return Endian::be_to_host(header_.answers);
742  }
743 
749  uint16_t authority_count() const {
750  return Endian::be_to_host(header_.authority);
751  }
752 
758  uint16_t additional_count() const {
759  return Endian::be_to_host(header_.additional);
760  }
761 
767  PDUType pdu_type() const {
768  return pdu_flag;
769  }
770 
774  uint32_t header_size() const;
775 
776  // Setters
777 
783  void id(uint16_t new_id);
784 
790  void type(QRType new_qr);
791 
797  void opcode(uint8_t new_opcode);
798 
805  void authoritative_answer(uint8_t new_aa);
806 
813  void truncated(uint8_t new_tc);
814 
821  void recursion_desired(uint8_t new_rd);
822 
829  void recursion_available(uint8_t new_ra);
830 
836  void z(uint8_t new_z);
837 
844  void authenticated_data(uint8_t new_ad);
845 
851  void checking_disabled(uint8_t new_cd);
852 
858  void rcode(uint8_t new_rcode);
859 
860  // Methods
861 
867  void add_query(const query& query);
868 
874  void add_answer(const resource& resource);
875 
881  void add_authority(const resource& resource);
882 
888  void add_additional(const resource& resource);
889 
895  queries_type queries() const;
896 
902  resources_type answers() const;
903 
909  resources_type authority() const;
910 
916  resources_type additional() const;
917 
933  static std::string encode_domain_name(const std::string& domain_name);
934 
947  static std::string decode_domain_name(const std::string& domain_name);
948 
956  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
957 
961  DNS* clone() const {
962  return new DNS(*this);
963  }
964 private:
965  friend class soa_record;
966 
967  TINS_BEGIN_PACK
968  struct dns_header {
969  uint16_t id;
970  #if TINS_IS_LITTLE_ENDIAN
971  uint16_t
972  rd:1,
973  tc:1,
974  aa:1,
975  opcode:4,
976  qr:1,
977  rcode:4,
978  cd:1,
979  ad:1,
980  z:1,
981  ra:1;
982  #elif TINS_IS_BIG_ENDIAN
983  uint16_t
984  qr:1,
985  opcode:4,
986  aa:1,
987  tc:1,
988  rd:1,
989  ra:1,
990  z:1,
991  ad:1,
992  cd:1,
993  rcode:4;
994  #endif
995  uint16_t questions, answers,
996  authority, additional;
997  } TINS_END_PACK;
998 
999  typedef std::vector<std::pair<uint32_t*, uint32_t> > sections_type;
1000 
1001  uint32_t compose_name(const uint8_t* ptr, char* out_ptr) const;
1002  void convert_records(const uint8_t* ptr,
1003  const uint8_t* end,
1004  resources_type& res) const;
1005  void skip_to_section_end(Memory::InputMemoryStream& stream,
1006  const uint32_t num_records) const;
1007  void skip_to_dname_end(Memory::InputMemoryStream& stream) const;
1008  void update_records(uint32_t& section_start,
1009  uint32_t num_records,
1010  uint32_t threshold,
1011  uint32_t offset);
1012  uint8_t* update_dname(uint8_t* ptr, uint32_t threshold, uint32_t offset);
1013  static void inline_convert_v4(uint32_t value, char* output);
1014  static bool contains_dname(uint16_t type);
1015  void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent);
1016  void add_record(const resource& resource, const sections_type& sections);
1017 
1018  dns_header header_;
1019  byte_array records_data_;
1020  uint32_t answers_idx_, authority_idx_, additional_idx_;
1021 };
1022 
1023 } // Tins
1024 
1025 #endif // TINS_DNS_H
uint8_t authoritative_answer() const
Setter for the authoritative answer field.
Definition: dns.h:655
uint8_t rcode() const
Setter for the rcode field.
Definition: dns.h:722
const std::string & dname() const
Getter for the domain name field.
Definition: dns.h:451
uint8_t authenticated_data() const
Setter for the authenticated data field.
Definition: dns.h:703
void preference(uint16_t data)
Setter for the preference field.
Definition: dns.h:574
QRType type() const
Setter for the query response field.
Definition: dns.h:636
PDUType pdu_type() const
Getter for the PDU's type.
Definition: dns.h:767
uint32_t expire() const
Getter for the expire field.
Definition: dns.h:348
QueryType
Query types enum.
Definition: dns.h:96
TINS_DEPRECATED(QueryType type() const)
Getter for the query type field.
Definition: dns.h:238
std::vector< uint8_t > byte_array
Definition: pdu.h:46
uint32_t ttl() const
Definition: dns.h:491
uint16_t id() const
Setter for the id field.
Definition: dns.h:626
Represents a DNS PDU.
Definition: dns.h:78
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:128
uint8_t z() const
Setter for the z desired field.
Definition: dns.h:693
void dname(const std::string &nm)
Setter for the name field.
Definition: dns.h:182
TINS_DEPRECATED(void type(QueryType tp))
Setter for the query type field.
Definition: dns.h:203
QueryType query_type() const
Getter for the query type field.
Definition: dns.h:226
uint8_t truncated() const
Setter for the truncated field.
Definition: dns.h:664
Struct that represent DNS queries.
Definition: dns.h:160
resource(const std::string &dname, const std::string &data, uint16_t type, uint16_t rclass, uint32_t ttl, uint16_t preference=0)
Definition: dns.h:434
Class that represents a Start Of Authority record.
Definition: dns.h:259
uint16_t query_type() const
Definition: dns.h:465
query()
Default constructs this Query.
Definition: dns.h:175
void query_class(QueryClass cl)
Setter for the query class field.
Definition: dns.h:212
uint8_t recursion_available() const
Setter for the recursion available field.
Definition: dns.h:684
uint32_t serial() const
Getter for the serial number field.
Definition: dns.h:324
uint16_t preference() const
Getter for the preferece field.
Definition: dns.h:500
DNS * clone() const
Definition: dns.h:961
TINS_DEPRECATED(uint16_t type() const)
Getter for the query type field.
Definition: dns.h:477
const std::string & data() const
Definition: dns.h:458
TINS_DEPRECATED(void type(uint16_t data))
Setter for the query type field.
Definition: dns.h:551
query(const std::string &nm, QueryType tp, QueryClass cl)
Constructs a DNS query.
Definition: dns.h:169
const std::string & mname() const
Getter for the primary source name field.
Definition: dns.h:305
PDU::serialization_type serialize() const
Serialize this SOA record.
Definition: dns.cpp:660
void dname(const std::string &data)
Definition: dns.h:507
QRType
Definition: dns.h:88
uint32_t minimum_ttl() const
Getter for the minimum TTL field.
Definition: dns.h:356
const std::string & dname() const
Getter for the name field.
Definition: dns.h:219
void data(const std::string &data)
Setter for the data field.
Definition: dns.h:523
void query_type(uint16_t data)
Definition: dns.h:539
uint8_t checking_disabled() const
Setter for the checking disabled field.
Definition: dns.h:713
uint16_t answers_count() const
Setter for the answers field.
Definition: dns.h:740
void query_class(uint16_t data)
Definition: dns.h:558
const std::string & rname() const
Getter for the responsible person name field.
Definition: dns.h:316
uint16_t query_class() const
Definition: dns.h:484
uint32_t refresh() const
Getter for the refresh field.
Definition: dns.h:332
uint8_t recursion_desired() const
Setter for the recursion desired field.
Definition: dns.h:674
Abstraction of an IPv4 address.
Definition: ip_address.h:44
void ttl(uint32_t data)
Definition: dns.h:565
void data(const soa_record &data)
Sets the contents of this resource to the provided SOA record.
Definition: dns.h:531
Definition: ipv6_address.h:44
uint16_t questions_count() const
Setter for the questions field.
Definition: dns.h:731
uint16_t authority_count() const
Setter for the authority field.
Definition: dns.h:749
byte_array serialization_type
Definition: pdu.h:113
QueryClass query_class() const
Getter for the query class field.
Definition: dns.h:245
Base class for protocol data units.
Definition: pdu.h:108
uint8_t opcode() const
Setter for the opcode field.
Definition: dns.h:645
uint32_t retry() const
Getter for the retry field.
Definition: dns.h:340
uint16_t additional_count() const
Setter for the additional field.
Definition: dns.h:758
Class that represent DNS resource records.
Definition: dns.h:422
void query_type(QueryType tp)
Setter for the query type field.
Definition: dns.h:191