Browse Source

[4254] Include client identifier in a DHCPv4 message.

Marcin Siodelski 9 years ago
parent
commit
5440709fd7

+ 15 - 0
src/bin/perfdhcp/test_control.cc

@@ -327,6 +327,7 @@ TestControl::createRequestFromAck(const dhcp::Pkt4Ptr& ack) {
     Pkt4Ptr msg(new Pkt4(DHCPREQUEST, generateTransid()));
     msg->setCiaddr(ack->getYiaddr());
     msg->setHWAddr(ack->getHWAddr());
+    msg->addOption(generateClientId(msg->getHWAddr()));
     return (msg);
 }
 
@@ -496,6 +497,15 @@ TestControl::generateMacAddress(uint8_t& randomized) const {
     return (mac_addr);
 }
 
+OptionPtr
+TestControl::generateClientId(const dhcp::HWAddrPtr& hwaddr) const {
+    std::vector<uint8_t> client_id(1, static_cast<uint8_t>(hwaddr->htype_));
+    client_id.insert(client_id.end(), hwaddr->hwaddr_.begin(),
+                     hwaddr->hwaddr_.end());
+    return (OptionPtr(new Option(Option::V4, DHO_DHCP_CLIENT_IDENTIFIER,
+                                 client_id)));
+}
+
 std::vector<uint8_t>
 TestControl::generateDuid(uint8_t& randomized) const {
     CommandOptions& options = CommandOptions::instance();
@@ -1559,6 +1569,9 @@ TestControl::sendDiscover4(const TestControlSocket& socket,
     // Set hardware address
     pkt4->setHWAddr(HTYPE_ETHER, mac_address.size(), mac_address);
 
+    // Set client identifier
+    pkt4->addOption(generateClientId(pkt4->getHWAddr()));
+
     pkt4->pack();
     IfaceMgr::instance().send(pkt4);
     if (!preload) {
@@ -1728,6 +1741,8 @@ TestControl::sendRequest4(const TestControlSocket& socket,
 
     // Set hardware address
     pkt4->setHWAddr(offer_pkt4->getHWAddr());
+    // Set client id.
+    pkt4->addOption(generateClientId(pkt4->getHWAddr()));
     // Set elapsed time.
     uint32_t elapsed_time = getElapsedTime<Pkt4Ptr>(discover_pkt4, offer_pkt4);
     pkt4->setSecs(static_cast<uint16_t>(elapsed_time / 1000));

+ 10 - 0
src/bin/perfdhcp/test_control.h

@@ -440,6 +440,16 @@ protected:
                                                uint16_t type,
                                                const dhcp::OptionBuffer& buf);
 
+    /// \brief Generate DHCPv4 client identifier from HW address.
+    ///
+    /// This method generates DHCPv4 client identifier option from a
+    /// HW address.
+    ///
+    /// \param hwaddr HW address.
+    ///
+    /// \return Pointer to an instance of the generated option.
+    dhcp::OptionPtr generateClientId(const dhcp::HWAddrPtr& hwaddr) const;
+
     /// \brief Generate DUID.
     ///
     /// Method generates unique DUID. The number of DUIDs it can generate

+ 29 - 0
src/bin/perfdhcp/tests/test_control_unittest.cc

@@ -102,6 +102,7 @@ public:
     using TestControl::factoryOptionRequestOption6;
     using TestControl::factoryRapidCommit6;
     using TestControl::factoryRequestList4;
+    using TestControl::generateClientId;
     using TestControl::generateDuid;
     using TestControl::generateMacAddress;
     using TestControl::getCurrentTimeout;
@@ -1075,6 +1076,34 @@ TEST_F(TestControlTest, reset) {
 
 }
 
+// This test verfies that the client id is generated from the HW address.
+TEST_F(TestControlTest, generateClientId) {
+    // Generate HW address.
+    std::vector<uint8_t> hwaddr;
+    for (unsigned int i = 0; i < 6; ++i) {
+        hwaddr.push_back(i);
+    }
+    HWAddrPtr hwaddr_ptr(new HWAddr(hwaddr, 5));
+
+    // Use generated HW address to generate client id.
+    NakedTestControl tc;
+    OptionPtr opt_client_id;
+    ASSERT_NO_THROW(opt_client_id = tc.generateClientId(hwaddr_ptr));
+    ASSERT_TRUE(opt_client_id);
+
+    // Extract the client id data.
+    const OptionBuffer& client_id = opt_client_id->getData();
+    ASSERT_EQ(7, client_id.size());
+
+    // Verify that the client identifier is generated correctly.
+
+    // First byte is the HW type.
+    EXPECT_EQ(5, client_id[0]);
+    // The rest of the client identifier should be equal to the HW address.
+    std::vector<uint8_t> sub(client_id.begin() + 1, client_id.end());
+    EXPECT_TRUE(hwaddr == sub);
+}
+
 TEST_F(TestControlTest, GenerateDuid) {
     // Simple command line that simulates one client only. Always the
     // same DUID will be generated.