]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
We are now a BOOTP client also :)
authorRoy Marples <roy@marples.name>
Wed, 19 Nov 2008 15:48:18 +0000 (15:48 +0000)
committerRoy Marples <roy@marples.name>
Wed, 19 Nov 2008 15:48:18 +0000 (15:48 +0000)
arp.c
dhcp.c
dhcpcd.8.in
dhcpcd.c

diff --git a/arp.c b/arp.c
index ba227075ff314db5541f1efa311e3bf149eb9ba5..412bf9c0f1086829ad09823a4a9081396723e24f 100644 (file)
--- 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 8a861f23cd2bb8ce0e92dc72917e455494095ea0..cd6d7195280b76ab75d4ac8e94b450bf8e66b3de 100644 (file)
--- 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) {
index 9a8ab030b423035a75af2ccedef200a951d1675d..8868f88ee1f962e29b12360b28b3d4a2d3699cda 100644 (file)
@@ -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 <roy@marples.name>
 .Sh BUGS
index 0a9244e9b497a27bd86e6565fa313ca1d18afdde..05ee45e17d66f417072dc8916cffee536f0766fe 100644 (file)
--- 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;