diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/dhcp/option_space.h | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/lib/dhcp/option_space.h b/src/lib/dhcp/option_space.h new file mode 100644 index 0000000..4826b0f --- /dev/null +++ b/src/lib/dhcp/option_space.h @@ -0,0 +1,183 @@ +// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef OPTION_SPACE_H +#define OPTION_SPACE_H + +#include <dhcp/std_option_defs.h> +#include <exceptions/exceptions.h> + +#include <boost/shared_ptr.hpp> +#include <map> +#include <stdint.h> +#include <string> + +namespace isc { +namespace dhcp { + +/// @brief Exception to be thrown when invalid option space +/// is specified. +class InvalidOptionSpace : public Exception { +public: + InvalidOptionSpace(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) { }; +}; + +/// OptionSpace forward declaration. +class OptionSpace; +/// A pointer to OptionSpace object. +typedef boost::shared_ptr<OptionSpace> OptionSpacePtr; +/// A collection of option spaces. +typedef std::map<std::string, OptionSpacePtr> OptionSpaceCollection; + +/// @brief DHCP option space. +/// +/// This class represents single option space. The option spaces are used +/// to group DHCP options having unique option codes. The special type +/// of the option space is so called "vendor specific option space". +/// It groups sub-options being sent within Vendor Encapsulated Options. +/// For DHCPv4 it is the option with code 43. The option spaces are +/// assigned to option instances represented by isc::dhcp::Option and +/// other classes derived from it. Each particular option may belong to +/// multiple option spaces. +/// This class may be used to represent any DHCPv4 option space. If the +/// option space is to group DHCPv4 Vendor Encapsulated Options then +/// "vendor space" flag must be set using \ref OptionSpace::setVendorSpace +/// or the argument passed to the constructor. In theory, this class can +/// be also used to represent non-vendor specific DHCPv6 option space +/// but this is discouraged. For DHCPv6 option spaces the OptionSpace6 +/// class should be used instead. +/// +/// @note this class is intended to be used to represent DHCPv4 option +/// spaces only. However, it hasn't been called OptionSpace4 (that would +/// suggest that it is specific to DHCPv4) because it can be also +/// used to represent some DHCPv6 option spaces and is a base class +/// for \ref OptionSpace6. Thus, if one declared the container as follows: +/// @code +/// std::vector<OptionSpace4> container; +/// @endcode +/// it would suggest that the container holds DHCPv4 option spaces while +/// it could hold both DHCPv4 and DHCPv6 option spaces as the OptionSpace6 +/// object could be upcast to OptionSpace4. This confusion does not appear +/// when OptionSpace is used as a name for the base class. +class OptionSpace { +public: + + /// @brief Constructor. + /// + /// @param name option space name. + /// @param vendor_space boolean value that indicates that the object + /// describes the vendor specific option space. + /// + /// @throw isc::dhcp::InvalidOptionSpace if given option space name + /// contains invalid characters or is empty. This constructor uses + /// \ref validateName function to check that the specified name is + /// correct. + OptionSpace(const std::string& name, const bool vendor_space = false); + + /// @brief Return option space name. + /// + /// @return option space name. + const std::string& getName() const { return (name_); } + + /// @brief Mark option space as non-vendor space. + void clearVendorSpace() { + vendor_space_ = false; + } + + /// @brief Check if option space is vendor specific. + /// + /// @return boolean value that indicates if the object describes + /// the vendor specific option space. + bool isVendorSpace() const { return (vendor_space_); } + + /// @brief Mark option space as vendor specific. + void setVendorSpace() { + vendor_space_ = true; + } + + /// @brief Checks that the provided option space name is valid. + /// + /// It is expected that option space name consists of upper or + /// lower case letters or digits. Also, it may contain underscores + /// or dashes. Other characters are prohibited. The empty option + /// space names are invalid. + /// + /// @param name option space name to be validated. + /// + /// @return true if the option space is valid, else it returns false. + static bool validateName(const std::string& name); + +private: + std::string name_; ///< Holds option space name. + + bool vendor_space_; ///< Is this the vendor space? + +}; + +/// @brief DHCPv6 option space with enterprise number assigned. +/// +/// This class extends the base class with the support for enterprise numbers. +/// The enterprise numbers are assigned by IANA to various organizations +/// and they are carried as uint32_t integers in DHCPv6 Vendor Specific +/// Information Options (VSIO). For more information refer to RFC 8415. +/// All option spaces that group VSIO options must have enterprise number +/// set. It can be set using a constructor or \ref setVendorSpace function. +/// The extra functionality of this class (enterprise numbers) allows to +/// represent DHCPv6 vendor-specific option spaces but this class is also +/// intended to be used for all other DHCPv6 option spaces. That way all +/// DHCPv6 option spaces can be stored in the container holding OptionSpace6 +/// objects. Also, it is easy to mark vendor-specific option space as non-vendor +/// specific option space (and the other way around) without a need to cast +/// between OptionSpace and OptionSpace6 types. +class OptionSpace6 : public OptionSpace { +public: + + /// @brief Constructor for non-vendor-specific options. + /// + /// This constructor marks option space as non-vendor specific. + /// + /// @param name option space name. + /// + /// @throw isc::dhcp::InvalidOptionSpace if given option space name + /// contains invalid characters or is empty. This constructor uses + /// \ref OptionSpace::validateName function to check that the specified + /// name is correct. + OptionSpace6(const std::string& name); + + /// @brief Constructor for vendor-specific options. + /// + /// This constructor marks option space as vendor specific and sets + /// enterprise number to a given value. + /// + /// @param name option space name. + /// @param enterprise_number enterprise number. + /// + /// @throw isc::dhcp::InvalidOptionSpace if given option space name + /// contains invalid characters or is empty. This constructor uses + /// \ref OptionSpace::validateName function to check that the specified + /// name is correct. + OptionSpace6(const std::string& name, const uint32_t enterprise_number); + + /// @brief Return enterprise number for the option space. + /// + /// @return enterprise number. + uint32_t getEnterpriseNumber() const { return (enterprise_number_); } + + /// @brief Mark option space as vendor specific. + /// + /// @param enterprise_number enterprise number. + void setVendorSpace(const uint32_t enterprise_number); + +private: + + uint32_t enterprise_number_; ///< IANA assigned enterprise number. +}; + +} // namespace dhcp +} // namespace isc + +#endif // OPTION_SPACE_H |