--- dhcp-3.0.5/server/bootp.c.unicast 2005-05-18 15:54:17.000000000 -0400 +++ dhcp-3.0.5/server/bootp.c 2007-03-30 16:16:00.000000000 -0400 @@ -62,6 +62,7 @@ char msgbuf [1024]; int ignorep; int peer_has_leases = 0; + int norelay = 0; if (packet -> raw -> op != BOOTREQUEST) return; @@ -77,7 +78,7 @@ ? 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; } @@ -357,6 +358,13 @@ 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 --- dhcp-3.0.5/server/dhcp.c.unicast 2007-03-30 16:13:36.000000000 -0400 +++ dhcp-3.0.5/server/dhcp.c 2007-03-30 16:19:35.000000000 -0400 @@ -3817,6 +3817,7 @@ struct data_string data; struct subnet *subnet = (struct subnet *)0; struct option_cache *oc; + int norelay = 0; /* See if there's a subnet selection option. */ oc = lookup_option (&dhcp_universe, packet -> options, @@ -3826,12 +3827,24 @@ 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 SSO, and it's valid, use it to figure out the @@ -3853,7 +3866,10 @@ 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. */ @@ -3861,7 +3877,10 @@ 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. */