*/
#include <getopt.h>
+#include <syslog.h>
#include "common.h"
#include "dhcpd.h"
#include "options.h"
-static int state;
/* Something is definitely wrong here. IPv4 addresses
* in variables of type long?? BTW, we use inet_ntoa()
* in the code. Manpage says that struct in_addr has a member of type long (!)
* which holds IPv4 address, and the struct is passed by value (!!)
*/
-static unsigned long requested_ip; /* = 0 */
+static unsigned timeout;
+static uint32_t requested_ip; /* = 0 */
static uint32_t server_addr;
-static unsigned long timeout;
static int packet_num; /* = 0 */
-static int fd = -1;
+static int sockfd = -1;
#define LISTEN_NONE 0
#define LISTEN_KERNEL 1
#define LISTEN_RAW 2
-static int listen_mode;
+static smallint listen_mode;
+
+static smallint state;
struct client_config_t client_config;
{
DEBUG("entering %s listen mode",
new_mode ? (new_mode == 1 ? "kernel" : "raw") : "none");
- if (fd >= 0) close(fd);
- fd = -1;
+ if (sockfd >= 0) {
+ close(sockfd);
+ sockfd = -1;
+ }
listen_mode = new_mode;
}
/* perform a release */
static void perform_release(void)
{
- char buffer[16];
+ char buffer[sizeof("255.255.255.255")];
struct in_addr temp_addr;
/* send release packet */
if (state == BOUND || state == RENEWING || state == REBINDING) {
temp_addr.s_addr = server_addr;
- sprintf(buffer, "%s", inet_ntoa(temp_addr));
+ strcpy(buffer, inet_ntoa(temp_addr));
temp_addr.s_addr = requested_ip;
bb_info_msg("Unicasting a release of %s to %s",
inet_ntoa(temp_addr), buffer);
change_mode(LISTEN_NONE);
state = RELEASED;
- timeout = 0x7fffffff;
+ timeout = INT_MAX;
}
static void client_background(void)
{
- udhcp_background(client_config.pidfile);
- client_config.foreground = 1; /* Do not fork again. */
+#ifdef __uClinux__
+ 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 */
+ if (client_config.pidfile)
+ write_pidfile(client_config.pidfile);
+#endif
+ /* Do not fork again. */
+ client_config.foreground = 1;
client_config.background_if_no_lease = 0;
}
}
-int udhcpc_main(int argc, char *argv[]);
-int udhcpc_main(int argc, char *argv[])
+int udhcpc_main(int argc, char **argv);
+int udhcpc_main(int argc, char **argv)
{
uint8_t *temp, *message;
char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_t;
- unsigned long t1 = 0, t2 = 0, xid = 0;
- unsigned long start = 0, lease = 0;
- long now;
+ uint32_t xid = 0;
+ uint32_t lease = 0; /* can be given as 32-bit quantity */
+ unsigned t1 = 0, t2 = 0;
+ unsigned start = 0;
+ unsigned now;
unsigned opt;
int max_fd;
int sig;
client_config.timeout = 3;
/* Parse command line */
- opt_complementary = "?:c--C:C--c" // mutually exclusive
+ opt_complementary = "c--C:C--c" // mutually exclusive
":hH:Hh"; // -h and -H are the same
#if ENABLE_GETOPT_LONG
applet_long_options = arg_options;
return 0;
}
- /* Start the log, sanitize fd's, and write a pid file */
- udhcp_start_log_and_pid(client_config.pidfile);
+ if (ENABLE_FEATURE_UDHCP_SYSLOG) {
+ openlog(applet_name, LOG_PID, LOG_LOCAL0);
+ logmode |= LOGMODE_SYSLOG;
+ }
if (read_interface(client_config.interface, &client_config.ifindex,
NULL, client_config.arp) < 0)
return 1;
+ /* Sanitize fd's and write pidfile */
+ udhcp_make_pidfile(client_config.pidfile);
+
/* if not set, and not suppressed, setup the default client ID */
if (!client_config.clientid && !no_clientid) {
client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
change_mode(LISTEN_RAW);
for (;;) {
- tv.tv_sec = timeout - uptime();
+ tv.tv_sec = timeout - monotonic_sec();
tv.tv_usec = 0;
- if (listen_mode != LISTEN_NONE && fd < 0) {
+ if (listen_mode != LISTEN_NONE && sockfd < 0) {
if (listen_mode == LISTEN_KERNEL)
- fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface);
+ sockfd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface);
else
- fd = raw_socket(client_config.ifindex);
+ sockfd = raw_socket(client_config.ifindex);
}
- max_fd = udhcp_sp_fd_set(&rfds, fd);
+ max_fd = udhcp_sp_fd_set(&rfds, sockfd);
if (tv.tv_sec > 0) {
DEBUG("Waiting on select...");
retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
} else retval = 0; /* If we already timed out, fall through */
- now = uptime();
+ now = monotonic_sec();
if (retval == 0) {
/* timeout dropped to zero */
switch (state) {
client_background();
} else if (client_config.abort_if_no_lease) {
bb_info_msg("No lease, failing");
- return 1;
+ retval = 1;
+ goto ret;
}
/* wait to try again */
packet_num = 0;
packet_num++;
} else {
/* timed out, go back to init state */
- if (state == RENEW_REQUESTED) udhcp_run_script(NULL, "deconfig");
+ if (state == RENEW_REQUESTED)
+ udhcp_run_script(NULL, "deconfig");
state = INIT_SELECTING;
timeout = now;
packet_num = 0;
break;
case RELEASED:
/* yah, I know, *you* say it would never happen */
- timeout = 0x7fffffff;
+ timeout = INT_MAX;
break;
}
- } else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) {
+ } else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) {
/* a packet is ready, read it */
if (listen_mode == LISTEN_KERNEL)
- len = udhcp_get_packet(&packet, fd);
- else len = get_raw_packet(&packet, fd);
+ len = udhcp_get_packet(&packet, sockfd);
+ else len = get_raw_packet(&packet, sockfd);
if (len == -1 && errno != EINTR) {
DEBUG("error on read, %s, reopening socket", strerror(errno));
if (len < 0) continue;
if (packet.xid != xid) {
- DEBUG("Ignoring XID %lx (our xid is %lx)",
- (unsigned long) packet.xid, xid);
+ DEBUG("Ignoring XID %x (our xid is %x)",
+ (unsigned)packet.xid, (unsigned)xid);
continue;
}
continue;
}
- if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
+ message = get_option(&packet, DHCP_MESSAGE_TYPE);
+ if (message == NULL) {
bb_error_msg("cannot get option from packet - ignoring");
continue;
}
t1 = lease / 2;
/* little fixed point for n * .875 */
- t2 = (lease * 0x7) >> 3;
+ t2 = (lease * 7) >> 3;
temp_addr.s_addr = packet.yiaddr;
- bb_info_msg("Lease of %s obtained, lease time %ld",
- inet_ntoa(temp_addr), lease);
+ bb_info_msg("Lease of %s obtained, lease time %u",
+ inet_ntoa(temp_addr), (unsigned)lease);
start = now;
timeout = t1 + start;
requested_ip = packet.yiaddr;
if (client_config.quit_after_lease) {
if (client_config.release_on_quit)
perform_release();
- return 0;
+ goto ret0;
}
if (!client_config.foreground)
client_background();
bb_info_msg("Received SIGTERM");
if (client_config.release_on_quit)
perform_release();
- return 0;
+ goto ret0;
}
} else if (retval == -1 && errno == EINTR) {
/* a signal was caught */
/* An error occured */
bb_perror_msg("select");
}
-
- }
- return 0;
+ } /* for (;;) */
+ ret0:
+ retval = 0;
+ ret:
+ if (client_config.pidfile)
+ remove_pidfile(client_config.pidfile);
+ return retval;
}