udhcpc6: carry along length of packet when parsing it.

This is to avoid parsing garbage past packet's actual end.

Also const-ize params to a few functions.

function                                             old     new   delta
d6_run_script_no_option                                -      12     +12
option_to_env                                        791     798      +7
d6_run_script                                        253     255      +2
perform_d6_release                                    95      93      -2
udhcpc6_main                                        2596    2592      -4
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/2 up/down: 21/-6)              Total: 15 bytes

Signed-off-by: David Decotigny <ddecotig@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
David Decotigny 2018-05-24 08:30:15 -07:00 committed by Denys Vlasenko
parent a174c791ec
commit 8f48fc01e9

View File

@ -215,7 +215,8 @@ static char** new_env(void)
return &client6_data.env_ptr[client6_data.env_idx++]; return &client6_data.env_ptr[client6_data.env_idx++];
} }
static char *string_option_to_env(uint8_t *option, uint8_t *option_end) static char *string_option_to_env(const uint8_t *option,
const uint8_t *option_end)
{ {
const char *ptr, *name = NULL; const char *ptr, *name = NULL;
unsigned val_len; unsigned val_len;
@ -244,7 +245,7 @@ static char *string_option_to_env(uint8_t *option, uint8_t *option_end)
} }
/* put all the parameters into the environment */ /* put all the parameters into the environment */
static void option_to_env(uint8_t *option, uint8_t *option_end) static void option_to_env(const uint8_t *option, const uint8_t *option_end)
{ {
#if ENABLE_FEATURE_UDHCPC6_RFC3646 #if ENABLE_FEATURE_UDHCPC6_RFC3646
int addrs, option_offset; int addrs, option_offset;
@ -422,7 +423,7 @@ static void option_to_env(uint8_t *option, uint8_t *option_end)
} }
} }
static char **fill_envp(struct d6_packet *packet) static char **fill_envp(const uint8_t *option, const uint8_t *option_end)
{ {
char **envp, **curr; char **envp, **curr;
@ -431,8 +432,8 @@ static char **fill_envp(struct d6_packet *packet)
*new_env() = xasprintf("interface=%s", client_config.interface); *new_env() = xasprintf("interface=%s", client_config.interface);
if (packet) if (option)
option_to_env(packet->d6_options, packet->d6_options + sizeof(packet->d6_options)); option_to_env(option, option_end);
envp = curr = client6_data.env_ptr; envp = curr = client6_data.env_ptr;
while (*curr) while (*curr)
@ -442,12 +443,13 @@ static char **fill_envp(struct d6_packet *packet)
} }
/* Call a script with a par file and env vars */ /* Call a script with a par file and env vars */
static void d6_run_script(struct d6_packet *packet, const char *name) static void d6_run_script(const uint8_t *option, const uint8_t *option_end,
const char *name)
{ {
char **envp, **curr; char **envp, **curr;
char *argv[3]; char *argv[3];
envp = fill_envp(packet); envp = fill_envp(option, option_end);
/* call script */ /* call script */
log1("executing %s %s", client_config.script, name); log1("executing %s %s", client_config.script, name);
@ -463,6 +465,11 @@ static void d6_run_script(struct d6_packet *packet, const char *name)
free(envp); free(envp);
} }
/* Call a script with a par file and no env var */
static void d6_run_script_no_option(const char *name)
{
d6_run_script(NULL, NULL, name);
}
/*** Sending/receiving packets ***/ /*** Sending/receiving packets ***/
@ -1038,7 +1045,7 @@ static void perform_renew(void)
state = RENEW_REQUESTED; state = RENEW_REQUESTED;
break; break;
case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ case RENEW_REQUESTED: /* impatient are we? fine, square 1 */
d6_run_script(NULL, "deconfig"); d6_run_script_no_option("deconfig");
case REQUESTING: case REQUESTING:
case RELEASED: case RELEASED:
change_listen_mode(LISTEN_RAW); change_listen_mode(LISTEN_RAW);
@ -1067,7 +1074,7 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou
* Users requested to be notified in all cases, even if not in one * Users requested to be notified in all cases, even if not in one
* of the states above. * of the states above.
*/ */
d6_run_script(NULL, "deconfig"); d6_run_script_no_option("deconfig");
change_listen_mode(LISTEN_NONE); change_listen_mode(LISTEN_NONE);
state = RELEASED; state = RELEASED;
} }
@ -1276,7 +1283,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
udhcp_sp_setup(); udhcp_sp_setup();
state = INIT_SELECTING; state = INIT_SELECTING;
d6_run_script(NULL, "deconfig"); d6_run_script_no_option("deconfig");
change_listen_mode(LISTEN_RAW); change_listen_mode(LISTEN_RAW);
packet_num = 0; packet_num = 0;
timeout = 0; timeout = 0;
@ -1357,7 +1364,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
continue; continue;
} }
leasefail: leasefail:
d6_run_script(NULL, "leasefail"); d6_run_script_no_option("leasefail");
#if BB_MMU /* -b is not supported on NOMMU */ #if BB_MMU /* -b is not supported on NOMMU */
if (opt & OPT_b) { /* background if no lease */ if (opt & OPT_b) { /* background if no lease */
bb_error_msg("no lease, forking to background"); bb_error_msg("no lease, forking to background");
@ -1431,7 +1438,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
} }
/* Timed out, enter init state */ /* Timed out, enter init state */
bb_error_msg("lease lost, entering init state"); bb_error_msg("lease lost, entering init state");
d6_run_script(NULL, "deconfig"); d6_run_script_no_option("deconfig");
state = INIT_SELECTING; state = INIT_SELECTING;
client_config.first_secs = 0; /* make secs field count from 0 */ client_config.first_secs = 0; /* make secs field count from 0 */
/*timeout = 0; - already is */ /*timeout = 0; - already is */
@ -1538,9 +1545,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
if (option && (option->data[0] | option->data[1]) != 0) { if (option && (option->data[0] | option->data[1]) != 0) {
/* return to init state */ /* return to init state */
bb_error_msg("received DHCP NAK (%u)", option->data[4]); bb_error_msg("received DHCP NAK (%u)", option->data[4]);
d6_run_script(&packet, "nak"); d6_run_script(packet.d6_options,
packet_end, "nak");
if (state != REQUESTING) if (state != REQUESTING)
d6_run_script(NULL, "deconfig"); d6_run_script_no_option("deconfig");
change_listen_mode(LISTEN_RAW); change_listen_mode(LISTEN_RAW);
sleep(3); /* avoid excessive network traffic */ sleep(3); /* avoid excessive network traffic */
state = INIT_SELECTING; state = INIT_SELECTING;
@ -1737,7 +1745,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
if (timeout < 0x10) if (timeout < 0x10)
timeout = 0x10; timeout = 0x10;
/* enter bound state */ /* enter bound state */
d6_run_script(&packet, state == REQUESTING ? "bound" : "renew"); d6_run_script(packet.d6_options, packet_end,
(state == REQUESTING ? "bound" : "renew"));
state = BOUND; state = BOUND;
change_listen_mode(LISTEN_NONE); change_listen_mode(LISTEN_NONE);