]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/dhcp-4.2.0-unicast-bootp.patch
dhcp: Update to 4.2.2.
[ipfire-2.x.git] / src / patches / dhcp-4.2.0-unicast-bootp.patch
diff --git a/src/patches/dhcp-4.2.0-unicast-bootp.patch b/src/patches/dhcp-4.2.0-unicast-bootp.patch
new file mode 100644 (file)
index 0000000..78bc078
--- /dev/null
@@ -0,0 +1,99 @@
+diff -up dhcp-4.2.0/server/bootp.c.unicast dhcp-4.2.0/server/bootp.c
+--- dhcp-4.2.0/server/bootp.c.unicast  2009-11-20 02:49:03.000000000 +0100
++++ dhcp-4.2.0/server/bootp.c  2010-07-21 13:40:25.000000000 +0200
+@@ -58,6 +58,7 @@ void bootp (packet)
+       char msgbuf [1024];
+       int ignorep;
+       int peer_has_leases = 0;
++      int norelay = 0;
+       if (packet -> raw -> op != BOOTREQUEST)
+               return;
+@@ -73,7 +74,7 @@ void bootp (packet)
+                ? inet_ntoa (packet -> raw -> giaddr)
+                : packet -> interface -> name);
+-      if (!locate_network (packet)) {
++      if ((norelay = locate_network (packet)) == 0) {
+               log_info ("%s: network unknown", msgbuf);
+               return;
+       }
+@@ -390,6 +391,13 @@ void bootp (packet)
+                                             from, &to, &hto);
+                       goto out;
+               }
++      } else if (norelay == 2) {
++              to.sin_addr = raw.ciaddr;
++              to.sin_port = remote_port;
++              if (fallback_interface) {
++                      result = send_packet (fallback_interface, (struct packet *)0, &raw, outgoing.packet_length, from, &to, &hto);
++                      goto out;
++              }
+       /* If it comes from a client that already knows its address
+          and is not requesting a broadcast response, and we can
+diff -up dhcp-4.2.0/server/dhcp.c.unicast dhcp-4.2.0/server/dhcp.c
+--- dhcp-4.2.0/server/dhcp.c.unicast   2010-06-01 19:29:59.000000000 +0200
++++ dhcp-4.2.0/server/dhcp.c   2010-07-21 13:40:25.000000000 +0200
+@@ -4185,6 +4185,7 @@ int locate_network (packet)
+       struct data_string data;
+       struct subnet *subnet = (struct subnet *)0;
+       struct option_cache *oc;
++      int norelay = 0;
+       /* See if there's a Relay Agent Link Selection Option, or a
+        * Subnet Selection Option.  The Link-Select and Subnet-Select
+@@ -4200,12 +4201,24 @@ int locate_network (packet)
+          from the interface, if there is one.   If not, fail. */
+       if (!oc && !packet -> raw -> giaddr.s_addr) {
+               if (packet -> interface -> shared_network) {
+-                      shared_network_reference
+-                              (&packet -> shared_network,
+-                               packet -> interface -> shared_network, MDL);
+-                      return 1;
++                      struct in_addr any_addr;
++                      any_addr.s_addr = INADDR_ANY;
++
++                      if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
++                              struct iaddr cip;
++                              memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4);
++                              cip.len = 4;
++                              if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL))
++                                      norelay = 2;
++                      }
++
++                      if (!norelay) {
++                              shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL);
++                              return 1;
++                      }
++              } else {
++                      return 0;
+               }
+-              return 0;
+       }
+       /* If there's an option indicating link connection, and it's valid,
+@@ -4228,7 +4241,10 @@ int locate_network (packet)
+               data_string_forget (&data, MDL);
+       } else {
+               ia.len = 4;
+-              memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
++              if (norelay)
++                      memcpy (ia.iabuf, &packet->raw->ciaddr, 4);
++              else
++                      memcpy (ia.iabuf, &packet->raw->giaddr, 4);
+       }
+       /* If we know the subnet on which the IP address lives, use it. */
+@@ -4236,7 +4252,10 @@ int locate_network (packet)
+               shared_network_reference (&packet -> shared_network,
+                                         subnet -> shared_network, MDL);
+               subnet_dereference (&subnet, MDL);
+-              return 1;
++              if (norelay)
++                      return norelay;
++              else
++                      return 1;
+       }
+       /* Otherwise, fail. */