aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp')
-rw-r--r--networking/udhcp/dhcpc.c170
-rw-r--r--networking/udhcp/dhcpc.h19
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)