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) {
} 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);
{
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) {
.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
.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 <roy@marples.name>
.Sh BUGS
/* 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
}
}
- 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;
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;