Browse Source

[3279] Drop DHCPv4 packets for which the server id doesn't match.

Marcin Siodelski 11 years ago
parent
commit
0d08bdc79a
2 changed files with 20 additions and 0 deletions
  1. 7 0
      src/bin/dhcp4/dhcp4_messages.mes
  2. 13 0
      src/bin/dhcp4/dhcp4_srv.cc

+ 7 - 0
src/bin/dhcp4/dhcp4_messages.mes

@@ -175,6 +175,13 @@ IPv4 DHCP server but it is not running.
 A debug message issued during startup, this indicates that the IPv4 DHCP
 server is about to open sockets on the specified port.
 
+% DHCP4_PACKET_NOT_FOR_US received DHCPv4 message dropped because it contains foreign server identifier, interface: %1
+This debug message is issued when received DHCPv4 message is dropped because
+it is addressed to a different server, i.e. a server identifier held by
+this message doesn't match the identifier used by our server. The argument
+of this message holds the name of the interface on which the message has
+been received.
+
 % DHCP4_OPEN_SOCKET_FAIL failed to create socket: %1
 A warning message issued when IfaceMgr fails to open and bind a socket. The reason
 for the failure is appended as an argument of the log message.

+ 13 - 0
src/bin/dhcp4/dhcp4_srv.cc

@@ -259,6 +259,14 @@ Dhcpv4Srv::run() {
             }
         }
 
+        // Check if the DHCPv4 packet has been sent to us, to to someone else.
+        // If it hasn't been sent to us, drop it!
+        if (!acceptServerId(query)) {
+            LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_PACKET_NOT_FOR_US)
+                .arg(query->getIface());
+            continue;
+        }
+
         // When receiving a packet without message type option, getType() will
         // throw. Let's set type to -1 as default error indicator.
         int type = -1;
@@ -1544,6 +1552,11 @@ Dhcpv4Srv::acceptServerId(const Pkt4Ptr& pkt) const {
     // and try to match with server identifiers used by the server.
     Option4AddrLstPtr option_addrs =
         boost::dynamic_pointer_cast<Option4AddrLst>(option);
+    // Unable to convert the option to the option type which encapsulates it.
+    // We treat this as non-matching server id.
+    if (!option_addrs) {
+        return (false);
+    }
     Option4AddrLst::AddressContainer addrs = option_addrs->getAddresses();
 
     if (addrs.size() != 1) {