libtins  4.0
dhcpv6.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_DHCPV6_H
31 #define TINS_DHCPV6_H
32 
33 #include <cstring>
34 #include <tins/pdu.h>
35 #include <tins/macros.h>
36 #include <tins/endianness.h>
37 #include <tins/small_uint.h>
38 #include <tins/ipv6_address.h>
39 #include <tins/pdu_option.h>
40 
41 namespace Tins {
42 namespace Memory {
43 
44 class OutputMemoryStream;
45 
46 } // Memory
47 
52 class TINS_API DHCPv6 : public PDU {
53 public:
58 
62  enum MessageType {
63  SOLICIT = 1,
64  ADVERTISE,
65  REQUEST,
66  CONFIRM,
67  RENEW,
68  REBIND,
69  REPLY,
70  RELEASE,
71  DECLINE,
72  RECONFIGURE,
73  INFO_REQUEST,
74  RELAY_FORWARD,
75  RELAY_REPLY,
76  LEASE_QUERY,
77  LEASE_QUERY_REPLY,
78  LEASE_QUERY_DONE,
79  LEASE_QUERY_DATA
80  };
81 
85  enum OptionTypes {
86  CLIENTID = 1,
87  SERVERID,
88  IA_NA,
89  IA_TA,
90  IA_ADDR,
91  OPTION_REQUEST,
92  PREFERENCE,
93  ELAPSED_TIME,
94  RELAY_MSG,
95  AUTH = 11,
96  UNICAST,
97  STATUS_CODE,
98  RAPID_COMMIT,
99  USER_CLASS,
100  VENDOR_CLASS,
101  VENDOR_OPTS,
102  INTERFACE_ID,
103  RECONF_MSG,
104  RECONF_ACCEPT,
105  SIP_SERVER_D,
106  SIP_SERVER_A,
107  DNS_SERVERS,
108  DOMAIN_LIST,
109  IA_PD,
110  IAPREFIX,
111  NIS_SERVERS,
112  NISP_SERVERS,
113  NIS_DOMAIN_NAME,
114  NISP_DOMAIN_NAME,
115  SNTP_SERVERS,
116  INFORMATION_REFRESH_TIME,
117  BCMCS_SERVER_D,
118  BCMCS_SERVER_A,
119  GEOCONF_CIVIC = 36,
120  REMOTE_ID,
121  SUBSCRIBER_ID,
122  CLIENT_FQDN,
123  PANA_AGENT,
124  NEW_POSIX_TIMEZONE,
125  NEW_TZDB_TIMEZONE,
126  ERO,
127  LQ_QUERY,
128  CLIENT_DATA,
129  CLT_TIME,
130  LQ_RELAY_DATA,
131  LQ_CLIENT_LINK,
132  MIP6_HNIDF,
133  MIP6_VDINF,
134  V6_LOST,
135  CAPWAP_AC_V6,
136  RELAY_ID,
137  NTP_SERVER,
138  V6_ACCESS_DOMAIN,
139  SIP_UA_CS_LIST,
140  BOOTFILE_URL,
141  BOOTFILE_PARAM,
142  CLIENT_ARCH_TYPE,
143  NII,
144  GEOLOCATION,
145  AFTR_NAME,
146  ERP_LOCAL_DOMAIN_NAME,
147  RSOO,
148  PD_EXCLUDE,
149  VSS,
150  MIP6_IDINF,
151  MIP6_UDINF,
152  MIP6_HNP,
153  MIP6_HAA,
154  MIP6_HAF,
155  RDNSS_SELECTION,
156  KRB_PRINCIPAL_NAME,
157  KRB_REALM_NAME,
158  KRB_DEFAULT_REALM_NAME,
159  KRB_KDC
160  };
161 
165  typedef std::vector<option> options_type;
166 
171 
175  static const PDU::PDUType pdu_flag = PDU::DHCPv6;
176 
181  struct ia_na_type {
182  typedef std::vector<uint8_t> options_type;
183 
184  uint32_t id, t1, t2;
185  options_type options;
186 
187  ia_na_type(uint32_t id = 0, uint32_t t1 = 0, uint32_t t2 = 0,
188  const options_type& options = options_type())
189  : id(id), t1(t1), t2(t2), options(options) {}
190 
191  static ia_na_type from_option(const option& opt);
192  };
193 
198  struct ia_ta_type {
199  typedef std::vector<uint8_t> options_type;
200 
201  uint32_t id;
202  options_type options;
203 
204  ia_ta_type(uint32_t id = 0,
205  const options_type& options = options_type())
206  : id(id), options(options) {}
207 
208  static ia_ta_type from_option(const option& opt);
209  };
210 
215  typedef std::vector<uint8_t> options_type;
216 
217  ipaddress_type address;
218  uint32_t preferred_lifetime, valid_lifetime;
219  options_type options;
220 
221  ia_address_type(ipaddress_type address = ipaddress_type(),
222  uint32_t preferred_lifetime = 0, uint32_t valid_lifetime = 0,
223  const options_type& options = options_type())
224  : address(address), preferred_lifetime(preferred_lifetime),
225  valid_lifetime(valid_lifetime), options(options) {}
226 
227  static ia_address_type from_option(const option& opt);
228  };
229 
234  typedef std::vector<uint8_t> auth_info_type;
235 
236  uint8_t protocol, algorithm, rdm;
237  uint64_t replay_detection;
238  auth_info_type auth_info;
239 
240  authentication_type(uint8_t protocol = 0, uint8_t algorithm = 0,
241  uint8_t rdm = 0, uint64_t replay_detection = 0,
242  const auth_info_type& auth_info = auth_info_type())
243  : protocol(protocol), algorithm(algorithm), rdm(rdm),
244  replay_detection(replay_detection), auth_info(auth_info) {}
245 
246  static authentication_type from_option(const option& opt);
247  };
248 
253  uint16_t code;
254  std::string message;
255 
256  status_code_type(uint16_t code = 0, const std::string& message = "")
257  : code(code), message(message) { }
258 
259  static status_code_type from_option(const option& opt);
260  };
261 
266  typedef std::vector<uint8_t> data_type;
267 
268  uint32_t enterprise_number;
269  data_type data;
270 
271  vendor_info_type(uint32_t enterprise_number = 0,
272  const data_type& data = data_type())
273  : enterprise_number(enterprise_number), data(data) { }
274 
275  static vendor_info_type from_option(const option& opt);
276  };
277 
278 
282  typedef std::vector<uint8_t> class_option_data_type;
283 
287  //typedef std::vector<class_option_data_type> user_class_type;
289  typedef std::vector<class_option_data_type> data_type;
290  data_type data;
291 
292  user_class_type(const data_type& data = data_type())
293  : data(data) { }
294 
295  static user_class_type from_option(const option& opt);
296  };
297 
302  typedef std::vector<class_option_data_type> class_data_type;
303 
304  uint32_t enterprise_number;
305  class_data_type vendor_class_data;
306 
307  vendor_class_type(uint32_t enterprise_number = 0,
308  const class_data_type& vendor_class_data = class_data_type())
309  : enterprise_number(enterprise_number),
310  vendor_class_data(vendor_class_data) { }
311 
312  static vendor_class_type from_option(const option& opt);
313  };
314 
319  struct duid_llt {
320  static const uint16_t duid_id = 1;
321  typedef std::vector<uint8_t> lladdress_type;
322 
323  uint16_t hw_type;
324  uint32_t time;
325  lladdress_type lladdress;
326 
327  duid_llt(uint16_t hw_type = 0, uint32_t time = 0,
328  const lladdress_type& lladdress = lladdress_type())
329  : hw_type(hw_type), time(time), lladdress(lladdress) {}
330 
331  PDU::serialization_type serialize() const;
332 
333  static duid_llt from_bytes(const uint8_t* buffer, uint32_t total_sz);
334  };
335 
339  struct duid_en {
340  static const uint16_t duid_id = 2;
341  typedef std::vector<uint8_t> identifier_type;
342 
343  uint32_t enterprise_number;
344  identifier_type identifier;
345 
346  duid_en(uint32_t enterprise_number = 0,
347  const identifier_type& identifier = identifier_type())
348  : enterprise_number(enterprise_number), identifier(identifier) {}
349 
350  PDU::serialization_type serialize() const;
351 
352  static duid_en from_bytes(const uint8_t* buffer, uint32_t total_sz);
353  };
354 
358  struct duid_ll {
359  static const uint16_t duid_id = 3;
360  typedef std::vector<uint8_t> lladdress_type;
361 
362  uint16_t hw_type;
363  lladdress_type lladdress;
364 
365  duid_ll(uint16_t hw_type = 0,
366  const lladdress_type& lladdress = lladdress_type())
367  : hw_type(hw_type), lladdress(lladdress) {}
368 
369  PDU::serialization_type serialize() const;
370 
371  static duid_ll from_bytes(const uint8_t* buffer, uint32_t total_sz);
372  };
373 
378  struct duid_type {
379  typedef PDU::serialization_type data_type;
380 
381  uint16_t id;
382  data_type data;
383 
384  duid_type(uint16_t id = 0, const data_type& data = data_type())
385  : id(id), data(data) {}
386 
387  duid_type(const duid_llt& identifier)
388  : id(duid_llt::duid_id), data(identifier.serialize()) {}
389 
390  duid_type(const duid_en& identifier)
391  : id(duid_en::duid_id), data(identifier.serialize()) {}
392 
393  duid_type(const duid_ll& identifier)
394  : id(duid_ll::duid_id), data(identifier.serialize()) {}
395 
396  static duid_type from_option(const option& opt);
397  };
398 
402  typedef std::vector<uint16_t> option_request_type;
403 
407  typedef std::vector<uint8_t> relay_msg_type;
408 
412  typedef std::vector<uint8_t> interface_id_type;
413 
420  static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
421 
425  DHCPv6();
426 
437  DHCPv6(const uint8_t* buffer, uint32_t total_sz);
438 
439  // Getters
440 
447  return static_cast<MessageType>(header_data_[0]);
448  }
449 
455  uint8_t hop_count() const {
456  return header_data_[1];
457  }
458 
465  return (header_data_[1] << 16) | (header_data_[2] << 8) | header_data_[3];
466  }
467 
473  const ipaddress_type& peer_address() const {
474  return peer_addr_;
475  }
476 
482  const ipaddress_type& link_address() const {
483  return link_addr_;
484  }
485 
491  const options_type& options() const {
492  return options_;
493  }
494 
495  // Setters
501  void msg_type(MessageType type);
502 
508  void hop_count(uint8_t count);
509 
515  void transaction_id(small_uint<24> id);
516 
522  void peer_address(const ipaddress_type& addr);
523 
529  void link_address(const ipaddress_type& addr);
530 
531  // Option getters
532 
540  ia_na_type ia_na() const;
541 
549  ia_ta_type ia_ta() const;
550 
557  ia_address_type ia_address() const;
558 
565  option_request_type option_request() const;
566 
573  uint8_t preference() const;
574 
581  uint16_t elapsed_time() const;
582 
589  relay_msg_type relay_message() const;
590 
597  authentication_type authentication() const;
598 
605  ipaddress_type server_unicast() const;
606 
613  status_code_type status_code() const;
614 
621  bool has_rapid_commit() const;
622 
629  user_class_type user_class() const;
630 
637  vendor_class_type vendor_class() const;
638 
645  vendor_info_type vendor_info() const;
646 
653  interface_id_type interface_id() const;
654 
661  uint8_t reconfigure_msg() const;
662 
669  bool has_reconfigure_accept() const;
670 
677  duid_type client_id() const;
678 
685  duid_type server_id() const;
686 
687  // Option setters
688 
695  void ia_na(const ia_na_type& value);
696 
703  void ia_ta(const ia_ta_type& value);
704 
710  void ia_address(const ia_address_type& value);
711 
717  void option_request(const option_request_type& value);
718 
724  void preference(uint8_t value);
725 
731  void elapsed_time(uint16_t value);
732 
738  void relay_message(const relay_msg_type& value);
739 
745  void authentication(const authentication_type& value);
746 
752  void server_unicast(const ipaddress_type& value);
753 
759  void status_code(const status_code_type& value);
760 
764  void rapid_commit();
765 
771  void user_class(const user_class_type& value);
772 
778  void vendor_class(const vendor_class_type& value);
779 
785  void vendor_info(const vendor_info_type& value);
786 
792  void interface_id(const interface_id_type& value);
793 
799  void reconfigure_msg(uint8_t value);
800 
804  void reconfigure_accept();
805 
811  void client_id(const duid_type& value);
812 
818  void server_id(const duid_type& value);
819 
820  // Other stuff
821 
825  bool is_relay_message() const;
826 
835  void add_option(const option& opt);
836 
846  bool remove_option(OptionTypes type);
847 
857  const option* search_option(OptionTypes type) const;
858 
859  // PDU stuff
860 
866  uint32_t header_size() const;
867 
875  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
876 
881  PDUType pdu_type() const {
882  return pdu_flag;
883  }
884 
888  DHCPv6* clone() const {
889  return new DHCPv6(*this);
890  }
891 private:
892  void write_serialization(uint8_t* buffer, uint32_t total_sz);
893  void write_option(const option& option, Memory::OutputMemoryStream& stream) const;
894  options_type::const_iterator search_option_iterator(OptionTypes type) const;
895  options_type::iterator search_option_iterator(OptionTypes type);
896 
897  template <template <typename> class Functor>
898  const option* safe_search_option(OptionTypes opt, uint32_t size) const {
899  const option* option = search_option(opt);
900  if (!option || Functor<uint32_t>()(option->data_size(), size)) {
901  throw option_not_found();
902  }
903  return option;
904  }
905 
906  template<typename T>
907  T search_and_convert(OptionTypes opt) const {
908  const option* option = search_option(opt);
909  if (!option) {
910  throw option_not_found();
911  }
912  return option->to<T>();
913  }
914 
915  uint8_t header_data_[4];
916  uint32_t options_size_;
917  ipaddress_type link_addr_, peer_addr_;
918  options_type options_;
919 };
920 
921 } // Tins
922 
923 #endif // TINS_DHCPV6_H
PDUOption< uint16_t, DHCPv6 > option
Definition: dhcpv6.h:57
Definition: dhcpv6.h:252
std::vector< option > options_type
Definition: dhcpv6.h:165
DHCPv6 * clone() const
Definition: dhcpv6.h:888
std::vector< uint16_t > option_request_type
Definition: dhcpv6.h:402
Definition: dhcpv6.h:301
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:127
PDUType pdu_type() const
Getter for the PDU&#39;s type.
Definition: dhcpv6.h:881
const ipaddress_type & link_address() const
Getter for the link address field.
Definition: dhcpv6.h:482
Definition: dhcpv6.h:181
std::vector< uint8_t > interface_id_type
Definition: dhcpv6.h:412
MessageType msg_type() const
Getter for the message type field.
Definition: dhcpv6.h:446
Represents a PDU option field.
Definition: pdu_option.h:201
Definition: dhcpv6.h:233
Definition: dhcpv6.h:265
Definition: dhcpv6.h:358
small_uint< 24 > transaction_id() const
Getter for the transaction id field.
Definition: dhcpv6.h:464
Definition: dhcpv6.h:378
IPv6Address ipaddress_type
Definition: dhcpv6.h:170
std::vector< uint8_t > class_option_data_type
Definition: dhcpv6.h:282
Represents a DHCPv6 PDU.
Definition: dhcpv6.h:52
Definition: dhcpv6.h:288
Definition: dhcpv6.h:319
The Tins namespace.
Definition: address_range.h:38
const options_type & options() const
Getter for the DHCPv6 options.
Definition: dhcpv6.h:491
T to() const
Constructs a T from this PDUOption.
Definition: pdu_option.h:389
Type used to store a PDU header&#39;s data.
Definition: pdu.h:194
Definition: dhcpv6.h:339
uint8_t hop_count() const
Getter for the hop count field.
Definition: dhcpv6.h:455
const ipaddress_type & peer_address() const
Getter for the peer address field.
Definition: dhcpv6.h:473
Definition: ipv6_address.h:45
OptionTypes
Definition: dhcpv6.h:85
byte_array serialization_type
Definition: pdu.h:112
size_t data_size() const
Retrieves the length of this option&#39;s data.
Definition: pdu_option.h:361
Base class for protocol data units.
Definition: pdu.h:107
Definition: dhcpv6.h:214
Exception thrown when an option is not found.
Definition: exceptions.h:56
Definition: dhcpv6.h:198
MessageType
Definition: dhcpv6.h:62
std::vector< uint8_t > relay_msg_type
Definition: dhcpv6.h:407