aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-03-25 20:32:38 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-03-25 20:32:38 +0100
commit7e6add1dfca95183bf409820066fab975979bf06 (patch)
tree0da56954d93e9b10e956235a32f0d0644a60063b
parent0454d9d6c314f381eee8022ad4e7447d2fa1dcf1 (diff)
downloadbusybox-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.h2
-rw-r--r--networking/udhcp/common.h8
-rw-r--r--networking/udhcp/dhcpc.c53
-rw-r--r--networking/udhcp/dhcpc.h1
-rw-r--r--networking/udhcp/dhcpd.h5
-rw-r--r--networking/udhcp/files.c6
-rw-r--r--networking/udhcp/options.c10
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
164struct option_set {
165 uint8_t *data;
166 struct option_set *next;
167};
168
164extern const struct dhcp_option dhcp_options[]; 169extern const struct dhcp_option dhcp_options[];
165extern const char dhcp_option_strings[]; 170extern const char dhcp_option_strings[];
166extern const uint8_t dhcp_option_lengths[]; 171extern 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
173char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC; 178char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC;
174uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC; 179uint8_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**" */
182int 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 334static 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. */
337static 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
16struct option_set {
17 uint8_t *data;
18 struct option_set *next;
19};
20
21struct static_lease { 16struct 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 */
148static int FAST_FUNC read_opt(const char *const_line, void *arg) 148int 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] */
223void FAST_FUNC udhcp_add_option_string(uint8_t *optionptr, uint8_t *string) 223void 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 */