From: Thomas Markwalder Date: Mon, 15 Aug 2016 10:52:58 +0000 (-0400) Subject: [master] Added "-id" command line argument to dhcrelay v4 mode X-Git-Tag: v4_4_0b1_f1~144 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edd6d8881bc4d8ec4b04173c66c1c840756bbe76;p=thirdparty%2Fdhcp.git [master] Added "-id" command line argument to dhcrelay v4 mode Merges in rt41547b. --- diff --git a/RELNOTES b/RELNOTES index 3927402d6..d85849866 100644 --- a/RELNOTES +++ b/RELNOTES @@ -878,8 +878,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. +- Add DHCPv4-mode, dhcrelay command line options, "-iu" and "-id", that + allow interfaces to be upstream or downstream respectively. Upstream + interfaces will accept and forward only BOOTP replies, while downstream + interfaces will accept and forward only BOOTP requests. [ISC-Bugs #41547] Changes since 4.2.0 (new features) diff --git a/relay/dhcrelay.8 b/relay/dhcrelay.8 index 1091edb7e..517b91a7b 100644 --- a/relay/dhcrelay.8 +++ b/relay/dhcrelay.8 @@ -77,6 +77,7 @@ dhcrelay - Dynamic Host Configuration Protocol Relay Agent .B -i .I interfaceN ] +] [ .B -iu .I interface0 @@ -85,9 +86,17 @@ dhcrelay - Dynamic Host Configuration Protocol Relay Agent .B -iu .I interfaceN ] -.B -l -.I interface ] +[ +.B -id +.I interface0 +[ +.B ... +.B -id +.I interfaceN +] +] +[ .B -U .I interface ] @@ -219,11 +228,16 @@ 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. +Specifies an upstream network interface: 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-iu\fR option. This argument is + intended to be used in conjunction with one or more -i or -id arguments. +.TP +-id \fIifname\fR +Specifies a downstream network interface: an interface from which requests +from clients and other relay agents will be accepted. Multiple interfaces +may be specified by using more than one \fB-id\fR option. This argument is +intended to be used in conjunction with one or more -i or -iu arguments. .TP -m \fIappend\fR|\fIreplace\fR|\fIforward\fR|\fIdiscard\fR Control the handling of incoming DHCPv4 packets which already contain diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 4127fccc2..344cee784 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -136,6 +136,8 @@ static int strip_relay_agent_options(struct interface_info *, struct interface_info **, struct dhcp_packet *, unsigned); +static void request_v4_interface(const char* name, int flags); + static const char copyright[] = "Copyright 2004-2016 Internet Systems Consortium."; static const char arr[] = "All rights reserved."; @@ -154,6 +156,7 @@ char *progname; " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ " [-iu interface0 [ ... -iu interfaceN]\n" \ +" [-id interface0 [ ... -id interfaceN]\n" \ " [-U interface]\n" \ " server0 [ ... serverN]\n\n" \ " %s -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ @@ -170,6 +173,7 @@ char *progname; " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ " [-iu interface0 [ ... -iu interfaceN]\n" \ +" [-id interface0 [ ... -id interfaceN]\n" \ " [-U interface]\n" \ " server0 [ ... serverN]\n\n" #endif @@ -217,7 +221,6 @@ main(int argc, char **argv) { isc_result_t status; struct servent *ent; struct server_list *sp = NULL; - struct interface_info *tmp = NULL; char *service_local = NULL, *service_remote = NULL; u_int16_t port_local = 0, port_remote = 0; int no_daemon = 0, quiet = 0; @@ -315,21 +318,8 @@ main(int argc, char **argv) { 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_STREAMS)); - interface_dereference(&tmp, MDL); + + request_v4_interface(argv[i], INTERFACE_STREAMS); } else if (!strcmp(argv[i], "-iu")) { #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { @@ -341,21 +331,21 @@ main(int argc, char **argv) { 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])); + + request_v4_interface(argv[i], INTERFACE_UPSTREAM); + } else if (!strcmp(argv[i], "-id")) { +#ifdef DHCPv6 + if (local_family_set && (local_family == AF_INET6)) { + usage(use_v4command, argv[i]); } - status = interface_allocate(&tmp, MDL); - if (status != ISC_R_SUCCESS) { - log_fatal("%s: interface_allocate: %s", - argv[i], - isc_result_totext(status)); + local_family_set = 1; + local_family = AF_INET; +#endif + if (++i == argc) { + usage(use_noarg, argv[i-1]); } - strcpy(tmp->name, argv[i]); - interface_snorf(tmp, (INTERFACE_REQUESTED | - INTERFACE_UPSTREAM)); - interface_dereference(&tmp, MDL); + + request_v4_interface(argv[i], INTERFACE_DOWNSTREAM); } else if (!strcmp(argv[i], "-a")) { #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { @@ -822,6 +812,11 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, if (out) return; + if (!(ip->flags & INTERFACE_DOWNSTREAM)) { + log_debug("Dropping request received on %s", ip->name); + return; + } + /* Add relay agent options if indicated. If something goes wrong, * drop the packet. Note this may set packet->giaddr if RFC3527 * is enabled. */ @@ -1878,3 +1873,40 @@ dhcp_set_control_state(control_object_state_t oldstate, exit(0); } + +/*! + * + * \brief Allocate an interface as requested with a given set of flags + * + * The requested interface is allocated, its flags field is set to + * INTERFACE_REQUESTED OR'd with the given flags, and then added to + * the list of interfaces. + * + * \param name - name of the requested interface + * \param flags - additional flags for the interface + * + * \return Nothing + */ +void request_v4_interface(const char* name, int flags) { + struct interface_info *tmp = NULL; + int len = strlen(name); + isc_result_t status; + + if (len >= sizeof(tmp->name)) { + log_fatal("%s: interface name too long (is %d)", name, len); + } + + status = interface_allocate(&tmp, MDL); + if (status != ISC_R_SUCCESS) { + log_fatal("%s: interface_allocate: %s", name, + isc_result_totext(status)); + } + + log_debug("Requesting: %s as upstream: %c downstream: %c", name, + (flags & INTERFACE_UPSTREAM ? 'Y' : 'N'), + (flags & INTERFACE_DOWNSTREAM ? 'Y' : 'N')); + + strncpy(tmp->name, name, len); + interface_snorf(tmp, (INTERFACE_REQUESTED | flags)); + interface_dereference(&tmp, MDL); +}