2008-08-01 21:16:41 +00:00
|
|
|
diff -up dhcp-4.0.0//server/bootp.c.unicast dhcp-4.0.0//server/bootp.c
|
|
|
|
--- dhcp-4.0.0//server/bootp.c.unicast 2007-10-26 12:46:50.000000000 -1000
|
|
|
|
+++ dhcp-4.0.0//server/bootp.c 2008-08-01 10:12:38.000000000 -1000
|
|
|
|
@@ -58,6 +58,7 @@ void bootp (packet)
|
2008-01-11 00:16:44 +00:00
|
|
|
char msgbuf [1024];
|
|
|
|
int ignorep;
|
|
|
|
int peer_has_leases = 0;
|
|
|
|
+ int norelay = 0;
|
|
|
|
|
|
|
|
if (packet -> raw -> op != BOOTREQUEST)
|
|
|
|
return;
|
2008-08-01 21:16:41 +00:00
|
|
|
@@ -73,7 +74,7 @@ void bootp (packet)
|
2008-01-11 00:16:44 +00:00
|
|
|
? 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;
|
|
|
|
}
|
2008-08-01 21:16:41 +00:00
|
|
|
@@ -384,6 +385,13 @@ void bootp (packet)
|
2008-01-11 00:16:44 +00:00
|
|
|
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
|
2008-08-01 21:16:41 +00:00
|
|
|
diff -up dhcp-4.0.0//server/dhcp.c.unicast dhcp-4.0.0//server/dhcp.c
|
|
|
|
--- dhcp-4.0.0//server/dhcp.c.unicast 2007-11-02 12:09:02.000000000 -1000
|
|
|
|
+++ dhcp-4.0.0//server/dhcp.c 2008-08-01 10:12:38.000000000 -1000
|
|
|
|
@@ -3904,6 +3904,7 @@ int locate_network (packet)
|
2008-01-11 00:16:44 +00:00
|
|
|
struct data_string data;
|
|
|
|
struct subnet *subnet = (struct subnet *)0;
|
|
|
|
struct option_cache *oc;
|
|
|
|
+ int norelay = 0;
|
|
|
|
|
2008-08-01 21:16:41 +00:00
|
|
|
/* See if there's a Relay Agent Link Selection Option, or a
|
|
|
|
* Subnet Selection Option. The Link-Select and Subnet-Select
|
|
|
|
@@ -3919,12 +3920,24 @@ int locate_network (packet)
|
2008-01-11 00:16:44 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-08-01 21:16:41 +00:00
|
|
|
/* If there's an option indicating link connection, and it's valid,
|
|
|
|
@@ -3947,7 +3960,10 @@ int locate_network (packet)
|
2008-01-11 00:16:44 +00:00
|
|
|
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. */
|
2008-08-01 21:16:41 +00:00
|
|
|
@@ -3955,7 +3971,10 @@ int locate_network (packet)
|
2008-01-11 00:16:44 +00:00
|
|
|
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. */
|