From: Tomek Mrugalski Date: Tue, 31 Dec 2013 14:09:57 +0000 (+0100) Subject: [3203] v6 vendor class is not intepreted as client class. X-Git-Tag: bind10-1.2.0beta1-release~130^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=71965bcfe5ce73408bddcef2b29e8ea9b459e5b5;p=thirdparty%2Fkea.git [3203] v6 vendor class is not intepreted as client class. --- diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes index 9678b4f2b7..e8e3895181 100644 --- a/src/bin/dhcp6/dhcp6_messages.mes +++ b/src/bin/dhcp6/dhcp6_messages.mes @@ -27,6 +27,10 @@ successfully established a session with the BIND 10 control channel. This debug message is issued just before the IPv6 DHCP server attempts to establish a session with the BIND 10 control channel. +% DHCP6_CLASS_ASSIGNED client packet has been assigned to the following class(es): %1 +This debug message informs that incoming packet has been assigned to specified +class or classes. This is a norma + % DHCP6_CLIENTID_MISSING mandatory client-id option is missing, message from %1 dropped This error message indicates that the received message is being dropped because it does not include the mandatory client-id option necessary for diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 506eefde82..d659c432f1 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -310,6 +310,9 @@ bool Dhcpv6Srv::run() { callout_handle->getArgument("query6", query); } + // Assign this packet to a class, if possible + classifyPacket(query); + try { NameChangeRequestPtr ncr; switch (query->getType()) { @@ -2409,6 +2412,37 @@ Dhcpv6Srv::unpackOptions(const OptionBuffer& buf, return (offset); } +void Dhcpv6Srv::classifyPacket(const Pkt6Ptr& pkt) { + + boost::shared_ptr vclass = + boost::dynamic_pointer_cast(pkt->getOption(D6O_VENDOR_CLASS)); + + if (!vclass) { + return; + } + + string classes = ""; + + // DOCSIS specific section + if (vclass->readString(2).find("docsis3.0") != std::string::npos) { + pkt->addClass("docsis3.0"); + classes += "docsis3.0 "; + } else + if (vclass->readString(2).find("eRouter1.0") != std::string::npos) { + pkt->addClass("eRouter1.0"); + classes += "eRouter1.0 "; + }else + { + // Otherwise use the string as is + classes += vclass->readString(2); + pkt->addClass(vclass->readString(2)); + } + + if (!classes.empty()) { + LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASS_ASSIGNED) + .arg(classes); + } +} }; }; diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h index 20b6ea1d06..7e68a97fc5 100644 --- a/src/bin/dhcp6/dhcp6_srv.h +++ b/src/bin/dhcp6/dhcp6_srv.h @@ -533,6 +533,16 @@ protected: size_t* relay_msg_offset, size_t* relay_msg_len); + /// @brief Assigns incoming packet to zero or more classes. + /// + /// @note For now, the client classification is very simple. It just uses + /// content of the vendor-class-identifier option as a class. The resulting + /// class will be stored in packet (see @ref isc::dhcp::Pkt6::classes_ and + /// @ref isc::dhcp::Pkt6::inClass). + /// + /// @param pkt packet to be classified + void classifyPacket(const Pkt6Ptr& pkt); + private: /// @brief Allocation Engine. /// Pointer to the allocation engine that we are currently using diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 393d466ce3..d08f2fe9d5 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -1673,6 +1673,35 @@ TEST_F(Dhcpv6SrvTest, unpackOptions) { EXPECT_EQ(0x0, option_bar->getValue()); } +// Checks if client packets are classified properly +TEST_F(Dhcpv6SrvTest, clientClassification) { + + NakedDhcpv6Srv srv(0); + + // 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->unpack()); + + srv.classifyPacket(sol1); + + // It should belong to docsis3.0 class. It should not belong to eRouter1.0 + EXPECT_TRUE(sol1->inClass("docsis3.0")); + EXPECT_FALSE(sol1->inClass("eRouter1.0")); + + // 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->unpack()); + + srv.classifyPacket(sol2); + + EXPECT_TRUE(sol2->inClass("eRouter1.0")); + EXPECT_FALSE(sol2->inClass("docsis3.0")); +} + /// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test /// to call processX() methods. diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index 2b6241ec08..82ff9847b8 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -112,6 +112,7 @@ public: using Dhcpv6Srv::createStatusCode; using Dhcpv6Srv::selectSubnet; using Dhcpv6Srv::sanityCheck; + using Dhcpv6Srv::classifyPacket; using Dhcpv6Srv::loadServerID; using Dhcpv6Srv::writeServerID; using Dhcpv6Srv::unpackOptions; @@ -477,6 +478,7 @@ public: Pkt6Ptr captureSimpleSolicit(); Pkt6Ptr captureRelayedSolicit(); Pkt6Ptr captureDocsisRelayedSolicit(); + Pkt6Ptr captureeRouterRelayedSolicit(); /// @brief Auxiliary method that sets Pkt6 fields /// diff --git a/src/bin/dhcp6/tests/wireshark.cc b/src/bin/dhcp6/tests/wireshark.cc index 4e96548129..cd2909673e 100644 --- a/src/bin/dhcp6/tests/wireshark.cc +++ b/src/bin/dhcp6/tests/wireshark.cc @@ -17,9 +17,9 @@ #include /// @file wireshark.cc -/// +/// /// @brief contains packet captures imported from Wireshark -/// +/// /// These are actual packets captured over wire. They are used in various /// tests. /// @@ -33,6 +33,10 @@ /// 6. Coding guidelines line restrictions apply, so wrap your code as necessary /// 7. Make sure you decribe the capture appropriately /// 8. Follow whatever rest of the methods are doing (set ports, ifaces etc.) +/// 9. To easily copy packet description, click File... -> Extract packet +/// dissections -> as plain text file... +/// (Make sure that the packet is expanded in the view. The text file will +/// contain whatever expansion level you have in the graphical tree.) using namespace std; @@ -81,7 +85,7 @@ Pkt6Ptr Dhcpv6SrvTest::captureRelayedSolicit() { // - ORO (7) // string exported from Wireshark - string hex_string = + string hex_string = "0c0500000000000000000000000000000000fc00000000000000000000000000000900" "12000231350009002c010517100001000e0001000151b5e46208002758f1e80003000c" "000000010000000000000000000600020007"; @@ -102,7 +106,7 @@ Pkt6Ptr Dhcpv6SrvTest::captureRelayedSolicit() { Pkt6Ptr isc::test::Dhcpv6SrvTest::captureDocsisRelayedSolicit() { // This is an actual DOCSIS packet - // RELAY-FORW (12) + // RELAY-FORW (12) // - Relay Message // - SOLICIT (1) // - client-id @@ -132,7 +136,7 @@ Pkt6Ptr isc::test::Dhcpv6SrvTest::captureDocsisRelayedSolicit() { // - Suboption 1026: Cable Modem MAC addr = 10:0d:7f:00:07:88 // string exported from Wireshark - string hex_string = + string hex_string = "0c002a0288fe00fe00015a8d09fffe7af955fe80000000000000120d7ffffe00078800" "090189010d397f0001000a00030001100d7f000788000300287f000788000000000000" "000000050018000000000000000000000000000000000000000000000000000e000000" @@ -159,5 +163,141 @@ Pkt6Ptr isc::test::Dhcpv6SrvTest::captureDocsisRelayedSolicit() { return (pkt); } +/// returns a buffer with relayed SOLICIT (from DOCSIS3.0 eRouter) +Pkt6Ptr isc::test::Dhcpv6SrvTest::captureeRouterRelayedSolicit() { + +/* Packet description exported from wireshark: +DHCPv6 + Message type: Relay-forw (12) + Hopcount: 0 + Link address: 2001:558:ffa8::1 (2001:558:ffa8::1) + Peer address: fe80::22e5:2aff:feb8:1515 (fe80::22e5:2aff:feb8:1515) + Relay Message + Option: Relay Message (9) + Length: 241 + Value: 01a90044000e000000140000000600080011001700180019... + DHCPv6 + Message type: Solicit (1) + Transaction ID: 0xa90044 + Rapid Commit + Option: Rapid Commit (14) + Length: 0 + Reconfigure Accept + Option: Reconfigure Accept (20) + Length: 0 + Option Request + Option: Option Request (6) + Length: 8 + Value: 0011001700180019 + Requested Option code: Vendor-specific Information (17) + Requested Option code: DNS recursive name server (23) + Requested Option code: Domain Search List (24) + Requested Option code: Identity Association for Prefix Delegation (25) + Vendor Class + Option: Vendor Class (16) + Length: 16 + Value: 0000118b000a65526f75746572312e30 + Enterprise ID: Cable Television Laboratories, Inc. (4491) + vendor-class-data: eRouter1.0 + Vendor-specific Information + Option: Vendor-specific Information (17) + Length: 112 + Value: 0000118b0002000745524f555445520003000b45434d3a45... + Enterprise ID: Cable Television Laboratories, Inc. (4491) + Suboption: Device Type = (2)"EROUTER" + Suboption: Embedded Components = (3)"ECM:EROUTER" + Suboption: Serial Number = (4)"2BR229U40044C" + Suboption: Hardware Version = (5)"1.04" + Suboption: Software Version = (6)"V1.33.03" + Suboption: Boot ROM Version = (7)"2.3.0R2" + Suboption: Organization Unique Identifier = (8)"00095B" + Suboption: Model Number = (9)"CG3000DCR" + Suboption: Vendor Name = (10)"Netgear" + Client Identifier + Option: Client Identifier (1) + Length: 10 + Value: 0003000120e52ab81515 + DUID: 0003000120e52ab81515 + DUID Type: link-layer address (3) + Hardware type: Ethernet (1) + Link-layer address: 20:e5:2a:b8:15:15 + Identity Association for Prefix Delegation + Option: Identity Association for Prefix Delegation (25) + Length: 41 + Value: 2ab815150000000000000000001a00190000000000000000... + IAID: 2ab81515 + T1: 0 + T2: 0 + IA Prefix + Option: IA Prefix (26) + Length: 25 + Value: 000000000000000038000000000000000000000000000000... + Preferred lifetime: 0 + Valid lifetime: 0 + Prefix length: 56 + Prefix address: :: (::) + Identity Association for Non-temporary Address + Option: Identity Association for Non-temporary Address (3) + Length: 12 + Value: 2ab815150000000000000000 + IAID: 2ab81515 + T1: 0 + T2: 0 + Elapsed time + Option: Elapsed time (8) + Length: 2 + Value: 0000 + Elapsed time: 0 ms + Vendor-specific Information + Option: Vendor-specific Information (17) + Length: 22 + Value: 0000118b0402000620e52ab815140401000401020300 + Enterprise ID: Cable Television Laboratories, Inc. (4491) + Suboption: CM MAC Address Option = (1026)20:e5:2a:b8:15:14 + Suboption: CMTS Capabilities Option : (1025) + Interface-Id + Option: Interface-Id (18) + Length: 4 + Value: 00000022 + Interface-ID: + Remote Identifier + Option: Remote Identifier (37) + Length: 14 + Value: 0000101300015c228d4110000122 + Enterprise ID: Arris Interactive LLC (4115) + Remote-ID: 00015c228d4110000122 + DHCP option 53 + Option: Unknown (53) + Length: 10 + Value: 0003000100015c228d3d + DUID: 0003000100015c228d3d + DUID Type: link-layer address (3) + Hardware type: Ethernet (1) + Link-layer address: 00:01:5c:22:8d:3d */ + + // string exported from Wireshark + string hex_string = + "0c0020010558ffa800000000000000000001fe8000000000000022e52afffeb8151500" + "0900f101a90044000e000000140000000600080011001700180019001000100000118b" + "000a65526f75746572312e30001100700000118b0002000745524f555445520003000b" + "45434d3a45524f555445520004000d3242523232395534303034344300050004312e30" + "340006000856312e33332e303300070007322e332e3052320008000630303039354200" + "090009434733303030444352000a00074e6574676561720001000a0003000120e52ab8" + "1515001900292ab815150000000000000000001a001900000000000000003800000000" + "0000000000000000000000000003000c2ab81515000000000000000000080002000000" + "1100160000118b0402000620e52ab81514040100040102030000120004000000220025" + "000e0000101300015c228d41100001220035000a0003000100015c228d3d"; + + std::vector bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); + captureSetDefaultFields(pkt); + return (pkt); +} + }; // end of isc::test namespace }; // end of isc namespace