]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[v4_1_esv] Add -id command line argument to dhcrelay
authorThomas Markwalder <tmark@isc.org>
Mon, 15 Aug 2016 11:26:06 +0000 (07:26 -0400)
committerThomas Markwalder <tmark@isc.org>
Mon, 15 Aug 2016 11:26:06 +0000 (07:26 -0400)
    Merges in rt41547b.

RELNOTES
relay/dhcrelay.8
relay/dhcrelay.c

index 49447803a03450cc9de328d514bc298f1ac31349..d66547cb908c970ea863657b660c462126c72c06 100644 (file)
--- 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
index 695a2145b3f549a0727a6d7af59f8b6522162af5..1fde7156ebfc3e53feaddfbeb5856c17e5ce60ad 100644 (file)
@@ -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
index a0bb5e69d34a586b3fa3d41ac8ef002aa50942a1..704a6b6e1571d865976b23ffe977d7d9596ac5d5 100644 (file)
@@ -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 <pid-file>] [--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 <hops>] [-p <port>]\n" \
 "                     [-pf <pid-file>] [--no-pid]\n"\
@@ -155,7 +157,8 @@ char *progname;
 "                [-pf <pid-file>] [--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);
+}