diff options
Diffstat (limited to 'networking/udhcp')
-rw-r--r-- | networking/udhcp/dhcpc.c | 170 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.h | 19 |
2 files changed, 92 insertions, 97 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index f1aa36fe6..d135ba74d 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -98,24 +98,15 @@ static void perform_release(uint32_t requested_ip, uint32_t server_addr) } +#if BB_MMU static void client_background(void) { -#if !BB_MMU - bb_error_msg("cannot background in uclinux (yet)"); -/* ... mainly because udhcpc calls client_background() - * in _the _middle _of _udhcpc _run_, not at the start! - * If that will be properly disabled for NOMMU, client_background() - * will work on NOMMU too */ -#else bb_daemonize(0); logmode &= ~LOGMODE_STDIO; /* rewrite pidfile, as our pid is different now */ write_pidfile(client_config.pidfile); -#endif - /* Do not fork again. */ - client_config.foreground = 1; - client_config.background_if_no_lease = 0; } +#endif static uint8_t* alloc_dhcp_option(int code, const char *str, int extra) @@ -138,9 +129,6 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) char *str_c, *str_V, *str_h, *str_F, *str_r; USE_FEATURE_UDHCP_PORT(char *str_P;) llist_t *list_O = NULL; -#if ENABLE_FEATURE_UDHCPC_ARPING - char *str_W; -#endif int tryagain_timeout = 20; int discover_timeout = 3; int discover_retries = 3; @@ -158,41 +146,11 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) struct dhcpMessage packet; fd_set rfds; - enum { - OPT_c = 1 << 0, - OPT_C = 1 << 1, - OPT_V = 1 << 2, - OPT_f = 1 << 3, - OPT_b = 1 << 4, - OPT_H = 1 << 5, - OPT_h = 1 << 6, - OPT_F = 1 << 7, - OPT_i = 1 << 8, - OPT_n = 1 << 9, - OPT_p = 1 << 10, - OPT_q = 1 << 11, - OPT_R = 1 << 12, - OPT_r = 1 << 13, - OPT_s = 1 << 14, - OPT_T = 1 << 15, - OPT_t = 1 << 16, - OPT_v = 1 << 17, - OPT_S = 1 << 18, - OPT_A = 1 << 19, -#if ENABLE_FEATURE_UDHCPC_ARPING - OPT_a = 1 << 20, - OPT_W = 1 << 21, -#endif - OPT_P = 1 << 22, - OPT_o = 1 << 23, - }; #if ENABLE_GETOPT_LONG static const char udhcpc_longopts[] ALIGN1 = "clientid\0" Required_argument "c" "clientid-none\0" No_argument "C" "vendorclass\0" Required_argument "V" - "foreground\0" No_argument "f" - "background\0" No_argument "b" "hostname\0" Required_argument "H" "fqdn\0" Required_argument "F" "interface\0" Required_argument "i" @@ -207,16 +165,62 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) "retries\0" Required_argument "t" "tryagain\0" Required_argument "A" "syslog\0" No_argument "S" + "request-option\0" Required_argument "O" + "no-default-options\0" No_argument "o" + "foreground\0" No_argument "f" + "background\0" No_argument "b" #if ENABLE_FEATURE_UDHCPC_ARPING "arping\0" No_argument "a" #endif - "request-option\0" Required_argument "O" #if ENABLE_FEATURE_UDHCP_PORT "client-port\0" Required_argument "P" #endif - "no-default-options\0" No_argument "o" ; #endif + enum { + OPT_c = 1 << 0, + OPT_C = 1 << 1, + OPT_V = 1 << 2, + OPT_H = 1 << 3, + OPT_h = 1 << 4, + OPT_F = 1 << 5, + OPT_i = 1 << 6, + OPT_n = 1 << 7, + OPT_p = 1 << 8, + OPT_q = 1 << 9, + OPT_R = 1 << 10, + OPT_r = 1 << 11, + OPT_s = 1 << 12, + OPT_T = 1 << 13, + OPT_t = 1 << 14, + OPT_v = 1 << 15, + OPT_S = 1 << 16, + OPT_A = 1 << 17, + OPT_O = 1 << 18, + OPT_o = 1 << 19, + OPT_f = 1 << 20, +/* The rest has variable bit positions, need to be clever */ + OPTBIT_f = 20, +#if BB_MMU + OPTBIT_b, +#endif +#if ENABLE_FEATURE_UDHCPC_ARPING + OPTBIT_a, +#endif +#if ENABLE_FEATURE_UDHCP_PORT + OPTBIT_P, +#endif +#if BB_MMU + OPT_b = 1 << OPTBIT_b, +#endif +#if ENABLE_FEATURE_UDHCPC_ARPING + OPT_a = 1 << OPTBIT_a, +#endif +#if ENABLE_FEATURE_UDHCP_PORT + OPT_P = 1 << OPTBIT_P, +#endif + }; + /* Default options. */ #if ENABLE_FEATURE_UDHCP_PORT SERVER_PORT = 67; @@ -231,28 +235,21 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) #if ENABLE_GETOPT_LONG applet_long_options = udhcpc_longopts; #endif - opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vSA:" - USE_FEATURE_UDHCPC_ARPING("aW:") + opt = getopt32(argv, "c:CV:H:h:F:i:np:qRr:s:T:t:vSA:O:of" + USE_FOR_MMU("b") + USE_FEATURE_UDHCPC_ARPING("a") USE_FEATURE_UDHCP_PORT("P:") - "O:o" , &str_c, &str_V, &str_h, &str_h, &str_F - , &client_config.interface, &client_config.pidfile, &str_r - , &client_config.script - , &discover_timeout, &discover_retries, &tryagain_timeout - USE_FEATURE_UDHCPC_ARPING(, &str_W) - USE_FEATURE_UDHCP_PORT(, &str_P) + , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ + , &client_config.script /* s */ + , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ , &list_O + USE_FEATURE_UDHCP_PORT(, &str_P) ); - if (opt & OPT_c) client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0); - //if (opt & OPT_C) if (opt & OPT_V) client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); - if (opt & OPT_f) - client_config.foreground = 1; - if (opt & OPT_b) - client_config.background_if_no_lease = 1; if (opt & (OPT_h|OPT_H)) client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); if (opt & OPT_F) { @@ -267,28 +264,12 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) /* client_config.fqdn[OPT_DATA + 1] = 0; - redundant */ /* client_config.fqdn[OPT_DATA + 2] = 0; - redundant */ } - // if (opt & OPT_i) client_config.interface = ... - if (opt & OPT_n) - client_config.abort_if_no_lease = 1; - // if (opt & OPT_p) client_config.pidfile = ... - if (opt & OPT_q) - client_config.quit_after_lease = 1; - if (opt & OPT_R) - client_config.release_on_quit = 1; if (opt & OPT_r) requested_ip = inet_addr(str_r); - // if (opt & OPT_s) client_config.script = ... - // if (opt & OPT_T) discover_timeout = xatoi_u(str_T); - // if (opt & OPT_t) discover_retries = xatoi_u(str_t); - // if (opt & OPT_A) tryagain_timeout = xatoi_u(str_A); if (opt & OPT_v) { puts("version "BB_VER); return 0; } - if (opt & OPT_S) { - openlog(applet_name, LOG_PID, LOG_LOCAL0); - logmode |= LOGMODE_SYSLOG; - } #if ENABLE_FEATURE_UDHCP_PORT if (opt & OPT_P) { CLIENT_PORT = xatou16(str_P); @@ -309,6 +290,17 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) if (read_interface(client_config.interface, &client_config.ifindex, NULL, client_config.arp)) return 1; +#if !BB_MMU + /* on NOMMU reexec (i.e., background) early */ + if (!(opt & OPT_f)) { + bb_daemonize_or_rexec(0 /* flags */, argv); + logmode = 0; + } +#endif + if (opt & OPT_S) { + openlog(applet_name, LOG_PID, LOG_LOCAL0); + logmode |= LOGMODE_SYSLOG; + } /* Make sure fd 0,1,2 are open */ bb_sanitize_stdio(); @@ -317,9 +309,8 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) /* Create pidfile */ write_pidfile(client_config.pidfile); - /* if (!..) bb_perror_msg("cannot create pidfile %s", pidfile); */ - /* Goes to stdout and possibly syslog */ + /* Goes to stdout (unless NOMMU) and possibly syslog */ bb_info_msg("%s (v"BB_VER") started", applet_name); /* if not set, and not suppressed, setup the default client ID */ @@ -393,10 +384,15 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) continue; } udhcp_run_script(NULL, "leasefail"); - if (client_config.background_if_no_lease) { +#if BB_MMU /* -b is not supported on NOMMU */ + if (opt & OPT_b) { /* background if no lease */ bb_info_msg("No lease, forking to background"); client_background(); - } else if (client_config.abort_if_no_lease) { + /* do not background again! */ + opt = ((opt & ~OPT_b) | OPT_f); + } else +#endif + if (opt & OPT_n) { /* abort if no lease */ bb_info_msg("No lease, failing"); retval = 1; goto ret; @@ -584,14 +580,18 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) state = BOUND; change_listen_mode(LISTEN_NONE); - if (client_config.quit_after_lease) { - if (client_config.release_on_quit) + if (opt & OPT_q) { /* quit after lease */ + if (opt & OPT_R) /* release on quit */ perform_release(requested_ip, server_addr); goto ret0; } - if (!client_config.foreground) +#if BB_MMU /* NOMMU case backgrounded earlier */ + if (!(opt & OPT_f)) { client_background(); - + /* do not background again! */ + opt = ((opt & ~OPT_b) | OPT_f); + } +#endif already_waited_sec = 0; continue; /* back to main loop */ } @@ -633,7 +633,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) break; case SIGTERM: bb_info_msg("Received SIGTERM"); - if (client_config.release_on_quit) + if (opt & OPT_R) /* release on quit */ perform_release(requested_ip, server_addr); goto ret0; } diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index 97d3b3c9d..1ebccd405 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h @@ -9,14 +9,15 @@ #endif struct client_config_t { + uint8_t arp[6]; /* Our arp address */ /* TODO: combine flag fields into single "unsigned opt" */ /* (can be set directly to the result of getopt32) */ - char foreground; /* Do not fork */ - char quit_after_lease; /* Quit after obtaining lease */ - char release_on_quit; /* Perform release on quit */ - char abort_if_no_lease; /* Abort if no lease */ - char background_if_no_lease; /* Fork to background if no lease */ char no_default_options; /* Do not include default optins in request */ +#if ENABLE_FEATURE_UDHCP_PORT + uint16_t port; +#endif + int ifindex; /* Index number of the interface to use */ + uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ const char *interface; /* The name of the interface to use */ char *pidfile; /* Optionally store the process ID */ const char *script; /* User script to run at dhcp events */ @@ -24,16 +25,10 @@ struct client_config_t { uint8_t *vendorclass; /* Optional vendor class-id to use */ uint8_t *hostname; /* Optional hostname to use */ uint8_t *fqdn; /* Optional fully qualified domain name to use */ - int ifindex; /* Index number of the interface to use */ -#if ENABLE_FEATURE_UDHCP_PORT - uint16_t port; -#endif - uint8_t arp[6]; /* Our arp address */ - uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ }; /* server_config sits in 1st half of bb_common_bufsiz1 */ -#define client_config (*(struct client_config_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE/2])) +#define client_config (*(struct client_config_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE / 2])) #if ENABLE_FEATURE_UDHCP_PORT #define CLIENT_PORT (client_config.port) |