.\" 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
.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
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 .
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)
{
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
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));
.\" 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
.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 .
{"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},
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;
/* 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
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;