]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- The subnet-mask option inclusion now conforms with RFC2132 section 3.3;
authorDavid Hankins <dhankins@isc.org>
Mon, 1 Oct 2007 16:24:44 +0000 (16:24 +0000)
committerDavid Hankins <dhankins@isc.org>
Mon, 1 Oct 2007 16:24:44 +0000 (16:24 +0000)
  it will only appear prior to the routers option if it is present on the
  Parameter-Request-List.  The subnet-mask option will also only be
  included by default (if it is not on the PRL) in response to DISCOVER
  or REQUEST messages.
  [ISC-Bugs #17117]
- The FQDN option is only supplied if the client supplied an FQDN option or
  if the FQDN option was explicitly requested on the PRL.
  [ISC-Bugs #17117]

RELNOTES
common/options.c

index 41557bdfbceede5f4afa054b09dd19fcb0b95171..7bc7a1deec6e83267576a81013dd6ad89d5ba96d 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -225,6 +225,15 @@ suggested fixes to <dhcp-users@isc.org>.
 
 - An assertion in lease counting relating to reserved leases was repaired.
 
+- The subnet-mask option inclusion now conforms with RFC2132 section 3.3;
+  it will only appear prior to the routers option if it is present on the
+  Parameter-Request-List.  The subnet-mask option will also only be
+  included by default (if it is not on the PRL) in response to DISCOVER
+  or REQUEST messages.
+
+- The FQDN option is only supplied if the client supplied an FQDN option or
+  if the FQDN option was explicitly requested on the PRL.
+
                        Changes since 3.1.0rc1
 
 - The parse warning that 'deny dyanmic bootp;' must be configured for
index 3c8ac93c3d84e8cfba57da8e491c88fbdd264be2..eb5f83c17b3f796bb33b75a4ce91cf5989d8055e 100644 (file)
@@ -621,19 +621,29 @@ int cons_options (inpacket, outpacket, lease, client_state,
                                        prl -> data [i];
                }
 
-               /* If the client doesn't request this option explicitly,
+               /* If the client doesn't request the FQDN option explicitly,
                 * to indicate priority, consider it lowest priority.  Fit
-                * in the packet if there is space.
+                * in the packet if there is space.  Note that the option
+                * may only be included if the client supplied one.
                 */
-               if (priority_len < PRIORITY_COUNT)
+               if ((priority_len < PRIORITY_COUNT) &&
+                   (lookup_option(&dhcp_universe, inpacket->options,
+                                  DHO_FQDN) != NULL))
                        priority_list[priority_len++] = DHO_FQDN;
 
                /* Some DHCP Servers will give the subnet-mask option if
                 * it is not on the parameter request list - so some client
                 * implementations have come to rely on this - so we will
                 * also make sure we supply this, at lowest priority.
+                *
+                * This is only done in response to DHCPDISCOVER or
+                * DHCPREQUEST messages, to avoid providing the option on
+                * DHCPINFORM or DHCPLEASEQUERY responses (if the client
+                * didn't request it).
                 */
-               if (priority_len < PRIORITY_COUNT)
+               if ((priority_len < PRIORITY_COUNT) &&
+                   ((inpacket->packet_type == DHCPDISCOVER) ||
+                    (inpacket->packet_type == DHCPREQUEST)))
                        priority_list[priority_len++] = DHO_SUBNET_MASK;
 
        } else {
@@ -1104,11 +1114,11 @@ int store_options (ocount, buffer, buflen, packet, lease, client_state,
 
        memset (&od, 0, sizeof od);
 
-       /* Eliminate duplicate options in the parameter request list.
-          There's got to be some clever knuthian way to do this:
-          Eliminate all but the first occurance of a value in an array
-          of values without otherwise disturbing the order of the array. */
+       /* Eliminate duplicate options from the parameter request list.
+        * Enforce RFC-mandated ordering of options that are present.
+        */
        for (i = 0; i < priority_len - 1; i++) {
+               /* Eliminate duplicates. */
                tto = 0;
                for (ix = i + 1; ix < priority_len + tto; ix++) {
                        if (tto)
@@ -1119,6 +1129,33 @@ int store_options (ocount, buffer, buflen, packet, lease, client_state,
                                priority_len--;
                        }
                }
+
+               /* Enforce ordering of SUBNET_MASK options, according to
+                * RFC2132 Section 3.3:
+                *
+                *   If both the subnet mask and the router option are
+                *   specified in a DHCP reply, the subnet mask option MUST
+                *   be first.
+                *
+                * This guidance does not specify what to do if the client
+                * PRL explicitly requests the options out of order, it is
+                * a general statement.
+                */
+               if (priority_list[i] == DHO_SUBNET_MASK) {
+                       for (ix = i - 1 ; ix >= 0 ; ix--) {
+                               /* We know that anything before 'i' can only
+                                * appear once.  So shovel the options to make
+                                * room to bubble the subnet mask ahead, and
+                                * then break out of the loop, we're done.
+                                */
+                               if (priority_list[ix] == DHO_ROUTERS) {
+                                       memmove(priority_list + ix + 1,
+                                               priority_list + ix, i - ix);
+                                       priority_list[ix] = DHO_SUBNET_MASK;
+                                       break;
+                               }
+                       }
+               }
        }
 
        /* Copy out the options in the order that they appear in the