udhcpc6: add ELAPSED_TIME option to outgoing packets

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>
This commit is contained in:
Denys Vlasenko 2019-09-24 14:01:00 +02:00
parent c58d785b9d
commit 11e024aa86
3 changed files with 21 additions and 5 deletions

View File

@ -481,15 +481,31 @@ static ALWAYS_INLINE uint32_t random_xid(void)
/* Initialize the packet with the proper defaults */ /* Initialize the packet with the proper defaults */
static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid) static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid)
{ {
uint8_t *ptr;
struct d6_option *clientid; struct d6_option *clientid;
unsigned secs;
memset(packet, 0, sizeof(*packet)); memset(packet, 0, sizeof(*packet));
packet->d6_xid32 = xid; packet->d6_xid32 = xid;
packet->d6_msg_type = type; 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; 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) static uint8_t *add_d6_client_options(uint8_t *ptr)

View File

@ -606,7 +606,7 @@ static ALWAYS_INLINE uint32_t random_xid(void)
/* Initialize the packet with the proper defaults */ /* Initialize the packet with the proper defaults */
static void init_packet(struct dhcp_packet *packet, char type) 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: */ /* Fill in: op, htype, hlen, cookie fields; message type option: */
udhcp_init_header(packet, type); 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) if (client_data.first_secs == 0)
client_data.first_secs = client_data.last_secs; client_data.first_secs = client_data.last_secs;
secs = client_data.last_secs - client_data.first_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); memcpy(packet->chaddr, client_data.client_mac, 6);
if (client_data.clientid) if (client_data.clientid)

View File

@ -22,8 +22,8 @@ struct client_data_t {
uint8_t *hostname; /* Optional hostname to use */ uint8_t *hostname; /* Optional hostname to use */
uint8_t *fqdn; /* Optional fully qualified domain name to use */ uint8_t *fqdn; /* Optional fully qualified domain name to use */
uint16_t first_secs; unsigned first_secs;
uint16_t last_secs; unsigned last_secs;
int sockfd; int sockfd;
smallint listen_mode; smallint listen_mode;