diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index a426b9933..85c410a7c 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -481,15 +481,31 @@ static ALWAYS_INLINE uint32_t random_xid(void) /* Initialize the packet with the proper defaults */ static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid) { + uint8_t *ptr; struct d6_option *clientid; + unsigned secs; memset(packet, 0, sizeof(*packet)); packet->d6_xid32 = xid; packet->d6_msg_type = type; + /* ELAPSED_TIME option is required to be present by the RFC, + * and some servers do check for its presense. [which?] + */ + ptr = packet->d6_options; /* NB: it is 32-bit aligned */ + *((uint32_t*)ptr) = htonl((D6_OPT_ELAPSED_TIME << 16) + 2); + ptr += 4; + client_data.last_secs = monotonic_sec(); + if (client_data.first_secs == 0) + client_data.first_secs = client_data.last_secs; + secs = client_data.last_secs - client_data.first_secs; + *((uint16_t*)ptr) = (secs < 0xffff) ? htons(secs) : 0xffff; + ptr += 2; + + /* add CLIENTID option */ clientid = (void*)client_data.clientid; - return mempcpy(packet->d6_options, clientid, clientid->len + 2+2); + return mempcpy(ptr, clientid, clientid->len + 2+2); } static uint8_t *add_d6_client_options(uint8_t *ptr) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 656295ff7..5a1f8fd7a 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -606,7 +606,7 @@ static ALWAYS_INLINE uint32_t random_xid(void) /* Initialize the packet with the proper defaults */ static void init_packet(struct dhcp_packet *packet, char type) { - uint16_t secs; + unsigned secs; /* Fill in: op, htype, hlen, cookie fields; message type option: */ udhcp_init_header(packet, type); @@ -617,7 +617,7 @@ static void init_packet(struct dhcp_packet *packet, char type) if (client_data.first_secs == 0) client_data.first_secs = client_data.last_secs; secs = client_data.last_secs - client_data.first_secs; - packet->secs = htons(secs); + packet->secs = (secs < 0xffff) ? htons(secs) : 0xffff; memcpy(packet->chaddr, client_data.client_mac, 6); if (client_data.clientid) diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index 42fe71a36..b407a6cdb 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h @@ -22,8 +22,8 @@ struct client_data_t { uint8_t *hostname; /* Optional hostname to use */ uint8_t *fqdn; /* Optional fully qualified domain name to use */ - uint16_t first_secs; - uint16_t last_secs; + unsigned first_secs; + unsigned last_secs; int sockfd; smallint listen_mode;