diff -ruN dhcp-4.0.0/includes/dhcpd.h dhcp-4.0.0_hacked/includes/dhcpd.h --- dhcp-4.0.0/includes/dhcpd.h 2007-12-08 14:36:00.000000000 -0500 +++ dhcp-4.0.0_hacked/includes/dhcpd.h 2008-08-13 08:40:27.000000000 -0400 @@ -621,6 +621,7 @@ #define SV_DHCPV6_LEASE_FILE_NAME 54 #define SV_DHCPV6_PID_FILE_NAME 55 #define SV_LIMIT_ADDRS_PER_IA 56 +#define SV_RELAY_TO_GIADDR 57 #if !defined (DEFAULT_PING_TIMEOUT) # define DEFAULT_PING_TIMEOUT 1 diff -ruN dhcp-4.0.0/includes/stamp-h1 dhcp-4.0.0_hacked/includes/stamp-h1 --- dhcp-4.0.0/includes/stamp-h1 1969-12-31 19:00:00.000000000 -0500 +++ dhcp-4.0.0_hacked/includes/stamp-h1 2008-08-13 09:19:54.000000000 -0400 @@ -0,0 +1 @@ +timestamp for includes/config.h diff -ruN dhcp-4.0.0/server/dhcp.c dhcp-4.0.0_hacked/server/dhcp.c --- dhcp-4.0.0/server/dhcp.c 2007-11-02 18:09:02.000000000 -0400 +++ dhcp-4.0.0_hacked/server/dhcp.c 2008-08-13 09:23:39.000000000 -0400 @@ -1275,6 +1275,7 @@ unsigned i; struct option_state *options = (struct option_state *)0; struct option_cache *oc = (struct option_cache *)0; + int ignorep; option_state_allocate (&options, MDL); memset (&outgoing, 0, sizeof outgoing); @@ -1403,7 +1404,20 @@ /* If this was gatewayed, send it back to the gateway. Otherwise, broadcast it on the local network. */ if (raw.giaddr.s_addr) { - to.sin_addr = raw.giaddr; + /* determine whether to send the packet back to giaddr + or to the src IP... */ + oc = lookup_option (&server_universe, options, SV_RELAY_TO_GIADDR); + if (!oc || evaluate_boolean_option_cache (&ignorep, packet, + (struct lease *)0, + (struct client_state *)0, + packet->options, options, + &global_scope, oc, MDL)) { + + to.sin_addr = raw.giaddr; + } else { + to.sin_addr = *(struct in_addr *)packet->client_addr.iabuf; + } + if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK)) to.sin_port = local_port; else @@ -2815,6 +2829,8 @@ int nulltp, bootpp, unicastp = 1; struct data_string d1; const char *s; + struct option_cache *oc; + int ignorep; if (!state) log_fatal ("dhcp_reply was supplied lease with no state!"); @@ -2934,7 +2950,21 @@ /* If this was gatewayed, send it back to the gateway... */ if (raw.giaddr.s_addr) { - to.sin_addr = raw.giaddr; + + /* determine whether to send the packet back to giaddr + or to the src IP... */ + oc = lookup_option (&server_universe, state->options, SV_RELAY_TO_GIADDR); + if (!oc || evaluate_boolean_option_cache (&ignorep, state->packet, + lease, (struct client_state *)0, + state->packet->options, + state->options, + &global_scope, oc, MDL)) { + + to.sin_addr = raw.giaddr; + } else { + to.sin_addr = *(struct in_addr *)state->packet->client_addr.iabuf; + } + if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK)) to.sin_port = local_port; else diff -ruN dhcp-4.0.0/server/dhcpd.conf.5 dhcp-4.0.0_hacked/server/dhcpd.conf.5 --- dhcp-4.0.0/server/dhcpd.conf.5 2007-11-20 13:34:37.000000000 -0500 +++ dhcp-4.0.0_hacked/server/dhcpd.conf.5 2008-08-13 09:17:18.000000000 -0400 @@ -2586,6 +2586,19 @@ .RE .PP The +.I relay-to-giaddr +statement +.RS 0.25i +.PP +.B relay-to-giaddr \fIflag\fB;\fR +.PP +The \fIrelay-to-giaddr\fR parameter controls whether or not to respond +to the giaddr or the src IP when recieving a packet from a dhcp relay. +Set this to \fIoff\fR if the server should respond to the src IP of the +packet. The \fIrelay-to-giaddr\fR parameter is on by default. +.RE +.PP +The .I server-identifier statement .RS 0.25i diff -ruN dhcp-4.0.0/server/stables.c dhcp-4.0.0_hacked/server/stables.c --- dhcp-4.0.0/server/stables.c 2007-11-20 13:34:37.000000000 -0500 +++ dhcp-4.0.0_hacked/server/stables.c 2008-08-13 09:16:21.000000000 -0400 @@ -238,6 +238,7 @@ { "dhcpv6-lease-file-name", "t", &server_universe, 54, 1 }, { "dhcpv6-pid-file-name", "t", &server_universe, 55, 1 }, { "limit-addrs-per-ia", "L", &server_universe, 56, 1 }, + { "relay-to-giaddr", "f", &server_universe, 57, 1 }, { NULL, NULL, NULL, 0, 0 } };