diff options
Diffstat (limited to 'networking/udhcp/dhcpc.c')
-rw-r--r-- | networking/udhcp/dhcpc.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 4bb90c2da..efe208814 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -109,7 +109,7 @@ static void perform_release(void) | |||
109 | 109 | ||
110 | static void client_background(void) | 110 | static void client_background(void) |
111 | { | 111 | { |
112 | #ifdef __uClinux__ | 112 | #if !BB_MMU |
113 | bb_error_msg("cannot background in uclinux (yet)"); | 113 | bb_error_msg("cannot background in uclinux (yet)"); |
114 | /* ... mainly because udhcpc calls client_background() | 114 | /* ... mainly because udhcpc calls client_background() |
115 | * in _the _middle _of _udhcpc _run_, not at the start! | 115 | * in _the _middle _of _udhcpc _run_, not at the start! |
@@ -119,8 +119,7 @@ static void client_background(void) | |||
119 | bb_daemonize(0); | 119 | bb_daemonize(0); |
120 | logmode &= ~LOGMODE_STDIO; | 120 | logmode &= ~LOGMODE_STDIO; |
121 | /* rewrite pidfile, as our pid is different now */ | 121 | /* rewrite pidfile, as our pid is different now */ |
122 | if (client_config.pidfile) | 122 | write_pidfile(client_config.pidfile); |
123 | write_pidfile(client_config.pidfile); | ||
124 | #endif | 123 | #endif |
125 | /* Do not fork again. */ | 124 | /* Do not fork again. */ |
126 | client_config.foreground = 1; | 125 | client_config.foreground = 1; |
@@ -148,19 +147,17 @@ int udhcpc_main(int argc, char **argv) | |||
148 | char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_t; | 147 | char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_t; |
149 | uint32_t xid = 0; | 148 | uint32_t xid = 0; |
150 | uint32_t lease = 0; /* can be given as 32-bit quantity */ | 149 | uint32_t lease = 0; /* can be given as 32-bit quantity */ |
151 | unsigned t1 = 0, t2 = 0; | 150 | unsigned t1 = 0, t2 = 0; /* what a wonderful names */ |
152 | unsigned start = 0; | 151 | unsigned start = 0; |
153 | unsigned now; | 152 | unsigned now; |
154 | unsigned opt; | 153 | unsigned opt; |
155 | int max_fd; | 154 | int max_fd; |
156 | int sig; | ||
157 | int retval; | 155 | int retval; |
158 | int len; | 156 | int len; |
159 | int no_clientid = 0; | ||
160 | fd_set rfds; | ||
161 | struct timeval tv; | 157 | struct timeval tv; |
162 | struct dhcpMessage packet; | ||
163 | struct in_addr temp_addr; | 158 | struct in_addr temp_addr; |
159 | struct dhcpMessage packet; | ||
160 | fd_set rfds; | ||
164 | 161 | ||
165 | enum { | 162 | enum { |
166 | OPT_c = 1 << 0, | 163 | OPT_c = 1 << 0, |
@@ -224,8 +221,7 @@ int udhcpc_main(int argc, char **argv) | |||
224 | 221 | ||
225 | if (opt & OPT_c) | 222 | if (opt & OPT_c) |
226 | client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0); | 223 | client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0); |
227 | if (opt & OPT_C) | 224 | //if (opt & OPT_C) |
228 | no_clientid = 1; | ||
229 | if (opt & OPT_V) | 225 | if (opt & OPT_V) |
230 | client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); | 226 | client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); |
231 | if (opt & OPT_f) | 227 | if (opt & OPT_f) |
@@ -262,7 +258,7 @@ int udhcpc_main(int argc, char **argv) | |||
262 | if (opt & OPT_t) | 258 | if (opt & OPT_t) |
263 | client_config.retries = xatoi_u(str_t); | 259 | client_config.retries = xatoi_u(str_t); |
264 | if (opt & OPT_v) { | 260 | if (opt & OPT_v) { |
265 | printf("version %s\n\n", BB_VER); | 261 | printf("version %s\n", BB_VER); |
266 | return 0; | 262 | return 0; |
267 | } | 263 | } |
268 | 264 | ||
@@ -272,14 +268,23 @@ int udhcpc_main(int argc, char **argv) | |||
272 | } | 268 | } |
273 | 269 | ||
274 | if (read_interface(client_config.interface, &client_config.ifindex, | 270 | if (read_interface(client_config.interface, &client_config.ifindex, |
275 | NULL, client_config.arp) < 0) | 271 | NULL, client_config.arp)) |
276 | return 1; | 272 | return 1; |
277 | 273 | ||
278 | /* Sanitize fd's and write pidfile */ | 274 | /* Make sure fd 0,1,2 are open */ |
279 | udhcp_make_pidfile(client_config.pidfile); | 275 | bb_sanitize_stdio(); |
276 | /* Equivalent of doing a fflush after every \n */ | ||
277 | setlinebuf(stdout); | ||
278 | |||
279 | /* Create pidfile */ | ||
280 | write_pidfile(client_config.pidfile); | ||
281 | /* if (!..) bb_perror_msg("cannot create pidfile %s", pidfile); */ | ||
282 | |||
283 | /* Goes to stdout and possibly syslog */ | ||
284 | bb_info_msg("%s (v%s) started", applet_name, BB_VER); | ||
280 | 285 | ||
281 | /* if not set, and not suppressed, setup the default client ID */ | 286 | /* if not set, and not suppressed, setup the default client ID */ |
282 | if (!client_config.clientid && !no_clientid) { | 287 | if (!client_config.clientid && !(opt & OPT_C)) { |
283 | client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); | 288 | client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); |
284 | client_config.clientid[OPT_DATA] = 1; | 289 | client_config.clientid[OPT_DATA] = 1; |
285 | memcpy(client_config.clientid + OPT_DATA+1, client_config.arp, 6); | 290 | memcpy(client_config.clientid + OPT_DATA+1, client_config.arp, 6); |
@@ -294,9 +299,12 @@ int udhcpc_main(int argc, char **argv) | |||
294 | state = INIT_SELECTING; | 299 | state = INIT_SELECTING; |
295 | udhcp_run_script(NULL, "deconfig"); | 300 | udhcp_run_script(NULL, "deconfig"); |
296 | change_mode(LISTEN_RAW); | 301 | change_mode(LISTEN_RAW); |
302 | tv.tv_sec = 0; | ||
303 | goto jump_in; | ||
297 | 304 | ||
298 | for (;;) { | 305 | for (;;) { |
299 | tv.tv_sec = timeout - monotonic_sec(); | 306 | tv.tv_sec = timeout - monotonic_sec(); |
307 | jump_in: | ||
300 | tv.tv_usec = 0; | 308 | tv.tv_usec = 0; |
301 | 309 | ||
302 | if (listen_mode != LISTEN_NONE && sockfd < 0) { | 310 | if (listen_mode != LISTEN_NONE && sockfd < 0) { |
@@ -307,13 +315,20 @@ int udhcpc_main(int argc, char **argv) | |||
307 | } | 315 | } |
308 | max_fd = udhcp_sp_fd_set(&rfds, sockfd); | 316 | max_fd = udhcp_sp_fd_set(&rfds, sockfd); |
309 | 317 | ||
318 | retval = 0; /* If we already timed out, fall through, else... */ | ||
310 | if (tv.tv_sec > 0) { | 319 | if (tv.tv_sec > 0) { |
311 | DEBUG("Waiting on select..."); | 320 | DEBUG("Waiting on select..."); |
312 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); | 321 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); |
313 | } else retval = 0; /* If we already timed out, fall through */ | 322 | } |
314 | 323 | ||
315 | now = monotonic_sec(); | 324 | now = monotonic_sec(); |
316 | if (retval == 0) { | 325 | if (retval < 0) { |
326 | /* EINTR? signal was caught, don't panic */ | ||
327 | if (errno != EINTR) { | ||
328 | /* Else: an error occured, panic! */ | ||
329 | bb_perror_msg_and_die("select"); | ||
330 | } | ||
331 | } else if (retval == 0) { | ||
317 | /* timeout dropped to zero */ | 332 | /* timeout dropped to zero */ |
318 | switch (state) { | 333 | switch (state) { |
319 | case INIT_SELECTING: | 334 | case INIT_SELECTING: |
@@ -377,9 +392,8 @@ int udhcpc_main(int argc, char **argv) | |||
377 | } else { | 392 | } else { |
378 | /* send a request packet */ | 393 | /* send a request packet */ |
379 | send_renew(xid, server_addr, requested_ip); /* unicast */ | 394 | send_renew(xid, server_addr, requested_ip); /* unicast */ |
380 | |||
381 | t1 = (t2 - t1) / 2 + t1; | 395 | t1 = (t2 - t1) / 2 + t1; |
382 | timeout = t1 + start; | 396 | timeout = start + t1; |
383 | } | 397 | } |
384 | break; | 398 | break; |
385 | case REBINDING: | 399 | case REBINDING: |
@@ -395,9 +409,8 @@ int udhcpc_main(int argc, char **argv) | |||
395 | } else { | 409 | } else { |
396 | /* send a request packet */ | 410 | /* send a request packet */ |
397 | send_renew(xid, 0, requested_ip); /* broadcast */ | 411 | send_renew(xid, 0, requested_ip); /* broadcast */ |
398 | |||
399 | t2 = (lease - t2) / 2 + t2; | 412 | t2 = (lease - t2) / 2 + t2; |
400 | timeout = t2 + start; | 413 | timeout = start + t2; |
401 | } | 414 | } |
402 | break; | 415 | break; |
403 | case RELEASED: | 416 | case RELEASED: |
@@ -405,7 +418,7 @@ int udhcpc_main(int argc, char **argv) | |||
405 | timeout = INT_MAX; | 418 | timeout = INT_MAX; |
406 | break; | 419 | break; |
407 | } | 420 | } |
408 | } else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) { | 421 | } else if (listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) { |
409 | /* a packet is ready, read it */ | 422 | /* a packet is ready, read it */ |
410 | 423 | ||
411 | if (listen_mode == LISTEN_KERNEL) | 424 | if (listen_mode == LISTEN_KERNEL) |
@@ -480,7 +493,7 @@ int udhcpc_main(int argc, char **argv) | |||
480 | bb_info_msg("Lease of %s obtained, lease time %u", | 493 | bb_info_msg("Lease of %s obtained, lease time %u", |
481 | inet_ntoa(temp_addr), (unsigned)lease); | 494 | inet_ntoa(temp_addr), (unsigned)lease); |
482 | start = now; | 495 | start = now; |
483 | timeout = t1 + start; | 496 | timeout = start + t1; |
484 | requested_ip = packet.yiaddr; | 497 | requested_ip = packet.yiaddr; |
485 | udhcp_run_script(&packet, | 498 | udhcp_run_script(&packet, |
486 | ((state == RENEWING || state == REBINDING) ? "renew" : "bound")); | 499 | ((state == RENEWING || state == REBINDING) ? "renew" : "bound")); |
@@ -511,8 +524,9 @@ int udhcpc_main(int argc, char **argv) | |||
511 | break; | 524 | break; |
512 | /* case BOUND, RELEASED: - ignore all packets */ | 525 | /* case BOUND, RELEASED: - ignore all packets */ |
513 | } | 526 | } |
514 | } else if (retval > 0 && (sig = udhcp_sp_read(&rfds))) { | 527 | } else { |
515 | switch (sig) { | 528 | int signo = udhcp_sp_read(&rfds); |
529 | switch (signo) { | ||
516 | case SIGUSR1: | 530 | case SIGUSR1: |
517 | perform_renew(); | 531 | perform_renew(); |
518 | break; | 532 | break; |
@@ -525,11 +539,6 @@ int udhcpc_main(int argc, char **argv) | |||
525 | perform_release(); | 539 | perform_release(); |
526 | goto ret0; | 540 | goto ret0; |
527 | } | 541 | } |
528 | } else if (retval == -1 && errno == EINTR) { | ||
529 | /* a signal was caught */ | ||
530 | } else { | ||
531 | /* An error occured */ | ||
532 | bb_perror_msg("select"); | ||
533 | } | 542 | } |
534 | } /* for (;;) */ | 543 | } /* for (;;) */ |
535 | ret0: | 544 | ret0: |