libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
dhcpv6.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_DHCPV6_H
31 #define TINS_DHCPV6_H
32 
33 #include <cstring>
34 #include <list>
35 #include "pdu.h"
36 #include "macros.h"
37 #include "endianness.h"
38 #include "small_uint.h"
39 #include "ipv6_address.h"
40 #include "pdu_option.h"
41 
42 namespace Tins {
43 namespace Memory {
44 
45 class OutputMemoryStream;
46 
47 } // Memory
48 
53 class TINS_API DHCPv6 : public PDU {
54 public:
59 
63  enum MessageType {
64  SOLICIT = 1,
65  ADVERTISE,
66  REQUEST,
67  CONFIRM,
68  RENEW,
69  REBIND,
70  REPLY,
71  RELEASE,
72  DECLINE,
73  RECONFIGURE,
74  INFO_REQUEST,
75  RELAY_FORWARD,
76  RELAY_REPLY,
77  LEASE_QUERY,
78  LEASE_QUERY_REPLY,
79  LEASE_QUERY_DONE,
80  LEASE_QUERY_DATA
81  };
82 
86  enum OptionTypes {
87  CLIENTID = 1,
88  SERVERID,
89  IA_NA,
90  IA_TA,
91  IA_ADDR,
92  OPTION_REQUEST,
93  PREFERENCE,
94  ELAPSED_TIME,
95  RELAY_MSG,
96  AUTH = 11,
97  UNICAST,
98  STATUS_CODE,
99  RAPID_COMMIT,
100  USER_CLASS,
101  VENDOR_CLASS,
102  VENDOR_OPTS,
103  INTERFACE_ID,
104  RECONF_MSG,
105  RECONF_ACCEPT,
106  SIP_SERVER_D,
107  SIP_SERVER_A,
108  DNS_SERVERS,
109  DOMAIN_LIST,
110  IA_PD,
111  IAPREFIX,
112  NIS_SERVERS,
113  NISP_SERVERS,
114  NIS_DOMAIN_NAME,
115  NISP_DOMAIN_NAME,
116  SNTP_SERVERS,
117  INFORMATION_REFRESH_TIME,
118  BCMCS_SERVER_D,
119  BCMCS_SERVER_A,
120  GEOCONF_CIVIC = 36,
121  REMOTE_ID,
122  SUBSCRIBER_ID,
123  CLIENT_FQDN,
124  PANA_AGENT,
125  NEW_POSIX_TIMEZONE,
126  NEW_TZDB_TIMEZONE,
127  ERO,
128  LQ_QUERY,
129  CLIENT_DATA,
130  CLT_TIME,
131  LQ_RELAY_DATA,
132  LQ_CLIENT_LINK,
133  MIP6_HNIDF,
134  MIP6_VDINF,
135  V6_LOST,
136  CAPWAP_AC_V6,
137  RELAY_ID,
138  NTP_SERVER,
139  V6_ACCESS_DOMAIN,
140  SIP_UA_CS_LIST,
141  BOOTFILE_URL,
142  BOOTFILE_PARAM,
143  CLIENT_ARCH_TYPE,
144  NII,
145  GEOLOCATION,
146  AFTR_NAME,
147  ERP_LOCAL_DOMAIN_NAME,
148  RSOO,
149  PD_EXCLUDE,
150  VSS,
151  MIP6_IDINF,
152  MIP6_UDINF,
153  MIP6_HNP,
154  MIP6_HAA,
155  MIP6_HAF,
156  RDNSS_SELECTION,
157  KRB_PRINCIPAL_NAME,
158  KRB_REALM_NAME,
159  KRB_DEFAULT_REALM_NAME,
160  KRB_KDC
161  };
162 
166  typedef std::list<option> options_type;
167 
172 
176  static const PDU::PDUType pdu_flag = PDU::DHCPv6;
177 
182  struct ia_na_type {
183  typedef std::vector<uint8_t> options_type;
184 
185  uint32_t id, t1, t2;
186  options_type options;
187 
188  ia_na_type(uint32_t id = 0, uint32_t t1 = 0, uint32_t t2 = 0,
189  const options_type& options = options_type())
190  : id(id), t1(t1), t2(t2), options(options) {}
191 
192  static ia_na_type from_option(const option& opt);
193  };
194 
199  struct ia_ta_type {
200  typedef std::vector<uint8_t> options_type;
201 
202  uint32_t id;
203  options_type options;
204 
205  ia_ta_type(uint32_t id = 0,
206  const options_type& options = options_type())
207  : id(id), options(options) {}
208 
209  static ia_ta_type from_option(const option& opt);
210  };
211 
216  typedef std::vector<uint8_t> options_type;
217 
218  ipaddress_type address;
219  uint32_t preferred_lifetime, valid_lifetime;
220  options_type options;
221 
223  uint32_t preferred_lifetime = 0, uint32_t valid_lifetime = 0,
224  const options_type& options = options_type())
225  : address(address), preferred_lifetime(preferred_lifetime),
226  valid_lifetime(valid_lifetime), options(options) {}
227 
228  static ia_address_type from_option(const option& opt);
229  };
230 
235  typedef std::vector<uint8_t> auth_info_type;
236 
237  uint8_t protocol, algorithm, rdm;
238  uint64_t replay_detection;
239  auth_info_type auth_info;
240 
241  authentication_type(uint8_t protocol = 0, uint8_t algorithm = 0,
242  uint8_t rdm = 0, uint64_t replay_detection = 0,
243  const auth_info_type& auth_info = auth_info_type())
244  : protocol(protocol), algorithm(algorithm), rdm(rdm),
245  replay_detection(replay_detection), auth_info(auth_info) {}
246 
247  static authentication_type from_option(const option& opt);
248  };
249 
254  uint16_t code;
255  std::string message;
256 
257  status_code_type(uint16_t code = 0, const std::string& message = "")
258  : code(code), message(message) { }
259 
260  static status_code_type from_option(const option& opt);
261  };
262 
267  typedef std::vector<uint8_t> data_type;
268 
269  uint32_t enterprise_number;
270  data_type data;
271 
272  vendor_info_type(uint32_t enterprise_number = 0,
273  const data_type& data = data_type())
274  : enterprise_number(enterprise_number), data(data) { }
275 
276  static vendor_info_type from_option(const option& opt);
277  };
278 
279 
283  typedef std::vector<uint8_t> class_option_data_type;
284 
288  //typedef std::vector<class_option_data_type> user_class_type;
290  typedef std::vector<class_option_data_type> data_type;
291  data_type data;
292 
293  user_class_type(const data_type& data = data_type())
294  : data(data) { }
295 
296  static user_class_type from_option(const option& opt);
297  };
298 
303  typedef std::vector<class_option_data_type> class_data_type;
304 
305  uint32_t enterprise_number;
306  class_data_type vendor_class_data;
307 
308  vendor_class_type(uint32_t enterprise_number = 0,
309  const class_data_type& vendor_class_data = class_data_type())
310  : enterprise_number(enterprise_number),
311  vendor_class_data(vendor_class_data) { }
312 
313  static vendor_class_type from_option(const option& opt);
314  };
315 
320  struct duid_llt {
321  static const uint16_t duid_id = 1;
322  typedef std::vector<uint8_t> lladdress_type;
323 
324  uint16_t hw_type;
325  uint32_t time;
326  lladdress_type lladdress;
327 
328  duid_llt(uint16_t hw_type = 0, uint32_t time = 0,
329  const lladdress_type& lladdress = lladdress_type())
330  : hw_type(hw_type), time(time), lladdress(lladdress) {}
331 
332  PDU::serialization_type serialize() const;
333 
334  static duid_llt from_bytes(const uint8_t* buffer, uint32_t total_sz);
335  };
336 
340  struct duid_en {
341  static const uint16_t duid_id = 2;
342  typedef std::vector<uint8_t> identifier_type;
343 
344  uint32_t enterprise_number;
345  identifier_type identifier;
346 
347  duid_en(uint32_t enterprise_number = 0,
348  const identifier_type& identifier = identifier_type())
349  : enterprise_number(enterprise_number), identifier(identifier) {}
350 
351  PDU::serialization_type serialize() const;
352 
353  static duid_en from_bytes(const uint8_t* buffer, uint32_t total_sz);
354  };
355 
359  struct duid_ll {
360  static const uint16_t duid_id = 3;
361  typedef std::vector<uint8_t> lladdress_type;
362 
363  uint16_t hw_type;
364  lladdress_type lladdress;
365 
366  duid_ll(uint16_t hw_type = 0,
367  const lladdress_type& lladdress = lladdress_type())
368  : hw_type(hw_type), lladdress(lladdress) {}
369 
370  PDU::serialization_type serialize() const;
371 
372  static duid_ll from_bytes(const uint8_t* buffer, uint32_t total_sz);
373  };
374 
379  struct duid_type {
380  typedef PDU::serialization_type data_type;
381 
382  uint16_t id;
383  data_type data;
384 
385  duid_type(uint16_t id = 0, const data_type& data = data_type())
386  : id(id), data(data) {}
387 
388  duid_type(const duid_llt& identifier)
389  : id(duid_llt::duid_id), data(identifier.serialize()) {}
390 
391  duid_type(const duid_en& identifier)
392  : id(duid_en::duid_id), data(identifier.serialize()) {}
393 
394  duid_type(const duid_ll& identifier)
395  : id(duid_en::duid_id), data(identifier.serialize()) {}
396 
397  static duid_type from_option(const option& opt);
398  };
399 
403  typedef std::vector<uint16_t> option_request_type;
404 
408  typedef std::vector<uint8_t> relay_msg_type;
409 
413  typedef std::vector<uint8_t> interface_id_type;
414 
421  static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
422 
426  DHCPv6();
427 
438  DHCPv6(const uint8_t* buffer, uint32_t total_sz);
439 
440  // Getters
441 
448  return static_cast<MessageType>(header_data_[0]);
449  }
450 
456  uint8_t hop_count() const {
457  return header_data_[1];
458  }
459 
466  return (header_data_[1] << 16) | (header_data_[2] << 8) | header_data_[3];
467  }
468 
474  const ipaddress_type& peer_address() const {
475  return peer_addr_;
476  }
477 
483  const ipaddress_type& link_address() const {
484  return link_addr_;
485  }
486 
492  const options_type& options() const {
493  return options_;
494  }
495 
496  // Setters
502  void msg_type(MessageType type);
503 
509  void hop_count(uint8_t count);
510 
516  void transaction_id(small_uint<24> id);
517 
523  void peer_address(const ipaddress_type& addr);
524 
530  void link_address(const ipaddress_type& addr);
531 
532  // Option getters
533 
541  ia_na_type ia_na() const;
542 
550  ia_ta_type ia_ta() const;
551 
558  ia_address_type ia_address() const;
559 
566  option_request_type option_request() const;
567 
574  uint8_t preference() const;
575 
582  uint16_t elapsed_time() const;
583 
590  relay_msg_type relay_message() const;
591 
598  authentication_type authentication() const;
599 
606  ipaddress_type server_unicast() const;
607 
614  status_code_type status_code() const;
615 
622  bool has_rapid_commit() const;
623 
630  user_class_type user_class() const;
631 
638  vendor_class_type vendor_class() const;
639 
646  vendor_info_type vendor_info() const;
647 
654  interface_id_type interface_id() const;
655 
662  uint8_t reconfigure_msg() const;
663 
670  bool has_reconfigure_accept() const;
671 
678  duid_type client_id() const;
679 
686  duid_type server_id() const;
687 
688  // Option setters
689 
696  void ia_na(const ia_na_type& value);
697 
704  void ia_ta(const ia_ta_type& value);
705 
711  void ia_address(const ia_address_type& value);
712 
718  void option_request(const option_request_type& value);
719 
725  void preference(uint8_t value);
726 
732  void elapsed_time(uint16_t value);
733 
739  void relay_message(const relay_msg_type& value);
740 
746  void authentication(const authentication_type& value);
747 
753  void server_unicast(const ipaddress_type& value);
754 
760  void status_code(const status_code_type& value);
761 
765  void rapid_commit();
766 
772  void user_class(const user_class_type& value);
773 
779  void vendor_class(const vendor_class_type& value);
780 
786  void vendor_info(const vendor_info_type& value);
787 
793  void interface_id(const interface_id_type& value);
794 
800  void reconfigure_msg(uint8_t value);
801 
805  void reconfigure_accept();
806 
812  void client_id(const duid_type& value);
813 
819  void server_id(const duid_type& value);
820 
821  // Other stuff
822 
826  bool is_relay_message() const;
827 
836  void add_option(const option& opt);
837 
847  bool remove_option(OptionTypes type);
848 
858  const option* search_option(OptionTypes type) const;
859 
860  // PDU stuff
861 
867  uint32_t header_size() const;
868 
876  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
877 
882  PDUType pdu_type() const {
883  return pdu_flag;
884  }
885 
889  DHCPv6* clone() const {
890  return new DHCPv6(*this);
891  }
892 private:
893  void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU *);
894  void write_option(const option& option, Memory::OutputMemoryStream& stream) const;
895  options_type::const_iterator search_option_iterator(OptionTypes type) const;
896  options_type::iterator search_option_iterator(OptionTypes type);
897 
898  template <template <typename> class Functor>
899  const option* safe_search_option(OptionTypes opt, uint32_t size) const {
900  const option* option = search_option(opt);
901  if (!option || Functor<uint32_t>()(option->data_size(), size)) {
902  throw option_not_found();
903  }
904  return option;
905  }
906 
907  template<typename T>
908  T search_and_convert(OptionTypes opt) const {
909  const option* option = search_option(opt);
910  if (!option) {
911  throw option_not_found();
912  }
913  return option->to<T>();
914  }
915 
916  uint8_t header_data_[4];
917  uint32_t options_size_;
918  ipaddress_type link_addr_, peer_addr_;
919  options_type options_;
920 };
921 
922 namespace Internals {
923 
924 template<typename InputIterator>
925 void class_option_data2option(InputIterator start,
926  InputIterator end,
927  std::vector<uint8_t>& buffer,
928  size_t start_index = 0) {
929  size_t index = start_index;
930  uint16_t uint16_t_buffer;
931  while (start != end) {
932  buffer.resize(buffer.size() + sizeof(uint16_t) + start->size());
933  uint16_t_buffer = Endian::host_to_be(static_cast<uint16_t>(start->size()));
934  std::memcpy(&buffer[index], &uint16_t_buffer, sizeof(uint16_t));
935  index += sizeof(uint16_t);
936  std::copy(start->begin(), start->end(), buffer.begin() + index);
937  index += start->size();
938 
939  start++;
940  }
941 }
942 
943 template<typename OutputType>
944 OutputType option2class_option_data(const uint8_t* ptr, uint32_t total_sz) {
945  typedef typename OutputType::value_type value_type;
946  OutputType output;
947  size_t index = 0;
948  while (index + 2 < total_sz) {
949  uint16_t size;
950  std::memcpy(&size, ptr + index, sizeof(uint16_t));
951  size = Endian::be_to_host(size);
952  index += sizeof(uint16_t);
953  if (index + size > total_sz) {
954  throw option_not_found();
955  }
956  output.push_back(
957  value_type(ptr + index, ptr + index + size)
958  );
959  index += size;
960  }
961  if (index != total_sz) {
962  throw malformed_option();
963  }
964  return output;
965 }
966 
967 } // Internals
968 } // Tins
969 
970 #endif // TINS_DHCPV6_H
PDUOption< uint16_t, DHCPv6 > option
Definition: dhcpv6.h:58
Definition: dhcpv6.h:253
DHCPv6 * clone() const
Definition: dhcpv6.h:889
std::vector< uint16_t > option_request_type
Definition: dhcpv6.h:403
Definition: dhcpv6.h:302
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:128
PDUType pdu_type() const
Getter for the PDU's type.
Definition: dhcpv6.h:882
const ipaddress_type & link_address() const
Getter for the link address field.
Definition: dhcpv6.h:483
Definition: dhcpv6.h:182
std::vector< uint8_t > interface_id_type
Definition: dhcpv6.h:413
MessageType msg_type() const
Getter for the message type field.
Definition: dhcpv6.h:447
Represents a PDU option field.
Definition: pdu_option.h:320
Definition: dhcpv6.h:234
Definition: dhcpv6.h:266
Definition: dhcpv6.h:359
small_uint< 24 > transaction_id() const
Getter for the transaction id field.
Definition: dhcpv6.h:465
Definition: dhcpv6.h:379
IPv6Address ipaddress_type
Definition: dhcpv6.h:171
std::vector< uint8_t > class_option_data_type
Definition: dhcpv6.h:283
Represents a DHCPv6 PDU.
Definition: dhcpv6.h:53
Definition: dhcpv6.h:289
Definition: dhcpv6.h:320
const options_type & options() const
Getter for the DHCPv6 options.
Definition: dhcpv6.h:492
Type used to store a PDU header's data.
Definition: pdu.h:195
Definition: dhcpv6.h:340
uint8_t hop_count() const
Getter for the hop count field.
Definition: dhcpv6.h:456
const ipaddress_type & peer_address() const
Getter for the peer address field.
Definition: dhcpv6.h:474
Definition: ipv6_address.h:44
OptionTypes
Definition: dhcpv6.h:86
std::list< option > options_type
Definition: dhcpv6.h:166
byte_array serialization_type
Definition: pdu.h:113
Base class for protocol data units.
Definition: pdu.h:108
Definition: dhcpv6.h:215
Exception thrown when an option is not found.
Definition: exceptions.h:53
Definition: dhcpv6.h:199
MessageType
Definition: dhcpv6.h:63
std::vector< uint8_t > relay_msg_type
Definition: dhcpv6.h:408