]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Add support for specifying authority on a per-network-segment basis.
authorTed Lemon <source@isc.org>
Tue, 9 Feb 1999 04:58:20 +0000 (04:58 +0000)
committerTed Lemon <source@isc.org>
Tue, 9 Feb 1999 04:58:20 +0000 (04:58 +0000)
includes/dhcpd.h
server/confpars.c
server/dhcp.c
server/dhcpd.conf.5

index 0457108a26444cdf49d866a1cadf10a11e8f8f37..a1059e94eb59b6f9ceb7f456766e131da61c99a8 100644 (file)
@@ -3,8 +3,8 @@
    Definitions for dhcpd... */
 
 /*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
- * All rights reserved.
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -208,6 +208,7 @@ struct group {
        int get_lease_hostnames;
        int use_host_decl_names;
        int use_lease_addr_for_default_route;
+       int authoritative;
 
        struct tree_cache *options [256];
 };
index 30753e75847faa753e6719f68b6484c0adba02d9..46a6ec674ed45dcbafe288058ed39b3031b57607 100644 (file)
@@ -42,7 +42,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: confpars.c,v 1.45.2.5 1999/02/04 22:13:02 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
+"$Id: confpars.c,v 1.45.2.6 1999/02/09 04:55:46 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -73,6 +73,7 @@ int readconf ()
        root_group.boot_unknown_clients = 1;
        root_group.allow_bootp = 1;
        root_group.allow_booting = 1;
+       root_group.authoritative = 1;
 
        if ((cfile = fopen (path_dhcpd_conf, "r")) == NULL)
                error ("Can't open %s: %m", path_dhcpd_conf);
@@ -240,16 +241,24 @@ int parse_statement (cfile, group, type, host_decl, declaration)
                share -> group -> shared_network = share;
 
                parse_subnet_declaration (cfile, share);
+
+               /* share -> subnets is the subnet we just parsed. */
                if (share -> subnets) {
                        share -> interface =
                                share -> subnets -> interface;
 
+                       /* Make the shared network name from network number. */
                        n = piaddr (share -> subnets -> net);
                        t = malloc (strlen (n) + 1);
                        if (!t)
                                error ("no memory for subnet name");
                        strcpy (t, n);
                        share -> name = t;
+
+                       /* Copy the authoritative parameter from the subnet,
+                          since there is no opportunity to declare it here. */
+                       share -> group -> authoritative =
+                               share -> subnets -> group -> authoritative;
                        enter_shared_network (share);
                }
                return 1;
@@ -307,6 +316,34 @@ int parse_statement (cfile, group, type, host_decl, declaration)
                        parse_boolean (cfile);
                break;
 
+             case TOKEN_NOT:
+               token = next_token (&val, cfile);
+               switch (token) {
+                     case AUTHORITATIVE:
+                       if (type == HOST_DECL ||
+                           (type == SUBNET_DECL && share &&
+                            share -> subnets &&
+                            share -> subnets -> next_sibling))
+                           parse_warn ("authority makes no sense here."); 
+                       group -> authoritative = 0;
+                       parse_semi (cfile);
+                       break;
+                     default:
+                       parse_warn ("expecting assertion");
+                       skip_to_semi (cfile);
+                       break;
+               }
+               break;
+                       
+             case AUTHORITATIVE:
+               if (type == HOST_DECL ||
+                   (type == SUBNET_DECL && share && share -> subnets &&
+                    share -> subnets -> next_sibling))
+                   parse_warn ("authority makes no sense here."); 
+               group -> authoritative = 1;
+               parse_semi (cfile);
+               break;
+
              case NEXT_SERVER:
                tree = parse_ip_addr_or_hostname (cfile, 0);
                if (!tree)
index ede3fe042870b88a5b4f534787d8b030fe1f8348..1c58cc403e2448fad2c1bf79ac511f974db1348d 100644 (file)
@@ -42,7 +42,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: dhcp.c,v 1.57.2.14 1999/02/04 22:13:04 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium.  All rights reserved.\n";
+"$Id: dhcp.c,v 1.57.2.15 1999/02/09 04:57:29 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -274,7 +274,9 @@ void dhcprequest (packet)
                   where it claims to have come from, it didn't come
                   from there.   Fry it. */
                if (!packet -> shared_network) {
-                       if (subnet) {
+                       if (subnet &&
+                           subnet -> shared_network -> group -> authoritative)
+                       {
                                nak_lease (packet, &cip);
                                return;
                        }
@@ -286,7 +288,8 @@ void dhcprequest (packet)
                   address that is not on that shared network, nak it. */
                subnet = find_grouped_subnet (packet -> shared_network, cip);
                if (!subnet) {
-                       nak_lease (packet, &cip);
+                       if (packet -> shared_network -> group -> authoritative)
+                               nak_lease (packet, &cip);
                        return;
                }
        }
@@ -297,7 +300,7 @@ void dhcprequest (packet)
        if (lease && !addr_eq (lease -> ip_addr, cip)) {
                /* If we found the address the client asked for, but
                    it wasn't what got picked, the lease belongs to us,
-                   so we can tenuously justify NAKing it. */
+                   so we should NAK it. */
                if (ours)
                        nak_lease (packet, &cip);
                return;
index c5669d9258fbc0d2f5ae80eed83d27288d9ca5d3..d0cf0b81b212d5aa52d030b147aa1c8f903df744 100644 (file)
@@ -1,7 +1,7 @@
 .\"    dhcpd.conf.5
 .\"
-.\" Copyright (c) 1995, 1996 The Internet Software Consortium.
-.\" All rights reserved.
+.\" Copyright (c) 1995, 1996, 1997, 1998, 1998
+.\" The Internet Software Consortium.    All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -663,6 +663,41 @@ An \fIoption host-name\fR statement within a host declaration will
 override the use of the name in the host declaration.
 .PP
 .B The
+.I authoritative
+.B statement
+.PP
+ \fBauthoritative;\fR
+.PP
+ \fBnot authoritative;\fR
+.PP
+The DHCP server will normally assume that the configuration
+information about a given network segment is known to be correct and
+is authoritative.   So if a client requests an IP address on a given
+network segment that the server knows is not valid for that segment,
+the server will respond with a DHCPNAK message, causing the client to
+forget its IP address and try to get a new one.
+.PP
+If a DHCP server is being configured by somebody who is not the
+network administrator and who therefore does not wish to assert this
+level of authority, then the statement "not authoritative" should be
+written in the appropriate scope in the configuration file.
+.PP
+Usually, writing \fBnot authoritative;\fR at the top level of the file
+should be sufficient.   However, if a DHCP server is to be set up so
+that it is aware of some networks for which it is authoritative and
+some networks for which it is not, it may be more appropriate to
+declare authority on a per-network-segment basis.
+.PP
+Note that the most specific scope for which the concept of authority
+makes any sense is the physical network segment - either a
+shared-network statement or a subnet statement that is not contained
+within a shared-network statement.  It is not meaningful to specify
+that the server is authoritative for some subnets within a shared
+network, but not authoritative for others, nor is it meaningful to
+specify that the server is authoritative for some host declarations
+and not others.
+.PP
+.B The
 .I use-lease-addr-for-default-route
 .B statement
 .PP