Kea: host.cc Source File

| Kea 3.2.0-git

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