]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add -X, --blacklist option to reject DHCP messages with a matching serverid.
authorRoy Marples <roy@marples.name>
Mon, 28 Jul 2008 13:21:47 +0000 (13:21 +0000)
committerRoy Marples <roy@marples.name>
Mon, 28 Jul 2008 13:21:47 +0000 (13:21 +0000)
client.c
dhcpcd.8.in
dhcpcd.c
dhcpcd.h

index f8dbd31cce3eb5da0a92628e1e8dde5e4eb8ea22..79a494e5e0fdfd3523fcf6b41b581cc268793666 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1330,13 +1330,13 @@ log_dhcp(int lvl, const char *msg, const struct dhcp_message *dhcp)
        struct in_addr server;
        int r;
 
+       r = get_option_addr(&server.s_addr, dhcp, DHCP_SERVERID);
        if (strcmp(msg, "NAK:") == 0)
                addr = get_option_string(dhcp, DHCP_MESSAGE);
        else {
                server.s_addr = dhcp->yiaddr;
                addr = xstrdup(inet_ntoa(server));
        }
-       r = get_option_addr(&server.s_addr, dhcp, DHCP_SERVERID);
        if (dhcp->servername[0] && r == 0)
                logger(lvl, "%s %s from %s `%s'", msg,
                       addr, inet_ntoa(server),
@@ -1356,14 +1356,38 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp,
        struct interface *iface = state->interface;
        struct dhcp_lease *lease = &state->lease;
        uint8_t type;
+       struct in_addr server;
+       size_t i;
+
+       /* reset the message counter */
+       state->messages = 0;
 
+       /* We have to have DHCP type to work */
        if (get_option_uint8(&type, dhcp, DHCP_MESSAGETYPE) == -1) {
                log_dhcp(LOG_ERR, "no DHCP type in", dhcp);
-               return -1;
+               return 0;
        }
 
-       /* reset the message counter */
-       state->messages = 0;
+       /* Ensure that it's not from a blacklisted server.
+        * We should expand this to check IP and/or hardware address
+        * at the packet level. */
+       if (options->blacklist_len != 0 &&
+           get_option_addr(&server.s_addr, dhcp, DHCP_SERVERID) == 0)
+       {
+               for (i = 0; i < options->blacklist_len; i++) {
+                       if (options->blacklist[i] != server.s_addr)
+                               continue;
+                       if (dhcp->servername[0])
+                               logger(LOG_WARNING,
+                                      "ignoring blacklisted server %s `%s'",
+                                       inet_ntoa(server), dhcp->servername);
+                       else
+                               logger(LOG_WARNING,
+                                      "ignoring blacklisted server %s",
+                                      inet_ntoa(server));
+                       return 0;
+               }
+       }
 
        /* We should restart on a NAK */
        if (type == DHCP_NAK) {
index 33287040a6bdff9c8eca972adbf62157fffeef20..dcf8448380f7cc22025af69741e48792939ef1ac 100644 (file)
@@ -46,6 +46,7 @@
 .Op Fl F , -fqdn Ar FQDN
 .Op Fl I , -clientid Ar clientid
 .Op Fl O , -nooption Ar option
+.Op Fl X , -blacklist Ar address
 .Ar interface
 .Nm
 .Fl k , -release
@@ -354,6 +355,13 @@ files.
 .It Fl V, -variables
 Display a list of option codes and the associated variable for use in
 .Xr dhcpcd-run-hooks 8 .
+.It Fl X, -blacklist Ar address
+Ignores all DHCP messages which have this
+.Ar address
+as the server ID.
+This may be expanded in future releases to ignore all packets
+matching either the IP or hardware
+.Ar address .
 .El
 .Sh NOTES
 .Nm
index 46e39a375d954cb312c9d95812b2a92c6090dd6d..3857b7c546fed063eacd1ae73a1a53fb35d89e0a 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -52,7 +52,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:TV"
+#define OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:TVX:"
 
 static int doversion = 0;
 static int dohelp = 0;
@@ -89,6 +89,7 @@ static const struct option longopts[] = {
        {"nooption",    optional_argument,  NULL, 'O'},
        {"test",        no_argument,        NULL, 'T'},
        {"variables",   no_argument,        NULL, 'V'},
+       {"blacklist",   required_argument,  NULL, 'X'},
        {"help",        no_argument,        &dohelp, 1},
        {"version",     no_argument,        &doversion, 1},
 #ifdef THERE_IS_NO_FORK
@@ -160,12 +161,10 @@ read_pid(const char *pidfile)
 static void
 usage(void)
 {
-#ifndef MINIMAL
        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] <interface>\n");
-#endif
+              "              [-I clientID] [-C hookscript] [-X ipaddr] <interface>\n");
 }
 
 static char * 
@@ -561,6 +560,17 @@ parse_option(int opt, char *oarg, struct options *options)
                        return -1;
                }
                break;
+       case 'X':
+               if (!inet_aton(oarg, &addr)) {
+                       logger(LOG_ERR, "`%s' is not a valid IP address",
+                              oarg);
+                       return -1;
+               }
+               options->blacklist = xrealloc(options->blacklist,
+                   sizeof(in_addr_t) * (options->blacklist_len + 1));
+               options->blacklist[options->blacklist_len] = addr.s_addr;
+               options->blacklist_len++;
+               break;
        default:
                return 0;
        }
@@ -983,6 +993,7 @@ abort:
                        free(options->environ[len++]);
                free(options->environ);
        }
+       free(options->blacklist);
        free(options);
 
 #ifdef THERE_IS_NO_FORK
index b06f5da177920472da8071db0fe7ef300f2a1121..c9a42e1c8b7b67321b99f082b6313a3f937b02b4 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -93,5 +93,8 @@ struct options {
        char clientid[CLIENTID_MAX_LEN + 1];
        uint8_t userclass[USERCLASS_MAX_LEN + 1];
        uint8_t vendor[VENDOR_MAX_LEN + 1];
+
+       size_t blacklist_len;
+       in_addr_t *blacklist;
 };
 #endif