From: Roy Marples Date: Wed, 19 Nov 2008 15:48:18 +0000 (+0000) Subject: We are now a BOOTP client also :) X-Git-Tag: v5.0.0~173 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=299662da4f99217bf4dfdd62147c273c0a5e3f1b;p=thirdparty%2Fdhcpcd.git We are now a BOOTP client also :) --- diff --git a/arp.c b/arp.c index ba227075..412bf9c0 100644 --- a/arp.c +++ b/arp.c @@ -217,9 +217,12 @@ send_arp_probe(void *arg) struct in_addr addr; struct timeval tv; - if (state->offer) - addr.s_addr = state->offer->yiaddr; - else + if (state->offer) { + if (state->offer->yiaddr) + addr.s_addr = state->offer->yiaddr; + else + addr.s_addr = state->offer->ciaddr; + } else addr.s_addr = iface->addr.s_addr; if (iface->arp_fd == -1) { @@ -239,7 +242,10 @@ send_arp_probe(void *arg) } else { tv.tv_sec = ANNOUNCE_WAIT; tv.tv_usec = 0; - if (IN_LINKLOCAL(htonl(addr.s_addr))) + /* We will bind IPv4LL and BOOTP addresses */ + if ((state->lease.server.s_addr == 0 && + state->lease.frominfo == 0) || + IN_LINKLOCAL(htonl(addr.s_addr))) add_timeout_tv(&tv, bind_interface, iface); else add_timeout_tv(&tv, send_request, iface); diff --git a/dhcp.c b/dhcp.c index 8a861f23..cd6d7195 100644 --- a/dhcp.c +++ b/dhcp.c @@ -1277,7 +1277,11 @@ get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp) { struct timeval now; - lease->addr.s_addr = dhcp->yiaddr; + /* BOOTP does not set yiaddr for replies when ciaddr is set. */ + if (dhcp->yiaddr) + lease->addr.s_addr = dhcp->yiaddr; + else + lease->addr.s_addr = dhcp->ciaddr; if (get_option_addr(&lease->net.s_addr, dhcp, DHO_SUBNETMASK) == -1) lease->net.s_addr = get_netmask(dhcp->yiaddr); if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) == 0) { diff --git a/dhcpcd.8.in b/dhcpcd.8.in index 9a8ab030..8868f88e 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -83,6 +83,10 @@ sets the hostname to the one supplied by the DHCP server. .Nm then daemonises and waits for the lease renewal time to lapse. Then it attempts to renew its lease and reconfigure if the new lease changes. +.Pp +.Nm +is also an implementation of the BOOTP client specified in +.Li RFC 951 . .Ss Local Link configuration If .Nm @@ -471,8 +475,8 @@ running on the .Xr if_nametoindex 3, .Xr fnmatch 3 .Sh STANDARDS -RFC 2131, RFC 2132, RFC 2855, RFC 3004, RFC 3361, RFC 3396, RFC 3397, -RFC 3442, RFC 3927, RFC 4361, RFC 4390, RFC 4702. +RFC 951, RFC 1534, RFC 2131, RFC 2132, RFC 2855, RFC 3004, RFC 3361, RFC 3396, +RFC 3397, RFC 3442, RFC 3927, RFC 4361, RFC 4390, RFC 4702. .Sh AUTHORS .An Roy Marples .Sh BUGS diff --git a/dhcpcd.c b/dhcpcd.c index 0a9244e9..05ee45e1 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -417,11 +417,9 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp) /* reset the message counter */ state->interval = 0; - /* We have to have DHCP type to work */ - if (get_option_uint8(&type, dhcp, DHO_MESSAGETYPE) == -1) { - log_dhcp(LOG_ERR, "no DHCP type in", iface, dhcp); - return; - } + /* We may have found a BOOTP server */ + if (get_option_uint8(&type, dhcp, DHO_MESSAGETYPE) == -1) + type = 0; /* Ensure that it's not from a blacklisted server. * We should expand this to check IP and/or hardware address @@ -476,10 +474,14 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp) } } - if (type == DHCP_OFFER && state->state == DHS_DISCOVER) { + if ((type == 0 || type == DHCP_OFFER) && + state->state == DHS_DISCOVER) + { lease->frominfo = 0; lease->addr.s_addr = dhcp->yiaddr; - get_option_addr(&lease->server.s_addr, dhcp, DHO_SERVERID); + lease->server.s_addr = 0; + if (type) + get_option_addr(&lease->server.s_addr, dhcp, DHO_SERVERID); log_dhcp(LOG_INFO, "offered", iface, dhcp); free(state->offer); state->offer = dhcp; @@ -507,24 +509,30 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp) return; } } - state->state = DHS_REQUEST; - send_request(iface); - return; + /* We don't request BOOTP addresses */ + if (type) { + state->state = DHS_REQUEST; + send_request(iface); + return; + } } - if (type == DHCP_OFFER) { - log_dhcp(LOG_INFO, "ignoring offer of", iface, dhcp); - return; - } + if (type) { + if (type == DHCP_OFFER) { + log_dhcp(LOG_INFO, "ignoring offer of", iface, dhcp); + return; + } - /* We should only be dealing with acks */ - if (type != DHCP_ACK) { - log_dhcp(LOG_ERR, "not ACK or OFFER", iface, dhcp); - return; + /* We should only be dealing with acks */ + if (type != DHCP_ACK) { + log_dhcp(LOG_ERR, "not ACK or OFFER", iface, dhcp); + return; + } + + if (!(ifo->options & DHCPCD_INFORM)) + log_dhcp(LOG_INFO, "acknowledged", iface, dhcp); } - if (!(ifo->options & DHCPCD_INFORM)) - log_dhcp(LOG_INFO, "acknowledged", iface, dhcp); close_sockets(iface); free(state->offer); state->offer = dhcp;