]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add -W, --whitelist addr/cidr
authorRoy Marples <roy@marples.name>
Sun, 5 Jul 2009 11:33:46 +0000 (11:33 +0000)
committerRoy Marples <roy@marples.name>
Sun, 5 Jul 2009 11:33:46 +0000 (11:33 +0000)
This only allows packets from the addresses listed and overrides
blacklist if set.

dhcpcd.8.in
dhcpcd.c
dhcpcd.conf.5.in
if-options.c
if-options.h

index 059a35a97b77d63a648751c259255cfaa32289b3..7e71245680d7f1d182b63afed6e717c784721e65 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd April 24, 2009
+.Dd July 5, 2009
 .Dt DHCPCD 8 SMM
 .Os
 .Sh NAME
@@ -51,6 +51,7 @@
 .Op Fl O , -nooption Ar option
 .Op Fl Q , -require Ar option
 .Op Fl S , -static Ar value
+.Op Fl W , -whitelist Ar address Ns Op Ar /cidr
 .Op Fl X , -blacklist Ar address Ns Op Ar /cidr
 .Op Fl Z , -denyinterfaces Ar pattern
 .Op interface
@@ -465,6 +466,13 @@ Display a list of option codes and the associated variable for use in
 Variables are prefixed with new_ and old_ unless the option number is -.
 Variables without an option are part of the DHCP message and cannot be
 directly requested.
+.It Fl W, -whitelist Ar address Ns Op /cidr
+Only accept packets from
+.Ar address Ns Op /cidr .
+.Fl X, -blacklist
+is ignored if
+.Fl W, -whitelist
+is set.
 .It Fl X, -blacklist Ar address Ns Op Ar /cidr
 Ignore all packets from
 .Ar address Ns Op Ar /cidr .
index 1b4dd9ae0e3013a4a1ebb64445e3ca49b71dc568..950dd16905a4f289969f0696f7d12b0bcc22b270 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -430,6 +430,19 @@ blacklisted_ip(const struct if_options *ifo, in_addr_t addr)
        return 0;
 }
 
+static int
+whitelisted_ip(const struct if_options *ifo, in_addr_t addr)
+{
+       size_t i;
+
+       if (ifo->whitelist_len == 0)
+               return -1;
+       for (i = 0; i < ifo->whitelist_len; i += 2)
+               if (ifo->whitelist[i] == (addr & ifo->whitelist[i + 1]))
+                       return 1;
+       return 0;
+}
+
 static void
 handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp)
 {
@@ -585,6 +598,7 @@ handle_dhcp_packet(void *arg)
        const uint8_t *pp;
        ssize_t bytes;
        struct in_addr from;
+       int i;
 
        /* We loop through until our buffer is empty.
         * The benefit is that if we get >1 DHCP packet in our buffer and
@@ -600,7 +614,15 @@ handle_dhcp_packet(void *arg)
                            iface->name, inet_ntoa(from));
                        continue;
                }
-               if (blacklisted_ip(iface->state->options, from.s_addr)) {
+               i = whitelisted_ip(iface->state->options, from.s_addr);
+               if (i == 0) {
+                       syslog(LOG_WARNING,
+                           "%s: non whitelisted DHCP packet from %s",
+                           iface->name, inet_ntoa(from));
+                       continue;
+               } else if (i != 1 &&
+                   blacklisted_ip(iface->state->options, from.s_addr) == 1)
+               {
                        syslog(LOG_WARNING,
                            "%s: blacklisted DHCP packet from %s",
                            iface->name, inet_ntoa(from));
index 689a90d532588fb823dacc5f1247e27516476541..c9efad72004789f1b040d2b3c362f6709b98a735 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd July 4, 2009
+.Dd July 5, 2009
 .Dt DHCPCD.CONF 5 SMM
 .Os
 .Sh NAME
@@ -76,6 +76,13 @@ carrier status.
 .It Ic blacklist Ar address Ns Op /cidr
 Ignores all packets from
 .Ar address Ns Op /cidr .
+.It Ic whitelist Ar address Ns Op /cidr
+Only accept packets from
+.Ar address Ns Op /cidr .
+.Ic blacklist
+is ignored if
+.Ic whitelist
+is set.
 .It Ic clientid Ar string
 Send the
 .Ar clientid .
index 7a9e5e3d4f6af4e8fa9e1bb04274a08168707dab..a22929b358602f8408c8534d89ab0c5946a6b76d 100644 (file)
@@ -90,6 +90,7 @@ const struct option cf_options[] = {
        {"static",          required_argument, NULL, 'S'},
        {"test",            no_argument,       NULL, 'T'},
        {"variables",       no_argument,       NULL, 'V'},
+       {"whitelist",       required_argument, NULL, 'W'},
        {"blacklist",       required_argument, NULL, 'X'},
        {"denyinterfaces",  required_argument, NULL, 'Z'},
        {"arping",          required_argument, NULL, O_ARPING},
@@ -653,6 +654,16 @@ parse_option(struct if_options *ifo, int opt, const char *arg)
                        ifo->config[s + 1] = NULL;
                }
                break;
+       case 'W':
+               if (parse_addr(&addr, &addr2, arg) != 0)
+                       return -1;
+               if (strchr(arg, '/') == NULL)
+                       addr2.s_addr = INADDR_BROADCAST;
+               ifo->whitelist = xrealloc(ifo->whitelist,
+                   sizeof(in_addr_t) * (ifo->whitelist_len + 2));
+               ifo->whitelist[ifo->whitelist_len++] = addr.s_addr;
+               ifo->whitelist[ifo->whitelist_len++] = addr2.s_addr;
+               break;
        case 'X':
                if (parse_addr(&addr, &addr2, arg) != 0)
                        return -1;
index 396f44ea5bbfd1d24ee317f75400f878fba3c3ef..3fa86396ac3cb3847cc72c9af10e289cbfbcf384 100644 (file)
@@ -37,7 +37,7 @@
 
 /* Don't set any optional arguments here so we retain POSIX
  * compatibility with getopt */
-#define IF_OPTS "bc:def:h:i:kl:m:no:pqr:s:t:u:v:xy:z:ABC:DEF:GI:KLN:O:Q:TVX:Z:"
+#define IF_OPTS "bc:def:h:i:kl:m:no:pqr:s:t:u:v:xy:z:ABC:DEF:GI:KLN:O:Q:TVW:X:Z:"
 
 #define DEFAULT_TIMEOUT                30
 #define DEFAULT_REBOOT         10
@@ -100,6 +100,8 @@ struct if_options {
 
        size_t blacklist_len;
        in_addr_t *blacklist;
+       size_t whitelist_len;
+       in_addr_t *whitelist;
        size_t arping_len;
        in_addr_t *arping;
        char *fallback;