From: Roy Marples Date: Sat, 18 Oct 2008 16:41:19 +0000 (+0000) Subject: Get INFORM support almost working again. X-Git-Tag: v5.0.0~215 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eae4f5b4724b0a237bdf036479435e553b6ecd90;p=thirdparty%2Fdhcpcd.git Get INFORM support almost working again. --- diff --git a/configure.c b/configure.c index d4652aa5..53fd9a8d 100644 --- a/configure.c +++ b/configure.c @@ -479,7 +479,8 @@ configure(struct interface *iface, const char *reason) /* This also changes netmask */ if (!(iface->state->options->options & DHCPCD_INFORM) || - !has_address(iface->name, &addr, &net)) { + !has_address(iface->name, &addr, &net)) + { syslog(LOG_DEBUG, "%s: adding IP address %s/%d", iface->name, inet_ntoa(addr), inet_ntocidr(net)); if (add_address(iface, &addr, &net, &brd) == -1 && @@ -512,7 +513,8 @@ configure(struct interface *iface, const char *reason) build_routes(); if (arp_flush() == -1) syslog(LOG_ERR, "arp_flush: %m"); - if (!iface->state->lease.frominfo) + if (!iface->state->lease.frominfo && + !(iface->state->options->options & DHCPCD_INFORM)) if (write_lease(iface, dhcp) == -1) syslog(LOG_ERR, "write_lease: %m"); run_script(iface, reason); diff --git a/dhcp.c b/dhcp.c index 59c648df..3b698dae 100644 --- a/dhcp.c +++ b/dhcp.c @@ -1198,10 +1198,10 @@ configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp, } ep = env; - if (dhcp->yiaddr) { + if (dhcp->yiaddr || dhcp->ciaddr) { /* Set some useful variables that we derive from the DHCP * message but are not necessarily in the options */ - addr.s_addr = dhcp->yiaddr; + addr.s_addr = dhcp->yiaddr ? dhcp->yiaddr : dhcp->ciaddr; setvar(&ep, prefix, "ip_address", inet_ntoa(addr)); if (get_option_addr(&net.s_addr, dhcp, DHO_SUBNETMASK) == -1) { net.s_addr = get_netmask(addr.s_addr); diff --git a/dhcpcd.c b/dhcpcd.c index d1ea55e2..47fb293b 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -302,6 +302,12 @@ send_message(struct interface *iface, int type, } } +static void +send_inform(void *arg) +{ + send_message((struct interface *)arg, DHCP_INFORM, send_inform); +} + static void send_discover(void *arg) { @@ -726,8 +732,13 @@ start_reboot(struct interface *iface) start_discover(iface); return; } - syslog(LOG_INFO, "%s: rebinding lease of %s", - iface->name, inet_ntoa(iface->state->lease.addr)); + if (ifo->options & DHCPCD_INFORM) { + syslog(LOG_INFO, "%s: informing address of %s", + iface->name, inet_ntoa(iface->state->lease.addr)); + } else { + syslog(LOG_INFO, "%s: rebinding lease of %s", + iface->name, inet_ntoa(iface->state->lease.addr)); + } iface->state->state = DHS_REBOOT; iface->state->xid = arc4random(); iface->state->lease.server.s_addr = 0; @@ -742,7 +753,9 @@ start_reboot(struct interface *iface) { iface->state->probes = 0; send_arp_probe(iface); - } else + } else if (ifo->options & DHCPCD_INFORM) + send_inform(iface); + else send_request(iface); } @@ -762,9 +775,25 @@ start_interface(void *arg) iface->start_uptime = uptime(); if (ifo->request_address.s_addr) { + /* This also changes netmask */ + if (iface->state->options->options & DHCPCD_INFORM && + !has_address(iface->name, &ifo->request_address, + &ifo->request_netmask)) + { + syslog(LOG_DEBUG, "%s: adding IP address %s/%d", + iface->name, inet_ntoa(ifo->request_address), + inet_ntocidr(ifo->request_netmask)); + if (add_address(iface, &ifo->request_address, + &ifo->request_netmask, NULL) == -1 && + errno != EEXIST) + { + syslog(LOG_ERR, "add_address: %m"); + } + } iface->state->offer = xzalloc(sizeof(*iface->state->offer)); iface->state->offer->yiaddr = ifo->request_address.s_addr; - ifo->request_address.s_addr = 0; + if (ifo->options & DHCPCD_REQUEST) + ifo->request_address.s_addr = 0; } else iface->state->offer = read_lease(iface); /* if (iface->state->offer) { @@ -835,7 +864,7 @@ configure_interface(struct interface *iface, int argc, char **argv) memcpy(iface->clientid + 2, iface->name, ifl); if (ifl < 4) memset(iface->clientid + 2 + ifl, - 0, 4 - ifl); + 0, 4 - ifl); } else { ifl = htonl(if_nametoindex(iface->name)); memcpy(iface->clientid + 2, &ifl, 4); @@ -845,7 +874,8 @@ configure_interface(struct interface *iface, int argc, char **argv) iface->clientid = xmalloc(len + 1); iface->clientid[0] = len; iface->clientid[1] = iface->family; - memcpy(iface->clientid + 2, iface->hwaddr, iface->hwlen); + memcpy(iface->clientid + 2, iface->hwaddr, + iface->hwlen); } } @@ -980,8 +1010,12 @@ handle_signal(_unused void *arg) break; if (do_release || ifl->state->options->options & DHCPCD_RELEASE) send_release(ifl); - if (!(ifl->state->options->options & DHCPCD_PERSISTENT)) + if ((ifl->state->options->options & DHCPCD_PERSISTENT)) { + free(ifl->state->new); + ifl->state->new = NULL; + } else { drop_config(ifl, do_release ? "RELEASE" : "STOP"); + } if (do_release || ifl->state->options->options & DHCPCD_RELEASE) unlink(ifl->leasefile); } diff --git a/if-bsd.c b/if-bsd.c index 61a84379..890664d0 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -121,7 +121,7 @@ if_address(const struct interface *iface, const struct in_addr *address, ADDADDR(ifa.ifra_addr, address); ADDADDR(ifa.ifra_mask, netmask); - if (action >= 0) { + if (action >= 0 && broadcast) { ADDADDR(ifa.ifra_broadaddr, broadcast); } #undef ADDADDR diff --git a/if-options.c b/if-options.c index 118ed3bf..85d2bfce 100644 --- a/if-options.c +++ b/if-options.c @@ -347,8 +347,7 @@ parse_option(struct if_options *ifo, int opt, const char *arg) ifo->options |= DHCPCD_QUIET; break; case 's': - ifo->options |= DHCPCD_INFORM; - ifo->options |= DHCPCD_PERSISTENT; + ifo->options |= DHCPCD_INFORM | DHCPCD_PERSISTENT; ifo->options &= ~DHCPCD_ARP; if (!arg || *arg == '\0') { ifo->request_address.s_addr = 0; diff --git a/net.c b/net.c index f99251b5..6d269056 100644 --- a/net.c +++ b/net.c @@ -287,9 +287,8 @@ do_interface(const char *ifname, char *buffer; struct ifreq *ifr; } ifreqs; - struct sockaddr_in address; + in_addr_t address, netmask; struct ifreq *ifr; - struct sockaddr_in netmask; if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) return -1; @@ -347,14 +346,13 @@ do_interface(const char *ifname, continue; memcpy(&netmask, &ifr->ifr_addr, sizeof(netmask)); if (act == 1) { - addr->s_addr = address.sin_addr.s_addr; - net->s_addr = netmask.sin_addr.s_addr; + addr->s_addr = address; + net->s_addr = netmask; retval = 1; break; } else { - if (address.sin_addr.s_addr == addr->s_addr && - (!net || - netmask.sin_addr.s_addr == net->s_addr)) + if (address == addr->s_addr && + (!net || netmask == net->s_addr)) { retval = 1; break;