aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/udhcp/d6_dhcpc.c18
-rw-r--r--networking/udhcp/dhcpc.c4
-rw-r--r--networking/udhcp/dhcpc.h4
3 files changed, 21 insertions, 5 deletions
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;