1 // Copyright (C) 2014-2019,2021 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 #ifndef HOST_H
8 #define HOST_H
9 
10 #include <asiolink/io_address.h>
11 #include <cc/data.h>
12 #include <cc/user_context.h>
13 #include <dhcp/classify.h>
14 #include <dhcp/duid.h>
15 #include <dhcp/hwaddr.h>
16 #include <dhcpsrv/cfg_option.h>
17 #include <dhcpsrv/subnet_id.h>
18 #include <boost/shared_ptr.hpp>
19 #include <boost/algorithm/string.hpp>
20 #include <list>
21 #include <map>
22 #include <string>
23 #include <utility>
24 
25 namespace isc {
26 namespace dhcp {
27 
28 /// @brief Maximum size of an IPv6 address represented as a text string.
29 ///
30 /// This is 32 hexadecimal characters written in 8 groups of four, plus seven
31 /// colon separators.
32 const size_t ADDRESS6_TEXT_MAX_LEN = 39;
33 
34 /// @brief Maximum length of classes stored in a dhcp4/6_client_classes
35 /// columns.
36 const size_t CLIENT_CLASSES_MAX_LEN = 255;
37 
38 /// @brief Maximum length of the hostname stored in DNS.
39 ///
40 /// This length is restricted by the length of the domain-name carried
41 /// in the Client FQDN %Option (see RFC4702 and RFC4704).
42 const size_t HOSTNAME_MAX_LEN = 255;
43 
44 /// @brief Maximum length of option value.
45 const size_t OPTION_VALUE_MAX_LEN = 4096;
46 
47 /// @brief Maximum length of option value specified in textual format.
48 const size_t OPTION_FORMATTED_VALUE_MAX_LEN = 8192;
49 
50 /// @brief Maximum length of option space name.
51 const size_t OPTION_SPACE_MAX_LEN = 128;
52 
53 /// @brief Maximum length of user context.
54 const size_t USER_CONTEXT_MAX_LEN = 8192;
55 
56 /// @brief Maximum length of the server hostname.
57 const size_t SERVER_HOSTNAME_MAX_LEN = 64;
58 
59 /// @brief Maximum length of the boot file name.
60 const size_t BOOT_FILE_NAME_MAX_LEN = 128;
61 
62 /// @brief Maximum length of authentication keys - 128 bits.
63 const uint8_t AUTH_KEY_LEN = 16;
64 
65 /// @brief Maximum length of authentication keys (coded in hexadecimal).
66 const size_t TEXT_AUTH_KEY_LEN = AUTH_KEY_LEN * 2;
67 
68 /// @brief HostID (used only when storing in MySQL, PostgreSQL or Cassandra)
69 typedef uint64_t HostID;
70 
71 /// @brief Authentication keys.
72 ///
73 /// This class represents authentication keys to be used for
74 /// calculating HMAC in the authentication field of the reconfigure message.
75 class AuthKey {
76 public:
77     /// @brief Constructor.
78     ///
79     /// Constructor for assigning auth keys in host reservation.
80     /// Ensures the key length is not greater than 16 bytes.
81     /// @param key auth key in binary to be stored.
82     AuthKey(const std::vector<uint8_t>& key);
83 
84     /// @brief Constructor.
85     ///
86     /// Constructor for assigning auth keys in host reservation.
87     /// Ensures the key length is not greater than AUTH_KEY_LEN (16) bytes
88     /// so TEXT_AUTH_KEY_LEN (32) hexadecimal digits.
89     /// See @c setKey for constraints on its input format.
90     ///
91     /// @param key auth key in hexadecimal to be stored.
92     AuthKey(const std::string& key);
93 
94     /// @brief Constructor.
95     ///
96     /// Constructor for generating auth keys, with no argument.
97     /// shall use the internal function for generationg random keys.
98     AuthKey();
99 
100     // @brief Get random string.
101     ///
102     /// Random string is generated by default will be used for
103     /// the keys to be used for signing Reconfigure Message.
104     /// @return Random binary string of 16 bytes.
105     static std::vector<uint8_t> getRandomKeyString();
106 
107     /// @brief Set auth key value from binary.
108     ///
109     /// Set the key value.
110     //  If the size is greater than 16 bytes, we resize to 16 bytes.
111     /// Doesn't throw an exception.
112     /// @param key auth key in binary to be stored
113     void setAuthKey(const std::vector<uint8_t>& key);
114 
115     /// @brief Set auth key value from hexadecimal.
116     ///
117     /// Set the key value.
118     /// If the size is greater than 16 bytes, we resize to 16 bytes.
119     /// @param key auth key in hexadecimal to be stored.
120     /// @throw BadValue if the string is not a valid hexadecimal encoding,
121     /// for instance has a not hexadecimal or odd number of digits.
122     void setAuthKey(const std::string& key);
123 
124     /// @brief Return auth key.
125     ///
126     /// @return auth key in binary.
getAuthKey()127     const std::vector<uint8_t>& getAuthKey() const {
128         return authKey_;
129     }
130 
131     /// @brief Return text format for keys.
132     ///
133     /// @return auth key as a string of hexadecimal digits.
134     std::string toText() const;
135 
136     ///
137     /// @brief Equality operator.
138     ///
139     /// equality operator to compare two AuthKey objects.
140     /// @param other Authkey to be compared against.
141     bool operator==(const AuthKey& other) const;
142 
143     /// @brief Inequality operator.
144     ///
145     /// inequality operator to compare two AuthKey objects.
146     /// @param other Authkey to be compared against.
147     bool operator!=(const AuthKey& other) const;
148 
149 private:
150     std::vector<uint8_t> authKey_;
151 };
152 
153 /// @brief IPv6 reservation for a host.
154 ///
155 /// This class represents a reservation for a host of a single IPv6
156 /// address or prefix (in @c Host object).
157 ///
158 /// The class holds the address and prefix length, a value of 128
159 /// for the latter implying that the reservation is for a single
160 /// IPv6 address.
161 class IPv6Resrv {
162 public:
163 
164     /// @brief Type of the reservation.
165     ///
166     /// Currently supported types are NA and PD.
167     enum Type {
168         TYPE_NA,
169         TYPE_PD
170     };
171 
172     /// @brief Constructor.
173     ///
174     /// Creates a reservation from the IPv6 address and prefix length
175     /// value. If the prefix length is not specified, the default value
176     /// of 128 is used. This value indicates that the reservation is made
177     /// for an IPv6 address.
178     ///
179     /// @param type Reservation type: NA or PD.
180     /// @param prefix Address or prefix to be reserved.
181     /// @param prefix_len Prefix length.
182     ///
183     /// @throw isc::BadValue if prefix is not IPv6 prefix, is a
184     /// multicast address or the prefix length is greater than 128.
185     IPv6Resrv(const Type& type,
186               const asiolink::IOAddress& prefix,
187               const uint8_t prefix_len = 128);
188 
189     /// @brief Returns prefix for the reservation.
getPrefix()190     const asiolink::IOAddress& getPrefix() const {
191         return (prefix_);
192     }
193 
194     /// @brief Returns prefix length.
getPrefixLen()195     uint8_t getPrefixLen() const {
196         return (prefix_len_);
197     }
198 
199     /// @brief Returns reservation type.
200     ///
201     /// The type of reservation is determined using a prefix length.
202     ///
203     /// @return NA for prefix length equal to 128, PD otherwise.
getType()204     Type getType() const {
205         return (type_);
206     }
207 
208     /// @brief Sets a new prefix and prefix length.
209     ///
210     /// @param type Reservation type: NA or PD.
211     /// @param prefix New prefix.
212     /// @param prefix_len New prefix length.
213     ///
214     /// @throw isc::BadValue if prefix is not IPv6 prefix, is a
215     /// multicast address or the prefix length is greater than 128.
216     void set(const Type& type, const asiolink::IOAddress& prefix,
217              const uint8_t prefix_len);
218 
219     /// @brief Returns information about the reservation in the textual format.
220     std::string toText() const;
221 
222     /// @brief Equality operator.
223     ///
224     /// @param other Reservation to compare to.
225     bool operator==(const IPv6Resrv& other) const;
226 
227     /// @brief Inequality operator.
228     ///
229     /// @param other Reservation to compare to.
230     bool operator!=(const IPv6Resrv& other) const;
231 
232 private:
233 
234     Type type_;                  ///< Reservation type.
235     asiolink::IOAddress prefix_; ///< Prefix
236     uint8_t prefix_len_;         ///< Prefix length.
237 };
238 
239 /// @brief Collection of IPv6 reservations for the host.
240 typedef std::multimap<IPv6Resrv::Type, IPv6Resrv> IPv6ResrvCollection;
241 typedef IPv6ResrvCollection::const_iterator IPv6ResrvIterator;
242 typedef std::pair<IPv6Resrv::Type, IPv6Resrv> IPv6ResrvTuple;
243 typedef std::pair<IPv6ResrvIterator, IPv6ResrvIterator> IPv6ResrvRange;
244 
245 /// @brief Represents a device with IPv4 and/or IPv6 reservations.
246 ///
247 /// This class represents a network device which can be identified
248 /// by a unique property, such as MAC address on the interface or
249 /// client identifier (DUID), and for which some resources are statically
250 /// assigned:
251 /// - IPv4 address which the device obtains when it contacts a DHCPv4 server
252 /// - IPv6 address(es) which the device obtains when it contacts a DHCPv6
253 /// server
254 /// - IPv6 prefix(es) obtained when the device contacts the DHCPv6 server
255 /// and requests allocation of prefixes using prefix delegation mechanism
256 /// - hostname which is used for dynamic DNS updates for both DHCPv4 and
257 /// DHCPv6 exchanges.
258 /// - client classes which the client is associated with
259 /// - DHCP options specifically configured for the device
260 ///
261 /// Note, that "host" in this context has a different meaning from
262 /// host construed as device attached to a network with (possibly) multiple
263 /// interfaces. For the MAC address based reservations, each interface on a
264 /// network device maps to a single @c Host object as each @c Host object
265 /// contains at most one MAC address. So, it is possible that a single
266 /// device is associated with multiple distinct @c Host objects if the
267 /// device has multiple interfaces. Under normal circumstances, a non-mobile
268 /// dual stack device using one interface should be represented by a single
269 /// @c Host object.
270 ///
271 /// A DHCPv6 DUID is common for all interfaces on a device. Therefore, for
272 /// DUID based reservations a @c Host object may represent a network device with
273 /// multiple interfaces. However, since @c Host objects are grouped by
274 /// subnets to which device's interfaces are connected a single instance of
275 /// @c Host object usually defines reservations for a single interface.
276 ///
277 /// The @c Host object combines reservations for both IPv4 and IPv6 resources
278 /// to allow for correlation of the information about the dual stack devices
279 /// using DHCPv4 and DHCPv6 respectively. For example: both the DHCPv4 and
280 /// DHCPv6 servers may use the same database for storing host reservations, so
281 /// the information about the DHCPv4 reservations are available for the
282 /// DHCPv6 server and vice versa. Also, this approach allows for reserving
283 /// common resources such as host name for DHCPv4 and DHCPv6 clients.
284 ///
285 /// This class also holds pointers to specific DHCP options reserved
286 /// for a host. Options instances are held in @c CfgOption objects.
287 /// There are two @c CfgOption objects in this class, one holding
288 /// DHCPv4 options, another one holding DHCPv6 options.
289 ///
290 /// @todo This class offers basic functionality for storing host information.
291 /// It will need to be extended to allow for the following operations:
292 /// - remove and replace IPv6 reservations
293 /// - remove and replace client classes
294 /// - disable IPv4 reservation without a need to set it to the 0.0.0.0 address
295 /// Note that the last three operations are mainly required for managing
296 /// host reservations which will be implemented later.
297 class Host : public data::UserContext {
298 public:
299 
300     /// @brief Type of the host identifier.
301     ///
302     /// Currently supported identifiers are:
303     /// - hardware address (DHCPv4 and DHCPv6) (identifier name: "hw-address"),
304     /// - DUID (DHCPv4 and DHCPv6) (identifier name: "duid"),
305     /// - circuit identifier (DHCPv4) (identifier name: "circuit-id"),
306     /// - client identifier (DHCPv4) (identifier name: "client-id")
307     enum IdentifierType {
308         IDENT_HWADDR,
309         IDENT_DUID,
310         IDENT_CIRCUIT_ID,
311         IDENT_CLIENT_ID,
312         IDENT_FLEX, ///< Flexible host identifier.
313     };
314 
315     /// @brief Constant pointing to the last identifier of the
316     /// @ref IdentifierType enumeration.
317     static const IdentifierType LAST_IDENTIFIER_TYPE = IDENT_FLEX;
318 
319     /// @brief Constructor.
320     ///
321     /// Creates a @c Host object using an identifier in a binary format. This
322     /// is most useful in cases where the identifier is obtained from the
323     /// database. The constructor will create an instance of the @c HWAddr
324     /// or @c DUID object depending on the identifier type.
325     ///
326     /// @param identifier Pointer to the binary value holding an identifier.
327     /// @param identifier_len Length of the identifier.
328     /// @param identifier_type Type of the identifier (hardware address or
329     /// DUID).
330     /// @param ipv4_subnet_id Identifier of the IPv4 subnet to which the host
331     /// is connected.
332     /// @param ipv6_subnet_id Identifier of the IPv6 subnet to which the host
333     /// is connected.
334     /// @param ipv4_reservation An IPv4 address reserved for the client. If
335     /// this address is set to 0, there is no reservation.
336     /// @param hostname Hostname to be allocated to both DHCPv4 and DHCPv6
337     /// clients. This is empty string if hostname is not allocated.
338     /// @param dhcp4_client_classes A string holding DHCPv4 client class names
339     /// separated by commas. The names get trimmed by this constructor.
340     /// @param dhcp6_client_classes A string holding DHCPv6 client class names
341     /// separated by commas. The names get trimmed by this constructor.
342     /// @param next_server IPv4 address of next server (siaddr).
343     /// @param server_host_name Server host name (a.k.a. sname).
344     /// @param boot_file_name Boot file name (a.k.a. file).
345     /// @param auth_key Authentication key.
346     ///
347     /// @throw BadValue if the provided values are invalid. In particular,
348     /// if the identifier is invalid.
349     Host(const uint8_t* identifier, const size_t identifier_len,
350          const IdentifierType& identifier_type,
351          const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
352          const asiolink::IOAddress& ipv4_reservation,
353          const std::string& hostname = "",
354          const std::string& dhcp4_client_classes = "",
355          const std::string& dhcp6_client_classes = "",
356          const asiolink::IOAddress& next_server = asiolink::IOAddress::IPV4_ZERO_ADDRESS(),
357          const std::string& server_host_name = "",
358          const std::string& boot_file_name = "",
359          const AuthKey& auth_key = AuthKey(""));
360 
361     /// @brief Constructor.
362     ///
363     /// Creates @c Host object using an identifier in a textual format. This
364     /// is useful in cases when the reservation is specified in the server
365     /// configuration file. Identifiers can be specified in the following
366     /// formats:
367     /// - "yy:yy:yy:yy:yy:yy"
368     /// - "yyyyyyyyyy",
369     /// - "0xyyyyyyyyyy",
370     /// - "'some identifier'".
371     /// where y is a hexadecimal digit.
372     ///
373     /// Note that it is possible to use textual representation, e.g. 'some identifier',
374     /// which is converted to a vector of ASCII codes representing characters in a
375     /// given string, excluding quotes. This is useful in cases when specific
376     /// identifiers, e.g. circuit-id are manually assigned user friendly values.
377     ///
378     /// @param identifier Identifier in the textual format. The expected formats
379     /// for the hardware address and other identifiers are provided above.
380     /// @param identifier_name One of the supported identifiers in the text form as
381     /// described for @ref IdentifierType.
382     /// @param ipv4_subnet_id Identifier of the IPv4 subnet to which the host
383     /// is connected.
384     /// @param ipv6_subnet_id Identifier of the IPv6 subnet to which the host
385     /// is connected.
386     /// @param ipv4_reservation An IPv4 address reserved for the client. If
387     /// this address is set to 0, there is no reservation.
388     /// @param hostname Hostname to be allocated to both DHCPv4 and DHCPv6
389     /// clients. This is empty string if hostname is not allocated.
390     /// @param dhcp4_client_classes A string holding DHCPv4 client class names
391     /// separated by commas. The names get trimmed by this constructor.
392     /// @param dhcp6_client_classes A string holding DHCPv6 client class names
393     /// separated by commas. The names get trimmed by this constructor.
394     /// @param next_server IPv4 address of next server (siaddr).
395     /// @param server_host_name Server host name (a.k.a. sname).
396     /// @param boot_file_name Boot file name (a.k.a. file).
397     /// @param auth_key Authentication key.
398     ///
399     /// @throw BadValue if the provided values are invalid. In particular,
400     /// if the identifier is invalid.
401     Host(const std::string& identifier, const std::string& identifier_name,
402          const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
403          const asiolink::IOAddress& ipv4_reservation,
404          const std::string& hostname = "",
405          const std::string& dhcp4_client_classes = "",
406          const std::string& dhcp6_client_classes = "",
407          const asiolink::IOAddress& next_server = asiolink::IOAddress::IPV4_ZERO_ADDRESS(),
408          const std::string& server_host_name = "",
409          const std::string& boot_file_name = "",
410          const AuthKey& auth_key = AuthKey(""));
411 
412     /// @brief Replaces currently used identifier with a new identifier.
413     ///
414     /// This method sets a new identifier type and value for a host.
415     /// This method is called by the @c Host constructor.
416     ///
417     /// @param identifier Pointer to a buffer holding an identifier.
418     /// @param len Length of the identifier that the @c identifier points to.
419     /// @param type Identifier type.
420     ///
421     /// @throw BadValue if the identifier is invalid.
422     void setIdentifier(const uint8_t* identifier, const size_t len,
423                        const IdentifierType& type);
424 
425     /// @brief Replaces currently used identifier with a new identifier.
426     ///
427     /// This method sets a new identifier type and value for a host.
428     /// This method is called by the @c Host constructor.
429     ///
430     /// @param identifier Reference to a new identifier in the textual format.
431     /// @param name One of the supported identifiers in the text form as
432     /// described for @ref IdentifierType.
433     ///
434     /// @throw BadValue if the identifier is invalid.
435     void setIdentifier(const std::string& identifier, const std::string& name);
436 
437     /// @brief Returns hardware address for which the reservations are made.
438     ///
439     /// @return Pointer to the @c HWAddr structure or null if the reservation
440     /// is not associated with a hardware address.
441     HWAddrPtr getHWAddress() const;
442 
443     /// @brief Returns DUID for which the reservations are made.
444     ///
445     /// @return Pointer to the @c DUID structure or null if the reservation
446     /// is not associated with a DUID.
447     DuidPtr getDuid() const;
448 
449     /// @brief Returns the identifier in a binary form.
450     ///
451     /// @return const reference to a vector<uint8_t> holding an identifier
452     /// value.
453     const std::vector<uint8_t>& getIdentifier() const;
454 
455     /// @brief Returns the identifier type.
456     ///
457     IdentifierType getIdentifierType() const;
458 
459     /// @brief Converts identifier name to identifier type.
460     ///
461     /// @param identifier_name Identifier name.
462     /// @return Identifier type.
463     static IdentifierType getIdentifierType(const std::string& identifier_name);
464 
465     /// @brief Returns host identifier in a textual form.
466     ///
467     /// @return Identifier in the form of type=value.
468     std::string getIdentifierAsText() const;
469 
470     /// @brief Returns name of the identifier of a specified type.
471     static std::string getIdentifierName(const IdentifierType& type);
472 
473     /// @brief Returns host identifier in textual form.
474     ///
475     /// @param type Identifier type.
476     /// @param value Pointer to a buffer holding identifier.
477     /// @param length Length of the identifier.
478     /// @return Identifier in the form of type=value.
479     static std::string getIdentifierAsText(const IdentifierType& type,
480                                            const uint8_t* value,
481                                            const size_t length);
482 
483     /// @brief Sets new IPv4 subnet identifier.
484     ///
485     /// @param ipv4_subnet_id New subnet identifier.
setIPv4SubnetID(const SubnetID ipv4_subnet_id)486     void setIPv4SubnetID(const SubnetID ipv4_subnet_id) {
487         ipv4_subnet_id_ = ipv4_subnet_id;
488     }
489 
490     /// @brief Sets new IPv6 subnet identifier.
491     ///
492     /// @param ipv6_subnet_id New subnet identifier.
setIPv6SubnetID(const SubnetID ipv6_subnet_id)493     void setIPv6SubnetID(const SubnetID ipv6_subnet_id) {
494         ipv6_subnet_id_ = ipv6_subnet_id;
495     }
496 
497     /// @brief Returns subnet identifier for IPv4 reservation.
getIPv4SubnetID()498     SubnetID getIPv4SubnetID() const {
499         return (ipv4_subnet_id_);
500     }
501 
502     /// @brief Returns subnet identifier for IPv6 reservations.
getIPv6SubnetID()503     SubnetID getIPv6SubnetID() const {
504         return (ipv6_subnet_id_);
505     }
506 
507     /// @brief Sets new IPv4 reservation.
508     ///
509     /// The new reservation removes a previous reservation.
510     ///
511     /// @param address Address to be reserved for the client.
512     ///
513     /// @throw isc::BadValue if the provided address is not an IPv4 address,
514     /// is a 0 address or broadcast address.
515     void setIPv4Reservation(const asiolink::IOAddress& address);
516 
517     /// @brief Removes the IPv4 reservation.
518     ///
519     /// Sets the IPv4 reserved address to 0.
520     void removeIPv4Reservation();
521 
522     /// @brief Returns reserved IPv4 address.
523     ///
524     /// @return IPv4 address or 0.0.0.0 if no IPv4 reservation specified.
getIPv4Reservation()525     const asiolink::IOAddress& getIPv4Reservation() const {
526         return (ipv4_reservation_);
527     }
528 
529     /// @brief Adds new IPv6 reservation.
530     ///
531     /// @param reservation New IPv6 reservation to be appended.
532     void addReservation(const IPv6Resrv& reservation);
533 
534     /// @brief Returns IPv6 reservations of a specified type.
535     ///
536     /// @param type Type of the reservations to be returned (NA or PD).
537     ///
538     /// @return A range of iterators pointing to the reservations of
539     /// the specified type.
540     IPv6ResrvRange getIPv6Reservations(const IPv6Resrv::Type& type) const;
541 
542     /// @brief Returns all IPv6 reservations.
543     ///
544     /// @return A range of iterators pointing to the reservations of
545     /// the specified type.
546     IPv6ResrvRange getIPv6Reservations() const;
547 
548     /// @brief Checks if there is at least one IPv6 reservation for this host.
549     ///
550     /// @return true if there is a reservation for the host, false otherwise.
551     bool hasIPv6Reservation() const;
552 
553     /// @brief Checks if specified IPv6 reservation exists for the host.
554     ///
555     /// @param reservation A reservation to be checked for the host.
556     ///
557     /// @return true if the reservation already exists for the host, false
558     /// otherwise.
559     bool hasReservation(const IPv6Resrv& reservation) const;
560 
561     /// @brief Sets new hostname.
562     ///
563     /// @param hostname New hostname.
setHostname(const std::string & hostname)564     void setHostname(const std::string& hostname) {
565         hostname_ = hostname;
566     }
567 
568     /// @brief Returns reserved hostname.
getHostname()569     const std::string& getHostname() const {
570         return (hostname_);
571     }
572 
573     /// @brief Returns reserved hostname in lower case.
getLowerHostname()574     std::string getLowerHostname() const {
575         return (boost::algorithm::to_lower_copy(hostname_));
576     }
577 
578     /// @brief Adds new client class for DHCPv4.
579     ///
580     /// @param class_name Class name.
581     void addClientClass4(const std::string& class_name);
582 
583     /// @brief Returns classes which DHCPv4 client is associated with.
getClientClasses4()584     const ClientClasses& getClientClasses4() const {
585         return (dhcp4_client_classes_);
586     }
587 
588     /// @brief Adds new client class for DHCPv6.
589     ///
590     /// @param class_name Class name.
591     void addClientClass6(const std::string& class_name);
592 
593     /// @brief Returns classes which DHCPv6 client is associated with.
getClientClasses6()594     const ClientClasses& getClientClasses6() const {
595         return (dhcp6_client_classes_);
596     }
597 
598     /// @brief Sets new value for next server field (siaddr).
599     ///
600     /// @param next_server New address of a next server.
601     ///
602     /// @throw isc::BadValue if the provided address is not an IPv4 address,
603     /// is broadcast address.
604     void setNextServer(const asiolink::IOAddress& next_server);
605 
606     /// @brief Returns value of next server field (siaddr).
getNextServer()607     const asiolink::IOAddress& getNextServer() const {
608         return (next_server_);
609     }
610 
611     /// @brief Sets new value for server hostname (sname).
612     ///
613     /// @param server_host_name New value for server hostname.
614     ///
615     /// @throw BadValue if hostname is longer than 63 bytes.
616     void setServerHostname(const std::string& server_host_name);
617 
618     /// @brief Returns value of server hostname (sname).
getServerHostname()619     const std::string& getServerHostname() const {
620         return (server_host_name_);
621     }
622 
623     /// @brief Sets new value for boot file name (file).
624     ///
625     /// @param boot_file_name New value of boot file name.
626     ///
627     /// @throw BadValue if boot file name is longer than 128 bytes.
628     void setBootFileName(const std::string& boot_file_name);
629 
630     /// @brief Returns value of boot file name (file).
getBootFileName()631     const std::string& getBootFileName() const {
632         return (boot_file_name_);
633     }
634 
635     /// @brief Returns pointer to the DHCPv4 option data configuration for
636     /// this host.
637     ///
638     /// Returned pointer can be used to add, remove and update options
639     /// reserved for a host.
getCfgOption4()640     CfgOptionPtr getCfgOption4() {
641         return (cfg_option4_);
642     }
643 
644     /// @brief Returns const pointer to the DHCPv4 option data configuration for
645     /// this host.
getCfgOption4()646     ConstCfgOptionPtr getCfgOption4() const {
647         return (cfg_option4_);
648     }
649 
650     /// @brief Returns pointer to the DHCPv6 option data configuration for
651     /// this host.
652     ///
653     /// Returned pointer can be used to add, remove and update options
654     /// reserved for a host.
getCfgOption6()655     CfgOptionPtr getCfgOption6() {
656         return (cfg_option6_);
657     }
658 
659     /// @brief Returns const pointer to the DHCPv6 option data configuration for
660     /// this host.
getCfgOption6()661     ConstCfgOptionPtr getCfgOption6() const {
662         return (cfg_option6_);
663     }
664 
665     /// @brief Returns information about the host in the textual format.
666     std::string toText() const;
667 
668     /// @brief Sets Host ID (primary key in MySQL, PostgreSQL and Cassandra backends)
669     /// @param id HostId value
setHostId(HostID id)670     void setHostId(HostID id) {
671         host_id_ = id;
672     }
673 
674     /// @brief Returns Host ID (primary key in MySQL, PostgreSQL and Cassandra backends)
675     /// @return id HostId value (or 0 if not set)
getHostId()676     HostID getHostId() const {
677         return (host_id_);
678     }
679 
680     /// @brief Sets the negative cached flag.
681     ///
682     /// @param negative sets whether this is a negative cached host,
683     /// i.e. a fake host in the cache which indicates non-existence
684     /// and avoids to lookup in a slow backend.
setNegative(bool negative)685     void setNegative(bool negative) {
686         negative_ = negative;
687     }
688 
689     /// @brief Return the negative cache flag value.
690     /// When true standard lookup methods return null host pointer instead.
getNegative()691     bool getNegative() const {
692         return (negative_);
693     }
694 
695     /// @brief Unparses (converts to Element representation) IPv4 host
696     ///
697     /// @return Element representation of the host
698     isc::data::ElementPtr toElement4() const;
699 
700     /// @brief Unparses (converts to Element representation) IPv6 host
701     ///
702     /// @return Element representation of the host
703     isc::data::ElementPtr toElement6() const;
704 
705     /// @brief sets key.
706     ///
707     /// Keys are used for signing the Reconfigure Message.
setKey(const AuthKey & key)708     void setKey(const AuthKey& key) {
709         key_ = key;
710     }
711 
712     /// @brief Returns the key.
713     ///
714     /// Keys are used for signing the Reconfigure Message.
getKey()715     AuthKey getKey() const {
716         return(key_);
717     }
718 
719 private:
720 
721     /// @brief Adds new client class for DHCPv4 or DHCPv6.
722     ///
723     /// This method is called internally by the @c addClientClass4 and
724     /// @c addClientClass6 functions. It adds the class of the specified name
725     /// to the supplied class set. The class names are trimmed before they are
726     /// added. Empty class names are ignored.
727     ///
728     /// @param [out] classes Set of classes to which the new class should be
729     /// inserted.
730     /// @param class_name Class name.
731     void addClientClassInternal(ClientClasses& classes,
732                                 const std::string& class_name);
733 
734     /// @brief Identifier type.
735     IdentifierType identifier_type_;
736     /// @brief Vector holding identifier value.
737     std::vector<uint8_t> identifier_value_;
738     /// @brief Subnet identifier for the DHCPv4 client.
739     SubnetID ipv4_subnet_id_;
740     /// @brief Subnet identifier for the DHCPv6 client.
741     SubnetID ipv6_subnet_id_;
742     /// @brief Reserved IPv4 address.
743     asiolink::IOAddress ipv4_reservation_;
744     /// @brief Collection of IPv6 reservations for the host.
745     IPv6ResrvCollection ipv6_reservations_;
746     /// @brief Name reserved for the host.
747     std::string hostname_;
748     /// @brief Collection of classes associated with a DHCPv4 client.
749     ClientClasses dhcp4_client_classes_;
750     /// @brief Collection of classes associated with a DHCPv6 client.
751     ClientClasses dhcp6_client_classes_;
752     /// @brief Next server (a.k.a. siaddr, carried in DHCPv4 message).
753     asiolink::IOAddress next_server_;
754     /// @brief Server host name (a.k.a. sname, carried in DHCPv4 message).
755     std::string server_host_name_;
756     /// @brief Boot file name (a.k.a. file, carried in DHCPv4 message)
757     std::string boot_file_name_;
758 
759     /// @brief HostID (a unique identifier assigned when the host is stored in
760     ///     MySQL, PostgreSQL or Cassandra)
761     uint64_t host_id_;
762 
763     /// @brief Pointer to the DHCPv4 option data configuration for this host.
764     CfgOptionPtr cfg_option4_;
765     /// @brief Pointer to the DHCPv6 option data configuration for this host.
766     CfgOptionPtr cfg_option6_;
767 
768     /// @brief Negative cached flag.
769     ///
770     /// This flag determines whether this object is a negative cache, i.e.
771     /// we queried other backends for specific host and there was no
772     /// entry for it.
773     bool negative_;
774 
775     /// @brief key for authentication .
776     ///
777     /// key is a 16 byte value to be used in the authentication field.
778     /// Server replies will contain the below key in authentication field
779     /// as specified in the RFC 8415. While sending reconfigure message
780     /// authentication field shall contain MD5 hash computed using this key.
781     AuthKey key_;
782 };
783 
784 /// @brief Pointer to the @c Host object.
785 typedef boost::shared_ptr<Host> HostPtr;
786 
787 /// @brief Const pointer to the @c Host object.
788 typedef boost::shared_ptr<const Host> ConstHostPtr;
789 
790 /// @brief Collection of the const Host objects.
791 typedef std::vector<ConstHostPtr> ConstHostCollection;
792 
793 /// @brief Collection of the @c Host objects.
794 typedef std::vector<HostPtr> HostCollection;
795 
796 }
797 }
798 
799 #endif // HOST_H
800