[PATCH] gdhcp: set secs in a RFC 951- and 2131-compliant manner

Grant Erickson marathon96 at gmail.com
Mon Feb 27 18:00:53 PST 2012


This patch sets the BOOTP secs field in a RFC 951- and 2131-compliant
manner for DHCPv4 DISCOVER and REQUEST/SELECT packets.

---
Certain DHCP servers, such as that implemented in Mac OS X (< 10.7)
for its "Internet Sharing" feature, refuse to issue a DHCP lease to
clients that have not set a non-zero value in their DISCOVER or
REQUEST packets.

Side-by-side packet analysis of Mac OS X, iOS, Android, ISC and
Windows clients show that these clients set the BOOTP 'secs' field and
are successfully issued a DHCP lease by Mac OS X. By contrast, a
connman-based client will issue 10 back-to-back DISCOVER packets and
will not be returned a DHCP OFFER from the server.

 gdhcp/client.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/gdhcp/client.c b/gdhcp/client.c
index a3b4b8a..761e6f9 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -85,6 +85,7 @@ struct _GDHCPClient {
    char *interface;
    uint8_t mac_address[6];
    uint32_t xid;
+   time_t start;
    uint32_t server_ip;
    uint32_t requested_ip;
    char *assigned_ip;
@@ -339,6 +340,14 @@ static void add_send_options(GDHCPClient *dhcp_client,
                add_binary_option, packet);
 }
 
+/* Return an RFC 951- and 2131-complaint BOOTP 'secs' value that
+ * represents the number of seconds elapsed from the start of
+ * attempting DHCP. */
+static uint16_t dhcp_attempt_secs(GDHCPClient *dhcp_client)
+{
+   return htons(MIN(time(0) - dhcp_client->start, UINT16_MAX));
+}
+
 static int send_discover(GDHCPClient *dhcp_client, uint32_t requested)
 {
    struct dhcp_packet packet;
@@ -348,6 +357,7 @@ static int send_discover(GDHCPClient *dhcp_client, uint32_t requested)
    init_packet(dhcp_client, &packet, DHCPDISCOVER);
 
    packet.xid = dhcp_client->xid;
+   packet.secs = dhcp_attempt_secs(dhcp_client);
 
    if (requested)
        dhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
@@ -374,6 +384,7 @@ static int send_select(GDHCPClient *dhcp_client)
    init_packet(dhcp_client, &packet, DHCPREQUEST);
 
    packet.xid = dhcp_client->xid;
+   packet.secs = dhcp_attempt_secs(dhcp_client);
 
    dhcp_add_simple_option(&packet, DHCP_REQUESTED_IP,
                    dhcp_client->requested_ip);
@@ -2240,7 +2251,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
            return re;
 
        dhcp_client->xid = rand();
+       dhcp_client->start = time(0);
    }
 
    if (last_address == NULL) {
-- 
1.7.8.2



More information about the connman mailing list