From: Tomek Mrugalski Date: Thu, 11 Dec 2014 11:05:46 +0000 (+0100) Subject: [3548] Patch as provided by Adam Kalmus X-Git-Tag: trac3504_base~15 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7a1acfe1909d1b8da8e1c27dbfe17181ada92593;p=thirdparty%2Fkea.git [3548] Patch as provided by Adam Kalmus --- diff --git a/src/lib/dhcp/pkt.cc b/src/lib/dhcp/pkt.cc old mode 100644 new mode 100755 index 72e0f86742..61ee750472 --- a/src/lib/dhcp/pkt.cc +++ b/src/lib/dhcp/pkt.cc @@ -142,6 +142,12 @@ Pkt::getMAC(uint32_t hw_addr_src) { } // Method 2: Extracted from DUID-LLT or DUID-LL + if(hw_addr_src & HWADDR_SOURCE_DUID) { + mac = getMACFromDUID(); + if (mac){ + return (mac); + } else return (HWAddrPtr()); + } // Method 3: Extracted from source IPv6 link-local address if (hw_addr_src & HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL) { diff --git a/src/lib/dhcp/pkt.h b/src/lib/dhcp/pkt.h old mode 100644 new mode 100755 index 2b5e73f4bf..4321b67645 --- a/src/lib/dhcp/pkt.h +++ b/src/lib/dhcp/pkt.h @@ -37,6 +37,61 @@ namespace dhcp { /// @note This is abstract class. Please instantiate derived classes /// such as @c Pkt4 or @c Pkt6. class Pkt { +<<<<<<< HEAD +======= +public: + + /// @defgroup hw_sources Specifies where a given MAC/hardware address was + /// obtained. + /// + /// @brief The list covers all possible MAC/hw address sources. + /// + /// @note The uncommented ones are currently supported. When you implement + /// a new method, please uncomment appropriate line here. + /// + /// @{ + + /// Not really a type, only used in getMAC() calls. + static const uint32_t HWADDR_SOURCE_ANY = 0xffff; + + /// Used when actual origin is not known, e.g. when reading from a + /// lease database that didn't store that information. + static const uint32_t HWADDR_SOURCE_UNKNOWN = 0x0000; + + /// Obtained first hand from raw socket (100% reliable). + static const uint32_t HWADDR_SOURCE_RAW = 0x0001; + + /// Extracted from DUID-LL or DUID-LLT (not 100% reliable as the client + /// can send fake DUID). + static const uint32_t HWADDR_SOURCE_DUID = 0x0002; + + /// Extracted from IPv6 link-local address. Not 100% reliable, as the + /// client can use different IID other than EUI-64, e.g. Windows supports + /// RFC4941 and uses random values instead of EUI-64. + static const uint32_t HWADDR_SOURCE_IPV6_LINK_LOCAL = 0x0004; + + /// Get it from RFC6939 option. (A relay agent can insert client link layer + /// address option). Note that a skilled attacker can fake that by sending + /// his request relayed, so the legitimate relay will think it's a second + /// relay. + static const uint32_t HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION = 0x0008; + + /// A relay can insert remote-id. In some deployments it contains a MAC + /// address (RFC4649). + //static const uint32_t HWADDR_SOURCE_REMOTE_ID = 0x0010; + + /// A relay can insert a subscriber-id option. In some deployments it + /// contains a MAC address (RFC4580). + //static const uint32_t HWADDR_SOURCE_SUBSCRIBER_ID = 0x0020; + + /// A CMTS (acting as DHCP relay agent) that supports DOCSIS standard + /// can insert DOCSIS options that contain client's MAC address. + /// Client in this context would be a cable modem. + //static const uint32_t HWADDR_SOURCE_DOCSIS_OPTIONS = 0x0040; + + /// @} + +>>>>>>> [3548] Patch as provided by Adam Kalmus protected: /// @brief Constructor. @@ -492,6 +547,8 @@ protected: /// @return hardware address (or NULL) virtual HWAddrPtr getMACFromIPv6RelayOpt() = 0; + virtual HWAddrPtr getMACFromDUID() = 0; + /// @brief Attempts to convert IPv6 address into MAC. /// /// Utility method that attempts to convert link-local IPv6 address to the @@ -508,6 +565,8 @@ protected: HWAddrPtr getMACFromIPv6(const isc::asiolink::IOAddress& addr); + + /// Transaction-id (32 bits for v4, 24 bits for v6) uint32_t transid_; diff --git a/src/lib/dhcp/pkt4.h b/src/lib/dhcp/pkt4.h old mode 100644 new mode 100755 index ba459a837c..43430695b8 --- a/src/lib/dhcp/pkt4.h +++ b/src/lib/dhcp/pkt4.h @@ -414,6 +414,10 @@ protected: return (HWAddrPtr()); } + virtual HWAddrPtr getMACFromDUID(){ + return (HWAddrPtr()); + } + /// local HW address (dst if receiving packet, src if sending packet) HWAddrPtr local_hwaddr_; diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc old mode 100644 new mode 100755 index 8dcc070917..adf4799983 --- a/src/lib/dhcp/pkt6.cc +++ b/src/lib/dhcp/pkt6.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -439,6 +440,36 @@ Pkt6::unpackTCP() { "not implemented yet."); } +HWAddrPtr +Pkt6::getMACFromDUID() { + OptionPtr opt_duid = getOption(D6O_CLIENTID); + uint8_t hlen = opt_duid->getData().size(); + vector hw_addr(hlen, 0); + std::vector duid_data = opt_duid->getData(); + + + uint16_t hwtype = 0; + std::memcpy(&hwtype, &duid_data[2], 2); // TODO nie jestem tego pewien + + + // checking if DUID is LLT or LL type + if ((duid_data[0] == 0x00) && (duid_data[1]== 0x01)){ + hlen -= 8; + std::memcpy(&hw_addr, &duid_data[8], hlen); + + } + else if ((duid_data[0] == 0x00) && (duid_data[1]== 0x03)){ + hlen -= 4; + std::memcpy(&hw_addr, &duid_data[4], hlen); + } + // if none of them return NULL + else return HWAddrPtr(); + + hw_addr.resize(hlen); + hwaddr_= HWAddrPtr(new HWAddr(hw_addr, hwtype)); + return (hwaddr_); +} + std::string Pkt6::toText() { diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h old mode 100644 new mode 100755 index f4b3391272..9a598f9d1d --- a/src/lib/dhcp/pkt6.h +++ b/src/lib/dhcp/pkt6.h @@ -305,6 +305,10 @@ protected: /// @return Hardware address (or NULL) virtual HWAddrPtr getMACFromIPv6RelayOpt(); + virtual HWAddrPtr getMACFromDUID(); + + HWAddrPtr hwaddr_; + /// @brief Builds on wire packet for TCP transmission. /// /// @todo This function is not implemented yet.