Kea: host.cc Source File

| Kea 3.0.3-git

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