Parcourir la source

[3548] Patch as provided by Adam Kalmus

Tomek Mrugalski il y a 10 ans
Parent
commit
7a1acfe190
5 fichiers modifiés avec 104 ajouts et 0 suppressions
  1. 6 0
      src/lib/dhcp/pkt.cc
  2. 59 0
      src/lib/dhcp/pkt.h
  3. 4 0
      src/lib/dhcp/pkt4.h
  4. 31 0
      src/lib/dhcp/pkt6.cc
  5. 4 0
      src/lib/dhcp/pkt6.h

+ 6 - 0
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) {

+ 59 - 0
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_;
 

+ 4 - 0
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_;
 

+ 31 - 0
src/lib/dhcp/pkt6.cc

@@ -18,6 +18,7 @@
 #include <dhcp/pkt6.h>
 #include <util/io_utilities.h>
 #include <exceptions/exceptions.h>
+#include <dhcp/duid.h>
 
 #include <iostream>
 #include <sstream>
@@ -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<uint8_t> hw_addr(hlen, 0);
+	std::vector<unsigned char> 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() {

+ 4 - 0
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.