Add 'echo-client-id' statment, so that RFC 6842 behaviour can be
authorkrw <krw@openbsd.org>
Mon, 24 Apr 2017 14:58:36 +0000 (14:58 +0000)
committerkrw <krw@openbsd.org>
Mon, 24 Apr 2017 14:58:36 +0000 (14:58 +0000)
turned off for those clients and networks that find it impossible to
move past RFC 2131. Modelled on the same statement in recent ISC
versions, though we default to 'on' (a.k.a. RFC 6842) rather that
'off' (a.k.a. RFC 2131).

Problems reported by Bastien Durel (Xerox Phaser 6022 printer) and
Bryan Vyhmeister (Hon Hai Precision router) via misc@. Thanks!

usr.sbin/dhcpd/conflex.c
usr.sbin/dhcpd/confpars.c
usr.sbin/dhcpd/dhcp.c
usr.sbin/dhcpd/dhcpd.conf.5
usr.sbin/dhcpd/dhcpd.h
usr.sbin/dhcpd/dhctoken.h

index 73d463a..c66be48 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: conflex.c,v 1.18 2017/04/12 19:12:01 krw Exp $        */
+/*     $OpenBSD: conflex.c,v 1.19 2017/04/24 14:58:36 krw Exp $        */
 
 /* Lexical scanner for dhcpd config file... */
 
@@ -311,6 +311,7 @@ static const struct keywords {
        { "dynamic-bootp",              TOK_DYNAMIC_BOOTP },
        { "dynamic-bootp-lease-cutoff", TOK_DYNAMIC_BOOTP_LEASE_CUTOFF },
        { "dynamic-bootp-lease-length", TOK_DYNAMIC_BOOTP_LEASE_LENGTH },
+       { "echo-client-id",             TOK_ECHO_CLIENT_ID },
        { "ends",                       TOK_ENDS },
        { "ethernet",                   TOK_ETHERNET },
        { "filename",                   TOK_FILENAME },
index 820556e..1dd4a55 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: confpars.c,v 1.32 2017/04/12 19:12:01 krw Exp $ */
+/*     $OpenBSD: confpars.c,v 1.33 2017/04/24 14:58:36 krw Exp $ */
 
 /*
  * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
@@ -82,6 +82,7 @@ readconf(void)
        root_group.allow_bootp = 1;
        root_group.allow_booting = 1;
        root_group.authoritative = 1;
+       root_group.echo_client_id = 1;
 
        if ((cfile = fopen(path_dhcpd_conf, "r")) == NULL)
                fatal("Can't open %s", path_dhcpd_conf);
@@ -319,6 +320,10 @@ parse_statement(FILE *cfile, struct group *group, int type,
                group->always_reply_rfc1048 = parse_boolean(cfile);
                break;
 
+       case TOK_ECHO_CLIENT_ID:
+               group->echo_client_id = parse_boolean(cfile);
+               break;
+
        case TOK_USE_HOST_DECL_NAMES:
                if (type == HOST_DECL)
                        parse_warn("use-host-decl-names not allowed here.");
index 27355eb..e55f4d4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcp.c,v 1.55 2017/02/13 23:04:05 krw Exp $ */
+/*     $OpenBSD: dhcp.c,v 1.56 2017/04/24 14:58:36 krw Exp $ */
 
 /*
  * Copyright (c) 1995, 1996, 1997, 1998, 1999
@@ -708,7 +708,7 @@ ack_lease(struct packet *packet, struct lease *lease, unsigned int offer,
        struct lease_state *state;
        time_t lease_time, offered_lease_time, max_lease_time, default_lease_time;
        struct class *vendor_class, *user_class;
-       int ulafdr, i;
+       int ulafdr, echo_client_id, i;
 
        /* If we're already acking this lease, don't do it again. */
        if (lease->state) {
@@ -1239,8 +1239,16 @@ ack_lease(struct packet *packet, struct lease *lease, unsigned int offer,
        memset(&state->options[i], 0, sizeof(state->options[i]));
 
        /* Echo back the client-identifier as RFC 6842 mandates. */
+       if (lease->host)
+               echo_client_id = lease->host->group->echo_client_id;
+       else if (user_class)
+               echo_client_id = user_class->group->echo_client_id;
+       else if (vendor_class)
+               echo_client_id = vendor_class->group->echo_client_id;
+       else
+               echo_client_id = lease->subnet->group->echo_client_id;
        i = DHO_DHCP_CLIENT_IDENTIFIER;
-       if (lease->client_identifier) {
+       if (lease->client_identifier && echo_client_id) {
                state->options[i] = new_tree_cache("dhcp-client-identifier");
                state->options[i]->flags = TC_TEMPORARY;
                state->options[i]->value = lease->client_identifier;
index 0910a67..459756b 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: dhcpd.conf.5,v 1.18 2017/02/04 22:21:57 jca Exp $
+.\"    $OpenBSD: dhcpd.conf.5,v 1.19 2017/04/24 14:58:36 krw Exp $
 .\"
 .\" Copyright (c) 1995, 1996, 1997, 1998, 1998, 1999
 .\" The Internet Software Consortium.    All rights reserved.
@@ -36,7 +36,7 @@
 .\" see ``http://www.isc.org/isc''.  To learn more about Vixie
 .\" Enterprises, see ``http://www.vix.com''.
 .\"
-.Dd $Mdocdate: February 4 2017 $
+.Dd $Mdocdate: April 24 2017 $
 .Dt DHCPD.CONF 5
 .Os
 .Sh NAME
@@ -919,6 +919,23 @@ Supplying a value for the
 option is equivalent to using the
 .Ic server-identifier
 statement.
+.Pp
+The
+.Ic echo-client-id
+statement
+.Pp
+.D1 Ic echo-client-id Ar flag ;
+.Pp
+is used to enable or disable RFC 6842 compliant behavior.
+If the
+.Ic echo-client-id
+statement is present and has a
+value of true or on, and a DHCP DISCOVER or REQUEST is received which contains
+the client identifier option (Option code 61), the server will copy the option
+into its response (DHCP ACK or NAK) per RFC 6842.
+In other words if the client sends the option it will receive it back.
+By default, this flag is on
+and client identifiers will be echoed back to the client.
 .Sh REFERENCE: OPTION STATEMENTS
 DHCP option statements are documented in the
 .Xr dhcp-options 5
index 94a8d86..3271b2d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpd.h,v 1.63 2017/04/18 13:59:09 krw Exp $ */
+/*     $OpenBSD: dhcpd.h,v 1.64 2017/04/24 14:58:36 krw Exp $ */
 
 /*
  * Copyright (c) 1995, 1996, 1997, 1998, 1999
@@ -223,6 +223,7 @@ struct group {
        int use_lease_addr_for_default_route;
        int authoritative;
        int always_reply_rfc1048;
+       int echo_client_id;
 
        struct tree_cache *options[256];
 };
index b600ab9..c925a79 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhctoken.h,v 1.7 2013/12/05 22:31:35 krw Exp $        */
+/*     $OpenBSD: dhctoken.h,v 1.8 2017/04/24 14:58:36 krw Exp $        */
 
 /* Tokens for config file lexer and parser. */
 
@@ -91,6 +91,7 @@
 #define TOK_TOKEN_NOT                  334
 #define TOK_ALWAYS_REPLY_RFC1048       335
 #define TOK_IPSEC_TUNNEL               336
+#define TOK_ECHO_CLIENT_ID             337
 
 #define is_identifier(x)       ((x) >= TOK_FIRST_TOKEN &&      \
                                 (x) != TOK_STRING &&   \