From: Thomas Markwalder Date: Wed, 10 Aug 2016 18:52:01 +0000 (-0400) Subject: [v4_1_esv] Added "-iu" command line argument to dhcrelay X-Git-Tag: v4_1_esv_r14b1~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=05e8c817bd531192cc04c45bf529bbf1ede5c569;p=thirdparty%2Fdhcp.git [v4_1_esv] Added "-iu" command line argument to dhcrelay Manually merged 41547a. --- diff --git a/RELNOTES b/RELNOTES index 22be8bb8c..49447803a 100644 --- a/RELNOTES +++ b/RELNOTES @@ -104,6 +104,10 @@ by Eric Young (eay@cryptsoft.com). it runs out. [ISC-Bugs #42452] +- Add a new command line option, "-iu", to dhcrelay which allows one + or more interfaces to be regisetered to listen only for BOOTP replies. + [ISC-Bugs #41547] + Changes since 4.1-ESV-R13b1 - None diff --git a/common/discover.c b/common/discover.c index da0c3f81d..81d20e085 100644 --- a/common/discover.c +++ b/common/discover.c @@ -950,8 +950,14 @@ discover_interfaces(int state) { ir = 0; else if (state == DISCOVER_UNCONFIGURED) ir = INTERFACE_REQUESTED | INTERFACE_AUTOMATIC; - else + else { ir = INTERFACE_REQUESTED; + if (state == DISCOVER_RELAY && local_family == AF_INET) { + /* We're a v4 relay without specifically requested + * interfaces, so mark them all as bidirectional. */ + ir |= INTERFACE_STREAMS; + } + } /* Cycle through the list of interfaces looking for IP addresses. */ while (next_iface(&info, &err, &ifaces)) { diff --git a/relay/dhcrelay.8 b/relay/dhcrelay.8 index 91d4e6c2b..695a2145b 100644 --- a/relay/dhcrelay.8 +++ b/relay/dhcrelay.8 @@ -76,6 +76,15 @@ dhcrelay - Dynamic Host Configuration Protocol Relay Agent [ .B ... .B -i +.I interfaceN +] +] +[ +.B -iu +.I interface0 +[ +.B ... +.B -iu .I interfaceN ] ] @@ -196,12 +205,19 @@ a query that came via a different relay agent. If this option is not specified, such packets will be relayed anyway. .TP -i \fIifname\fR -Listen for DHCPv4/BOOTP queries on interface \fIifname\fR. Multiple +Listen for DHCPv4/BOOTP traffic on interface \fIifname\fR. Multiple interfaces may be specified by using more than one \fB-i\fR option. If no interfaces are specified on the command line, dhcrelay will identify all network interfaces, eliminating non-broadcast interfaces if possible, and attempt to listen on all of them. .TP +-iu \fIifname\fR +Specifies an upstream network interface for DHCPv4 relay mode: an +interface from which replies from servers and other relay agents will be +accepted. Multiple interfaces may be specified by using more +than one \fB-u\fR option. This argument is intended to be used +in conjunction with one or more -i arguments. +.TP -m \fIappend\fR|\fIreplace\fR|\fIforward\fR|\fIdiscard\fR Control the handling of incoming DHCPv4 packets which already contain relay agent options. If such a packet does not have \fIgiaddr\fR set in diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index f52e64349..a0bb5e69d 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -141,6 +141,7 @@ char *progname; " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ +" [-ui interface0 [ ... -ui interfaceN]\n" \ " server0 [ ... serverN]\n\n" \ " %s -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ " [-pf ] [--no-pid]\n"\ @@ -154,6 +155,7 @@ char *progname; " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ +" [-ui interface0 [ ... -ui interfaceN]\n" \ " server0 [ ... serverN]\n\n" #endif @@ -311,7 +313,34 @@ main(int argc, char **argv) { isc_result_totext(status)); } strcpy(tmp->name, argv[i]); - interface_snorf(tmp, INTERFACE_REQUESTED); + interface_snorf(tmp, (INTERFACE_REQUESTED + | INTERFACE_STREAMS)); + interface_dereference(&tmp, MDL); + } else if (!strcmp(argv[i], "-iu")) { +#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 (++i == argc) { + usage(use_noarg, argv[i-1]); + } + if (strlen(argv[i]) >= sizeof(tmp->name)) { + log_fatal("%s: interface name too long " + "(is %ld)", + argv[i], (long)strlen(argv[i])); + } + status = interface_allocate(&tmp, MDL); + if (status != ISC_R_SUCCESS) { + log_fatal("%s: interface_allocate: %s", + argv[i], + isc_result_totext(status)); + } + strcpy(tmp->name, argv[i]); + interface_snorf(tmp, (INTERFACE_REQUESTED + | INTERFACE_UPSTREAM)); interface_dereference(&tmp, MDL); } else if (!strcmp(argv[i], "-a")) { #ifdef DHCPv6 @@ -670,6 +699,11 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, /* If it's a bootreply, forward it to the client. */ if (packet->op == BOOTREPLY) { + if (!(ip->flags & INTERFACE_UPSTREAM)) { + log_debug("Dropping reply received on %s", ip->name); + return; + } + if (!(packet->flags & htons(BOOTP_BROADCAST)) && can_unicast_without_arp(out)) { to.sin_addr = packet->yiaddr;