udhcpc6: add ELAPSED_TIME option to outgoing packets
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 24 Sep 2019 12:01:00 +0000 (14:01 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 24 Sep 2019 12:01:00 +0000 (14:01 +0200)
function                                             old     new   delta
init_d6_packet                                        53     121     +68
udhcpc_main                                         2577    2582      +5
udhcpc6_main                                        2593    2597      +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 77/0)               Total: 77 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
networking/udhcp/d6_dhcpc.c
networking/udhcp/dhcpc.c
networking/udhcp/dhcpc.h

index a426b9933e2d988a9335e66299fbca120d8bd2ae..85c410a7cae8714084c4e9098a9b7524bf442fa0 100644 (file)
@@ -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)
index 656295ff7ca39dcbde41bdb8222bb1b23c652dfd..5a1f8fd7ab166fa4c54f9d33700f2b93b5027216 100644 (file)
@@ -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)
index 42fe71a368083b39d3fd466040cf783c9135fbdd..b407a6cdbf7f01d3b82d3ac3d8b16f2d37a3781c 100644 (file)
@@ -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;