diff options
-rw-r--r-- | networking/udhcp/Kbuild | 4 | ||||
-rw-r--r-- | networking/udhcp/common.c | 60 | ||||
-rw-r--r-- | networking/udhcp/common.h | 8 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 21 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 78 |
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: |