You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.1 KiB
101 lines
3.1 KiB
diff -up dhcp-4.2.4b1/server/bootp.c.unicast dhcp-4.2.4b1/server/bootp.c |
|
--- dhcp-4.2.4b1/server/bootp.c.unicast 2012-04-10 23:27:06.000000000 +0200 |
|
+++ dhcp-4.2.4b1/server/bootp.c 2012-04-16 17:28:42.095919022 +0200 |
|
@@ -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 |
|
--- dhcp-4.2.4b1/server/dhcp.c.unicast 2012-03-09 12:28:12.000000000 +0100 |
|
+++ dhcp-4.2.4b1/server/dhcp.c 2012-04-16 17:26:55.067418285 +0200 |
|
@@ -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. */
|
|
|