libtins 4.5
Loading...
Searching...
No Matches
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
41namespace Tins {
42namespace Memory {
43
44class OutputMemoryStream;
45
46} // Memory
47
52class TINS_API DHCPv6 : public PDU {
53public:
58
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
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
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
474 return peer_addr_;
475 }
476
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 }
891private:
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
Represents a DHCPv6 PDU.
Definition dhcpv6.h:52
MessageType
Definition dhcpv6.h:62
PDUOption< uint16_t, DHCPv6 > option
Definition dhcpv6.h:57
PDUType pdu_type() const
Getter for the PDU's type.
Definition dhcpv6.h:881
const ipaddress_type & peer_address() const
Getter for the peer address field.
Definition dhcpv6.h:473
const options_type & options() const
Getter for the DHCPv6 options.
Definition dhcpv6.h:491
uint8_t hop_count() const
Getter for the hop count field.
Definition dhcpv6.h:455
std::vector< uint8_t > class_option_data_type
Definition dhcpv6.h:282
small_uint< 24 > transaction_id() const
Getter for the transaction id field.
Definition dhcpv6.h:464
MessageType msg_type() const
Getter for the message type field.
Definition dhcpv6.h:446
const ipaddress_type & link_address() const
Getter for the link address field.
Definition dhcpv6.h:482
std::vector< uint8_t > relay_msg_type
Definition dhcpv6.h:407
OptionTypes
Definition dhcpv6.h:85
DHCPv6 * clone() const
Definition dhcpv6.h:888
std::vector< uint8_t > interface_id_type
Definition dhcpv6.h:412
std::vector< uint16_t > option_request_type
Definition dhcpv6.h:402
IPv6Address ipaddress_type
Definition dhcpv6.h:170
std::vector< option > options_type
Definition dhcpv6.h:165
Definition ipv6_address.h:45
Represents a PDU option field.
Definition rsn_information.h:43
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
Exception thrown when an option is not found.
Definition exceptions.h:56
Represents a field of n bits.
Definition small_uint.h:52
The Tins namespace.
Definition address_range.h:38
Definition dhcpv6.h:233
Definition dhcpv6.h:339
Definition dhcpv6.h:358
Definition dhcpv6.h:319
Definition dhcpv6.h:378
Definition dhcpv6.h:214
Definition dhcpv6.h:181
Definition dhcpv6.h:198
Definition dhcpv6.h:252
Definition dhcpv6.h:288
Definition dhcpv6.h:301
Definition dhcpv6.h:265
Type used to store a PDU header's data.
Definition pdu.h:197