From: Roy Marples Date: Fri, 27 Feb 2009 21:18:01 +0000 (+0000) Subject: Blacklist now accepts networks as well as addresses. X-Git-Tag: v5.0.0~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e095a6ebb581216ef8369d1e468a6682332498a7;p=thirdparty%2Fdhcpcd.git Blacklist now accepts networks as well as addresses. It also matches on the address offered as well as the server address. --- diff --git a/dhcpcd.8.in b/dhcpcd.8.in index 1d184804..c1b8f637 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd February 17, 2009 +.Dd February 27, 2009 .Dt DHCPCD 8 SMM .Sh NAME .Nm dhcpcd @@ -50,7 +50,7 @@ .Op Fl O , -nooption Ar option .Op Fl Q , -require Ar option .Op Fl S , -static Ar value -.Op Fl X , -blacklist Ar address +.Op Fl X , -blacklist Ar address Ns Op Ar /cidr .Op Fl Z , -denyinterfaces Ar pattern .Op interface .Op ... @@ -451,10 +451,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 +.It Fl X, -blacklist Ar address Ns Op Ar /cidr Ignores all DHCP messages which have this .Ar address -as the server ID. +as the server ID or offered address. +If +.Ar cidr +is given then we match against that network as well. This may be expanded in future releases to ignore all packets matching either the IP or hardware .Ar address . diff --git a/dhcpcd.c b/dhcpcd.c index 56d21b55..a937335d 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -420,8 +420,9 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp) struct dhcp_message *dhcp = *dhcpp; struct dhcp_lease *lease = &state->lease; uint8_t type, tmp; - struct in_addr addr; + struct in_addr addr, addr2; size_t i; + char *a; /* reset the message counter */ state->interval = 0; @@ -433,22 +434,46 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp) /* 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 (ifo->blacklist_len != 0 && - get_option_addr(&addr.s_addr, dhcp, DHO_SERVERID) == 0) - { - for (i = 0; i < ifo->blacklist_len; i++) { - if (ifo->blacklist[i] != addr.s_addr) - continue; - if (dhcp->servername[0]) - syslog(LOG_WARNING, - "%s: ignoring blacklisted server %s `%s'", - iface->name, - inet_ntoa(addr), dhcp->servername); - else - syslog(LOG_WARNING, - "%s: ignoring blacklisted server %s", - iface->name, inet_ntoa(addr)); - return; + if (ifo->blacklist_len != 0) { + if (get_option_addr(&addr.s_addr, dhcp, DHO_SERVERID) != 0) + addr.s_addr = 0; + for (i = 0; i < ifo->blacklist_len; i += 2) { + if (ifo->blacklist[i] == + (addr.s_addr & ifo->blacklist[i + 1])) + { + if (dhcp->servername[0]) + syslog(LOG_WARNING, + "%s: blacklisted server %s `%s'", + iface->name, + inet_ntoa(addr), dhcp->servername); + else + syslog(LOG_WARNING, + "%s: blacklisted server %s", + iface->name, inet_ntoa(addr)); + return; + } + if (ifo->blacklist[i] == + (dhcp->yiaddr & ifo->blacklist[i + 1])) + { + addr2.s_addr = dhcp->yiaddr; + a = xstrdup(inet_ntoa(addr2)); + if (dhcp->servername[0]) + syslog(LOG_WARNING, + "%s: blacklisted offer" + " %s from %s `%s'", + iface->name, a, + inet_ntoa(addr), dhcp->servername); + else if (addr.s_addr) + syslog(LOG_WARNING, + "%s: blacklisted offer %s from %s", + iface->name, a, inet_ntoa(addr)); + else + syslog(LOG_WARNING, + "%s: blacklisted offer %s", + iface->name, a); + free(a); + return; + } } } diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index 5b677619..3c6ca1a0 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd January 28, 2009 +.Dd February 27, 2009 .Dt DHCPCD.CONF 5 SMM .Sh NAME .Nm dhcpcd.conf @@ -60,10 +60,13 @@ which is a space or comma separated list of patterns passed to Background immediately. This is useful for startup scripts which don't disable link messages for carrier status. -.It Ic blacklist Ar address +.It Ic blacklist Ar address Ns Op Ar /cidr Ignores all DHCP messages which have this .Ar address -as the server ID. +as the server ID or offered address. +If +.Ar cidr +is given then we match against that network as well. This may be expanded in future releases to ignore all packets matching either the IP or hardware .Ar address . diff --git a/if-options.c b/if-options.c index 119d6dea..1e4ff981 100644 --- a/if-options.c +++ b/if-options.c @@ -287,6 +287,8 @@ parse_addr(struct in_addr *addr, struct in_addr *net, const char *arg) syslog(LOG_ERR, "`%s' is not a valid IP address", arg); return -1; } + if (p) + *--p = '/'; return 0; } @@ -296,7 +298,7 @@ parse_option(struct if_options *ifo, int opt, const char *arg) int i; char *p = NULL, *np; ssize_t s; - struct in_addr addr; + struct in_addr addr, addr2; struct rt *rt; switch(opt) { @@ -624,15 +626,13 @@ parse_option(struct if_options *ifo, int opt, const char *arg) } break; case 'X': - if (!inet_aton(arg, &addr)) { - syslog(LOG_ERR, "`%s' is not a valid IP address", - arg); + addr2.s_addr = ~0U; + if (parse_addr(&addr, &addr2, arg) != 0) return -1; - } ifo->blacklist = xrealloc(ifo->blacklist, - sizeof(in_addr_t) * (ifo->blacklist_len + 1)); - ifo->blacklist[ifo->blacklist_len] = addr.s_addr; - ifo->blacklist_len++; + sizeof(in_addr_t) * (ifo->blacklist_len + 2)); + ifo->blacklist[ifo->blacklist_len++] = addr.s_addr; + ifo->blacklist[ifo->blacklist_len++] = addr2.s_addr; break; case 'Z': /* We only set this if we haven't got any interfaces */