Browse Source

[master] Merge branch 'trac3553' (MAC address from docsis options)

Tomek Mrugalski 10 years ago
parent
commit
ad0a377277

+ 14 - 4
doc/guide/dhcp6-srv.xml

@@ -1921,7 +1921,7 @@ should include options from the isc option space:
         </simpara>
       </listitem>
       <listitem>
-        <simpara><command>remote-id</command> <ulink
+        <simpara><command>remote-id</command> - <ulink
         url="http://tools.ietf.org/html/rfc4649">RFC 4649</ulink>
         defines remote-id option that is inserted by a relay agent. Depending
         on the relay agent configuration, the inserted option may convey client's
@@ -1941,10 +1941,20 @@ should include options from the isc option space:
         </simpara>
       </listitem>
       <listitem>
-        <simpara><command>docsis</command> - Yet another possible source of MAC
+        <simpara><command>docsis-cmts</command> - Yet another possible source of MAC
         address information are DOCSIS options inserted by a CMTS that acts
-        as a DHCPv6 relay agent in cable networks. This method is
-        currently not implemented.
+        as a DHCPv6 relay agent in cable networks. This method attempts to extract
+        MAC address information from suboption 1026 (cm mac) of the vendor specific option
+        with vendor-id=4491. This vendor option is extracted from the relay-forward message,
+        not the original client's message.
+        </simpara>
+      </listitem>
+      <listitem>
+        <simpara><command>docsis-modem</command> - Yet another possible source of MAC
+        address information are DOCSIS options inserted by the cable modem itself.
+        This method attempts to extract MAC address information from suboption 36 (device id)
+        of the vendor specific option with vendor-id=4491. This vendor option is extracted from
+        the original client's message, not from any relay options.
         </simpara>
       </listitem>
     </itemizedlist>

+ 0 - 1
src/bin/dhcp4/tests/Makefile.am

@@ -80,7 +80,6 @@ dhcp4_unittests_SOURCES += dhcp4_unittests.cc
 dhcp4_unittests_SOURCES += dhcp4_srv_unittest.cc
 dhcp4_unittests_SOURCES += dhcp4_test_utils.cc dhcp4_test_utils.h
 dhcp4_unittests_SOURCES += direct_client_unittest.cc
-dhcp4_unittests_SOURCES += wireshark.cc
 dhcp4_unittests_SOURCES += ctrl_dhcp4_srv_unittest.cc
 dhcp4_unittests_SOURCES += config_parser_unittest.cc
 dhcp4_unittests_SOURCES += fqdn_unittest.cc

+ 8 - 6
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc

@@ -18,6 +18,7 @@
 #include <asiolink/io_address.h>
 #include <config/ccsession.h>
 #include <dhcp4/tests/dhcp4_test_utils.h>
+#include <dhcp/tests/pkt_captures.h>
 #include <dhcp/dhcp4.h>
 #include <dhcp/iface_mgr.h>
 #include <dhcp/option.h>
@@ -56,6 +57,7 @@ using namespace isc::data;
 using namespace isc::asiolink;
 using namespace isc::hooks;
 using namespace isc::dhcp::test;
+using namespace isc::test;
 
 namespace {
 
@@ -1159,7 +1161,7 @@ TEST_F(Dhcpv4SrvTest, relayAgentInfoEcho) {
     // added option 82 (relay agent info) with 3 suboptions. The server
     // is supposed to echo it back in its response.
     Pkt4Ptr dis;
-    ASSERT_NO_THROW(dis = captureRelayedDiscover());
+    ASSERT_NO_THROW(dis = PktCaptures::captureRelayedDiscover());
 
     // Simulate that we have received that traffic
     srv.fakeReceive(dis);
@@ -1235,7 +1237,7 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsDocsis) {
     // added option 82 (relay agent info) with 3 suboptions. The server
     // is supposed to echo it back in its response.
     Pkt4Ptr dis;
-    ASSERT_NO_THROW(dis = captureRelayedDiscover());
+    ASSERT_NO_THROW(dis = PktCaptures::captureRelayedDiscover());
 
     // Simulate that we have received that traffic
     srv.fakeReceive(dis);
@@ -2935,7 +2937,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4ReleaseSkip) {
 TEST_F(Dhcpv4SrvTest, docsisVendorOptionsParse) {
 
     // Let's get a traffic capture from DOCSIS3.0 modem
-    Pkt4Ptr dis = captureRelayedDiscover();
+    Pkt4Ptr dis = PktCaptures::captureRelayedDiscover();
     ASSERT_NO_THROW(dis->unpack());
 
     // Check if the packet contain
@@ -2959,7 +2961,7 @@ TEST_F(Dhcpv4SrvTest, docsisVendorOptionsParse) {
 TEST_F(Dhcpv4SrvTest, docsisVendorORO) {
 
     // Let's get a traffic capture from DOCSIS3.0 modem
-    Pkt4Ptr dis = captureRelayedDiscover();
+    Pkt4Ptr dis = PktCaptures::captureRelayedDiscover();
     EXPECT_NO_THROW(dis->unpack());
 
     // Check if the packet contains vendor specific information option
@@ -3127,7 +3129,7 @@ TEST_F(Dhcpv4SrvTest, clientClassification) {
     // Let's create a relayed DISCOVER. This particular relayed DISCOVER has
     // vendor-class set to docsis3.0
     Pkt4Ptr dis1;
-    ASSERT_NO_THROW(dis1 = captureRelayedDiscover());
+    ASSERT_NO_THROW(dis1 = PktCaptures::captureRelayedDiscover());
     ASSERT_NO_THROW(dis1->unpack());
 
     srv.classifyPacket(dis1);
@@ -3138,7 +3140,7 @@ TEST_F(Dhcpv4SrvTest, clientClassification) {
     // Let's create a relayed DISCOVER. This particular relayed DISCOVER has
     // vendor-class set to eRouter1.0
     Pkt4Ptr dis2;
-    ASSERT_NO_THROW(dis2 = captureRelayedDiscover2());
+    ASSERT_NO_THROW(dis2 = PktCaptures::captureRelayedDiscover2());
     ASSERT_NO_THROW(dis2->unpack());
 
     srv.classifyPacket(dis2);

+ 2 - 30
src/bin/dhcp4/tests/dhcp4_test_utils.h

@@ -335,21 +335,6 @@ public:
     /// @param expected_clientid expected value of client-id
     void checkClientId(const Pkt4Ptr& rsp, const OptionPtr& expected_clientid);
 
-    /// @brief sets default fields in a captured packet
-    ///
-    /// Sets UDP ports, addresses and interface.
-    ///
-    /// @param pkt packet to have default fields set
-    void captureSetDefaultFields(const Pkt4Ptr& pkt);
-
-    /// @brief returns captured DISCOVER that went through a relay
-    ///
-    /// See method code for a detailed explanation. This is a discover from
-    /// docsis3.0 device (Cable Modem)
-    ///
-    /// @return relayed DISCOVER
-    Pkt4Ptr captureRelayedDiscover();
-
     /// @brief Create packet from output buffer of another packet.
     ///
     /// This function creates a packet using an output buffer from another
@@ -373,21 +358,8 @@ public:
     /// @return assertion result indicating if a function completed with
     /// success or failure.
     static ::testing::AssertionResult
-    createPacketFromBuffer(const Pkt4Ptr& src_pkt,
-                           Pkt4Ptr& dst_pkt);
-
-    /// @brief returns captured DISCOVER that went through a relay
-    ///
-    /// See method code for a detailed explanation. This is a discover from
-    /// eRouter1.0 device (CPE device integrated with cable modem)
-    ///
-    /// @return relayed DISCOVER
-    Pkt4Ptr captureRelayedDiscover2();
-
-    /// @brief generates a DHCPv4 packet based on provided hex string
-    ///
-    /// @return created packet
-    Pkt4Ptr packetFromCapture(const std::string& hex_string);
+    createPacketFromBuffer(const isc::dhcp::Pkt4Ptr& src_pkt,
+                           isc::dhcp::Pkt4Ptr& dst_pkt);
 
     /// @brief Tests if Discover or Request message is processed correctly
     ///

+ 0 - 1
src/bin/dhcp6/tests/Makefile.am

@@ -79,7 +79,6 @@ dhcp6_unittests_SOURCES += dhcp6_test_utils.cc dhcp6_test_utils.h
 dhcp6_unittests_SOURCES += d2_unittest.cc d2_unittest.h
 dhcp6_unittests_SOURCES += marker_file.cc
 dhcp6_unittests_SOURCES += ctrl_dhcp6_srv_unittest.cc
-dhcp6_unittests_SOURCES += wireshark.cc
 dhcp6_unittests_SOURCES += dhcp6_client.cc dhcp6_client.h
 dhcp6_unittests_SOURCES += rebind_unittest.cc
 dhcp6_unittests_SOURCES += sarr_unittest.cc

+ 13 - 12
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2015  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -40,6 +40,8 @@
 #include <hooks/server_hooks.h>
 
 #include <dhcp6/tests/dhcp6_test_utils.h>
+#include <dhcp/tests/pkt_captures.h>
+#include <config/ccsession.h>
 #include <boost/pointer_cast.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <gtest/gtest.h>
@@ -50,7 +52,6 @@
 
 using namespace isc;
 using namespace isc::data;
-using namespace isc::config;
 using namespace isc::test;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
@@ -1443,7 +1444,7 @@ TEST_F(Dhcpv6SrvTest, portsDirectTraffic) {
     NakedDhcpv6Srv srv(0);
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = captureSimpleSolicit();
+    Pkt6Ptr sol = PktCaptures::captureSimpleSolicit();
 
     // Simulate that we have received that traffic
     srv.fakeReceive(sol);
@@ -1468,7 +1469,7 @@ TEST_F(Dhcpv6SrvTest, portsRelayedTraffic) {
     NakedDhcpv6Srv srv(0);
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = captureRelayedSolicit();
+    Pkt6Ptr sol = PktCaptures::captureRelayedSolicit();
 
     // Simulate that we have received that traffic
     srv.fakeReceive(sol);
@@ -1495,7 +1496,7 @@ TEST_F(Dhcpv6SrvTest, docsisTraffic) {
     NakedDhcpv6Srv srv(0);
 
     // Let's get a traffic capture from DOCSIS3.0 modem
-    Pkt6Ptr sol = captureDocsisRelayedSolicit();
+    Pkt6Ptr sol = PktCaptures::captureDocsisRelayedSolicit();
 
     // Simulate that we have received that traffic
     srv.fakeReceive(sol);
@@ -1515,7 +1516,7 @@ TEST_F(Dhcpv6SrvTest, docsisTraffic) {
 TEST_F(Dhcpv6SrvTest, docsisVendorOptionsParse) {
 
     // Let's get a traffic capture from DOCSIS3.0 modem
-    Pkt6Ptr sol = captureDocsisRelayedSolicit();
+    Pkt6Ptr sol = PktCaptures::captureDocsisRelayedSolicit();
     EXPECT_NO_THROW(sol->unpack());
 
     // Check if the packet contain
@@ -1550,7 +1551,7 @@ TEST_F(Dhcpv6SrvTest, docsisVendorORO) {
     NakedDhcpv6Srv srv(0);
 
     // Let's get a traffic capture from DOCSIS3.0 modem
-    Pkt6Ptr sol = captureDocsisRelayedSolicit();
+    Pkt6Ptr sol = PktCaptures::captureDocsisRelayedSolicit();
     ASSERT_NO_THROW(sol->unpack());
 
     // Check if the packet contains vendor options option
@@ -1698,13 +1699,13 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsDocsisDefinitions) {
     // This should fail (missing option definition)
     EXPECT_NO_THROW(x = configureDhcp6Server(srv, json_bogus));
     ASSERT_TRUE(x);
-    comment_ = parseAnswer(rcode_, x);
+    comment_ = isc::config::parseAnswer(rcode_, x);
     ASSERT_EQ(1, rcode_);
 
     // This should work (option definition present)
     EXPECT_NO_THROW(x = configureDhcp6Server(srv, json_valid));
     ASSERT_TRUE(x);
-    comment_ = parseAnswer(rcode_, x);
+    comment_ = isc::config::parseAnswer(rcode_, x);
     ASSERT_EQ(0, rcode_);
 }
 
@@ -1789,7 +1790,7 @@ TEST_F(Dhcpv6SrvTest, clientClassification) {
     // Let's create a relayed SOLICIT. This particular relayed SOLICIT has
     // vendor-class set to docsis3.0
     Pkt6Ptr sol1;
-    ASSERT_NO_THROW(sol1 = captureDocsisRelayedSolicit());
+    ASSERT_NO_THROW(sol1 = PktCaptures::captureDocsisRelayedSolicit());
     ASSERT_NO_THROW(sol1->unpack());
 
     srv.classifyPacket(sol1);
@@ -1801,7 +1802,7 @@ TEST_F(Dhcpv6SrvTest, clientClassification) {
     // Let's get a relayed SOLICIT. This particular relayed SOLICIT has
     // vendor-class set to eRouter1.0
     Pkt6Ptr sol2;
-    ASSERT_NO_THROW(sol2 = captureeRouterRelayedSolicit());
+    ASSERT_NO_THROW(sol2 = PktCaptures::captureeRouterRelayedSolicit());
     ASSERT_NO_THROW(sol2->unpack());
 
     srv.classifyPacket(sol2);
@@ -1902,7 +1903,7 @@ TEST_F(Dhcpv6SrvTest, cableLabsShortVendorClass) {
     NakedDhcpv6Srv srv(0);
 
     // Create a simple Solicit with the 4-byte long vendor class option.
-    Pkt6Ptr sol = captureCableLabsShortVendorClass();
+    Pkt6Ptr sol = PktCaptures::captureCableLabsShortVendorClass();
 
     // Simulate that we have received that traffic
     srv.fakeReceive(sol);

+ 2 - 1
src/bin/dhcp6/tests/dhcp6_test_utils.cc

@@ -15,6 +15,7 @@
 #include <gtest/gtest.h>
 #include <dhcp6/tests/dhcp6_test_utils.h>
 #include <dhcp6/json_config_parser.h>
+#include <config/ccsession.h>
 
 using namespace isc::data;
 using namespace isc::dhcp;
@@ -603,7 +604,7 @@ Dhcpv6SrvTest::configure(const std::string& config, NakedDhcpv6Srv& srv) {
     EXPECT_NO_THROW(status = configureDhcp6Server(srv, json));
     ASSERT_TRUE(status);
     int rcode;
-    ConstElementPtr comment = config::parseAnswer(rcode, status);
+    ConstElementPtr comment = isc::config::parseAnswer(rcode, status);
     ASSERT_EQ(0, rcode);
 
     CfgMgr::instance().commit();

+ 0 - 17
src/bin/dhcp6/tests/dhcp6_test_utils.h

@@ -33,7 +33,6 @@
 #include <dhcpsrv/lease_mgr_factory.h>
 #include <dhcp6/dhcp6_srv.h>
 #include <hooks/hooks_manager.h>
-#include <config/ccsession.h>
 
 #include <list>
 
@@ -521,22 +520,6 @@ public:
     testReleaseReject(isc::dhcp::Lease::Type type,
                       const isc::asiolink::IOAddress& addr);
 
-    // see wireshark.cc for descriptions
-    // The descriptions are too large and too closely related to the
-    // code, so it is kept in .cc rather than traditionally in .h
-    isc::dhcp::Pkt6Ptr captureSimpleSolicit();
-    isc::dhcp::Pkt6Ptr captureRelayedSolicit();
-    isc::dhcp::Pkt6Ptr captureDocsisRelayedSolicit();
-    isc::dhcp::Pkt6Ptr captureeRouterRelayedSolicit();
-    isc::dhcp::Pkt6Ptr captureCableLabsShortVendorClass();
-
-    /// @brief Auxiliary method that sets Pkt6 fields
-    ///
-    /// Used to reconstruct captured packets. Sets UDP ports, interface names,
-    /// and other fields to some believable values.
-    /// @param pkt packet that will have its fields set
-    void captureSetDefaultFields(const isc::dhcp::Pkt6Ptr& pkt);
-
     /// A subnet used in most tests
     isc::dhcp::Subnet6Ptr subnet_;
 

+ 17 - 16
src/bin/dhcp6/tests/hooks_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -28,6 +28,8 @@
 #include <hooks/server_hooks.h>
 
 #include <dhcp6/tests/dhcp6_test_utils.h>
+#include <dhcp/tests/pkt_captures.h>
+#include <config/ccsession.h>
 #include <boost/scoped_ptr.hpp>
 #include <gtest/gtest.h>
 #include <unistd.h>
@@ -37,7 +39,6 @@
 
 using namespace isc;
 using namespace isc::data;
-using namespace isc::config;
 using namespace isc::test;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
@@ -524,7 +525,7 @@ TEST_F(HooksDhcpv6SrvTest, simple_buffer6_receive) {
                         "buffer6_receive", buffer6_receive_callout));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -557,7 +558,7 @@ TEST_F(HooksDhcpv6SrvTest, valueChange_buffer6_receive) {
                         "buffer6_receive", buffer6_receive_change_clientid));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -594,7 +595,7 @@ TEST_F(HooksDhcpv6SrvTest, deleteClientId_buffer6_receive) {
                         "buffer6_receive", buffer6_receive_delete_clientid));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -618,7 +619,7 @@ TEST_F(HooksDhcpv6SrvTest, skip_buffer6_receive) {
                         "buffer6_receive", buffer6_receive_skip));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -645,7 +646,7 @@ TEST_F(HooksDhcpv6SrvTest, simple_pkt6_receive) {
                         "pkt6_receive", pkt6_receive_callout));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -678,7 +679,7 @@ TEST_F(HooksDhcpv6SrvTest, valueChange_pkt6_receive) {
                         "pkt6_receive", pkt6_receive_change_clientid));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -714,7 +715,7 @@ TEST_F(HooksDhcpv6SrvTest, deleteClientId_pkt6_receive) {
                         "pkt6_receive", pkt6_receive_delete_clientid));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -738,7 +739,7 @@ TEST_F(HooksDhcpv6SrvTest, skip_pkt6_receive) {
                         "pkt6_receive", pkt6_receive_skip));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -763,7 +764,7 @@ TEST_F(HooksDhcpv6SrvTest, simple_pkt6_send) {
                         "pkt6_send", pkt6_send_callout));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -799,7 +800,7 @@ TEST_F(HooksDhcpv6SrvTest, valueChange_pkt6_send) {
                         "pkt6_send", pkt6_send_change_serverid));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -836,7 +837,7 @@ TEST_F(HooksDhcpv6SrvTest, deleteServerId_pkt6_send) {
                         "pkt6_send", pkt6_send_delete_serverid));
 
     // Let's create a simple SOLICIT
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -867,7 +868,7 @@ TEST_F(HooksDhcpv6SrvTest, skip_pkt6_send) {
                         "pkt6_send", pkt6_send_skip));
 
     // Let's create a simple REQUEST
-    Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
+    Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
 
     // Simulate that we have received that traffic
     srv_->fakeReceive(sol);
@@ -919,7 +920,7 @@ TEST_F(HooksDhcpv6SrvTest, subnet6_select) {
     // Configure the server and make sure the config is accepted
     EXPECT_NO_THROW(status = configureDhcp6Server(*srv_, json));
     ASSERT_TRUE(status);
-    comment_ = parseAnswer(rcode_, status);
+    comment_ = isc::config::parseAnswer(rcode_, status);
     ASSERT_EQ(0, rcode_);
 
     CfgMgr::instance().commit();
@@ -990,7 +991,7 @@ TEST_F(HooksDhcpv6SrvTest, subnet_select_change) {
     // Configure the server and make sure the config is accepted
     EXPECT_NO_THROW(status = configureDhcp6Server(*srv_, json));
     ASSERT_TRUE(status);
-    comment_ = parseAnswer(rcode_, status);
+    comment_ = isc::config::parseAnswer(rcode_, status);
     ASSERT_EQ(0, rcode_);
 
     CfgMgr::instance().commit();

+ 5 - 1
src/lib/dhcp/dhcp4.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2011, 2014 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2011, 2014-2015 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1995-2003 by Internet Software Consortium
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -54,6 +54,10 @@ static const uint16_t BOOTP_BROADCAST = 32768L;
 /* Possible values for hardware type (htype) field... */
 enum HType {
     HTYPE_ETHER = 1,   /* Ethernet 10Mbps */
+    HTYPE_DOCSIS = 1,  /* The traffic captures we have from cable modems as well
+                          as this list by IANA: http://www.iana.org/assignments/
+                          arp-parameters/arp-parameters.xhtml suggest that
+                          Ethernet (1) should be used in DOCSIS environment. */
     HTYPE_IEEE802 = 6, /* IEEE 802.2 Token Ring */
     HTYPE_FDDI = 8     /* FDDI */
     /// TODO Add infiniband here

+ 8 - 1
src/lib/dhcp/docsis3_option_defs.h

@@ -42,9 +42,14 @@ const int DOCSIS3_V4_DEFS_SIZE  = sizeof(DOCSIS3_V4_DEFS) / sizeof(OptionDefPara
 #define DOCSIS3_V6_TFTP_SERVERS 32
 #define DOCSIS3_V6_CONFIG_FILE 33
 #define DOCSIS3_V6_SYSLOG_SERVERS 34
+#define DOCSIS3_V6_DEVICE_ID 36
 #define DOCSIS3_V6_TIME_SERVERS 37
 #define DOCSIS3_V6_TIME_OFFSET 38
 
+// The following DOCSIS3 options are inserted by the CMTS (which acts as
+// a relay agent)
+#define DOCSIS3_V6_CMTS_CM_MAC 1026
+
 /// @brief Definitions of standard DHCPv6 options.
 const OptionDefParams DOCSIS3_V6_DEFS[] = {
     { "oro",            DOCSIS3_V6_ORO, OPT_UINT16_TYPE, true, NO_RECORD_DEF, "" },
@@ -54,7 +59,9 @@ const OptionDefParams DOCSIS3_V6_DEFS[] = {
     { "time-servers",   DOCSIS3_V6_TIME_SERVERS, OPT_IPV6_ADDRESS_TYPE, true, NO_RECORD_DEF, "" },
     { "config-file",    DOCSIS3_V6_CONFIG_FILE, OPT_STRING_TYPE, false, NO_RECORD_DEF, "" },
     { "syslog-servers", DOCSIS3_V6_SYSLOG_SERVERS, OPT_IPV6_ADDRESS_TYPE, true, NO_RECORD_DEF, "" },
-    { "time-offset",    DOCSIS3_V6_TIME_OFFSET, OPT_INT32_TYPE, false, NO_RECORD_DEF, "" }
+    { "device-id",      DOCSIS3_V6_DEVICE_ID, OPT_BINARY_TYPE, false, NO_RECORD_DEF, "" },
+    { "time-offset",    DOCSIS3_V6_TIME_OFFSET, OPT_INT32_TYPE, false, NO_RECORD_DEF, "" },
+    { "cmts-cm-mac",    DOCSIS3_V6_CMTS_CM_MAC, OPT_BINARY_TYPE, false, NO_RECORD_DEF, "" }
     // @todo add definitions for all remaning options.
 };
 

+ 2 - 1
src/lib/dhcp/hwaddr.cc

@@ -35,7 +35,8 @@ const uint32_t HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL = 0x00000004;
 const uint32_t HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION = 0x00000008;
 const uint32_t HWAddr::HWADDR_SOURCE_REMOTE_ID = 0x00000010;
 const uint32_t HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID = 0x00000020;
-const uint32_t HWAddr::HWADDR_SOURCE_DOCSIS = 0x00000040;
+const uint32_t HWAddr::HWADDR_SOURCE_DOCSIS_CMTS = 0x00000040;
+const uint32_t HWAddr::HWADDR_SOURCE_DOCSIS_MODEM = 0x00000080;
 
 HWAddr::HWAddr()
     :htype_(HTYPE_ETHER), source_(0) {

+ 9 - 2
src/lib/dhcp/hwaddr.h

@@ -76,8 +76,15 @@ public:
 
     /// 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;
+    /// This specific option is suboption 1026 in vendor-class option with
+    /// vendor-id=4491. Client in this context would be a cable modem.
+    static const uint32_t HWADDR_SOURCE_DOCSIS_CMTS;
+
+    /// A cable modem (acting as DHCP client) that supports DOCSIS standard
+    /// can insert DOCSIS options that contain client's MAC address.
+    /// This specific option is suboption 36 in vendor-class option with
+    /// vendor-id=4491.
+    static const uint32_t HWADDR_SOURCE_DOCSIS_MODEM;
 
     /// @}
 

+ 24 - 2
src/lib/dhcp/pkt.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -129,6 +129,8 @@ HWAddrPtr
 Pkt::getMAC(uint32_t hw_addr_src) {
     HWAddrPtr mac;
 
+    /// @todo: Implement an array of method pointers instead of set of ifs
+
     // Method 1: from raw sockets.
     if (hw_addr_src & HWAddr::HWADDR_SOURCE_RAW) {
         mac = getRemoteHWAddr();
@@ -182,8 +184,28 @@ Pkt::getMAC(uint32_t hw_addr_src) {
     // Method 6: From subscriber-id option inserted by a relay
 
     // Method 7: From docsis options
+    if (hw_addr_src & HWAddr::HWADDR_SOURCE_DOCSIS_CMTS) {
+        mac = getMACFromDocsisCMTS();
+        if (mac) {
+            return (mac);
+        } else if (hw_addr_src == HWAddr::HWADDR_SOURCE_DOCSIS_CMTS) {
+            // If we're interested only in CMTS options as a source of that
+            // info, there's no point in trying other options.
+            return (HWAddrPtr());
+        }
+    }
 
-    /// @todo: add other MAC acquisition methods here
+    // Method 8: From docsis options
+    if (hw_addr_src & HWAddr::HWADDR_SOURCE_DOCSIS_MODEM) {
+        mac = getMACFromDocsisModem();
+        if (mac) {
+            return (mac);
+        } else if (hw_addr_src == HWAddr::HWADDR_SOURCE_DOCSIS_MODEM) {
+            // If we're interested only in CMTS options as a source of that
+            // info, there's no point in trying other options.
+            return (HWAddrPtr());
+        }
+    }
 
     // Ok, none of the methods were suitable. Return NULL.
     return (HWAddrPtr());

+ 26 - 0
src/lib/dhcp/pkt.h

@@ -523,6 +523,32 @@ protected:
     HWAddrPtr
     getMACFromIPv6(const isc::asiolink::IOAddress& addr);
 
+    /// @brief Attempts to extract MAC/Hardware address from DOCSIS options
+    ///        inserted by the modem itself.
+    ///
+    /// This is a generic mechanism for extracting hardware address from the
+    /// DOCSIS options.
+    ///
+    /// @note This is a pure virtual method and must be implemented in
+    /// the derived classes. The @c Pkt6 class have respective implementation.
+    /// This method is currently not implemented in DHCPv4.
+    ///
+    /// @return hardware address (if necessary DOCSIS suboptions are present)
+    virtual HWAddrPtr getMACFromDocsisModem() = 0;
+
+    /// @brief Attempts to extract MAC/Hardware address from DOCSIS options
+    ///        inserted by the CMTS (the relay agent)
+    ///
+    /// This is a generic mechanism for extracting hardware address from the
+    /// DOCSIS options.
+    ///
+    /// @note This is a pure virtual method and must be implemented in
+    /// the derived classes. The @c Pkt6 class have respective implementation.
+    /// This method is currently not implemented in DHCPv4.
+    ///
+    /// @return hardware address (if necessary DOCSIS suboptions are present)
+    virtual HWAddrPtr getMACFromDocsisCMTS() = 0;
+
     /// Transaction-id (32 bits for v4, 24 bits for v6)
     uint32_t transid_;
 

+ 22 - 0
src/lib/dhcp/pkt4.h

@@ -416,6 +416,17 @@ protected:
 
     /// @brief No-op
     ///
+    /// This is a DHCPv4 version of the function that attempts to extract
+    /// MAC address from the options inserted by a cable modem. It is currently
+    /// not implemented for v4.
+    ///
+    /// @return always NULL
+    virtual HWAddrPtr getMACFromDocsisModem() {
+        return (HWAddrPtr());
+    }
+
+    /// @brief No-op
+    ///
     /// This method returns hardware address extracted from DUID.
     /// Currently it is a no-op, even though there's RFC that defines how to
     /// use DUID in DHCPv4 (see RFC4361). We may implement it one day.
@@ -425,6 +436,17 @@ protected:
         return (HWAddrPtr());
     }
 
+    /// @brief No-op
+    ///
+    /// This is a DHCPv4 version of the function that attempts to extract
+    /// MAC address from the options inserted by a CMTS. It is currently
+    /// not implemented for v4.
+    ///
+    /// @return always NULL
+    virtual HWAddrPtr getMACFromDocsisCMTS() {
+        return (HWAddrPtr());
+    }
+
     /// local HW address (dst if receiving packet, src if sending packet)
     HWAddrPtr local_hwaddr_;
 

+ 59 - 2
src/lib/dhcp/pkt6.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,10 @@
 #include <dhcp/dhcp6.h>
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option.h>
+#include <dhcp/option_vendor_class.h>
+#include <dhcp/option_vendor.h>
 #include <dhcp/pkt6.h>
+#include <dhcp/docsis3_option_defs.h>
 #include <util/io_utilities.h>
 #include <exceptions/exceptions.h>
 #include <dhcp/duid.h>
@@ -620,8 +623,62 @@ Pkt6::getMACFromIPv6RelayOpt() {
         // +2, -2 means to skip the initial 2 bytes which are hwaddress type
         return (HWAddrPtr(new HWAddr(&data[0] + 2, data.size() - 2,
                                      opt->getUint16())));
+    } else {
+        return (HWAddrPtr());
+    }
+}
+
+HWAddrPtr
+Pkt6::getMACFromDocsisModem() {
+    OptionVendorPtr vendor = boost::dynamic_pointer_cast<
+        OptionVendor>(getOption(D6O_VENDOR_OPTS));
+
+    // Check if this is indeed DOCSIS3 environment
+    if (!vendor || vendor->getVendorId() != VENDOR_ID_CABLE_LABS) {
+        return (HWAddrPtr());
+    }
+
+    // If it is, try to get device-id option
+    OptionPtr device_id = vendor->getOption(DOCSIS3_V6_DEVICE_ID);
+    if (!device_id) {
+        return (HWAddrPtr());
+    }
+
+    // If the option contains any data, use it as MAC address
+    if (!device_id->getData().empty()) {
+        return (HWAddrPtr(new HWAddr(device_id->getData(), HTYPE_DOCSIS)));
+    } else {
+        return (HWAddrPtr());
     }
-    else {
+}
+
+HWAddrPtr
+Pkt6::getMACFromDocsisCMTS() {
+    if (relay_info_.empty()) {
+        // This message didn't pass through a CMTS, so there won't be any
+        // CMTS-specific options in it.
+        return (HWAddrPtr());
+    }
+
+    OptionVendorPtr vendor = boost::dynamic_pointer_cast<
+        OptionVendor>(getAnyRelayOption(D6O_VENDOR_OPTS,
+                                        RELAY_SEARCH_FROM_CLIENT));
+
+    // Check if this is indeed DOCSIS3 environment
+    if (!vendor || vendor->getVendorId() != VENDOR_ID_CABLE_LABS) {
+        return (HWAddrPtr());
+    }
+
+    // If it is, try to get cable modem mac
+    OptionPtr cm_mac = vendor->getOption(DOCSIS3_V6_CMTS_CM_MAC);
+    if (!cm_mac) {
+        return (HWAddrPtr());
+    }
+
+    // If the option contains any data, use it as MAC address
+    if (!cm_mac->getData().empty()) {
+        return (HWAddrPtr(new HWAddr(cm_mac->getData(), HTYPE_DOCSIS)));
+    } else {
         return (HWAddrPtr());
     }
 }

+ 34 - 1
src/lib/dhcp/pkt6.h

@@ -305,9 +305,42 @@ protected:
     /// @return Hardware address (or NULL)
     virtual HWAddrPtr getMACFromIPv6RelayOpt();
 
+    /// @brief Extract MAC/Hardware address from client-id.
+    ///
+    /// This method attempts to extract MAC/Hardware address from DUID sent
+    /// as client-id. This method may fail, as only DUID-LLT and DUID-LL are
+    /// based on link-layer addresses. Client may use other valid DUID types
+    /// and this method will fail.
+    ///
+    /// @return Hardware address (or NULL)
     virtual HWAddrPtr getMACFromDUID();
 
-    HWAddrPtr hwaddr_;
+    /// @brief Attempts to extract MAC/Hardware address from DOCSIS options
+    ///        inserted by the modem itself.
+    ///
+    /// The mechanism extracts that information from DOCSIS option
+    /// (vendor-specific info, vendor-id=4491, suboption 36). Note that
+    /// in a DOCSIS capable network, the MAC address information is provided
+    /// several times. The first is specified by the modem itself. The second
+    /// is added by the CMTS, which acts as a relay agent. This method
+    /// attempts to extract the former. See @ref getMACFromDocsisCMTS
+    /// for a similar method that extracts from the CMTS (relay) options.
+    ///
+    /// @return hardware address (if DOCSIS suboption 36 is present)
+    virtual HWAddrPtr getMACFromDocsisModem();
+
+    /// @brief Attempts to extract MAC/Hardware address from DOCSIS options.
+    ///
+    /// The DHCPv6 mechanism extracts that information from DOCSIS option
+    /// (vendor-specific info, vendor-id=4491, suboption 1026). Note that
+    /// in a DOCSIS capable network, the MAC address information is provided
+    /// several times. The first is specified by the modem itself. The second
+    /// is added by the CMTS, which acts as a relay agent. This method
+    /// attempts to extract the latter. See @ref getMACFromDocsisModem
+    /// for a similar method that extracts from the modem (client) options.
+    ///
+    /// @return hardware address (if DOCSIS suboption 1026 is present)
+    virtual HWAddrPtr getMACFromDocsisCMTS();
 
     /// @brief Builds on wire packet for TCP transmission.
     ///

+ 2 - 0
src/lib/dhcp/tests/Makefile.am

@@ -37,6 +37,7 @@ noinst_LTLIBRARIES = libdhcptest.la
 libdhcptest_la_SOURCES  = iface_mgr_test_config.cc iface_mgr_test_config.h
 libdhcptest_la_SOURCES  += pkt_filter_test_stub.cc pkt_filter_test_stub.h
 libdhcptest_la_SOURCES  += pkt_filter6_test_stub.cc pkt_filter6_test_stub.h
+libdhcptest_la_SOURCES  += pkt_captures4.cc pkt_captures6.cc pkt_captures.h
 libdhcptest_la_CXXFLAGS  = $(AM_CXXFLAGS)
 libdhcptest_la_CPPFLAGS  = $(AM_CPPFLAGS)
 libdhcptest_la_LDFLAGS   = $(AM_LDFLAGS)
@@ -68,6 +69,7 @@ libdhcp___unittests_SOURCES += option_space_unittest.cc
 libdhcp___unittests_SOURCES += option_string_unittest.cc
 libdhcp___unittests_SOURCES += option_vendor_unittest.cc
 libdhcp___unittests_SOURCES += option_vendor_class_unittest.cc
+libdhcp___unittests_SOURCES  += pkt_captures4.cc pkt_captures6.cc pkt_captures.h
 libdhcp___unittests_SOURCES += pkt4_unittest.cc
 libdhcp___unittests_SOURCES += pkt6_unittest.cc
 libdhcp___unittests_SOURCES += pkt_filter_unittest.cc

+ 59 - 0
src/lib/dhcp/tests/pkt6_unittest.cc

@@ -21,10 +21,12 @@
 #include <dhcp/option6_ia.h>
 #include <dhcp/option_int.h>
 #include <dhcp/option_int_array.h>
+#include <dhcp/option_vendor.h>
 #include <dhcp/iface_mgr.h>
 #include <dhcp/pkt6.h>
 #include <dhcp/hwaddr.h>
 #include <dhcp/docsis3_option_defs.h>
+#include <dhcp/tests/pkt_captures.h>
 #include <util/range_utilities.h>
 
 #include <boost/bind.hpp>
@@ -1183,4 +1185,61 @@ TEST_F(Pkt6Test, getMACFromDUID) {
     EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_DUID));
 }
 
+// Test checks whether getMAC(DOCSIS_MODEM) is working properly.
+// We only have a small number of actual traffic captures from
+// cable networks, so the scope of unit-tests is somewhat limited.
+TEST_F(Pkt6Test, getMAC_DOCSIS_Modem) {
+
+    // Let's use a captured traffic. The one we have comes from a
+    // modem with MAC address 10:0d:7f:00:07:88.
+    Pkt6Ptr pkt = isc::test::PktCaptures::captureDocsisRelayedSolicit();
+    ASSERT_NO_THROW(pkt->unpack());
+
+    // The method should return MAC based on the vendor-specific info,
+    // suboption 36, which is inserted by the modem itself.
+    HWAddrPtr found = pkt->getMAC(HWAddr::HWADDR_SOURCE_DOCSIS_MODEM);
+    ASSERT_TRUE(found);
+
+    // Let's check the info.
+    EXPECT_EQ("hwtype=1 10:0d:7f:00:07:88", found->toText(true));
+
+    // Now let's remove the option
+    OptionVendorPtr vendor = boost::dynamic_pointer_cast<
+        OptionVendor>(pkt->getOption(D6O_VENDOR_OPTS));
+    ASSERT_TRUE(vendor);
+    ASSERT_TRUE(vendor->delOption(DOCSIS3_V6_DEVICE_ID));
+
+    // Ok, there's no more suboption 36. Now getMAC() should fail.
+    EXPECT_FALSE(pkt->getMAC(HWAddr::HWADDR_SOURCE_DOCSIS_MODEM));
+}
+
+// Test checks whether getMAC(DOCSIS_CMTS) is working properly.
+// We only have a small number of actual traffic captures from
+// cable networks, so the scope of unit-tests is somewhat limited.
+TEST_F(Pkt6Test, getMAC_DOCSIS_CMTS) {
+
+    // Let's use a captured traffic. The one we have comes from a
+    // modem with MAC address 20:e5:2a:b8:15:14.
+    Pkt6Ptr pkt = isc::test::PktCaptures::captureeRouterRelayedSolicit();
+    ASSERT_NO_THROW(pkt->unpack());
+
+    // The method should return MAC based on the vendor-specific info,
+    // suboption 36, which is inserted by the modem itself.
+    HWAddrPtr found = pkt->getMAC(HWAddr::HWADDR_SOURCE_DOCSIS_CMTS);
+    ASSERT_TRUE(found);
+
+    // Let's check the info.
+    EXPECT_EQ("hwtype=1 20:e5:2a:b8:15:14", found->toText(true));
+
+    // Now let's remove the suboption 1026 that is inserted by the
+    // relay.
+    OptionVendorPtr vendor = boost::dynamic_pointer_cast<
+        OptionVendor>(pkt->getAnyRelayOption(D6O_VENDOR_OPTS,
+                          isc::dhcp::Pkt6::RELAY_SEARCH_FROM_CLIENT));
+    ASSERT_TRUE(vendor);
+    EXPECT_TRUE(vendor->delOption(DOCSIS3_V6_CMTS_CM_MAC));
+
+    EXPECT_FALSE(pkt->getMAC(HWAddr::HWADDR_SOURCE_DOCSIS_CMTS));
+}
+
 }

+ 72 - 0
src/lib/dhcp/tests/pkt_captures.h

@@ -0,0 +1,72 @@
+// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <dhcp/pkt4.h>
+#include <dhcp/pkt6.h>
+
+namespace isc {
+namespace test {
+
+class PktCaptures {
+public:
+
+    /// @brief returns captured DISCOVER that went through a relay
+    ///
+    /// See method code for a detailed explanation. This is a discover from
+    /// docsis3.0 device (Cable Modem)
+    ///
+    /// @return relayed DISCOVER
+    static isc::dhcp::Pkt4Ptr captureRelayedDiscover();
+
+    /// @brief returns captured DISCOVER that went through a relay
+    ///
+    /// See method code for a detailed explanation. This is a discover from
+    /// eRouter1.0 device (CPE device integrated with cable modem)
+    ///
+    /// @return relayed DISCOVER
+    static isc::dhcp::Pkt4Ptr captureRelayedDiscover2();
+
+    // see pkt_captures6.cc for descriptions
+    // The descriptions are too large and too closely related to the
+    // code, so it is kept in .cc rather than traditionally in .h
+    static isc::dhcp::Pkt6Ptr captureSimpleSolicit();
+    static isc::dhcp::Pkt6Ptr captureRelayedSolicit();
+    static isc::dhcp::Pkt6Ptr captureDocsisRelayedSolicit();
+    static isc::dhcp::Pkt6Ptr captureeRouterRelayedSolicit();
+    static isc::dhcp::Pkt6Ptr captureCableLabsShortVendorClass();
+
+protected:
+    /// @brief Auxiliary method that sets Pkt6 fields
+    ///
+    /// Used to reconstruct captured packets. Sets UDP ports, interface names,
+    /// and other fields to some believable values.
+    /// @param pkt packet that will have its fields set
+    static void captureSetDefaultFields(const isc::dhcp::Pkt6Ptr& pkt);
+
+
+    /// @brief generates a DHCPv4 packet based on provided hex string
+    ///
+    /// @return created packet
+    static isc::dhcp::Pkt4Ptr packetFromCapture(const std::string& hex_string);
+
+    /// @brief sets default fields in a captured packet
+    ///
+    /// Sets UDP ports, addresses and interface.
+    ///
+    /// @param pkt packet to have default fields set
+    static void captureSetDefaultFields(const isc::dhcp::Pkt4Ptr& pkt);
+};
+
+};
+};

+ 8 - 9
src/bin/dhcp4/tests/wireshark.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2015  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <config.h>
-#include <dhcp4/tests/dhcp4_test_utils.h>
+#include <dhcp/tests/pkt_captures.h>
 #include <string>
 #include <asiolink/io_address.h>
 #include <util/encode/hex.h>
@@ -41,13 +41,13 @@
 ///    contain whatever expansion level you have in the graphical tree.)
 
 using namespace std;
+using namespace isc::dhcp;
 using namespace isc::asiolink;
 
 namespace isc {
-namespace dhcp {
 namespace test {
 
-Pkt4Ptr Dhcpv4SrvTest::packetFromCapture(const std::string& hex_string) {
+Pkt4Ptr PktCaptures::packetFromCapture(const std::string& hex_string) {
     std::vector<uint8_t> bin;
 
     // Decode the hex string and store it in bin (which happens
@@ -60,7 +60,7 @@ Pkt4Ptr Dhcpv4SrvTest::packetFromCapture(const std::string& hex_string) {
     return (pkt);
 }
 
-void Dhcpv4SrvTest::captureSetDefaultFields(const Pkt4Ptr& pkt) {
+void PktCaptures::captureSetDefaultFields(const Pkt4Ptr& pkt) {
     pkt->setRemotePort(546);
     pkt->setRemoteAddr(IOAddress("fe80::1"));
     pkt->setLocalPort(0);
@@ -69,7 +69,7 @@ void Dhcpv4SrvTest::captureSetDefaultFields(const Pkt4Ptr& pkt) {
     pkt->setIface("eth0");
 }
 
-Pkt4Ptr Dhcpv4SrvTest::captureRelayedDiscover() {
+Pkt4Ptr PktCaptures::captureRelayedDiscover() {
 
 /* This is packet 1 from capture
    dhcp-val/pcap/docsis-*-CG3000DCR-Registration-Filtered.cap
@@ -132,7 +132,7 @@ Bootstrap Protocol
     return (packetFromCapture(hex_string));
 }
 
-Pkt4Ptr Dhcpv4SrvTest::captureRelayedDiscover2() {
+Pkt4Ptr PktCaptures::captureRelayedDiscover2() {
 
 /* This is packet 5 from capture
    dhcp-val/pcap/docsis-*-CG3000DCR-Registration-Filtered.cap
@@ -185,6 +185,5 @@ Bootstrap Protocol
     return (packetFromCapture(hex_string));
 }
 
-}; // end of isc::dhcp::test namespace
-}; // end of isc::dhcp namespace
+}; // end of isc::test namespace
 }; // end of isc namespace

+ 12 - 9
src/bin/dhcp6/tests/wireshark.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -13,10 +13,12 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <config.h>
-#include <dhcp6/tests/dhcp6_test_utils.h>
+#include <dhcp/pkt6.h>
+#include <util/encode/hex.h>
+#include <dhcp/tests/pkt_captures.h>
 #include <string>
 
-/// @file   wireshark.cc
+/// @file   pkt_captures6.cc
 ///
 /// @brief  contains packet captures imported from Wireshark
 ///
@@ -45,7 +47,7 @@ using namespace std;
 namespace isc {
 namespace test {
 
-void Dhcpv6SrvTest::captureSetDefaultFields(const Pkt6Ptr& pkt) {
+void PktCaptures::captureSetDefaultFields(const Pkt6Ptr& pkt) {
     pkt->setRemotePort(546);
     pkt->setRemoteAddr(IOAddress("fe80::1"));
     pkt->setLocalPort(0);
@@ -55,7 +57,7 @@ void Dhcpv6SrvTest::captureSetDefaultFields(const Pkt6Ptr& pkt) {
 }
 
 // This function returns buffer for very simple Solicit
-Pkt6Ptr Dhcpv6SrvTest::captureSimpleSolicit() {
+Pkt6Ptr PktCaptures::captureSimpleSolicit() {
     uint8_t data[] = {
         1,  // type 1 = SOLICIT
         0xca, 0xfe, 0x01, // trans-id = 0xcafe01
@@ -75,7 +77,7 @@ Pkt6Ptr Dhcpv6SrvTest::captureSimpleSolicit() {
     return (pkt);
 }
 
-Pkt6Ptr Dhcpv6SrvTest::captureRelayedSolicit() {
+Pkt6Ptr PktCaptures::captureRelayedSolicit() {
 
     // This is a very simple relayed SOLICIT message:
     // RELAY-FORW
@@ -105,7 +107,7 @@ Pkt6Ptr Dhcpv6SrvTest::captureRelayedSolicit() {
 }
 
 /// returns a buffer with relayed SOLICIT (from DOCSIS3.0 cable modem)
-Pkt6Ptr isc::test::Dhcpv6SrvTest::captureDocsisRelayedSolicit() {
+Pkt6Ptr isc::test::PktCaptures::captureDocsisRelayedSolicit() {
 
     // This is an actual DOCSIS packet
     // RELAY-FORW (12)
@@ -115,6 +117,7 @@ Pkt6Ptr isc::test::Dhcpv6SrvTest::captureDocsisRelayedSolicit() {
     //      - IA_NA (iaid=7f000788, t2=0, t2=0)
     //        - IAAddress (::, pref=0,valid=0)
     //      - rapid-commit
+    //      - elapsed
     //      - ORO
     //      - Reconfigure-accept
     //      - Vendor-Class ("docsis3.0")
@@ -166,7 +169,7 @@ Pkt6Ptr isc::test::Dhcpv6SrvTest::captureDocsisRelayedSolicit() {
 }
 
 /// returns a buffer with relayed SOLICIT (from DOCSIS3.0 eRouter)
-Pkt6Ptr isc::test::Dhcpv6SrvTest::captureeRouterRelayedSolicit() {
+Pkt6Ptr isc::test::PktCaptures::captureeRouterRelayedSolicit() {
 
 /* Packet description exported from wireshark:
 DHCPv6
@@ -301,7 +304,7 @@ DHCPv6
     return (pkt);
 }
 
-Pkt6Ptr isc::test::Dhcpv6SrvTest::captureCableLabsShortVendorClass() {
+Pkt6Ptr isc::test::PktCaptures::captureCableLabsShortVendorClass() {
     // This is a simple non-relayed Solicit:
     // - client-identifier
     // - IA_NA

+ 2 - 1
src/lib/dhcpsrv/cfg_mac_source.cc

@@ -42,7 +42,8 @@ uint32_t CfgMACSource::MACSourceFromText(const std::string& name) {
         { "rfc4649", HWAddr::HWADDR_SOURCE_REMOTE_ID },
         { "subscriber-id", HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID },
         { "rfc4580", HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID },
-        { "docsis", HWAddr::HWADDR_SOURCE_DOCSIS }
+        { "docsis-cmts", HWAddr::HWADDR_SOURCE_DOCSIS_CMTS },
+        { "docsis-modem", HWAddr::HWADDR_SOURCE_DOCSIS_MODEM }
     };
 
     for (int i=0; i < sizeof(sources)/sizeof(sources[0]); ++i) {

+ 4 - 3
src/lib/dhcpsrv/tests/cfg_mac_source_unittest.cc

@@ -46,9 +46,10 @@ TEST(CfgMACSourceTest, MACSourceFromText) {
               CfgMACSource::MACSourceFromText("subscriber-id"));
     EXPECT_EQ(HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID,
               CfgMACSource::MACSourceFromText("rfc4580"));
-    EXPECT_EQ(HWAddr::HWADDR_SOURCE_DOCSIS,
-              CfgMACSource::MACSourceFromText("docsis"));
-
+    EXPECT_EQ(HWAddr::HWADDR_SOURCE_DOCSIS_CMTS,
+              CfgMACSource::MACSourceFromText("docsis-cmts"));
+    EXPECT_EQ(HWAddr::HWADDR_SOURCE_DOCSIS_MODEM,
+              CfgMACSource::MACSourceFromText("docsis-modem"));
 }
 
 };