| diff -up dhcp-4.2.4b1/server/bootp.c.unicast dhcp-4.2.4b1/server/bootp.c |
| |
| |
| @@ -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; |
| } |
| @@ -399,6 +400,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.2.4b1/server/dhcp.c.unicast dhcp-4.2.4b1/server/dhcp.c |
| |
| |
| @@ -4299,6 +4299,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 |
| @@ -4314,12 +4315,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, |
| @@ -4342,7 +4355,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. */ |
| @@ -4350,7 +4366,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. */ |