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 */ |
