2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 18:07:25 +00:00

dhcrelay: option to force giaddr

Use option  -g ipaddr  to replace the giaddr sent to clients with
the given ipaddr to workaround bogus clients like Solaris 11 grub
which use giaddr instead of the announced router (3) to setup its
default route.
This commit is contained in:
Jens Elkner 2022-01-29 09:32:04 +01:00 committed by Tomek Mrugalski
parent 726912a1c9
commit 57913f7f7f
2 changed files with 35 additions and 4 deletions

View File

@ -103,6 +103,10 @@ dhcrelay - Dynamic Host Configuration Protocol Relay Agent
.B -U
.I interface
]
[
.B -g
.I ipaddr
]
.I server0
[
.I ...serverN
@ -234,6 +238,12 @@ Information options that indicate they were generated in response to
a query that came via a different relay agent. If this option is not
specified, such packets will be relayed anyway.
.TP
-g \fIipaddr\fR
When a package gets sent back to the client, replace the gateway's IP
address (giaddr) with the given \fIipaddr\fR. This can be used as a
workaround for bogus clients like Solaris 11 grub, which use the giaddr
instead of the announced router (3) to setup its default route.
.TP
-i \fIifname\fR
Listen for DHCPv4/BOOTP traffic on interface \fIifname\fR. Multiple
interfaces may be specified by using more than one \fB-i\fR option. If

View File

@ -105,6 +105,8 @@ struct server_list {
} *servers;
struct interface_info *uplink = NULL;
static isc_boolean_t fake_gw = ISC_FALSE;
static struct in_addr gw ;
#ifdef DHCPv6
struct stream_list {
@ -169,7 +171,7 @@ char *progname;
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip_address>]\n" \
" server0 [ ... serverN]\n\n" \
" %s -6 [-d] [-q] [-I] [-c <hops>]\n" \
" [-p <port> | -rp <relay-port>]\n" \
@ -189,7 +191,7 @@ char *progname;
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip_address>]\n" \
" server0 [ ... serverN]\n\n" \
" %s -6 [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
" [-pf <pid-file>] [--no-pid]\n" \
@ -210,7 +212,7 @@ char *progname;
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip_address>]\n" \
" server0 [ ... serverN]\n\n" \
" %s {--version|--help|-h}"
#else
@ -221,7 +223,7 @@ char *progname;
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip_address>]\n" \
" server0 [ ... serverN]\n\n" \
" %s {--version|--help|-h}"
#endif
@ -547,6 +549,21 @@ main(int argc, char **argv) {
/* Turn on -a, in case they don't do so explicitly */
add_agent_options = 1;
add_rfc3527_suboption = 1;
} else if (!strcmp(argv[i], "-g")) {
if (++i == argc)
usage(use_noarg, argv[i-1]);
#ifdef DHCPv6
if (local_family_set && (local_family == AF_INET6)) {
usage(use_v4command, argv[i]);
}
local_family_set = 1;
local_family = AF_INET;
#endif
if (inet_pton(AF_INET, argv[i], &gw) <= 0) {
usage("Invalid gateway address '%s'", argv[i]);
} else {
fake_gw = ISC_TRUE;
}
} else if (!strcmp(argv[i], "-D")) {
#ifdef DHCPv6
if (local_family_set && (local_family == AF_INET6)) {
@ -878,6 +895,7 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
return;
}
log_debug("BOOTREPLY giaddr: %s\n", inet_ntoa(packet->giaddr));
if (!(packet->flags & htons(BOOTP_BROADCAST)) &&
can_unicast_without_arp(out)) {
to.sin_addr = packet->yiaddr;
@ -916,6 +934,9 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
return;
}
if (fake_gw) {
packet->giaddr = gw;
}
if (send_packet(out, NULL, packet, length, out->addresses[0],
&to, htop) < 0) {
++server_packet_errors;