summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrei Pavel <andrei@isc.org>2021-05-18 16:24:39 +0200
committerAndrei Pavel <andrei@isc.org>2021-06-25 15:24:35 +0200
commit2a92725a1a531c5587cc5b98bd10cb19a98d6abc (patch)
treead0220e79157db2c8743e7cf0a2f4d0ad3852060 /src
parent[#1894] limit docsis oro lookup to cable labs 4491 (diff)
downloadkea-2a92725a1a531c5587cc5b98bd10cb19a98d6abc.tar.xz
kea-2a92725a1a531c5587cc5b98bd10cb19a98d6abc.zip
[#1894] negative test for cable labs vendor ID
Diffstat (limited to 'src')
-rw-r--r--src/bin/dhcp4/tests/vendor_opts_unittest.cc196
-rw-r--r--src/bin/dhcp6/tests/vendor_opts_unittest.cc211
2 files changed, 229 insertions, 178 deletions
diff --git a/src/bin/dhcp4/tests/vendor_opts_unittest.cc b/src/bin/dhcp4/tests/vendor_opts_unittest.cc
index 1230f4cb3c..55fde87672 100644
--- a/src/bin/dhcp4/tests/vendor_opts_unittest.cc
+++ b/src/bin/dhcp4/tests/vendor_opts_unittest.cc
@@ -48,7 +48,110 @@ using namespace isc::dhcp::test;
/// groups all vendor related tests under a single name. There were too many
/// tests in Dhcpv4SrvTest class anyway.
class VendorOptsTest : public Dhcpv4SrvTest {
-
+public:
+ void testVendorOptionsORO(int vendor_id) {
+ IfaceMgrTestConfig test_config(true);
+ IfaceMgr::instance().openSockets4();
+
+ NakedDhcpv4Srv srv(0);
+
+ string config = R"(
+ {
+ "interfaces-config": {
+ "interfaces": [ "*" ]
+ },
+ "option-data": [
+ {
+ "code": 2,
+ "csv-format": true,
+ "data": "192.0.2.1, 192.0.2.2",
+ "name": "tftp-servers",
+ "space": "vendor-4491"
+ }
+ ],
+ "subnet4": [
+ {
+ "interface": "eth0",
+ "pools": [
+ {
+ "pool": "192.0.2.0/25"
+ }
+ ],
+ "subnet": "192.0.2.0/24"
+ }
+ ]
+ }
+ )";
+
+ ConstElementPtr json;
+ ASSERT_NO_THROW(json = parseDHCP4(config));
+
+ ConstElementPtr x;
+ EXPECT_NO_THROW(x = configureDhcp4Server(srv, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ ASSERT_EQ(0, rcode_);
+
+ CfgMgr::instance().commit();
+
+ boost::shared_ptr<Pkt4> dis(new Pkt4(DHCPDISCOVER, 1234));
+ // Set the giaddr and hops to non-zero address as if it was relayed.
+ dis->setGiaddr(IOAddress("192.0.2.1"));
+ dis->setHops(1);
+
+ OptionPtr clientid = generateClientId();
+ dis->addOption(clientid);
+ // Set interface. It is required by the server to generate server id.
+ dis->setIface("eth0");
+ dis->setIndex(ETH0_INDEX);
+
+ // Pass it to the server and get an advertise
+ Pkt4Ptr offer = srv.processDiscover(dis);
+
+ // check if we get response at all
+ ASSERT_TRUE(offer);
+
+ // We did not include any vendor opts in DISCOVER, so there should be none
+ // in OFFER.
+ ASSERT_FALSE(offer->getOption(DHO_VIVSO_SUBOPTIONS));
+
+ // Let's add a vendor-option (vendor-id=4491) with a single sub-option.
+ // That suboption has code 1 and is a docsis ORO option.
+ boost::shared_ptr<OptionUint8Array> vendor_oro(new OptionUint8Array(Option::V4,
+ DOCSIS3_V4_ORO));
+ vendor_oro->addValue(DOCSIS3_V4_TFTP_SERVERS); // Request option 33
+ OptionPtr vendor(new OptionVendor(Option::V4, vendor_id));
+ vendor->addOption(vendor_oro);
+ dis->addOption(vendor);
+
+ // Need to process SOLICIT again after requesting new option.
+ offer = srv.processDiscover(dis);
+ ASSERT_TRUE(offer);
+
+ // Check if there is (or not) a vendor option in the response.
+ OptionPtr tmp = offer->getOption(DHO_VIVSO_SUBOPTIONS);
+ if (vendor_id != VENDOR_ID_CABLE_LABS) {
+ EXPECT_FALSE(tmp);
+ return;
+ }
+ ASSERT_TRUE(tmp);
+
+ // The response should be OptionVendor object
+ boost::shared_ptr<OptionVendor> vendor_resp =
+ boost::dynamic_pointer_cast<OptionVendor>(tmp);
+ ASSERT_TRUE(vendor_resp);
+
+ OptionPtr docsis2 = vendor_resp->getOption(DOCSIS3_V4_TFTP_SERVERS);
+ ASSERT_TRUE(docsis2);
+
+ Option4AddrLstPtr tftp_srvs = boost::dynamic_pointer_cast<Option4AddrLst>(docsis2);
+ ASSERT_TRUE(tftp_srvs);
+
+ Option4AddrLst::AddressContainer addrs = tftp_srvs->getAddresses();
+ ASSERT_EQ(2, addrs.size());
+ EXPECT_EQ("192.0.2.1", addrs[0].toText());
+ EXPECT_EQ("192.0.2.2", addrs[1].toText());
+ }
};
/// @todo Add more extensive vendor options tests, including multiple
@@ -184,92 +287,13 @@ TEST_F(VendorOptsTest, docsisVendorORO) {
// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491)
// vendor options is parsed correctly and the requested options are actually assigned.
TEST_F(VendorOptsTest, vendorOptionsORO) {
- IfaceMgrTestConfig test_config(true);
- IfaceMgr::instance().openSockets4();
-
- NakedDhcpv4Srv srv(0);
-
- ConstElementPtr x;
- string config = "{ \"interfaces-config\": {"
- " \"interfaces\": [ \"*\" ]"
- "},"
- " \"option-data\": [ {"
- " \"name\": \"tftp-servers\","
- " \"space\": \"vendor-4491\","
- " \"code\": 2,"
- " \"data\": \"192.0.2.1, 192.0.2.2\","
- " \"csv-format\": true"
- " }],"
- "\"subnet4\": [ { "
- " \"pools\": [ { \"pool\": \"192.0.2.0/25\" } ],"
- " \"subnet\": \"192.0.2.0/24\", "
- " \"interface\": \"eth0\" "
- " } ]"
- "}";
-
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseDHCP4(config));
-
- EXPECT_NO_THROW(x = configureDhcp4Server(srv, json));
- ASSERT_TRUE(x);
- comment_ = parseAnswer(rcode_, x);
- ASSERT_EQ(0, rcode_);
-
- CfgMgr::instance().commit();
-
- boost::shared_ptr<Pkt4> dis(new Pkt4(DHCPDISCOVER, 1234));
- // Set the giaddr and hops to non-zero address as if it was relayed.
- dis->setGiaddr(IOAddress("192.0.2.1"));
- dis->setHops(1);
-
- OptionPtr clientid = generateClientId();
- dis->addOption(clientid);
- // Set interface. It is required by the server to generate server id.
- dis->setIface("eth0");
- dis->setIndex(ETH0_INDEX);
-
- // Pass it to the server and get an advertise
- Pkt4Ptr offer = srv.processDiscover(dis);
-
- // check if we get response at all
- ASSERT_TRUE(offer);
-
- // We did not include any vendor opts in DISCOVER, so there should be none
- // in OFFER.
- ASSERT_FALSE(offer->getOption(DHO_VIVSO_SUBOPTIONS));
-
- // Let's add a vendor-option (vendor-id=4491) with a single sub-option.
- // That suboption has code 1 and is a docsis ORO option.
- boost::shared_ptr<OptionUint8Array> vendor_oro(new OptionUint8Array(Option::V4,
- DOCSIS3_V4_ORO));
- vendor_oro->addValue(DOCSIS3_V4_TFTP_SERVERS); // Request option 33
- OptionPtr vendor(new OptionVendor(Option::V4, 4491));
- vendor->addOption(vendor_oro);
- dis->addOption(vendor);
-
- // Need to process SOLICIT again after requesting new option.
- offer = srv.processDiscover(dis);
- ASSERT_TRUE(offer);
-
- // Check if there is a vendor option response
- OptionPtr tmp = offer->getOption(DHO_VIVSO_SUBOPTIONS);
- ASSERT_TRUE(tmp);
-
- // The response should be OptionVendor object
- boost::shared_ptr<OptionVendor> vendor_resp =
- boost::dynamic_pointer_cast<OptionVendor>(tmp);
- ASSERT_TRUE(vendor_resp);
-
- OptionPtr docsis2 = vendor_resp->getOption(DOCSIS3_V4_TFTP_SERVERS);
- ASSERT_TRUE(docsis2);
-
- Option4AddrLstPtr tftp_srvs = boost::dynamic_pointer_cast<Option4AddrLst>(docsis2);
- ASSERT_TRUE(tftp_srvs);
+ testVendorOptionsORO(VENDOR_ID_CABLE_LABS);
+}
- Option4AddrLst::AddressContainer addrs = tftp_srvs->getAddresses();
- ASSERT_EQ(2, addrs.size());
- EXPECT_EQ("192.0.2.1", addrs[0].toText());
- EXPECT_EQ("192.0.2.2", addrs[1].toText());
+// Same as vendorOptionsORO except a different vendor ID than Cable Labs is
+// provided and vendor options are expected to not be present in the response.
+TEST_F(VendorOptsTest, vendorOptionsORODifferentVendorID) {
+ testVendorOptionsORO(32768);
}
// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491)
diff --git a/src/bin/dhcp6/tests/vendor_opts_unittest.cc b/src/bin/dhcp6/tests/vendor_opts_unittest.cc
index 034592e74d..3e75074445 100644
--- a/src/bin/dhcp6/tests/vendor_opts_unittest.cc
+++ b/src/bin/dhcp6/tests/vendor_opts_unittest.cc
@@ -43,6 +43,113 @@ using namespace isc::asiolink;
/// @brief Class dedicated to testing vendor options in DHCPv6
class VendorOptsTest : public Dhcpv6SrvTest {
public:
+ void testVendorOptionsORO(int vendor_id) {
+ IfaceMgrTestConfig test_config(true);
+
+ string config = R"(
+ {
+ "interfaces-config": {
+ "interfaces": [ "*" ]
+ },
+ "option-data": [
+ {
+ "data": "normal_erouter_v6.cm",
+ "name": "config-file",
+ "space": "vendor-4491"
+ }
+ ],
+ "option-def": [
+ {
+ "code": 33,
+ "name": "config-file",
+ "space": "vendor-4491",
+ "type": "string"
+ }
+ ],
+ "preferred-lifetime": 3000,
+ "rebind-timer": 2000,
+ "renew-timer": 1000,
+ "subnet6": [
+ {
+ "interface": "eth0",
+ "interface-id": "",
+ "pools": [
+ {
+ "pool": "2001:db8:1::/64"
+ }
+ ],
+ "preferred-lifetime": 3000,
+ "rebind-timer": 1000,
+ "renew-timer": 1000,
+ "subnet": "2001:db8:1::/48",
+ "valid-lifetime": 4000
+ }
+ ],
+ "valid-lifetime": 4000
+ }
+ )";
+
+ ASSERT_NO_THROW(configure(config));
+
+ Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
+ sol->setRemoteAddr(IOAddress("fe80::abcd"));
+ sol->setIface("eth0");
+ sol->setIndex(ETH0_INDEX);
+ sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
+ OptionPtr clientid = generateClientId();
+ sol->addOption(clientid);
+
+ // Pass it to the server and get an advertise
+ AllocEngine::ClientContext6 ctx;
+ bool drop = false;
+ srv_.initContext(sol, ctx, drop);
+ ASSERT_FALSE(drop);
+ Pkt6Ptr adv = srv_.processSolicit(ctx);
+
+ // check if we get response at all
+ ASSERT_TRUE(adv);
+
+ // We did not include any vendor opts in SOLICIT, so there should be none
+ // in ADVERTISE.
+ ASSERT_FALSE(adv->getOption(D6O_VENDOR_OPTS));
+
+ // Let's add a vendor-option (vendor-id=4491) with a single sub-option.
+ // That suboption has code 1 and is a docsis ORO option.
+ boost::shared_ptr<OptionUint16Array> vendor_oro(new OptionUint16Array(Option::V6,
+ DOCSIS3_V6_ORO));
+ vendor_oro->addValue(DOCSIS3_V6_CONFIG_FILE); // Request option 33
+ OptionPtr vendor(new OptionVendor(Option::V6, vendor_id));
+ vendor->addOption(vendor_oro);
+ sol->addOption(vendor);
+
+ // Need to process SOLICIT again after requesting new option.
+ AllocEngine::ClientContext6 ctx2;
+ srv_.initContext(sol, ctx2, drop);
+ ASSERT_FALSE(drop);
+ adv = srv_.processSolicit(ctx2);
+ ASSERT_TRUE(adv);
+
+ // Check if there is (or not) a vendor option in the response.
+ OptionPtr tmp = adv->getOption(D6O_VENDOR_OPTS);
+ if (vendor_id != VENDOR_ID_CABLE_LABS) {
+ EXPECT_FALSE(tmp);
+ return;
+ }
+ ASSERT_TRUE(tmp);
+
+ // The response should be OptionVendor object
+ boost::shared_ptr<OptionVendor> vendor_resp =
+ boost::dynamic_pointer_cast<OptionVendor>(tmp);
+ ASSERT_TRUE(vendor_resp);
+
+ OptionPtr docsis33 = vendor_resp->getOption(33);
+ ASSERT_TRUE(docsis33);
+
+ OptionStringPtr config_file = boost::dynamic_pointer_cast<OptionString>(docsis33);
+ ASSERT_TRUE(config_file);
+ EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue());
+ }
+
/// @brief Test what options a client can use to request vendor options.
void testRequestingOfVendorOptions(vector<int8_t> const& client_options) {
IfaceMgrTestConfig test_config(true);
@@ -76,12 +183,12 @@ public:
client.addExtraOption(vendor_option);
}
- // Let's check whether the server is not able to process this packet
- // and include vivso with appropriate sub-options
+ // Let's check whether the server is able to process this packet
+ // and include the appropriate options.
EXPECT_NO_THROW(client.doSolicit());
ASSERT_TRUE(client.getContext().response_);
- // Check there's a response if an option was properly requested.
+ // Check that there is a response if an option was properly requested.
// Otherwise check that a response has not been provided and stop here.
OptionPtr response(
client.getContext().response_->getOption(D6O_VENDOR_OPTS));
@@ -98,9 +205,9 @@ public:
ASSERT_TRUE(response_vendor_options);
EXPECT_EQ(vendor_id_, response_vendor_options->getVendorId());
- // Now check that it contains requested option with the appropriate
- // content.
- OptionPtr suboption(response_vendor_options->getOption(option_));
+ // Check that it contains requested option with the appropriate content.
+ OptionPtr suboption(
+ response_vendor_options->getOption(option_));
ASSERT_TRUE(suboption);
vector<uint8_t> binary_suboption = suboption->toBinary(false);
string text(binary_suboption.begin(), binary_suboption.end());
@@ -235,93 +342,13 @@ TEST_F(VendorOptsTest, docsisVendorORO) {
// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491)
// vendor options is parsed correctly and the requested options are actually assigned.
TEST_F(VendorOptsTest, vendorOptionsORO) {
+ testVendorOptionsORO(VENDOR_ID_CABLE_LABS);
+}
- IfaceMgrTestConfig test_config(true);
-
- string config = "{ \"interfaces-config\": {"
- " \"interfaces\": [ \"*\" ]"
- "},"
- "\"preferred-lifetime\": 3000,"
- "\"rebind-timer\": 2000, "
- "\"renew-timer\": 1000, "
- " \"option-def\": [ {"
- " \"name\": \"config-file\","
- " \"code\": 33,"
- " \"type\": \"string\","
- " \"space\": \"vendor-4491\""
- " } ],"
- " \"option-data\": [ {"
- " \"name\": \"config-file\","
- " \"space\": \"vendor-4491\","
- " \"data\": \"normal_erouter_v6.cm\""
- " }],"
- "\"subnet6\": [ { "
- " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
- " \"subnet\": \"2001:db8:1::/48\", "
- " \"renew-timer\": 1000, "
- " \"rebind-timer\": 1000, "
- " \"preferred-lifetime\": 3000,"
- " \"valid-lifetime\": 4000,"
- " \"interface-id\": \"\","
- " \"interface\": \"eth0\""
- " } ],"
- "\"valid-lifetime\": 4000 }";
-
- ASSERT_NO_THROW(configure(config));
-
- Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
- sol->setRemoteAddr(IOAddress("fe80::abcd"));
- sol->setIface("eth0");
- sol->setIndex(ETH0_INDEX);
- sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
- OptionPtr clientid = generateClientId();
- sol->addOption(clientid);
-
- // Pass it to the server and get an advertise
- AllocEngine::ClientContext6 ctx;
- bool drop = false;
- srv_.initContext(sol, ctx, drop);
- ASSERT_FALSE(drop);
- Pkt6Ptr adv = srv_.processSolicit(ctx);
-
- // check if we get response at all
- ASSERT_TRUE(adv);
-
- // We did not include any vendor opts in SOLICIT, so there should be none
- // in ADVERTISE.
- ASSERT_FALSE(adv->getOption(D6O_VENDOR_OPTS));
-
- // Let's add a vendor-option (vendor-id=4491) with a single sub-option.
- // That suboption has code 1 and is a docsis ORO option.
- boost::shared_ptr<OptionUint16Array> vendor_oro(new OptionUint16Array(Option::V6,
- DOCSIS3_V6_ORO));
- vendor_oro->addValue(DOCSIS3_V6_CONFIG_FILE); // Request option 33
- OptionPtr vendor(new OptionVendor(Option::V6, 4491));
- vendor->addOption(vendor_oro);
- sol->addOption(vendor);
-
- // Need to process SOLICIT again after requesting new option.
- AllocEngine::ClientContext6 ctx2;
- srv_.initContext(sol, ctx2, drop);
- ASSERT_FALSE(drop);
- adv = srv_.processSolicit(ctx2);
- ASSERT_TRUE(adv);
-
- // Check if there is vendor option response
- OptionPtr tmp = adv->getOption(D6O_VENDOR_OPTS);
- ASSERT_TRUE(tmp);
-
- // The response should be OptionVendor object
- boost::shared_ptr<OptionVendor> vendor_resp =
- boost::dynamic_pointer_cast<OptionVendor>(tmp);
- ASSERT_TRUE(vendor_resp);
-
- OptionPtr docsis33 = vendor_resp->getOption(33);
- ASSERT_TRUE(docsis33);
-
- OptionStringPtr config_file = boost::dynamic_pointer_cast<OptionString>(docsis33);
- ASSERT_TRUE(config_file);
- EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue());
+// Same as vendorOptionsORO except a different vendor ID than Cable Labs is
+// provided and vendor options are expected to not be present in the response.
+TEST_F(VendorOptsTest, vendorOptionsORODifferentVendorID) {
+ testVendorOptionsORO(32768);
}
// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491)