1 // Copyright (C) 2013-2015 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 HWADDR_H 8 #define HWADDR_H 9 10 #include <vector> 11 #include <stdint.h> 12 #include <stddef.h> 13 #include <dhcp/dhcp4.h> 14 #include <boost/shared_ptr.hpp> 15 16 namespace isc { 17 namespace dhcp { 18 19 /// @brief Hardware type that represents information from DHCPv4 packet 20 struct HWAddr { 21 public: 22 23 /// @brief Size of an ethernet hardware address. 24 static const size_t ETHERNET_HWADDR_LEN = 6; 25 26 /// @brief Maximum size of a hardware address. 27 static const size_t MAX_HWADDR_LEN = 20; 28 29 /// @defgroup hw_sources Specifies where a given MAC/hardware address was 30 /// obtained. 31 /// 32 /// @brief The list covers all possible MAC/hw address sources. 33 /// 34 /// @{ 35 36 /// Not really a type, only used in getMAC() calls. 37 static const uint32_t HWADDR_SOURCE_ANY; 38 39 /// Used when actual origin is not known, e.g. when reading from a 40 /// lease database that didn't store that information. 41 static const uint32_t HWADDR_SOURCE_UNKNOWN; 42 43 /// Obtained first hand from raw socket (100% reliable). 44 static const uint32_t HWADDR_SOURCE_RAW; 45 46 /// Extracted from DUID-LL or DUID-LLT (not 100% reliable as the client 47 /// can send fake DUID). 48 static const uint32_t HWADDR_SOURCE_DUID; 49 50 /// Extracted from IPv6 link-local address. Not 100% reliable, as the 51 /// client can use different IID other than EUI-64, e.g. Windows supports 52 /// RFC4941 and uses random values instead of EUI-64. 53 static const uint32_t HWADDR_SOURCE_IPV6_LINK_LOCAL; 54 55 /// Get it from RFC6939 option. (A relay agent can insert client link layer 56 /// address option). Note that a skilled attacker can fake that by sending 57 /// his request relayed, so the legitimate relay will think it's a second 58 /// relay. 59 static const uint32_t HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION; 60 61 /// A relay can insert remote-id. In some deployments it contains a MAC 62 /// address (RFC4649). 63 static const uint32_t HWADDR_SOURCE_REMOTE_ID; 64 65 /// A relay can insert a subscriber-id option. In some deployments it 66 /// contains a MAC address (RFC4580). 67 static const uint32_t HWADDR_SOURCE_SUBSCRIBER_ID; 68 69 /// A CMTS (acting as DHCP relay agent) that supports DOCSIS standard 70 /// can insert DOCSIS options that contain client's MAC address. 71 /// This specific option is suboption 1026 in vendor-class option with 72 /// vendor-id=4491. Client in this context would be a cable modem. 73 static const uint32_t HWADDR_SOURCE_DOCSIS_CMTS; 74 75 /// A cable modem (acting as DHCP client) that supports DOCSIS standard 76 /// can insert DOCSIS options that contain client's MAC address. 77 /// This specific option is suboption 36 in vendor-class option with 78 /// vendor-id=4491. 79 static const uint32_t HWADDR_SOURCE_DOCSIS_MODEM; 80 81 /// @} 82 83 /// @brief default constructor 84 HWAddr(); 85 86 /// @brief constructor, based on C-style pointer and length 87 /// @param hwaddr pointer to hardware address 88 /// @param len length of the address pointed by hwaddr 89 /// @param htype hardware type 90 HWAddr(const uint8_t* hwaddr, size_t len, uint16_t htype); 91 92 /// @brief constructor, based on C++ vector<uint8_t> 93 /// @param hwaddr const reference to hardware address 94 /// @param htype hardware type 95 HWAddr(const std::vector<uint8_t>& hwaddr, uint16_t htype); 96 97 // Vector that keeps the actual hardware address 98 std::vector<uint8_t> hwaddr_; 99 100 /// Hardware type 101 /// 102 /// @note It used to be uint8_t as used in DHCPv4. However, since we're 103 /// expanding MAC addresses support to DHCPv6 that uses hw_type as 104 /// 16 bits, we need to be able to store that wider format. 105 uint16_t htype_; 106 107 /// @brief Hardware address source 108 /// 109 /// This variable specifies how the hardware address was obtained. 110 /// @todo This is a stub implementation. Proper implementation will move 111 /// constants from Pkt::HWADDR_SOURCE_* here. Currently always initialized 112 /// to zero. 113 uint32_t source_; 114 115 /// @brief Returns textual representation of a hardware address 116 /// (e.g. 00:01:02:03:04:05) 117 /// 118 /// @param include_htype Boolean value which controls whether the hardware 119 /// type is included in the returned string (true), or not (false). 120 /// 121 /// @return Hardware address in the textual format. 122 std::string toText(bool include_htype = true) const; 123 124 /// @brief Creates instance of the hardware address from textual format. 125 /// 126 /// This function parses HW address specified as text and creates the 127 /// corresponding @c HWAddr instance. The hexadecimal digits representing 128 /// individual bytes of the hardware address should be separated with 129 /// colons. Typically, two digits per byte are used. However, this function 130 /// allows for 1 digit per HW address byte. In this case, the digit is 131 /// prepended with '0' during conversion to binary value. 132 /// 133 /// This function can be used to perform a reverse operation to the 134 /// @c HWAddr::toText(false). 135 /// 136 /// The instance created by this function sets HTYPE_ETHER as a hardware 137 /// type. 138 /// 139 /// @param text HW address in the textual format. 140 /// @param htype Hardware type. 141 /// 142 /// @return Instance of the HW address created from text. 143 static HWAddr fromText(const std::string& text, 144 const uint16_t htype = HTYPE_ETHER); 145 146 /// @brief Compares two hardware addresses for equality 147 bool operator==(const HWAddr& other) const; 148 149 /// @brief Compares two hardware addresses for inequality 150 bool operator!=(const HWAddr& other) const; 151 }; 152 153 /// @brief Shared pointer to a hardware address structure 154 typedef boost::shared_ptr<HWAddr> HWAddrPtr; 155 156 }; // end of isc::dhcp namespace 157 }; // end of isc namespace 158 159 #endif // HWADDR_H 160