aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp')
-rw-r--r--networking/udhcp/Kbuild4
-rw-r--r--networking/udhcp/common.c60
-rw-r--r--networking/udhcp/common.h8
-rw-r--r--networking/udhcp/dhcpc.c21
-rw-r--r--networking/udhcp/dhcpd.c78
5 files changed, 105 insertions, 66 deletions
diff --git a/networking/udhcp/Kbuild b/networking/udhcp/Kbuild
index 57d2511f0..aed40b98c 100644
--- a/networking/udhcp/Kbuild
+++ b/networking/udhcp/Kbuild
@@ -6,9 +6,9 @@
#
lib-y:=
-lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \
+lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o \
signalpipe.o socket.o
-lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \
+lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o \
signalpipe.o socket.o
lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \
script.o
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index 3704ba71a..7b2e19c42 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -22,40 +22,56 @@ long uptime(void)
return info.uptime;
}
-void udhcp_background(const char *pidfile)
+
+static const char *saved_pidfile;
+
+static void pidfile_delete(void)
+{
+ if (saved_pidfile)
+ unlink(saved_pidfile);
+}
+
+static int pidfile_acquire(const char *pidfile)
{
-#ifdef __uClinux__
- bb_error_msg("cannot background in uclinux (yet)");
-#else /* __uClinux__ */
int pid_fd;
+ if (!pidfile) return -1;
- /* hold lock during fork. */
- pid_fd = pidfile_acquire(pidfile);
- setsid();
- xdaemon(0, 0);
- logmode &= ~LOGMODE_STDIO;
- pidfile_write_release(pid_fd);
-#endif /* __uClinux__ */
+ pid_fd = open(pidfile, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+ if (pid_fd < 0) {
+ bb_perror_msg("cannot open pidfile %s", pidfile);
+ } else {
+ /* lockf(pid_fd, F_LOCK, 0); */
+ if (!saved_pidfile)
+ atexit(pidfile_delete);
+ saved_pidfile = pidfile;
+ }
+
+ return pid_fd;
+}
+
+static void pidfile_write_release(int pid_fd)
+{
+ if (pid_fd < 0) return;
+
+ fdprintf(pid_fd, "%d\n", getpid());
+ /* lockf(pid_fd, F_UNLCK, 0); */
+ close(pid_fd);
}
-void udhcp_start_log_and_pid(const char *pidfile)
+
+void udhcp_make_pidfile(const char *pidfile)
{
int pid_fd;
- /* Make sure our syslog fd isn't overwritten */
+ /* Make sure fd 0,1,2 are open */
bb_sanitize_stdio();
- /* do some other misc startup stuff while we are here to save bytes */
- pid_fd = pidfile_acquire(pidfile);
- pidfile_write_release(pid_fd);
-
- /* equivelent of doing a fflush after every \n */
+ /* Equivalent of doing a fflush after every \n */
setlinebuf(stdout);
- if (ENABLE_FEATURE_UDHCP_SYSLOG) {
- openlog(applet_name, LOG_PID, LOG_LOCAL0);
- logmode |= LOGMODE_SYSLOG;
- }
+ /* Create pidfile */
+ pid_fd = pidfile_acquire(pidfile);
+ pidfile_write_release(pid_fd);
bb_info_msg("%s (v%s) started", applet_name, BB_VER);
}
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index a80691b4a..00890ac1c 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -60,16 +60,12 @@ int udhcp_kernel_packet(struct dhcpMessage *payload,
/**/
-void udhcp_background(const char *pidfile);
-void udhcp_start_log_and_pid(const char *pidfile);
+void udhcp_make_pidfile(const char *pidfile);
void udhcp_run_script(struct dhcpMessage *packet, const char *name);
// Still need to clean these up...
-/* from pidfile.h */
-#define pidfile_acquire udhcp_pidfile_acquire
-#define pidfile_write_release udhcp_pidfile_write_release
/* from options.h */
#define get_option udhcp_get_option
#define end_option udhcp_end_option
@@ -91,8 +87,6 @@ int udhcp_sp_read(fd_set *rfds);
int raw_socket(int ifindex);
int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t *arp);
int listen_socket(uint32_t ip, int port, const char *inf);
-int pidfile_acquire(const char *pidfile);
-void pidfile_write_release(int pid_fd);
int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface);
#if ENABLE_FEATURE_UDHCP_DEBUG
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index a59c5db74..dc10386d5 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -9,6 +9,7 @@
*/
#include <getopt.h>
+#include <syslog.h>
#include "common.h"
#include "dhcpd.h"
@@ -103,7 +104,16 @@ static void perform_release(void)
static void client_background(void)
{
- udhcp_background(client_config.pidfile);
+#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(DAEMON_CHDIR_ROOT);
+ logmode &= ~LOGMODE_STDIO;
+#endif
client_config.foreground = 1; /* Do not fork again. */
client_config.background_if_no_lease = 0;
}
@@ -246,13 +256,18 @@ int udhcpc_main(int argc, char *argv[])
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);
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 90d8f0d17..ef9aa584e 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -10,6 +10,7 @@
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
+#include <syslog.h>
#include "common.h"
#include "dhcpd.h"
#include "options.h"
@@ -33,16 +34,30 @@ int udhcpd_main(int argc, char *argv[])
struct option_set *option;
struct dhcpOfferedAddr *lease, static_lease;
+//Huh, dhcpd don't have --foreground, --syslog options?? TODO
+
+ if (!ENABLE_FEATURE_UDHCP_DEBUG) {
+ bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
+ logmode &= ~LOGMODE_STDIO;
+ }
+
+ if (ENABLE_FEATURE_UDHCP_SYSLOG) {
+ openlog(applet_name, LOG_PID, LOG_LOCAL0);
+ logmode |= LOGMODE_SYSLOG;
+ }
+
+ /* Would rather not do read_config before daemonization -
+ * otherwise NOMMU machines will parse config twice */
read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
- /* Start the log, sanitize fd's, and write a pid file */
- udhcp_start_log_and_pid(server_config.pidfile);
+ udhcp_make_pidfile(server_config.pidfile);
- if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
+ option = find_option(server_config.options, DHCP_LEASE_TIME);
+ if (option) {
memcpy(&server_config.lease, option->data + 2, 4);
server_config.lease = ntohl(server_config.lease);
- }
- else server_config.lease = LEASE_TIME;
+ } else
+ server_config.lease = LEASE_TIME;
/* Sanity check */
num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
@@ -60,9 +75,6 @@ int udhcpd_main(int argc, char *argv[])
&server_config.server, server_config.arp) < 0)
return 1;
- if (!ENABLE_FEATURE_UDHCP_DEBUG)
- udhcp_background(server_config.pidfile); /* hold lock during fork. */
-
/* Setup the signal pipe */
udhcp_sp_setup();
@@ -106,7 +118,8 @@ int udhcpd_main(int argc, char *argv[])
default: continue; /* signal or error (probably EINTR) */
}
- if ((bytes = udhcp_get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
+ bytes = udhcp_get_packet(&packet, server_socket); /* this waits for a packet - idle */
+ if (bytes < 0) {
if (bytes == -1 && errno != EINTR) {
DEBUG("error on read, %s, reopening socket", strerror(errno));
close(server_socket);
@@ -115,7 +128,8 @@ int udhcpd_main(int argc, char *argv[])
continue;
}
- if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
+ state = get_option(&packet, DHCP_MESSAGE_TYPE);
+ if (state == NULL) {
bb_error_msg("cannot get option from packet, ignoring");
continue;
}
@@ -131,7 +145,6 @@ int udhcpd_main(int argc, char *argv[])
static_lease.expires = 0;
lease = &static_lease;
-
} else {
lease = find_lease_by_chaddr(packet.chaddr);
}
@@ -157,25 +170,23 @@ int udhcpd_main(int argc, char *argv[])
if (server_id) {
/* SELECTING State */
DEBUG("server_id = %08x", ntohl(server_id_align));
- if (server_id_align == server_config.server && requested &&
- requested_align == lease->yiaddr) {
+ if (server_id_align == server_config.server && requested
+ && requested_align == lease->yiaddr
+ ) {
sendACK(&packet, lease->yiaddr);
}
+ } else if (requested) {
+ /* INIT-REBOOT State */
+ if (lease->yiaddr == requested_align)
+ sendACK(&packet, lease->yiaddr);
+ else
+ sendNAK(&packet);
+ } else if (lease->yiaddr == packet.ciaddr) {
+ /* RENEWING or REBINDING State */
+ sendACK(&packet, lease->yiaddr);
} else {
- if (requested) {
- /* INIT-REBOOT State */
- if (lease->yiaddr == requested_align)
- sendACK(&packet, lease->yiaddr);
- else sendNAK(&packet);
- } else {
- /* RENEWING or REBINDING State */
- if (lease->yiaddr == packet.ciaddr)
- sendACK(&packet, lease->yiaddr);
- else {
- /* don't know what to do!!!! */
- sendNAK(&packet);
- }
- }
+ /* don't know what to do!!!! */
+ sendNAK(&packet);
}
/* what to do if we have no record of the client */
@@ -184,19 +195,22 @@ int udhcpd_main(int argc, char *argv[])
} else if (requested) {
/* INIT-REBOOT State */
- if ((lease = find_lease_by_yiaddr(requested_align))) {
+ lease = find_lease_by_yiaddr(requested_align);
+ if (lease) {
if (lease_expired(lease)) {
/* probably best if we drop this lease */
memset(lease->chaddr, 0, 16);
/* make some contention for this address */
- } else sendNAK(&packet);
- } else if (requested_align < server_config.start ||
- requested_align > server_config.end) {
+ } else
+ sendNAK(&packet);
+ } else if (requested_align < server_config.start
+ || requested_align > server_config.end
+ ) {
sendNAK(&packet);
} /* else remain silent */
} else {
- /* RENEWING or REBINDING State */
+ /* RENEWING or REBINDING State */
}
break;
case DHCPDECLINE: