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