From: Roy Marples Date: Mon, 23 Mar 2009 22:02:37 +0000 (+0000) Subject: Improve PTP INFORM support some more. X-Git-Tag: v5.0.0~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a4bcf7cf5fa713dd62912f0c1c7c2e1ef543e4b;p=thirdparty%2Fdhcpcd.git Improve PTP INFORM support some more. --- diff --git a/configure.c b/configure.c index 159f1479..dbb9118d 100644 --- a/configure.c +++ b/configure.c @@ -42,6 +42,7 @@ #include "config.h" #include "common.h" #include "configure.h" +#include "dhcp.h" #include "if-options.h" #include "if-pref.h" #include "net.h" @@ -513,7 +514,8 @@ add_subnet_route(struct rt *rt, const struct interface *iface) } static struct rt * -get_routes(const struct interface *iface) { +get_routes(const struct interface *iface) +{ struct rt *rt, *nrt = NULL, *r = NULL; if (iface->state->options->routes != NULL) { @@ -538,6 +540,22 @@ get_routes(const struct interface *iface) { return get_option_routes(iface->state->new); } +static struct rt * +add_destination_route(struct rt *rt, const struct interface *iface) +{ + struct rt *r; + + if (!(iface->flags & IFF_POINTOPOINT) || + !has_option_mask(iface->state->options->dstmask, DHO_ROUTER)) + return rt; + r = xmalloc(sizeof(*r)); + r->dest.s_addr = INADDR_ANY; + r->net.s_addr = INADDR_ANY; + r->gate.s_addr = iface->dst.s_addr; + r->next = rt; + return r; +} + void build_routes(void) { @@ -549,6 +567,7 @@ build_routes(void) continue; dnr = get_routes(ifp); dnr = add_subnet_route(dnr, ifp); + dnr = add_destination_route(dnr, ifp); for (rt = dnr; rt && (rtn = rt->next, 1); lrt = rt, rt = rtn) { rt->iface = ifp; /* Is this route already in our table? */ @@ -618,6 +637,7 @@ configure(struct interface *iface) { struct dhcp_message *dhcp = iface->state->new; struct dhcp_lease *lease = &iface->state->lease; + struct if_options *ifo = iface->state->options; struct rt *rt; /* As we are now adjusting an interface, we need to ensure @@ -633,7 +653,7 @@ configure(struct interface *iface) } /* This also changes netmask */ - if (!(iface->state->options->options & DHCPCD_INFORM) || + if (!(ifo->options & DHCPCD_INFORM) || !has_address(iface->name, &lease->addr, &lease->net)) { syslog(LOG_DEBUG, "%s: adding IP address %s/%d", @@ -668,7 +688,7 @@ configure(struct interface *iface) build_routes(); if (!iface->state->lease.frominfo && - !(iface->state->options->options & DHCPCD_INFORM)) + !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))) if (write_lease(iface, dhcp) == -1) syslog(LOG_ERR, "write_lease: %m"); run_script(iface); diff --git a/dhcp.c b/dhcp.c index 203dc939..c5feccad 100644 --- a/dhcp.c +++ b/dhcp.c @@ -759,6 +759,31 @@ encode_rfc1035(const char *src, uint8_t *dst) memcpy(p, &_val.s_addr, 4); \ p += 4; \ } + +int +dhcp_message_add_addr(struct dhcp_message *dhcp, + uint8_t type, struct in_addr addr) +{ + uint8_t *p; + size_t len; + + p = dhcp->options; + while (*p != DHO_END) { + p++; + p += *p + 1; + } + + len = p - (uint8_t *)dhcp; + if (len + 6 > sizeof(*dhcp)) { + errno = ENOMEM; + return -1; + } + + PUTADDR(type, addr); + *p = DHO_END; + return 0; +} + ssize_t make_message(struct dhcp_message **message, const struct interface *iface, diff --git a/dhcp.h b/dhcp.h index c8d8d6fe..90e69f52 100644 --- a/dhcp.h +++ b/dhcp.h @@ -186,6 +186,7 @@ struct rt *get_option_routes(const struct dhcp_message *); ssize_t configure_env(char **, const char *, const struct dhcp_message *, const struct if_options *); +int dhcp_message_add_addr(struct dhcp_message *, uint8_t, struct in_addr); ssize_t make_message(struct dhcp_message **, const struct interface *, uint8_t); int valid_dhcp_packet(unsigned char *); diff --git a/dhcpcd.c b/dhcpcd.c index f3ab5ee9..f3b96a9d 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -600,7 +600,7 @@ handle_dhcp_packet(void *arg) continue; } if (iface->flags & IFF_POINTOPOINT && - iface->state->lease.server.s_addr != from.s_addr) + iface->dst.s_addr != from.s_addr) { syslog(LOG_WARNING, "%s: server %s is not destination", @@ -687,10 +687,11 @@ configure_interface(struct interface *iface, int argc, char **argv) free_options(ifs->options); ifo = ifs->options = read_config(cffile, iface->name, iface->ssid); add_options(ifo, argc, argv); - if (iface->flags & IFF_NOARP) - ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL); if (iface->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM)) ifo->options |= DHCPCD_STATIC; + if (iface->flags & IFF_NOARP || + ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) + ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL); if (ifo->options & DHCPCD_LINK && carrier_status(iface->name) == -1) ifo->options &= ~DHCPCD_LINK; @@ -1132,32 +1133,6 @@ handle_interface(int action, const char *ifname) } } -static int -dhcp_message_add_addr(struct dhcp_message *dhcp, char c, struct in_addr *addr) -{ - uint8_t *p; - size_t len; - - p = dhcp->options; - while (*p != DHO_END) { - p++; - p += *p + 1; - } - - len = p - (uint8_t *)dhcp; - if (len + 6 > sizeof(*dhcp)) { - errno = ENOMEM; - return -1; - } - - *p++ = c; - *p++ = sizeof(addr->s_addr); - memcpy(p, &addr->s_addr, sizeof(addr->s_addr)); - p += sizeof(addr->s_addr); - *p = DHO_END; - return 0; -} - void handle_ifa(int type, const char *ifname, struct in_addr *addr, struct in_addr *net, struct in_addr *dst) @@ -1188,12 +1163,14 @@ handle_ifa(int type, const char *ifname, free(ifp->state->old); ifp->state->old = ifp->state->new; ifp->state->new = dhcp_message_new(addr, net); + ifp->dst.s_addr = dst ? dst->s_addr : INADDR_ANY; if (dst) { for (i = 1; i < 255; i++) - if (has_option_mask(ifo->dstmask, i)) + if (i != DHO_ROUTER && + has_option_mask(ifo->dstmask, i)) dhcp_message_add_addr( ifp->state->new, - i, dst); + i, *dst); } ifp->state->reason = "STATIC"; build_routes(); @@ -1201,9 +1178,10 @@ handle_ifa(int type, const char *ifname, if (ifo->options & DHCPCD_INFORM) { ifp->state->state = DHS_INFORM; ifp->state->xid = arc4random(); + ifp->state->lease.server.s_addr = + dst ? dst->s_addr : INADDR_ANY; ifp->addr = *addr; ifp->net = *net; - ifp->state->lease.server = *dst; open_sockets(ifp); send_inform(ifp); } diff --git a/dhcpcd.h b/dhcpcd.h index 927f019f..a65e8633 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -100,6 +100,7 @@ struct interface { struct in_addr addr; struct in_addr net; + struct in_addr dst; char leasefile[PATH_MAX]; time_t start_uptime;