diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-25 20:32:38 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-25 20:32:38 +0100 |
commit | 7e6add1dfca95183bf409820066fab975979bf06 (patch) | |
tree | 0da56954d93e9b10e956235a32f0d0644a60063b | |
parent | 0454d9d6c314f381eee8022ad4e7447d2fa1dcf1 (diff) | |
download | busybox-w32-7e6add1dfca95183bf409820066fab975979bf06.tar.gz busybox-w32-7e6add1dfca95183bf409820066fab975979bf06.tar.bz2 busybox-w32-7e6add1dfca95183bf409820066fab975979bf06.zip |
udhcpc: add -x OPT:VAL option
function old new delta
udhcp_str2optset - 443 +443
add_client_options - 160 +160
udhcpc_main 2753 2857 +104
packed_usage 26670 26689 +19
attach_option 380 385 +5
udhcpd_main 1964 1965 +1
udhcp_add_option_string 94 86 -8
add_param_req_option 128 - -128
read_opt 443 - -443
------------------------------------------------------------------------------
(add/remove: 2/2 grow/shrink: 4/1 up/down: 732/-579) Total: 153 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/usage.h | 2 | ||||
-rw-r--r-- | networking/udhcp/common.h | 8 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 53 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.h | 1 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.h | 5 | ||||
-rw-r--r-- | networking/udhcp/files.c | 6 | ||||
-rw-r--r-- | networking/udhcp/options.c | 10 |
7 files changed, 61 insertions, 24 deletions
diff --git a/include/usage.h b/include/usage.h index 40cb6b2bb..a343b41da 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -4821,6 +4821,7 @@ | |||
4821 | "\n -t,--retries N Send up to N discover packets" \ | 4821 | "\n -t,--retries N Send up to N discover packets" \ |
4822 | "\n -T,--timeout N Pause between packets (default 3 seconds)" \ | 4822 | "\n -T,--timeout N Pause between packets (default 3 seconds)" \ |
4823 | "\n -A,--tryagain N Wait N seconds (default 20) after failure" \ | 4823 | "\n -A,--tryagain N Wait N seconds (default 20) after failure" \ |
4824 | "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" \ | ||
4824 | "\n -O,--request-option OPT Request DHCP option OPT (cumulative)" \ | 4825 | "\n -O,--request-option OPT Request DHCP option OPT (cumulative)" \ |
4825 | "\n -o,--no-default-options Don't request any options (unless -O is given)" \ | 4826 | "\n -o,--no-default-options Don't request any options (unless -O is given)" \ |
4826 | "\n -f,--foreground Run in foreground" \ | 4827 | "\n -f,--foreground Run in foreground" \ |
@@ -4851,6 +4852,7 @@ | |||
4851 | "\n -t N Send up to N discover packets" \ | 4852 | "\n -t N Send up to N discover packets" \ |
4852 | "\n -T N Pause between packets (default 3 seconds)" \ | 4853 | "\n -T N Pause between packets (default 3 seconds)" \ |
4853 | "\n -A N Wait N seconds (default 20) after failure" \ | 4854 | "\n -A N Wait N seconds (default 20) after failure" \ |
4855 | "\n -x OPT:VAL Include option OPT in sent packets" \ | ||
4854 | "\n -O OPT Request DHCP option OPT (cumulative)" \ | 4856 | "\n -O OPT Request DHCP option OPT (cumulative)" \ |
4855 | "\n -o Don't request any options (unless -O is given)" \ | 4857 | "\n -o Don't request any options (unless -O is given)" \ |
4856 | "\n -f Run in foreground" \ | 4858 | "\n -f Run in foreground" \ |
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 15fe785c1..9c3b4960b 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -161,6 +161,11 @@ struct dhcp_option { | |||
161 | uint8_t code; | 161 | uint8_t code; |
162 | }; | 162 | }; |
163 | 163 | ||
164 | struct option_set { | ||
165 | uint8_t *data; | ||
166 | struct option_set *next; | ||
167 | }; | ||
168 | |||
164 | extern const struct dhcp_option dhcp_options[]; | 169 | extern const struct dhcp_option dhcp_options[]; |
165 | extern const char dhcp_option_strings[]; | 170 | extern const char dhcp_option_strings[]; |
166 | extern const uint8_t dhcp_option_lengths[]; | 171 | extern const uint8_t dhcp_option_lengths[]; |
@@ -173,6 +178,9 @@ void udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data) FA | |||
173 | char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC; | 178 | char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC; |
174 | uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC; | 179 | uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC; |
175 | #endif | 180 | #endif |
181 | /* 2nd param is actually "struct option_set**" */ | ||
182 | int FAST_FUNC udhcp_str2optset(const char *const_line, void *arg); | ||
183 | |||
176 | 184 | ||
177 | // RFC 2131 Table 5: Fields and options used by DHCP clients | 185 | // RFC 2131 Table 5: Fields and options used by DHCP clients |
178 | // | 186 | // |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 758750907..4565d7fd2 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -331,11 +331,11 @@ static void init_packet(struct dhcp_packet *packet, char type) | |||
331 | } | 331 | } |
332 | } | 332 | } |
333 | 333 | ||
334 | /* Add a parameter request list for stubborn DHCP servers. Pull the data | 334 | static void add_client_options(struct dhcp_packet *packet) |
335 | * from the struct in options.c. Don't do bounds checking here because it | ||
336 | * goes towards the head of the packet. */ | ||
337 | static void add_param_req_option(struct dhcp_packet *packet) | ||
338 | { | 335 | { |
336 | /* Add am "param req" option with the list of options we'd like to have | ||
337 | * from stubborn DHCP servers. Pull the data from the struct in options.c. | ||
338 | * No bounds checking because it goes towards the head of the packet. */ | ||
339 | uint8_t c; | 339 | uint8_t c; |
340 | int end = udhcp_end_option(packet->options); | 340 | int end = udhcp_end_option(packet->options); |
341 | int i, len = 0; | 341 | int i, len = 0; |
@@ -355,6 +355,19 @@ static void add_param_req_option(struct dhcp_packet *packet) | |||
355 | packet->options[end + OPT_LEN] = len; | 355 | packet->options[end + OPT_LEN] = len; |
356 | packet->options[end + OPT_DATA + len] = DHCP_END; | 356 | packet->options[end + OPT_DATA + len] = DHCP_END; |
357 | } | 357 | } |
358 | |||
359 | /* Add -x options if any */ | ||
360 | { | ||
361 | struct option_set *curr = client_config.options; | ||
362 | while (curr) { | ||
363 | udhcp_add_option_string(packet->options, curr->data); | ||
364 | curr = curr->next; | ||
365 | } | ||
366 | // if (client_config.sname) | ||
367 | // strncpy((char*)packet->sname, client_config.sname, sizeof(packet->sname) - 1); | ||
368 | // if (client_config.boot_file) | ||
369 | // strncpy((char*)packet->file, client_config.boot_file, sizeof(packet->file) - 1); | ||
370 | } | ||
358 | } | 371 | } |
359 | 372 | ||
360 | /* RFC 2131 | 373 | /* RFC 2131 |
@@ -395,7 +408,7 @@ static int send_discover(uint32_t xid, uint32_t requested) | |||
395 | /* Explicitly saying that we want RFC-compliant packets helps | 408 | /* Explicitly saying that we want RFC-compliant packets helps |
396 | * some buggy DHCP servers to NOT send bigger packets */ | 409 | * some buggy DHCP servers to NOT send bigger packets */ |
397 | udhcp_add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576)); | 410 | udhcp_add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576)); |
398 | add_param_req_option(&packet); | 411 | add_client_options(&packet); |
399 | 412 | ||
400 | bb_info_msg("Sending discover..."); | 413 | bb_info_msg("Sending discover..."); |
401 | return raw_bcast_from_client_config_ifindex(&packet); | 414 | return raw_bcast_from_client_config_ifindex(&packet); |
@@ -414,7 +427,7 @@ static int send_select(uint32_t xid, uint32_t server, uint32_t requested) | |||
414 | packet.xid = xid; | 427 | packet.xid = xid; |
415 | udhcp_add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); | 428 | udhcp_add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); |
416 | udhcp_add_simple_option(packet.options, DHCP_SERVER_ID, server); | 429 | udhcp_add_simple_option(packet.options, DHCP_SERVER_ID, server); |
417 | add_param_req_option(&packet); | 430 | add_client_options(&packet); |
418 | 431 | ||
419 | addr.s_addr = requested; | 432 | addr.s_addr = requested; |
420 | bb_info_msg("Sending select for %s...", inet_ntoa(addr)); | 433 | bb_info_msg("Sending select for %s...", inet_ntoa(addr)); |
@@ -429,7 +442,7 @@ static int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | |||
429 | init_packet(&packet, DHCPREQUEST); | 442 | init_packet(&packet, DHCPREQUEST); |
430 | packet.xid = xid; | 443 | packet.xid = xid; |
431 | packet.ciaddr = ciaddr; | 444 | packet.ciaddr = ciaddr; |
432 | add_param_req_option(&packet); | 445 | add_client_options(&packet); |
433 | 446 | ||
434 | bb_info_msg("Sending renew..."); | 447 | bb_info_msg("Sending renew..."); |
435 | if (server) | 448 | if (server) |
@@ -728,6 +741,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
728 | const char *str_c, *str_V, *str_h, *str_F, *str_r; | 741 | const char *str_c, *str_V, *str_h, *str_F, *str_r; |
729 | IF_FEATURE_UDHCP_PORT(char *str_P;) | 742 | IF_FEATURE_UDHCP_PORT(char *str_P;) |
730 | llist_t *list_O = NULL; | 743 | llist_t *list_O = NULL; |
744 | llist_t *list_x = NULL; | ||
731 | int tryagain_timeout = 20; | 745 | int tryagain_timeout = 20; |
732 | int discover_timeout = 3; | 746 | int discover_timeout = 3; |
733 | int discover_retries = 3; | 747 | int discover_retries = 3; |
@@ -792,9 +806,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
792 | OPT_A = 1 << 16, | 806 | OPT_A = 1 << 16, |
793 | OPT_O = 1 << 17, | 807 | OPT_O = 1 << 17, |
794 | OPT_o = 1 << 18, | 808 | OPT_o = 1 << 18, |
795 | OPT_f = 1 << 19, | 809 | OPT_x = 1 << 19, |
810 | OPT_f = 1 << 20, | ||
796 | /* The rest has variable bit positions, need to be clever */ | 811 | /* The rest has variable bit positions, need to be clever */ |
797 | OPTBIT_f = 19, | 812 | OPTBIT_f = 20, |
798 | USE_FOR_MMU( OPTBIT_b,) | 813 | USE_FOR_MMU( OPTBIT_b,) |
799 | IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,) | 814 | IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,) |
800 | IF_FEATURE_UDHCP_PORT( OPTBIT_P,) | 815 | IF_FEATURE_UDHCP_PORT( OPTBIT_P,) |
@@ -811,14 +826,14 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
811 | str_V = "udhcp "BB_VER; | 826 | str_V = "udhcp "BB_VER; |
812 | 827 | ||
813 | /* Parse command line */ | 828 | /* Parse command line */ |
814 | /* Cc: mutually exclusive; O: list; -T,-t,-A take numeric param */ | 829 | /* Cc: mutually exclusive; O,x: list; -T,-t,-A take numeric param */ |
815 | opt_complementary = "c--C:C--c:O::T+:t+:A+" | 830 | opt_complementary = "c--C:C--c:O::x::T+:t+:A+" |
816 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | 831 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 |
817 | ":vv" | 832 | ":vv" |
818 | #endif | 833 | #endif |
819 | ; | 834 | ; |
820 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) | 835 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) |
821 | opt = getopt32(argv, "c:CV:H:h:F:i:np:qRr:s:T:t:SA:O:of" | 836 | opt = getopt32(argv, "c:CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:f" |
822 | USE_FOR_MMU("b") | 837 | USE_FOR_MMU("b") |
823 | IF_FEATURE_UDHCPC_ARPING("a") | 838 | IF_FEATURE_UDHCPC_ARPING("a") |
824 | IF_FEATURE_UDHCP_PORT("P:") | 839 | IF_FEATURE_UDHCP_PORT("P:") |
@@ -828,6 +843,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
828 | , &client_config.script /* s */ | 843 | , &client_config.script /* s */ |
829 | , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ | 844 | , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ |
830 | , &list_O | 845 | , &list_O |
846 | , &list_x | ||
831 | IF_FEATURE_UDHCP_PORT(, &str_P) | 847 | IF_FEATURE_UDHCP_PORT(, &str_P) |
832 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | 848 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 |
833 | , &dhcp_verbose | 849 | , &dhcp_verbose |
@@ -868,6 +884,19 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
868 | n = dhcp_options[n].code; | 884 | n = dhcp_options[n].code; |
869 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); | 885 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); |
870 | } | 886 | } |
887 | while (list_x) { | ||
888 | int n; | ||
889 | char *optstr = llist_pop(&list_x); | ||
890 | char *colon = strchr(optstr, ':'); | ||
891 | if (colon) | ||
892 | *colon = '\0'; | ||
893 | n = index_in_strings(dhcp_option_strings, optstr); | ||
894 | if (n < 0) | ||
895 | bb_error_msg_and_die("unknown option '%s'", optstr); | ||
896 | if (colon) | ||
897 | *colon = ' '; | ||
898 | udhcp_str2optset(optstr, &client_config.options); | ||
899 | } | ||
871 | 900 | ||
872 | if (udhcp_read_interface(client_config.interface, | 901 | if (udhcp_read_interface(client_config.interface, |
873 | &client_config.ifindex, | 902 | &client_config.ifindex, |
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index 4c173533c..fba747f0c 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h | |||
@@ -13,6 +13,7 @@ struct client_config_t { | |||
13 | const char *interface; /* The name of the interface to use */ | 13 | const char *interface; /* The name of the interface to use */ |
14 | char *pidfile; /* Optionally store the process ID */ | 14 | char *pidfile; /* Optionally store the process ID */ |
15 | const char *script; /* User script to run at dhcp events */ | 15 | const char *script; /* User script to run at dhcp events */ |
16 | struct option_set *options; /* list of DHCP options to send to server */ | ||
16 | uint8_t *clientid; /* Optional client id to use */ | 17 | uint8_t *clientid; /* Optional client id to use */ |
17 | uint8_t *vendorclass; /* Optional vendor class-id to use */ | 18 | uint8_t *vendorclass; /* Optional vendor class-id to use */ |
18 | uint8_t *hostname; /* Optional hostname to use */ | 19 | uint8_t *hostname; /* Optional hostname to use */ |
diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index b163ce7eb..a4e9a58ff 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h | |||
@@ -13,11 +13,6 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
13 | #define DHCPD_CONF_FILE "/etc/udhcpd.conf" | 13 | #define DHCPD_CONF_FILE "/etc/udhcpd.conf" |
14 | 14 | ||
15 | 15 | ||
16 | struct option_set { | ||
17 | uint8_t *data; | ||
18 | struct option_set *next; | ||
19 | }; | ||
20 | |||
21 | struct static_lease { | 16 | struct static_lease { |
22 | struct static_lease *next; | 17 | struct static_lease *next; |
23 | uint32_t nip; | 18 | uint32_t nip; |
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 05a7b998a..fddda4cba 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c | |||
@@ -145,7 +145,7 @@ static NOINLINE void attach_option( | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /* read a dhcp option and add it to opt_list */ | 147 | /* read a dhcp option and add it to opt_list */ |
148 | static int FAST_FUNC read_opt(const char *const_line, void *arg) | 148 | int FAST_FUNC udhcp_str2optset(const char *const_line, void *arg) |
149 | { | 149 | { |
150 | struct option_set **opt_list = arg; | 150 | struct option_set **opt_list = arg; |
151 | char *opt, *val, *endptr; | 151 | char *opt, *val, *endptr; |
@@ -292,8 +292,8 @@ static const struct config_keyword keywords[] = { | |||
292 | {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, | 292 | {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, |
293 | {"siaddr", read_nip, &(server_config.siaddr_nip), "0.0.0.0"}, | 293 | {"siaddr", read_nip, &(server_config.siaddr_nip), "0.0.0.0"}, |
294 | /* keywords with no defaults must be last! */ | 294 | /* keywords with no defaults must be last! */ |
295 | {"option", read_opt, &(server_config.options), ""}, | 295 | {"option", udhcp_str2optset, &(server_config.options), ""}, |
296 | {"opt", read_opt, &(server_config.options), ""}, | 296 | {"opt", udhcp_str2optset, &(server_config.options), ""}, |
297 | {"notify_file", read_str, &(server_config.notify_file), ""}, | 297 | {"notify_file", read_str, &(server_config.notify_file), ""}, |
298 | {"sname", read_str, &(server_config.sname), ""}, | 298 | {"sname", read_str, &(server_config.sname), ""}, |
299 | {"boot_file", read_str, &(server_config.boot_file), ""}, | 299 | {"boot_file", read_str, &(server_config.boot_file), ""}, |
diff --git a/networking/udhcp/options.c b/networking/udhcp/options.c index b4d2d2de3..af3c217e8 100644 --- a/networking/udhcp/options.c +++ b/networking/udhcp/options.c | |||
@@ -212,7 +212,7 @@ int FAST_FUNC udhcp_end_option(uint8_t *optionptr) | |||
212 | 212 | ||
213 | while (optionptr[i] != DHCP_END) { | 213 | while (optionptr[i] != DHCP_END) { |
214 | if (optionptr[i] != DHCP_PADDING) | 214 | if (optionptr[i] != DHCP_PADDING) |
215 | i += optionptr[i + OPT_LEN] + 1; | 215 | i += optionptr[i + OPT_LEN] + OPT_DATA-1; |
216 | i++; | 216 | i++; |
217 | } | 217 | } |
218 | return i; | 218 | return i; |
@@ -222,7 +222,8 @@ int FAST_FUNC udhcp_end_option(uint8_t *optionptr) | |||
222 | /* option bytes: [code][len][data1][data2]..[dataLEN] */ | 222 | /* option bytes: [code][len][data1][data2]..[dataLEN] */ |
223 | void FAST_FUNC udhcp_add_option_string(uint8_t *optionptr, uint8_t *string) | 223 | void FAST_FUNC udhcp_add_option_string(uint8_t *optionptr, uint8_t *string) |
224 | { | 224 | { |
225 | int end = udhcp_end_option(optionptr); | 225 | unsigned len; |
226 | unsigned end = udhcp_end_option(optionptr); | ||
226 | 227 | ||
227 | /* end position + string length + option code/length + end option */ | 228 | /* end position + string length + option code/length + end option */ |
228 | if (end + string[OPT_LEN] + 2 + 1 >= DHCP_OPTIONS_BUFSIZE) { | 229 | if (end + string[OPT_LEN] + 2 + 1 >= DHCP_OPTIONS_BUFSIZE) { |
@@ -231,8 +232,9 @@ void FAST_FUNC udhcp_add_option_string(uint8_t *optionptr, uint8_t *string) | |||
231 | return; | 232 | return; |
232 | } | 233 | } |
233 | log_option("Adding option", string); | 234 | log_option("Adding option", string); |
234 | memcpy(optionptr + end, string, string[OPT_LEN] + 2); | 235 | len = OPT_DATA + string[OPT_LEN]; |
235 | optionptr[end + string[OPT_LEN] + 2] = DHCP_END; | 236 | memcpy(optionptr + end, string, len); |
237 | optionptr[end + len] = DHCP_END; | ||
236 | } | 238 | } |
237 | 239 | ||
238 | /* add a one to four byte option to a packet */ | 240 | /* add a one to four byte option to a packet */ |