From: Roy Marples Date: Thu, 15 Apr 2010 13:22:41 +0000 (+0000) Subject: Check to see if any routers require a host route if they are on a X-Git-Tag: v5.2.3~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=559b81c3f1b64faa05d7350ce72adb0bd6ae202f;p=thirdparty%2Fdhcpcd.git Check to see if any routers require a host route if they are on a different subnet. This fixes issues with badly configured DHCP servers. We may need to extent this check to any route with a host destination in the future. --- diff --git a/configure.c b/configure.c index 3e6dc98f..6ab86bd8 100644 --- a/configure.c +++ b/configure.c @@ -567,6 +567,51 @@ add_destination_route(struct rt *rt, const struct interface *iface) return r; } +/* We should check to ensure the routers are on the same subnet + * OR supply a host route. If not, warn and add a host route. */ +static struct rt * +add_router_host_route(struct rt *rt, const struct interface *ifp) +{ + struct rt *rtp, *rtl, *rtn; + const char *cp, *cp2, *cp3, *cplim; + + for (rtp = rt, rtl = NULL; rtp; rtl = rtp, rtp = rtp->next) { + if (rtp->dest.s_addr != INADDR_ANY) + continue; + /* Scan for a route to match */ + for (rtn = rt; rtn != rtp; rtn = rtn->next) { + /* match host */ + if (rtn->dest.s_addr == rtp->gate.s_addr) + break; + /* match subnet */ + cp = (const char *)&rtp->gate.s_addr; + cp2 = (const char *)&rtn->dest.s_addr; + cp3 = (const char *)&rtn->net.s_addr; + cplim = cp3 + sizeof(rtn->net.s_addr); + while (cp3 < cplim) { + if ((*cp++ ^ *cp2++) & *cp3++) + break; + } + if (cp3 == cplim) + break; + } + if (rtn != rtp) + continue; + syslog(LOG_WARNING, "%s: router %s requires a host route", + ifp->name, inet_ntoa(rtp->gate)); + rtn = xmalloc(sizeof(*rtn)); + rtn->dest.s_addr = rtp->gate.s_addr; + rtn->net.s_addr = INADDR_BROADCAST; + rtn->gate.s_addr = rtp->gate.s_addr; + rtn->next = rtp; + if (rtl == NULL) + rt = rtn; + else + rtl->next = rtn; + } + return rt; +} + void build_routes(void) { @@ -578,6 +623,7 @@ build_routes(void) continue; dnr = get_routes(ifp); dnr = add_subnet_route(dnr, ifp); + dnr = add_router_host_route(dnr, ifp); dnr = add_destination_route(dnr, ifp); for (rt = dnr; rt && (rtn = rt->next, 1); lrt = rt, rt = rtn) { rt->iface = ifp;