]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
The require directive now requires that the required options are present in each...
authorRoy Marples <roy@marples.name>
Mon, 18 Aug 2008 12:43:05 +0000 (12:43 +0000)
committerRoy Marples <roy@marples.name>
Mon, 18 Aug 2008 12:43:05 +0000 (12:43 +0000)
client.c
dhcp.c
dhcp.h
dhcpcd.8.in
dhcpcd.c
dhcpcd.conf.5.in
dhcpcd.h

index 7d23c3910e168bd3122b04e9fef86f9c7feff653..18be14aac42a5c002963ace80bc0bdeb6d574438 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1357,7 +1357,7 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp,
        struct dhcp_message *dhcp = *dhcpp;
        struct interface *iface = state->interface;
        struct dhcp_lease *lease = &state->lease;
-       uint8_t type;
+       uint8_t type, tmp;
        struct in_addr addr;
        size_t i;
        int r;
@@ -1415,6 +1415,16 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp,
        /* No NAK, so reset the backoff */
        state->nakoff = 1;
 
+       /* Ensure that all required options are present */
+       for (i = 1; i < 255; i++) {
+               if (has_option_mask(options->requiremask, i) &&
+                   get_option_uint8(&tmp, dhcp, i) != 0)
+               {
+                       log_dhcp(LOG_WARNING, "reject", dhcp);
+                       return 0;
+               }
+       }
+
        if (type == DHCP_OFFER && state->state == STATE_DISCOVERING) {
                lease->addr.s_addr = dhcp->yiaddr;
                get_option_addr(&lease->server.s_addr, dhcp, DHO_SERVERID);
diff --git a/dhcp.c b/dhcp.c
index 460d7c5f04d10acebedac54628668fb5ce5e5d00..a9ef632cc5684d8642528e871fc7d7f8df60fb6a 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -166,7 +166,7 @@ print_options(void)
                        printf("%03d %s\n", opt->option, opt->var);
 }
 
-int make_reqmask(uint8_t *mask, char **opts, int add)
+int make_option_mask(uint8_t *mask, char **opts, int add)
 {
        char *token, *p = *opts, *t;
        const struct dhcp_opt *opt;
@@ -190,11 +190,11 @@ int make_reqmask(uint8_t *mask, char **opts, int add)
                        }
                        if (match) {    
                                if (add == 1)
-                                       add_reqmask(mask,
-                                                   opt->option);
+                                       add_option_mask(mask,
+                                                       opt->option);
                                else
-                                       del_reqmask(mask,
-                                                   opt->option);
+                                       del_option_mask(mask,
+                                                       opt->option);
                                break;
                        }
                }
@@ -908,7 +908,7 @@ make_message(struct dhcp_message **message,
                *p++ = 0;
                for (opt = dhcp_opts; opt->option; opt++) {
                        if (!(opt->type & REQUEST || 
-                             has_reqmask(options->reqmask, opt->option)))
+                             has_option_mask(options->requestmask, opt->option)))
                                continue;
                        switch (opt->option) {
                        case DHO_RENEWALTIME:   /* FALLTHROUGH */
@@ -1176,7 +1176,7 @@ configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
                for (opt = dhcp_opts; opt->option; opt++) {
                        if (!opt->var)
                                continue;
-                       if (has_reqmask(options->nomask, opt->option))
+                       if (has_option_mask(options->nomask, opt->option))
                                continue;
                        if (get_option_raw(dhcp, opt->option))
                                e++;
@@ -1219,7 +1219,7 @@ configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
        for (opt = dhcp_opts; opt->option; opt++) {
                if (!opt->var)
                        continue;
-               if (has_reqmask(options->nomask, opt->option))
+               if (has_option_mask(options->nomask, opt->option))
                        continue;
                val = NULL;
                p = get_option(dhcp, opt->option, &pl, NULL);
diff --git a/dhcp.h b/dhcp.h
index f135f649b0135dc0fa7241a59e918fb524d042c9..e584452c2a02240c3a02ccf8839515582daf16e1 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -154,10 +154,10 @@ struct dhcp_lease {
        uint8_t frominfo;
 };
 
-#define add_reqmask(var, val) (var[val >> 3] |= 1 << (val & 7))
-#define del_reqmask(var, val) (var[val >> 3] &= ~(1 << (val & 7)))
-#define has_reqmask(var, val) (var[val >> 3] & (1 << (val & 7)))
-int make_reqmask(uint8_t *, char **, int);
+#define add_option_mask(var, val) (var[val >> 3] |= 1 << (val & 7))
+#define del_option_mask(var, val) (var[val >> 3] &= ~(1 << (val & 7)))
+#define has_option_mask(var, val) (var[val >> 3] & (1 << (val & 7)))
+int make_option_mask(uint8_t *, char **, int);
 void print_options(void);
 char *get_option_string(const struct dhcp_message *, uint8_t);
 int get_option_addr(uint32_t *, const struct dhcp_message *, uint8_t);
index 90586310f0d5d9ee504d137d360fff9f845222ea..993a4c0830883acd0559e0ab7138eb466957b4a2 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd August 13, 2008
+.Dd August 18, 2008
 .Dt DHCPCD 8 SMM
 .Sh NAME
 .Nm dhcpcd
@@ -46,6 +46,7 @@
 .Op Fl F , -fqdn Ar FQDN
 .Op Fl I , -clientid Ar clientid
 .Op Fl O , -nooption Ar option
+.Op Fl Q , -require Ar option
 .Op Fl X , -blacklist Ar address
 .Ar interface
 .Nm
@@ -351,6 +352,10 @@ Don't use IPv4LL (aka APIPA, aka Bonjour, aka ZeroConf).
 Don't request the specified option.
 If no option given, then don't request any options other than those to
 configure the interface and routing.
+.It Fl Q , -require Ar option
+Requires the
+.Ar option
+to be present in all DHCP messages, otherwise the message is ignored.
 .It Fl T, -test
 On receipt of OFFER messages just call
 .Pa @SCRIPT@
index 3cd02b0d8b55cdf335382f8f83d9d9683cf50940..c32ffd92f14bd29992c1b73d586c9eedc8a80037 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -53,7 +53,7 @@ const char copyright[] = "Copyright (c) 2006-2008 Roy Marples";
 
 /* Don't set any optional arguments here so we retain POSIX
  * compatibility with getopt */
-#define OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:TVX:"
+#define OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:Q:TVX:"
 
 static int doversion = 0;
 static int dohelp = 0;
@@ -88,6 +88,7 @@ static const struct option longopts[] = {
        {"nolink",        no_argument,        NULL, 'K'},
        {"noipv4ll",      no_argument,        NULL, 'L'},
        {"nooption",      optional_argument,  NULL, 'O'},
+       {"require",       required_argument,  NULL, 'Q'},
        {"test",          no_argument,        NULL, 'T'},
        {"variables",     no_argument,        NULL, 'V'},
        {"blacklist",     required_argument,  NULL, 'X'},
@@ -154,7 +155,7 @@ usage(void)
        printf("usage: "PACKAGE" [-dknpqxADEGHKLOTV] [-c script] [-f file ] [-h hostname]\n"
               "              [-i classID ] [-l leasetime] [-m metric] [-o option] [-r ipaddr]\n"
               "              [-s ipaddr] [-t timeout] [-u userclass] [-F none|ptr|both]\n"
-              "              [-I clientID] [-C hookscript] [-X ipaddr] <interface>\n");
+              "              [-I clientID] [-C hookscript] [-Q option] [-X ipaddr] <interface>\n");
 }
 
 static char * 
@@ -361,7 +362,7 @@ parse_option(int opt, char *oarg, struct options *options)
                }
                break;
        case 'o':
-               if (make_reqmask(options->reqmask, &oarg, 1) != 0) {
+               if (make_option_mask(options->requestmask, &oarg, 1) != 0) {
                        logger(LOG_ERR, "unknown option `%s'", oarg);
                        return -1;
                }
@@ -531,13 +532,22 @@ parse_option(int opt, char *oarg, struct options *options)
                options->options &= ~DHCPCD_IPV4LL;
                break;
        case 'O':
-               if (make_reqmask(options->reqmask, &optarg, -1) != 0 ||
-                   make_reqmask(options->nomask, &optarg, 1) != 0)
+               if (make_option_mask(options->requestmask, &oarg, -1) != 0 ||
+                   make_option_mask(options->requiremask, &oarg, -1) != 0 ||
+                   make_option_mask(options->nomask, &oarg, 1) != 0)
                {
                        logger(LOG_ERR, "unknown option `%s'", optarg);
                        return -1;
                }
                break;
+       case 'Q':
+               if (make_option_mask(options->requiremask, &oarg, 1) != 0 ||
+                   make_option_mask(options->requestmask, &oarg, 1) != 0)
+               {
+                       logger(LOG_ERR, "unknown option `%s'", oarg);
+                       return -1;
+               }
+               break;
        case 'X':
                if (!inet_aton(oarg, &addr)) {
                        logger(LOG_ERR, "`%s' is not a valid IP address",
@@ -617,12 +627,12 @@ main(int argc, char **argv)
                                             "%s %s", PACKAGE, VERSION);
 
 #ifdef CMDLINE_COMPAT
-       add_reqmask(options->reqmask, DHO_DNSSERVER);
-       add_reqmask(options->reqmask, DHO_DNSDOMAIN);
-       add_reqmask(options->reqmask, DHO_DNSSEARCH);
-       add_reqmask(options->reqmask, DHO_NISSERVER);
-       add_reqmask(options->reqmask, DHO_NISDOMAIN);
-       add_reqmask(options->reqmask, DHO_NTPSERVER);
+       add_requestmask(options->requestmask, DHO_DNSSERVER);
+       add_requestmask(options->reqmask, DHO_DNSDOMAIN);
+       add_requestmask(options->reqmask, DHO_DNSSEARCH);
+       add_requestmask(options->reqmask, DHO_NISSERVER);
+       add_requestmask(options->reqmask, DHO_NISDOMAIN);
+       add_requestmask(options->reqmask, DHO_NTPSERVER);
 
        /* If the duid file exists, then enable duid by default
         * This means we don't break existing clients that easily :) */
@@ -771,22 +781,22 @@ main(int argc, char **argv)
 #ifdef CMDLINE_COMPAT
                case 'H': /* FALLTHROUGH */
                case 'M':
-                       del_reqmask(options->reqmask, DHO_MTU);
+                       del_requestmask(options->reqmask, DHO_MTU);
                        break;
                case 'N':
-                       del_reqmask(options->reqmask, DHO_NTPSERVER);
+                       del_requestmask(options->reqmask, DHO_NTPSERVER);
                        break;
                case 'R':
-                       del_reqmask(options->reqmask, DHO_DNSSERVER);
-                       del_reqmask(options->reqmask, DHO_DNSDOMAIN);
-                       del_reqmask(options->reqmask, DHO_DNSSEARCH);
+                       del_requestmask(options->reqmask, DHO_DNSSERVER);
+                       del_requestmask(options->reqmask, DHO_DNSDOMAIN);
+                       del_requestmask(options->reqmask, DHO_DNSSEARCH);
                        break;
                case 'S':
-                       add_reqmask(options->reqmask, DHO_MSCSR);
+                       add_requestmask(options->reqmask, DHO_MSCSR);
                        break;
                case 'Y':
-                       del_reqmask(options->reqmask, DHO_NISSERVER);
-                       del_reqmask(options->reqmask, DHO_NISDOMAIN);
+                       del_requestmask(options->reqmask, DHO_NISSERVER);
+                       del_requestmask(options->reqmask, DHO_NISDOMAIN);
                        break;
 #endif
                default:
index f58c087f52b48749504464c6dab5063386cc45ef..899aea35c8770bb20fc04c73e6a7d5da8432cb4b 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd August 17, 2008
+.Dd August 18, 2008
 .Dt DHCPCD.CONF 5 SMM
 .Sh NAME
 .Nm dhcpcd.conf
@@ -103,14 +103,22 @@ See
 .It Ic nolink
 Don't receive link messages about carrier status.
 You should only set this for buggy interface drivers.
-.It Ic option Ar dhcp-option
+.It Ic option Ar option
 Requests the
-.Ar dhcp-option
+.Ar option
 from the server.
 It can be a variable to be used in
 .Xr dhcpcd-run-hooks 8
 or the numerical value.
-You can specify more seperated by commas, spaces or more option lines.
+You can specify more options seperated by commas, spaces or more option lines.
+.It Ic require Ar option
+Requires the
+.Ar option
+to be present in all DHCP messages, otherwise the message is ignored.
+It can be a variable to be used in
+.Xr dhcpcd-run-hooks 8
+or the numerical value.
+You can specify more options seperated by commas, spaces or more require lines.
 .It Ic script Ar script
 Use
 .Ar script
index dc7cff417877539a6fe31f29b32a3d7f16317ad8..1cd2b5d5ffac36d4ebbcec1d996e30fd512ae2fd 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -68,7 +68,8 @@
 struct options {
        char interface[IF_NAMESIZE];
        int metric;
-       uint8_t reqmask[256 / 8];
+       uint8_t requestmask[256 / 8];
+       uint8_t requiremask[256 / 8];
        uint8_t nomask[256 / 8];
        uint32_t leasetime;
        time_t timeout;