From: Thomas Markwalder Date: Mon, 15 Aug 2016 11:26:06 +0000 (-0400) Subject: [v4_1_esv] Add -id command line argument to dhcrelay X-Git-Tag: v4_1_esv_r14b1~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=166ff076a56252812aa65d2cd345505f2540855a;p=thirdparty%2Fdhcp.git [v4_1_esv] Add -id command line argument to dhcrelay Merges in rt41547b. --- diff --git a/RELNOTES b/RELNOTES index 49447803a..d66547cb9 100644 --- a/RELNOTES +++ b/RELNOTES @@ -104,8 +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. +- Add DHCPv4-mode, dhcrelay command line options, "-iu" and "-id", that + allow interfaces to be upstream or downstream respectively. Upstream + interfaces will only accept and forward BOOTP replies, while downstream + interfaces will only accept and forward BOOTP requests. [ISC-Bugs #41547] Changes since 4.1-ESV-R13b1 diff --git a/relay/dhcrelay.8 b/relay/dhcrelay.8 index 695a2145b..1fde7156e 100644 --- a/relay/dhcrelay.8 +++ b/relay/dhcrelay.8 @@ -1,6 +1,6 @@ .\" dhcrelay.8 .\" -.\" Copyright (c) 2009-2012 by Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (c) 2009-2016 by Internet Systems Consortium, Inc. ("ISC") .\" Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC") .\" Copyright (c) 1997-2003 by Internet Software Consortium .\" @@ -88,6 +88,15 @@ dhcrelay - Dynamic Host Configuration Protocol Relay Agent .I interfaceN ] ] +[ +.B -id +.I interface0 +[ +.B ... +.B -id +.I interfaceN +] +] .I server0 [ .I ...serverN @@ -212,11 +221,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 a0bb5e69d..704a6b6e1 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -123,6 +123,7 @@ static int find_interface_by_agent_option(struct dhcp_packet *, 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."; @@ -141,7 +142,8 @@ char *progname; " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ -" [-ui interface0 [ ... -ui interfaceN]\n" \ +" [-iu interface0 [ ... -iu interfaceN]\n" \ +" [-id interface0 [ ... -id interfaceN]\n" \ " server0 [ ... serverN]\n\n" \ " %s -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ " [-pf ] [--no-pid]\n"\ @@ -155,7 +157,8 @@ char *progname; " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ -" [-ui interface0 [ ... -ui interfaceN]\n" \ +" [-iu interface0 [ ... -iu interfaceN]\n" \ +" [-id interface0 [ ... -id interfaceN]\n" \ " server0 [ ... serverN]\n\n" #endif @@ -202,7 +205,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; @@ -301,21 +303,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)) { @@ -327,21 +316,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)) { @@ -761,6 +750,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. */ if (!(length = add_relay_agent_options(ip, packet, length, @@ -1769,3 +1763,41 @@ dhcp_set_control_state(control_object_state_t oldstate, control_object_state_t newstate) { return ISC_R_SUCCESS; } + + +/*! + * + * \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); +}