+++ /dev/null
-diff -up dhcp-4.3.0a1/server/bootp.c.unicast dhcp-4.3.0a1/server/bootp.c
---- dhcp-4.3.0a1/server/bootp.c.unicast 2013-12-11 01:25:12.000000000 +0100
-+++ dhcp-4.3.0a1/server/bootp.c 2013-12-19 15:12:12.974671154 +0100
-@@ -59,6 +59,7 @@ void bootp (packet)
- char msgbuf [1024];
- int ignorep;
- int peer_has_leases = 0;
-+ int norelay = 0;
-
- if (packet -> raw -> op != BOOTREQUEST)
- return;
-@@ -74,7 +75,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;
- }
-@@ -396,6 +397,15 @@ void bootp (packet)
-
- goto out;
- }
-+ } else if (norelay == 2) {
-+ to.sin_addr = raw.ciaddr;
-+ to.sin_port = remote_port;
-+ if (fallback_interface) {
-+ result = send_packet (fallback_interface, NULL, &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.3.0a1/server/dhcp.c.unicast dhcp-4.3.0a1/server/dhcp.c
---- dhcp-4.3.0a1/server/dhcp.c.unicast 2013-12-13 21:50:38.000000000 +0100
-+++ dhcp-4.3.0a1/server/dhcp.c 2013-12-19 15:12:12.975671140 +0100
-@@ -4627,6 +4627,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
-@@ -4642,12 +4643,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,
-@@ -4670,7 +4683,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. */
-@@ -4678,7 +4694,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. */