RFCViolation);
}
-// This test verifies if the sanityCheck() really checks options content,
-// especially truncated client-id.
-TEST_F(Dhcpv6SrvTest, truncatedClientId) {
+// This test verifies that sanity checking against valid and invalid
+// client ids
+TEST_F(Dhcpv6SrvTest, sanityCheckClientId) {
NakedDhcpv6Srv srv(0);
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
// Case 1: completely empty (size 0)
- pkt->addOption(generateClientId(0));
+ pkt->addOption(generateBinaryOption(D6O_CLIENTID, 0));
EXPECT_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::MANDATORY, Dhcpv6Srv::FORBIDDEN),
RFCViolation);
// Case 2: too short (at the very least 3 bytes are needed)
pkt->delOption(D6O_CLIENTID);
- pkt->addOption(generateClientId(2));
+ pkt->addOption(generateBinaryOption(D6O_CLIENTID, 2));
EXPECT_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::MANDATORY, Dhcpv6Srv::FORBIDDEN),
RFCViolation);
// Case 3: the shortest DUID possible (3 bytes) is ok:
pkt->delOption(D6O_CLIENTID);
- pkt->addOption(generateClientId(3));
+ pkt->addOption(generateBinaryOption(D6O_CLIENTID, 3));
EXPECT_NO_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::MANDATORY, Dhcpv6Srv::FORBIDDEN));
+
+ // Case 4: longest possible is 128, should be ok
+ pkt->delOption(D6O_CLIENTID);
+ pkt->addOption(generateBinaryOption(D6O_CLIENTID, DUID::MAX_DUID_LEN));
+ EXPECT_NO_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::MANDATORY, Dhcpv6Srv::FORBIDDEN));
+
+ // Case 5: too long
+ pkt->delOption(D6O_CLIENTID);
+ pkt->addOption(generateBinaryOption(D6O_CLIENTID, DUID::MAX_DUID_LEN + 1));
+ EXPECT_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::MANDATORY, Dhcpv6Srv::FORBIDDEN),
+ RFCViolation);
}
-// This test verifies if the sanityCheck() really checks options content,
-// especially truncated server-id.
-TEST_F(Dhcpv6SrvTest, truncatedServerId) {
+// This test verifies that sanity checking against valid and invalid
+// server ids
+TEST_F(Dhcpv6SrvTest, sanityCheckServerId) {
NakedDhcpv6Srv srv(0);
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
// Case 1: completely empty (size 0)
- pkt->addOption(generateServerId(0));
+ pkt->addOption(generateBinaryOption(D6O_SERVERID, 0));
EXPECT_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::FORBIDDEN, Dhcpv6Srv::MANDATORY),
RFCViolation);
// Case 2: too short (at the very least 3 bytes are needed)
pkt->delOption(D6O_SERVERID);
- pkt->addOption(generateServerId(2));
+ pkt->addOption(generateBinaryOption(D6O_SERVERID, 2));
EXPECT_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::FORBIDDEN, Dhcpv6Srv::MANDATORY),
RFCViolation);
// Case 3: the shortest DUID possible (3 bytes) is ok:
pkt->delOption(D6O_SERVERID);
- pkt->addOption(generateServerId(3));
+ pkt->addOption(generateBinaryOption(D6O_SERVERID, 3));
EXPECT_NO_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::FORBIDDEN, Dhcpv6Srv::MANDATORY));
-}
+ // Case 4: longest possible is 128, should be ok
+ pkt->delOption(D6O_SERVERID);
+ pkt->addOption(generateBinaryOption(D6O_SERVERID, DUID::MAX_DUID_LEN));
+ EXPECT_NO_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::FORBIDDEN, Dhcpv6Srv::MANDATORY));
+
+ // Case 5: too long
+ pkt->delOption(D6O_SERVERID);
+ pkt->addOption(generateBinaryOption(D6O_SERVERID, DUID::MAX_DUID_LEN + 1));
+ EXPECT_THROW(srv.sanityCheck(pkt, Dhcpv6Srv::FORBIDDEN, Dhcpv6Srv::MANDATORY),
+ RFCViolation);
+}
// Check that the server is testing if server identifier received in the
// query, matches server identifier used by the server.
D6O_INTERFACE_ID, tmp)));
}
- // Generate client-id option
- isc::dhcp::OptionPtr generateClientId(size_t duid_size = 32) {
-
- if (duid_size == 0) {
+ /// @brief Generate binary data option
+ ///
+ /// Creates an Option in the V6 space with the given type and binary data
+ /// of the given number of bytes. The data is initialized to the values
+ /// 100 to 100 + n, where n is the desired number of bytes.
+ ///
+ /// @param type option type for the new option
+ /// @param data_size number of bytes of data to generate
+ ///
+ /// @return Pointer to the new option
+ isc::dhcp::OptionPtr generateBinaryOption(const DHCPv6OptionType type, size_t data_size) {
+ if (data_size == 0) {
return (isc::dhcp::OptionPtr
- (new isc::dhcp::Option(isc::dhcp::Option::V6, D6O_CLIENTID)));
+ (new isc::dhcp::Option(isc::dhcp::Option::V6, type)));
}
- isc::dhcp::OptionBuffer clnt_duid(duid_size);
- for (size_t i = 0; i < duid_size; i++) {
- clnt_duid[i] = 100 + i;
+ isc::dhcp::OptionBuffer data_data(data_size);
+ for (size_t i = 0; i < data_size; i++) {
+ data_data[i] = 100 + i;
}
- duid_ = isc::dhcp::DuidPtr(new isc::dhcp::DUID(clnt_duid));
-
return (isc::dhcp::OptionPtr
- (new isc::dhcp::Option(isc::dhcp::Option::V6, D6O_CLIENTID,
- clnt_duid.begin(),
- clnt_duid.begin() + duid_size)));
+ (new isc::dhcp::Option(isc::dhcp::Option::V6, type,
+ data_data.begin(),
+ data_data.begin() + data_size)));
+ }
+
+ // Generate client-id option
+ isc::dhcp::OptionPtr generateClientId(size_t duid_size = 32) {
+ isc::dhcp::OptionPtr opt = generateBinaryOption(D6O_CLIENTID, duid_size);
+ duid_ = isc::dhcp::DuidPtr(new isc::dhcp::DUID(opt->getData()));
+ return (opt);
}
/// Generate server-id option
/// @param duid_size size of the duid
isc::dhcp::OptionPtr generateServerId(size_t duid_size = 32) {
-
- if (duid_size == 0) {
- return (isc::dhcp::OptionPtr
- (new isc::dhcp::Option(isc::dhcp::Option::V6, D6O_SERVERID)));
-
- }
-
- isc::dhcp::OptionBuffer clnt_duid(duid_size);
- for (size_t i = 0; i < duid_size; i++) {
- clnt_duid[i] = 100 + i;
- }
-
- duid_ = isc::dhcp::DuidPtr(new isc::dhcp::DUID(clnt_duid));
-
- return (isc::dhcp::OptionPtr
- (new isc::dhcp::Option(isc::dhcp::Option::V6, D6O_SERVERID,
- clnt_duid.begin(),
- clnt_duid.begin() + duid_size)));
+ isc::dhcp::OptionPtr opt = generateBinaryOption(D6O_SERVERID, duid_size);
+ duid_ = isc::dhcp::DuidPtr(new isc::dhcp::DUID(opt->getData()));
+ return (opt);
}
// Checks if server response (ADVERTISE or REPLY) includes proper
DUID::DUID(const std::vector<uint8_t>& duid) {
if (duid.size() > MAX_DUID_LEN) {
- isc_throw(isc::BadValue, "DUID too large");
+ isc_throw(isc::BadValue, "DUID is " << duid.size()
+ << ", exceeds max of " << MAX_DUID_LEN);
}
if (duid.empty()) {
isc_throw(isc::BadValue, "Empty DUIDs are not allowed");
DUID::DUID(const uint8_t* data, size_t len) {
if (len > MAX_DUID_LEN) {
- isc_throw(isc::BadValue, "DUID too large");
+ isc_throw(isc::BadValue, "DUID is " << len
+ << ", exceeds max of " << MAX_DUID_LEN);
}
if (len == 0) {
isc_throw(isc::BadValue, "Empty DUIDs/Client-ids not allowed");