// and whether the client is known, i.e., has a lease.
if (!fake_allocation && !opt_serverid && opt_requested_address) {
Lease4Ptr lease;
- if (hwaddr) {
- lease = LeaseMgrFactory::instance().getLease4(*hwaddr,
- subnet->getID());
+ if (client_id) {
+ lease = LeaseMgrFactory::instance().getLease4(*client_id, subnet->getID());
}
- if (!lease && client_id) {
- lease = LeaseMgrFactory::instance().getLease4(*client_id,
- subnet->getID());
- }
- // Got a lease so we can check the address.
- if (lease && (lease->addr_ != hint)) {
- LOG_DEBUG(bad_packet_logger, DBG_DHCP4_DETAIL,
- DHCP4_PACKET_NAK_0002)
- .arg(query->getLabel())
- .arg(hint.toText());
- resp->setType(DHCPNAK);
- resp->setYiaddr(IOAddress::IPV4_ZERO_ADDRESS());
- return;
+ if (!lease && hwaddr) {
+ lease = LeaseMgrFactory::instance().getLease4(*hwaddr, subnet->getID());
}
- // Now check the second error case: unknown client.
- if (!lease) {
+
+ // Check the first error case: unknown client. We check this before
+ // validating the address sent because we don't want to respond if
+ // we don't know this client.
+ if (!lease || !lease->belongsToClient(hwaddr, client_id)) {
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL,
DHCP4_NO_LEASE_INIT_REBOOT)
.arg(hint.toText())
ex.deleteResponse();
return;
}
+
+ // We know this client so we can now check if his notion of the
+ // IP address is correct.
+ if (lease && (lease->addr_ != hint)) {
+ LOG_DEBUG(bad_packet_logger, DBG_DHCP4_DETAIL,
+ DHCP4_PACKET_NAK_0002)
+ .arg(query->getLabel())
+ .arg(hint.toText());
+
+ resp->setType(DHCPNAK);
+ resp->setYiaddr(IOAddress::IPV4_ZERO_ADDRESS());
+ return;
+ }
}
Dhcp4Client client(Dhcp4Client::SELECTING);
// Configure DHCP server.
configure(DORA_CONFIGS[0], *client.getServer());
+ client.includeClientId("11:22");
// Obtain a lease from the server using the 4-way exchange.
ASSERT_NO_THROW(client.doDORA(boost::shared_ptr<
IOAddress>(new IOAddress("10.0.0.50"))));
resp = client.getContext().response_;
EXPECT_EQ(DHCPNAK, static_cast<int>(resp->getType()));
- // Try to request from a different client.
+ // Change client identifier. The server should treat the request
+ // as a resquest from unknown client and ignore it.
+ client.includeClientId("12:34");
+ ASSERT_NO_THROW(client.doRequest());
+ ASSERT_FALSE(client.getContext().response_);
+
+ // Now let's fix the IP address. The client identifier is still
+ // invalid so the message should be dropped.
+ client.config_.lease_.addr_ = IOAddress("10.0.0.50");
+ ASSERT_NO_THROW(client.doRequest());
+ ASSERT_FALSE(client.getContext().response_);
+
+ // Restore original client identifier.
+ client.includeClientId("11:22");
+
+ // Try to request from a different HW address. This should be successful
+ // because the client identifier matches.
client.modifyHWAddr();
ASSERT_NO_THROW(client.doRequest());
- // The server should not respond.
- EXPECT_FALSE(client.getContext().response_);
+ // Make sure that the server responded.
+ ASSERT_TRUE(client.getContext().response_);
+ resp = client.getContext().response_;
+ // Make sure that the server has responded with DHCPACK.
+ ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
+ // Make sure that the client has got the lease with the requested address.
+ ASSERT_EQ("10.0.0.50", client.config_.lease_.addr_.toText());
}
// Check that the ciaddr returned by the server is correct for DHCPOFFER and