Mercurial > hg > dhcpcd
changeset 1321:6b6deaa097de draft
Although RFC2131 requires a ServerID we can actually work without one.
Some broken servers don't send a ServerID, so make the requirement optional.
We default to requiring ServerID in dhcpcd.conf though as some other broken
servers NAK incorrectly without a ServerID.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Wed, 13 May 2009 19:17:21 +0000 |
| parents | 8c7fd91fb635 |
| children | ba7d6f1ebe43 |
| files | dhcpcd.c dhcpcd.conf |
| diffstat | 2 files changed, 52 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/dhcpcd.c Wed May 13 18:49:49 2009 +0000 +++ b/dhcpcd.c Wed May 13 19:17:21 2009 +0000 @@ -365,19 +365,6 @@ } void -start_rebind(void *arg) -{ - struct interface *iface = arg; - - syslog(LOG_ERR, "%s: failed to renew, attmepting to rebind", - iface->name); - iface->state->state = DHS_REBIND; - delete_timeout(send_renew, iface); - iface->state->lease.server.s_addr = 0; - send_rebind(iface); -} - -void start_expire(void *arg) { struct interface *iface = arg; @@ -413,10 +400,11 @@ if (strcmp(msg, "NAK:") == 0) a = get_option_string(dhcp, DHO_MESSAGE); - else { + else if (dhcp->yiaddr != 0) { addr.s_addr = dhcp->yiaddr; a = xstrdup(inet_ntoa(addr)); - } + } else + a = NULL; r = get_option_addr(&addr.s_addr, dhcp, DHO_SERVERID); if (dhcp->servername[0] && r == 0) syslog(lvl, "%s: %s %s from %s `%s'", iface->name, msg, a, @@ -424,8 +412,10 @@ else if (r == 0) syslog(lvl, "%s: %s %s from %s", iface->name, msg, a, inet_ntoa(addr)); + else if (a != NULL) + syslog(lvl, "%s: %s %s", iface->name, msg, a); else - syslog(lvl, "%s: %s %s", iface->name, msg, a); + syslog(lvl, "%s: %s", iface->name, msg); free(a); } @@ -457,15 +447,16 @@ /* We may have found a BOOTP server */ if (get_option_uint8(&type, dhcp, DHO_MESSAGETYPE) == -1) type = 0; - else if (get_option_addr(&addr.s_addr, dhcp, DHO_SERVERID) == -1) { - /* We should ignore invalid NAK messages without a ServerID */ - syslog(LOG_WARNING, "%s: ignoring DHCP message; no Server ID", - iface->name); - return; - } - /* We should restart on a NAK */ if (type == DHCP_NAK) { + /* For NAK, only check if we require the ServerID */ + if (has_option_mask(ifo->requiremask, DHO_SERVERID) && + get_option_addr(&addr.s_addr, dhcp, DHO_SERVERID) == -1) + { + log_dhcp(LOG_WARNING, "reject NAK", iface, dhcp); + return; + } + /* We should restart on a NAK */ log_dhcp(LOG_WARNING, "NAK:", iface, dhcp); drop_config(iface, "NAK"); unlink(iface->leasefile); @@ -482,27 +473,31 @@ return; } - /* No NAK, so reset the backoff */ - state->nakoff = 1; - /* Ensure that all required options are present */ for (i = 1; i < 255; i++) { if (has_option_mask(ifo->requiremask, i) && get_option_uint8(&tmp, dhcp, i) != 0) { - log_dhcp(LOG_WARNING, "reject", iface, dhcp); + /* If we are bootp, then ignore the need for serverid. + * To ignore bootp, require dhcp_message_type instead. */ + if (type == 0 && i == DHO_SERVERID) + continue; + log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp); return; } - } + } + + /* No NAK, so reset the backoff */ + state->nakoff = 1; if ((type == 0 || type == DHCP_OFFER) && state->state == DHS_DISCOVER) { lease->frominfo = 0; lease->addr.s_addr = dhcp->yiaddr; - lease->server.s_addr = 0; + lease->server.s_addr = INADDR_ANY; if (type != 0) - lease->server.s_addr = addr.s_addr; + get_option_addr(&lease->server.s_addr, dhcp, DHO_SERVERID); log_dhcp(LOG_INFO, "offered", iface, dhcp); free(state->offer); state->offer = dhcp; @@ -871,6 +866,21 @@ send_renew(iface); } +void +start_rebind(void *arg) +{ + struct interface *iface = arg; + + syslog(LOG_ERR, "%s: failed to renew, attmepting to rebind", + iface->name); + iface->state->state = DHS_REBIND; + delete_timeout(send_renew, iface); + iface->state->lease.server.s_addr = 0; + if (iface->raw_fd == -1) + open_sockets(iface); + send_rebind(iface); +} + static void start_timeout(void *arg) {
--- a/dhcpcd.conf Wed May 13 18:49:49 2009 +0000 +++ b/dhcpcd.conf Wed May 13 19:17:21 2009 +0000 @@ -1,19 +1,25 @@ # A sample configuration for dhcpcd. # See dhcpcd.conf(5) for details. -# We normally want to inform the DHCP server of our hostname for DDNS. +# Inform the DHCP server of our hostname for DDNS. hostname -# A list of options we should request from the DHCP server. +# A list of options to request from the DHCP server. option domain_name_servers, domain_name, domain_search, host_name -# Most distros have ntp support. +# Most distributions have NTP support. option ntp_servers -# We should behave nicely on networks and respect their MTU. +# Behave nicely on networks and respect their MTU. # However, a lot of buggy DHCP servers set invalid MTUs so this is not # enabled by default. #option interface_mtu -# We provide a hook script to lookup the hostname if not set by the DHCP -# server, but we should not run it by default. +# A ServerID is required by RFC2131. +# Some broken DHCP servers do not send one and dhcpcd can work without it. +# Some broken DHCP servers NAK incorrectly and do not include a ServerID either so +# the default is to require a ServerID. +require dhcp_server_identifier + +# A hook script is provided to lookup the hostname if not set by the DHCP +# server, but it should not be run by default. nohook lookup-hostname
