Kea 2.5.5
host.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2023 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
12#include <dhcp/pkt4.h>
13#include <dhcpsrv/host.h>
15
16#include <util/encode/hex.h>
17#include <util/strutil.h>
18
19#include <sstream>
20
21using namespace isc::data;
22using namespace isc::asiolink;
23
24namespace isc {
25namespace dhcp {
26
27AuthKey::AuthKey(const std::vector<uint8_t>& key) {
28 setAuthKey(key);
29}
30
31AuthKey::AuthKey(const std::string& key) {
32 setAuthKey(key);
33}
34
36 authKey_ = AuthKey::getRandomKeyString();
37}
38
39std::vector<uint8_t>
42}
43
44std::string
46 if (authKey_.empty()) {
47 return ("");
48 }
49 return (util::encode::encodeHex(authKey_));
50}
51
52void
53AuthKey::setAuthKey(const std::vector<uint8_t>& key) {
54 authKey_ = key;
55 if (authKey_.size() > AUTH_KEY_LEN) {
56 authKey_.resize(AUTH_KEY_LEN);
57 }
58}
59
60void
61AuthKey::setAuthKey(const std::string& key) {
62 if (key.empty()) {
63 authKey_.clear();
64 return;
65 }
66 try {
67 std::vector<uint8_t> bin;
69 setAuthKey(bin);
70 } catch (const std::exception& ex) {
71 isc_throw(BadValue, "bad auth key: " << ex.what());
72 }
73}
74
75bool
76AuthKey::operator==(const AuthKey& other) const {
77 return (authKey_ == other.authKey_);
78}
79
80bool
81AuthKey::operator!=(const AuthKey& other) const {
82 return (authKey_ != other.authKey_);
83}
84
86 const asiolink::IOAddress& prefix,
87 const uint8_t prefix_len)
88 : type_(type), prefix_(asiolink::IOAddress("::")), prefix_len_(128) {
89 // Validate and set the actual values.
90 set(type, prefix, prefix_len);
91}
92
93void
94IPv6Resrv::set(const Type& type, const asiolink::IOAddress& prefix,
95 const uint8_t prefix_len) {
96 if (!prefix.isV6() || prefix.isV6Multicast()) {
97 isc_throw(isc::BadValue, "invalid prefix '" << prefix
98 << "' for new IPv6 reservation");
99
100 } else if (prefix_len > 128) {
101 isc_throw(isc::BadValue, "invalid prefix length '"
102 << static_cast<int>(prefix_len)
103 << "' for new IPv6 reservation");
104
105 } else if ((type == TYPE_NA) && (prefix_len != 128)) {
106 isc_throw(isc::BadValue, "invalid prefix length '"
107 << static_cast<int>(prefix_len)
108 << "' for reserved IPv6 address, expected 128");
109 }
110
111 type_ = type;
112 prefix_ = prefix;
113 prefix_len_ = prefix_len;
114}
115
116std::string
118 std::ostringstream s;
119 s << prefix_;
120 // For PD, append prefix length.
121 if (getType() == TYPE_PD) {
122 s << "/" << static_cast<int>(prefix_len_);
123 }
124 return (s.str());
125}
126
127bool
128IPv6Resrv::operator==(const IPv6Resrv& other) const {
129 return (type_ == other.type_ &&
130 prefix_ == other.prefix_ &&
131 prefix_len_ == other.prefix_len_);
132}
133
134bool
135IPv6Resrv::operator!=(const IPv6Resrv& other) const {
136 return (!operator==(other));
137}
138
139Host::Host(const uint8_t* identifier, const size_t identifier_len,
140 const IdentifierType& identifier_type,
141 const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
142 const asiolink::IOAddress& ipv4_reservation,
143 const std::string& hostname,
144 const std::string& dhcp4_client_classes,
145 const std::string& dhcp6_client_classes,
146 const asiolink::IOAddress& next_server,
147 const std::string& server_host_name,
148 const std::string& boot_file_name,
149 const AuthKey& auth_key)
150
151 : identifier_type_(identifier_type),
152 identifier_value_(), ipv4_subnet_id_(ipv4_subnet_id),
153 ipv6_subnet_id_(ipv6_subnet_id),
154 ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
155 hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
156 dhcp6_client_classes_(dhcp6_client_classes),
157 next_server_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
158 server_host_name_(server_host_name), boot_file_name_(boot_file_name),
159 host_id_(0), cfg_option4_(new CfgOption()),
160 cfg_option6_(new CfgOption()), negative_(false),
161 key_(auth_key) {
162
163 // Initialize host identifier.
164 setIdentifier(identifier, identifier_len, identifier_type);
165
166 if (!ipv4_reservation.isV4Zero()) {
167 // Validate and set IPv4 address reservation.
168 setIPv4Reservation(ipv4_reservation);
169 }
170
171 if (!next_server.isV4Zero()) {
172 // Validate and set next server address.
173 setNextServer(next_server);
174 }
175}
176
177Host::Host(const std::string& identifier, const std::string& identifier_name,
178 const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
179 const asiolink::IOAddress& ipv4_reservation,
180 const std::string& hostname,
181 const std::string& dhcp4_client_classes,
182 const std::string& dhcp6_client_classes,
183 const asiolink::IOAddress& next_server,
184 const std::string& server_host_name,
185 const std::string& boot_file_name,
186 const AuthKey& auth_key)
187 : identifier_type_(IDENT_HWADDR),
188 identifier_value_(), ipv4_subnet_id_(ipv4_subnet_id),
189 ipv6_subnet_id_(ipv6_subnet_id),
190 ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
191 hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
192 dhcp6_client_classes_(dhcp6_client_classes),
193 next_server_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
194 server_host_name_(server_host_name), boot_file_name_(boot_file_name),
195 host_id_(0), cfg_option4_(new CfgOption()),
196 cfg_option6_(new CfgOption()), negative_(false),
197 key_(auth_key) {
198
199 // Initialize host identifier.
200 setIdentifier(identifier, identifier_name);
201
202 if (!ipv4_reservation.isV4Zero()) {
203 // Validate and set IPv4 address reservation.
204 setIPv4Reservation(ipv4_reservation);
205 }
206
207 if (!next_server.isV4Zero()) {
208 // Validate and set next server address.
209 setNextServer(next_server);
210 }
211}
212
213size_t
215 switch (type) {
216 case IDENT_HWADDR:
217 return (HWAddr::MAX_HWADDR_LEN);
218 case IDENT_DUID:
219 return (DUID::MAX_DUID_LEN);
220 case IDENT_CLIENT_ID:
222 default:
223 // In fact it is backend dependent but for compatibility we take
224 // the lowest value.
225 return (128);
226 }
227}
228
229const std::vector<uint8_t>&
231 return (identifier_value_);
232}
233
236 return (identifier_type_);
237}
238
240Host::getIdentifierType(const std::string& identifier_name) {
241 if (identifier_name == "hw-address") {
242 return (IDENT_HWADDR);
243
244 } else if (identifier_name == "duid") {
245 return (IDENT_DUID);
246
247 } else if (identifier_name == "circuit-id") {
248 return (IDENT_CIRCUIT_ID);
249
250 } else if (identifier_name == "client-id") {
251 return (IDENT_CLIENT_ID);
252 } else if (identifier_name == "flex-id") {
253 return (IDENT_FLEX);
254 } else {
255 isc_throw(isc::BadValue, "invalid client identifier type '"
256 << identifier_name << "'");
257 }
258}
259
262 return ((identifier_type_ == IDENT_HWADDR) ?
263 HWAddrPtr(new HWAddr(identifier_value_, HTYPE_ETHER)) : HWAddrPtr());
264}
265
268 return ((identifier_type_ == IDENT_DUID) ?
269 DuidPtr(new DUID(identifier_value_)) : DuidPtr());
270}
271
272
273std::string
275 return (getIdentifierAsText(identifier_type_, &identifier_value_[0],
276 identifier_value_.size()));
277}
278
279std::string
280Host::getIdentifierAsText(const IdentifierType& type, const uint8_t* value,
281 const size_t length) {
282 // Convert identifier into <type>=<value> form.
283 std::ostringstream s;
284 switch (type) {
285 case IDENT_HWADDR:
286 s << "hwaddr";
287 break;
288 case IDENT_DUID:
289 s << "duid";
290 break;
291 case IDENT_CIRCUIT_ID:
292 s << "circuit-id";
293 break;
294 case IDENT_CLIENT_ID:
295 s << "client-id";
296 break;
297 case IDENT_FLEX:
298 s << "flex-id";
299 break;
300 default:
301 // This should never happen actually, unless we add new identifier
302 // and forget to add a case for it above.
303 s << "(invalid-type)";
304 }
305 std::vector<uint8_t> vec(value, value + length);
306 s << "=" << (length > 0 ? util::encode::encodeHex(vec) : "(null)");
307 return (s.str());
308}
309
310std::string
312 switch (type) {
314 return ("hw-address");
315
316 case Host::IDENT_DUID:
317 return ("duid");
318
320 return ("circuit-id");
321
323 return ("client-id");
324
325 case Host::IDENT_FLEX:
326 return ("flex-id");
327
328 default:
329 ;
330 }
331 return ("(unknown)");
332}
333
334
335void
336Host::setIdentifier(const uint8_t* identifier, const size_t len,
337 const IdentifierType& type) {
338 if (len < 1) {
339 isc_throw(BadValue, "invalid client identifier length 0");
340 } else if (len > getIdentifierMaxLength(type)) {
341 isc_throw(BadValue, "too long client identifier type "
342 << getIdentifierName(type)
343 << " length " << len);
344 }
345
346 identifier_type_ = type;
347 identifier_value_.assign(identifier, identifier + len);
348}
349
350void
351Host::setIdentifier(const std::string& identifier, const std::string& name) {
352 // Empty identifier is not allowed.
353 if (identifier.empty()) {
354 isc_throw(isc::BadValue, "empty host identifier used");
355 }
356
357 // Set identifier type.
358 identifier_type_ = getIdentifierType(name);
359
360 // Identifier value can either be specified as string of hexadecimal
361 // digits or a string in quotes. The latter is copied to a vector excluding
362 // quote characters.
363
364 // Try to convert the values in quotes into a vector of ASCII codes.
365 // If the identifier lacks opening and closing quote, this will return
366 // an empty value, in which case we'll try to decode it as a string of
367 // hexadecimal digits.
368 bool too_long = false;
369 try {
370 std::vector<uint8_t> binary = util::str::quotedStringToBinary(identifier);
371 if (binary.empty()) {
372 util::str::decodeFormattedHexString(identifier, binary);
373 }
374
375 size_t len = binary.size();
376 if (len > getIdentifierMaxLength(identifier_type_)) {
377 // Message does not matter as it will be replaced below...
378 too_long = true;
379 isc_throw(BadValue, "too long client identifier type " << name
380 << " length " << len);
381 }
382
383 // Successfully decoded the identifier, so let's use it.
384 identifier_value_.swap(binary);
385
386 } catch (...) {
387 // The string doesn't match any known pattern, so we have to
388 // report an error at this point.
389 if (too_long) {
390 throw;
391 }
392 isc_throw(isc::BadValue, "invalid host identifier value '"
393 << identifier << "'");
394 }
395}
396
397void
399 identifier_type_ = type;
400}
401
402void
404 if (!address.isV4()) {
405 isc_throw(isc::BadValue, "address '" << address << "' is not a valid"
406 " IPv4 address");
407 } else if (address.isV4Zero() || address.isV4Bcast()) {
408 isc_throw(isc::BadValue, "must not make reservation for the '"
409 << address << "' address");
410 }
411 ipv4_reservation_ = address;
412}
413
414void
416 ipv4_reservation_ = asiolink::IOAddress::IPV4_ZERO_ADDRESS();
417}
418
419void
420Host::addReservation(const IPv6Resrv& reservation) {
421 // Check if it is not duplicating existing reservation.
422 if (hasReservation(reservation)) {
423 isc_throw(isc::InvalidOperation, "failed on attempt to add a duplicated"
424 " host reservation for " << reservation.toText());
425 }
426 // Add it.
427 ipv6_reservations_.insert(IPv6ResrvTuple(reservation.getType(),
428 reservation));
429}
430
433 return (ipv6_reservations_.equal_range(type));
434}
435
438 return (IPv6ResrvRange(ipv6_reservations_.begin(),
439 ipv6_reservations_.end()));
440}
441
442bool
444 return (!ipv6_reservations_.empty());
445}
446
447bool
448Host::hasReservation(const IPv6Resrv& reservation) const {
449 IPv6ResrvRange reservations = getIPv6Reservations(reservation.getType());
450 if (std::distance(reservations.first, reservations.second) > 0) {
451 for (IPv6ResrvIterator it = reservations.first;
452 it != reservations.second; ++it) {
453 if (it->second == reservation) {
454 return (true);
455 }
456 }
457 }
458
459 // No matching reservations found.
460 return (false);
461}
462
463void
464Host::addClientClass4(const std::string& class_name) {
465 addClientClassInternal(dhcp4_client_classes_, class_name);
466}
467
468
469void
470Host::addClientClass6(const std::string& class_name) {
471 addClientClassInternal(dhcp6_client_classes_, class_name);
472}
473
474void
475Host::addClientClassInternal(ClientClasses& classes,
476 const std::string& class_name) {
477 std::string trimmed = util::str::trim(class_name);
478 if (!trimmed.empty()) {
479 classes.insert(ClientClass(trimmed));
480 }
481}
482
483void
485 if (!next_server.isV4()) {
486 isc_throw(isc::BadValue, "next server address '" << next_server
487 << "' is not a valid IPv4 address");
488 } else if (next_server.isV4Bcast()) {
489 isc_throw(isc::BadValue, "invalid next server address '"
490 << next_server << "'");
491 }
492
493 next_server_ = next_server;
494}
495
496void
497Host::setServerHostname(const std::string& server_host_name) {
498 if (server_host_name.size() > Pkt4::MAX_SNAME_LEN - 1) {
499 isc_throw(isc::BadValue, "server hostname length must not exceed "
500 << (Pkt4::MAX_SNAME_LEN - 1));
501 }
502 server_host_name_ = server_host_name;
503}
504
505void
506Host::setBootFileName(const std::string& boot_file_name) {
507 if (boot_file_name.size() > Pkt4::MAX_FILE_LEN - 1) {
508 isc_throw(isc::BadValue, "boot file length must not exceed "
509 << (Pkt4::MAX_FILE_LEN - 1));
510 }
511 boot_file_name_ = boot_file_name;
512}
513
516
517 // Prepare the map
519 // Set the user context
520 contextToElement(map);
521 // Set the identifier
523 if (id_type == Host::IDENT_HWADDR) {
524 HWAddrPtr hwaddr = getHWAddress();
525 map->set("hw-address", Element::create(hwaddr->toText(false)));
526 } else if (id_type == Host::IDENT_DUID) {
527 DuidPtr duid = getDuid();
528 map->set("duid", Element::create(duid->toText()));
529 } else if (id_type == Host::IDENT_CIRCUIT_ID) {
530 const std::vector<uint8_t>& bin = getIdentifier();
531 std::string circuit_id = util::encode::encodeHex(bin);
532 map->set("circuit-id", Element::create(circuit_id));
533 } else if (id_type == Host::IDENT_CLIENT_ID) {
534 const std::vector<uint8_t>& bin = getIdentifier();
535 std::string client_id = util::encode::encodeHex(bin);
536 map->set("client-id", Element::create(client_id));
537 } else if (id_type == Host::IDENT_FLEX) {
538 const std::vector<uint8_t>& bin = getIdentifier();
539 std::string flex = util::encode::encodeHex(bin);
540 map->set("flex-id", Element::create(flex));
541 } else {
542 isc_throw(ToElementError, "invalid identifier type: " << id_type);
543 }
544 // Set the reservation (if not 0.0.0.0 which may not be re-read)
545 const IOAddress& address = getIPv4Reservation();
546 if (!address.isV4Zero()) {
547 map->set("ip-address", Element::create(address.toText()));
548 }
549 // Set the hostname
550 const std::string& hostname = getHostname();
551 map->set("hostname", Element::create(hostname));
552 // Set next-server
553 const IOAddress& next_server = getNextServer();
554 map->set("next-server", Element::create(next_server.toText()));
555 // Set server-hostname
556 const std::string& server_hostname = getServerHostname();
557 map->set("server-hostname", Element::create(server_hostname));
558 // Set boot-file-name
559 const std::string& boot_file_name = getBootFileName();
560 map->set("boot-file-name", Element::create(boot_file_name));
561 // Set client-classes
562 const ClientClasses& cclasses = getClientClasses4();
564 for (ClientClasses::const_iterator cclass = cclasses.cbegin();
565 cclass != cclasses.cend(); ++cclass) {
566 classes->add(Element::create(*cclass));
567 }
568 map->set("client-classes", classes);
569 // Set option-data
571 map->set("option-data", opts->toElement());
572
573 return (map);
574}
575
578 // Prepare the map
580 // Set the user context
581 contextToElement(map);
582 // Set the identifier
584 if (id_type == Host::IDENT_HWADDR) {
585 HWAddrPtr hwaddr = getHWAddress();
586 map->set("hw-address", Element::create(hwaddr->toText(false)));
587 } else if (id_type == Host::IDENT_DUID) {
588 DuidPtr duid = getDuid();
589 map->set("duid", Element::create(duid->toText()));
590 } else if (id_type == Host::IDENT_CIRCUIT_ID) {
591 isc_throw(ToElementError, "unexpected circuit-id DUID type");
592 } else if (id_type == Host::IDENT_CLIENT_ID) {
593 isc_throw(ToElementError, "unexpected client-id DUID type");
594 } else if (id_type == Host::IDENT_FLEX) {
595 const std::vector<uint8_t>& bin = getIdentifier();
596 std::string flex = util::encode::encodeHex(bin);
597 map->set("flex-id", Element::create(flex));
598 } else {
599 isc_throw(ToElementError, "invalid DUID type: " << id_type);
600 }
601 // Set reservations (ip-addresses)
604 for (IPv6ResrvIterator resv = na_resv.first;
605 resv != na_resv.second; ++resv) {
606 resvs->add(Element::create(resv->second.toText()));
607 }
608 map->set("ip-addresses", resvs);
609 // Set reservations (prefixes)
611 resvs = Element::createList();
612 for (IPv6ResrvIterator resv = pd_resv.first;
613 resv != pd_resv.second; ++resv) {
614 resvs->add(Element::create(resv->second.toText()));
615 }
616 map->set("prefixes", resvs);
617 // Set the hostname
618 const std::string& hostname = getHostname();
619 map->set("hostname", Element::create(hostname));
620 // Set client-classes
621 const ClientClasses& cclasses = getClientClasses6();
623 for (ClientClasses::const_iterator cclass = cclasses.cbegin();
624 cclass != cclasses.cend(); ++cclass) {
625 classes->add(Element::create(*cclass));
626 }
627 map->set("client-classes", classes);
628
629 // Set option-data
631 map->set("option-data", opts->toElement());
632
633 // Set auth key
634 //@todo: uncomment once storing in configuration file is enabled
635 //map->set("auth-key", Element::create(getKey().toText()));
636
637 return (map);
638}
639
640void
642 if (!cfg_option4_->isEncapsulated()) {
643 cfg_option4_->encapsulate();
644 }
645 if (!cfg_option6_->isEncapsulated()) {
646 cfg_option6_->encapsulate();
647 }
648}
649
650std::string
652 std::ostringstream s;
653
654 // Add HW address or DUID.
655 s << getIdentifierAsText();
656
657 // Add IPv4 subnet id if exists.
658 if (ipv4_subnet_id_ != SUBNET_ID_UNUSED) {
659 s << " ipv4_subnet_id=" << ipv4_subnet_id_;
660 }
661
662 // Add IPv6 subnet id if exists.
663 if (ipv6_subnet_id_ != SUBNET_ID_UNUSED) {
664 s << " ipv6_subnet_id=" << ipv6_subnet_id_;
665 }
666
667 // Add hostname.
668 s << " hostname=" << (hostname_.empty() ? "(empty)" : hostname_);
669
670 // Add IPv4 reservation.
671 s << " ipv4_reservation=" << (ipv4_reservation_.isV4Zero() ? "(no)" :
672 ipv4_reservation_.toText());
673
674 // Add next server.
675 s << " siaddr=" << (next_server_.isV4Zero() ? "(no)" :
676 next_server_.toText());
677
678 // Add server host name.
679 s << " sname=" << (server_host_name_.empty() ? "(empty)" : server_host_name_);
680
681 // Add boot file name.
682 s << " file=" << (boot_file_name_.empty() ? "(empty)" : boot_file_name_);
683
684 s << " key=" << (key_.toText().empty() ? "(empty)" : key_.toText());
685
686 if (ipv6_reservations_.empty()) {
687 s << " ipv6_reservations=(none)";
688
689 } else {
690 // Add all IPv6 reservations.
691 for (IPv6ResrvIterator resrv = ipv6_reservations_.begin();
692 resrv != ipv6_reservations_.end(); ++resrv) {
693 s << " ipv6_reservation"
694 << std::distance(ipv6_reservations_.begin(), resrv)
695 << "=" << resrv->second.toText();
696 }
697 }
698
699 // Add DHCPv4 client classes.
700 for (ClientClasses::const_iterator cclass = dhcp4_client_classes_.cbegin();
701 cclass != dhcp4_client_classes_.cend(); ++cclass) {
702 s << " dhcp4_class"
703 << std::distance(dhcp4_client_classes_.cbegin(), cclass)
704 << "=" << *cclass;
705 }
706
707 // Add DHCPv6 client classes.
708 for (ClientClasses::const_iterator cclass = dhcp6_client_classes_.cbegin();
709 cclass != dhcp6_client_classes_.cend(); ++cclass) {
710 s << " dhcp6_class"
711 << std::distance(dhcp6_client_classes_.cbegin(), cclass)
712 << "=" << *cclass;
713 }
714
715 // Add negative cached.
716 if (negative_) {
717 s << " negative cached";
718 }
719
720 return (s.str());
721}
722
723} // end of namespace isc::dhcp
724} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
Cannot unparse error.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:249
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:304
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:299
Authentication keys.
Definition: host.h:75
AuthKey()
Constructor.
Definition: host.cc:35
bool operator!=(const AuthKey &other) const
Inequality operator.
Definition: host.cc:81
static std::vector< uint8_t > getRandomKeyString()
Random string is generated by default will be used for the keys to be used for signing Reconfigure Me...
Definition: host.cc:40
std::string toText() const
Return text format for keys.
Definition: host.cc:45
void setAuthKey(const std::vector< uint8_t > &key)
Set auth key value from binary.
Definition: host.cc:53
bool operator==(const AuthKey &other) const
Equality operator.
Definition: host.cc:76
Represents option data configuration for the DHCP server.
Definition: cfg_option.h:351
Container for storing client class names.
Definition: classify.h:108
ClientClassContainer::const_iterator const_iterator
Type of iterators.
Definition: classify.h:112
void insert(const ClientClass &class_name)
Insert an element.
Definition: classify.h:128
const_iterator cbegin() const
Iterators to the first element.
Definition: classify.h:152
const_iterator cend() const
Iterators to the past the end element.
Definition: classify.h:165
static constexpr size_t MAX_CLIENT_ID_LEN
Maximum size of a client ID.
Definition: duid.h:231
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:138
static constexpr size_t MAX_DUID_LEN
maximum duid size
Definition: duid.h:151
void addClientClass4(const std::string &class_name)
Adds new client class for DHCPv4.
Definition: host.cc:464
void setServerHostname(const std::string &server_host_name)
Sets new value for server hostname (sname).
Definition: host.cc:497
static size_t getIdentifierMaxLength(const IdentifierType &type)
Get maximum identifier length.
Definition: host.cc:214
void encapsulateOptions() const
Encapsulates host-specific options with their suboptions.
Definition: host.cc:641
const ClientClasses & getClientClasses6() const
Returns classes which DHCPv6 client is associated with.
Definition: host.h:601
CfgOptionPtr getCfgOption4()
Returns pointer to the DHCPv4 option data configuration for this host.
Definition: host.h:647
std::string toText() const
Returns information about the host in the textual format.
Definition: host.cc:651
void addClientClass6(const std::string &class_name)
Adds new client class for DHCPv6.
Definition: host.cc:470
IdentifierType
Type of the host identifier.
Definition: host.h:307
@ IDENT_HWADDR
Definition: host.h:308
@ IDENT_FLEX
Flexible host identifier.
Definition: host.h:312
@ IDENT_CLIENT_ID
Definition: host.h:311
@ IDENT_CIRCUIT_ID
Definition: host.h:310
IdentifierType getIdentifierType() const
Returns the identifier type.
Definition: host.cc:235
void setIdentifier(const uint8_t *identifier, const size_t len, const IdentifierType &type)
Replaces currently used identifier with a new identifier.
Definition: host.cc:336
const asiolink::IOAddress & getIPv4Reservation() const
Returns reserved IPv4 address.
Definition: host.h:532
void setIdentifierType(const IdentifierType &type)
Set the identifier type.
Definition: host.cc:398
const std::string & getHostname() const
Returns reserved hostname.
Definition: host.h:576
IPv6ResrvRange getIPv6Reservations() const
Returns all IPv6 reservations.
Definition: host.cc:437
const std::string & getBootFileName() const
Returns value of boot file name (file).
Definition: host.h:638
bool hasIPv6Reservation() const
Checks if there is at least one IPv6 reservation for this host.
Definition: host.cc:443
Host(const uint8_t *identifier, const size_t identifier_len, const IdentifierType &identifier_type, const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id, const asiolink::IOAddress &ipv4_reservation, const std::string &hostname="", const std::string &dhcp4_client_classes="", const std::string &dhcp6_client_classes="", const asiolink::IOAddress &next_server=asiolink::IOAddress::IPV4_ZERO_ADDRESS(), const std::string &server_host_name="", const std::string &boot_file_name="", const AuthKey &auth_key=AuthKey(""))
Constructor.
Definition: host.cc:139
const std::vector< uint8_t > & getIdentifier() const
Returns the identifier in a binary form.
Definition: host.cc:230
isc::data::ElementPtr toElement6() const
Unparses (converts to Element representation) IPv6 host.
Definition: host.cc:577
void addReservation(const IPv6Resrv &reservation)
Adds new IPv6 reservation.
Definition: host.cc:420
const ClientClasses & getClientClasses4() const
Returns classes which DHCPv4 client is associated with.
Definition: host.h:591
static std::string getIdentifierName(const IdentifierType &type)
Returns name of the identifier of a specified type.
Definition: host.cc:311
const std::string & getServerHostname() const
Returns value of server hostname (sname).
Definition: host.h:626
void setBootFileName(const std::string &boot_file_name)
Sets new value for boot file name (file).
Definition: host.cc:506
void setNextServer(const asiolink::IOAddress &next_server)
Sets new value for next server field (siaddr).
Definition: host.cc:484
CfgOptionPtr getCfgOption6()
Returns pointer to the DHCPv6 option data configuration for this host.
Definition: host.h:662
bool hasReservation(const IPv6Resrv &reservation) const
Checks if specified IPv6 reservation exists for the host.
Definition: host.cc:448
const asiolink::IOAddress & getNextServer() const
Returns value of next server field (siaddr).
Definition: host.h:614
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
Definition: host.cc:274
isc::data::ElementPtr toElement4() const
Unparses (converts to Element representation) IPv4 host.
Definition: host.cc:515
DuidPtr getDuid() const
Returns DUID for which the reservations are made.
Definition: host.cc:267
void removeIPv4Reservation()
Removes the IPv4 reservation.
Definition: host.cc:415
HWAddrPtr getHWAddress() const
Returns hardware address for which the reservations are made.
Definition: host.cc:261
void setIPv4Reservation(const asiolink::IOAddress &address)
Sets new IPv4 reservation.
Definition: host.cc:403
IPv6 reservation for a host.
Definition: host.h:161
void set(const Type &type, const asiolink::IOAddress &prefix, const uint8_t prefix_len)
Sets a new prefix and prefix length.
Definition: host.cc:94
Type getType() const
Returns reservation type.
Definition: host.h:204
Type
Type of the reservation.
Definition: host.h:167
std::string toText() const
Returns information about the reservation in the textual format.
Definition: host.cc:117
IPv6Resrv(const Type &type, const asiolink::IOAddress &prefix, const uint8_t prefix_len=128)
Constructor.
Definition: host.cc:85
bool operator==(const IPv6Resrv &other) const
Equality operator.
Definition: host.cc:128
bool operator!=(const IPv6Resrv &other) const
Inequality operator.
Definition: host.cc:135
static const size_t MAX_SNAME_LEN
length of the SNAME field in DHCPv4 message
Definition: pkt4.h:44
static const size_t MAX_FILE_LEN
length of the FILE field in DHCPv4 message
Definition: pkt4.h:47
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
IPv6ResrvCollection::const_iterator IPv6ResrvIterator
Definition: host.h:241
std::string ClientClass
Defines a single class name.
Definition: classify.h:42
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:132
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
Definition: host.h:243
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
const uint8_t AUTH_KEY_LEN
Maximum length of authentication keys - 128 bits.
Definition: host.h:63
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
std::pair< IPv6Resrv::Type, IPv6Resrv > IPv6ResrvTuple
Definition: host.h:242
@ HTYPE_ETHER
Ethernet 10Mbps.
Definition: dhcp4.h:56
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
Definition: cfg_option.h:806
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 ('hex') format.
Definition: base_n.cc:483
void decodeHex(const string &input, vector< uint8_t > &result)
Decode a text encoded in the base16 ('hex') format into the original data.
Definition: base_n.cc:488
void decodeFormattedHexString(const std::string &hex_string, std::vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
Definition: strutil.cc:273
std::vector< uint8_t > quotedStringToBinary(const std::string &quoted_string)
Converts a string in quotes into vector.
Definition: strutil.cc:196
string trim(const string &instring)
Trim Leading and Trailing Spaces.
Definition: strutil.cc:53
Defines the logger used by the top-level component of kea-lfc.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition: user_context.cc:15
Hardware type that represents information from DHCPv4 packet.
Definition: hwaddr.h:20
static const size_t MAX_HWADDR_LEN
Maximum size of a hardware address.
Definition: hwaddr.h:27