summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Dill2003-12-18 22:25:38 +0000
committerRuss Dill2003-12-18 22:25:38 +0000
commit4e864a36b611f56c6b347be1dace4e5e805a3eb8 (patch)
tree6582084290de4bead010f5fb8ff0a0a6d2b573fd
parente30495654d8bb38f7ea234d9d0ab0929525501e3 (diff)
downloadbusybox-4e864a36b611f56c6b347be1dace4e5e805a3eb8.zip
busybox-4e864a36b611f56c6b347be1dace4e5e805a3eb8.tar.gz
Finish remerging busybox udhcp and udhcp. Some cleanups as well.
-rw-r--r--networking/udhcp/AUTHORS2
-rw-r--r--networking/udhcp/ChangeLog8
-rw-r--r--networking/udhcp/Makefile.in20
-rw-r--r--networking/udhcp/README13
-rw-r--r--networking/udhcp/TODO2
-rw-r--r--networking/udhcp/arpping.c4
-rw-r--r--networking/udhcp/clientsocket.c62
-rw-r--r--networking/udhcp/clientsocket.h7
-rw-r--r--networking/udhcp/common.c142
-rw-r--r--networking/udhcp/common.h23
-rw-r--r--networking/udhcp/dhcpc.c51
-rw-r--r--networking/udhcp/dhcpc.h5
-rw-r--r--networking/udhcp/dhcpd.c61
-rw-r--r--networking/udhcp/files.c98
-rw-r--r--networking/udhcp/leases.c1
-rw-r--r--networking/udhcp/leases.h2
-rw-r--r--networking/udhcp/leases_file.c1
-rw-r--r--networking/udhcp/libbb_udhcp.h20
-rw-r--r--networking/udhcp/pidfile.c75
-rw-r--r--networking/udhcp/pidfile.h25
-rw-r--r--networking/udhcp/script.c44
-rw-r--r--networking/udhcp/signalpipe.c78
-rw-r--r--networking/udhcp/signalpipe.h22
-rw-r--r--networking/udhcp/socket.c26
-rw-r--r--networking/udhcp/socket.h1
25 files changed, 509 insertions, 284 deletions
diff --git a/networking/udhcp/AUTHORS b/networking/udhcp/AUTHORS
index 3772aed..bb58de1 100644
--- a/networking/udhcp/AUTHORS
+++ b/networking/udhcp/AUTHORS
@@ -9,6 +9,6 @@ Other Credits:
--------------
Moreton Bay (http://www.moretonbay.com/)
Lineo (http://opensource.lineo.com)
-Vladimir Oleynik <dzo@simtrea.ru>, optimize and more integrate for busybox
+Vladimir Oleynik <dzo@simtrea.ru> Size optimizations
diff --git a/networking/udhcp/ChangeLog b/networking/udhcp/ChangeLog
index 9ee9753..f1aac06 100644
--- a/networking/udhcp/ChangeLog
+++ b/networking/udhcp/ChangeLog
@@ -1,8 +1,6 @@
-0.9.10
- Size optimization (over 3k), more busybox integration
- (Vladimir Oleynik <dzo@simtreas.ru>
-
0.9.9 (pending)
++ Various other size optimizations (Vladimir)
++ Change strerror(errno) to %m (Vladimir N. Oleynik <dzo@simtreas.ru>)
+ Fixed a little endian problem in mton (Bastian Blank <waldi@debian.org>)
+ Fixed a arpping alignment problem (Rui He <rhe@3eti.com>)
+ Added sanity check for max_leases (udhcp bug #1285) (me)
@@ -36,7 +34,7 @@
udhcp bug#1256
+ Fixed reading of client id (David Poole <davep@portsmith.com>)
+ change sys_errlist[] to strerror() as it aparently doesn't exist
- (Erik Andersen <andersen@codepoet.org>)
+ (Erik Andersen <andersee@codepoet.org>)
+ fixed get_raw_packet so it returns -2 on non fatal errors
(Ted Lemon <Ted.Lemon@nominum.com>)
+ Improved (hopefully) NAKing behavior (me)
diff --git a/networking/udhcp/Makefile.in b/networking/udhcp/Makefile.in
index d06e809..4d3f270 100644
--- a/networking/udhcp/Makefile.in
+++ b/networking/udhcp/Makefile.in
@@ -33,22 +33,14 @@ CONFIG_UDHCP_SHARED=n
endif
endif
-ifeq ($(CONFIG_UDHCPD), y)
-CONFIG_UDHCP_LEASES_FILE=y
-else
-ifeq ($(CONFIG_UDHCPD), y)
-CONFIG_UDHCP_LEASES_FILE=y
-else
-CONFIG_UDHCP_LEASES_FILE=n
-endif
-endif
-
UDHCP-y:=
-UDHCP-$(CONFIG_UDHCP_SHARED) += options.c socket.c packet.c common.c
-UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c script.c
-UDHCP-$(CONFIG_UDHCPD) += dhcpd.c arpping.c files.c leases.c serverpacket.c
+UDHCP-$(CONFIG_UDHCP_SHARED) += common.c options.c packet.c pidfile.c \
+ signalpipe.c socket.c
+UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c clientsocket.c \
+ script.c
+UDHCP-$(CONFIG_UDHCPD) += dhcpd.c arpping.c files.c leases.c \
+ serverpacket.c
UDHCP-$(CONFIG_DUMPLEASES) += dumpleases.c
-UDHCP-$(CONFIG_UDHCP_LEASES_FILE) += leases_file.c
UDHCP_OBJS=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y))
libraries-y+=$(UDHCP_DIR)$(UDHCP_AR)
diff --git a/networking/udhcp/README b/networking/udhcp/README
index 5f4bb78..eddb24b 100644
--- a/networking/udhcp/README
+++ b/networking/udhcp/README
@@ -11,19 +11,22 @@ compile time options
The Makefile contains three of the compile time options:
- DEBUG: If DEBUG is defined, udhcpd will output extra debugging
- output, compile with -g, and not fork to the background when run.
- SYSLOG: If SYSLOG is defined, udhcpd will log all its messages
- syslog, otherwise, it will attempt to log them to stdout.
+ UDHCP_DEBUG: If UDHCP_DEBUG is defined, udhcpd will output extra
+ debugging output, compile with -g, and not fork to the background when
+ run.
+ UDHCP_SYSLOG: If UDHCP_SYSLOG is defined, udhcpd will log all its
+ messages syslog, otherwise, it will attempt to log them to stdout.
COMBINED_BINARY: If COMBINED_BINARY is define, one binary, udhcpd,
is created. If called as udhcpd, the dhcp server will be started.
If called as udhcpc, the dhcp client will be started.
-dhcpd.h contains the other two compile time options:
+dhcpd.h contains the other three compile time options:
LEASE_TIME: The default lease time if not specified in the config
file.
+
+ LEASES_FILE: The default file for storing leases.
DHCPD_CONFIG_FILE: The defualt config file to use.
diff --git a/networking/udhcp/TODO b/networking/udhcp/TODO
index f88694a..6febe5a 100644
--- a/networking/udhcp/TODO
+++ b/networking/udhcp/TODO
@@ -1,5 +1,6 @@
TODO
----
++ Check for valid IP, netmask, hostname, paths, strings, etc
+ Integrade README.*'s with manpages
+ using time(0) breaks if the system clock changes, find a portable solution
+ make failure of reading functions revert to previous value, not the default
@@ -9,6 +10,7 @@ TODO
+ make sure packet generation works on a wide varitey of arches
+ Interoperability testing
+ Hooks within the DHCP server
+ * Server notification when a lease is added/removed
+ Additional bootp support in client/server
+ Make serverid option in server configurable
+ Possibly add failure message to DHCP NAK
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c
index e20395a..363408d 100644
--- a/networking/udhcp/arpping.c
+++ b/networking/udhcp/arpping.c
@@ -44,7 +44,11 @@ int arpping(u_int32_t yiaddr, u_int32_t ip, unsigned char *mac, char *interface)
if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) {
+#ifdef IN_BUSYBOX
LOG(LOG_ERR, bb_msg_can_not_create_raw_socket);
+#else
+ LOG(LOG_ERR, "Could not open raw socket");
+#endif
return -1;
}
diff --git a/networking/udhcp/clientsocket.c b/networking/udhcp/clientsocket.c
new file mode 100644
index 0000000..7c1b6e8
--- /dev/null
+++ b/networking/udhcp/clientsocket.c
@@ -0,0 +1,62 @@
+/*
+ * clientsocket.c -- DHCP client socket creation
+ *
+ * udhcp client
+ *
+ * Russ Dill <Russ.Dill@asu.edu> July 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <features.h>
+#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
+#include <netpacket/packet.h>
+#include <net/ethernet.h>
+#else
+#include <asm/types.h>
+#include <linux/if_packet.h>
+#include <linux/if_ether.h>
+#endif
+
+#include "clientsocket.h"
+#include "common.h"
+
+
+int raw_socket(int ifindex)
+{
+ int fd;
+ struct sockaddr_ll sock;
+
+ DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex);
+ if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
+ DEBUG(LOG_ERR, "socket call failed: %m");
+ return -1;
+ }
+
+ sock.sll_family = AF_PACKET;
+ sock.sll_protocol = htons(ETH_P_IP);
+ sock.sll_ifindex = ifindex;
+ if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
+ DEBUG(LOG_ERR, "bind call failed: %m");
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
diff --git a/networking/udhcp/clientsocket.h b/networking/udhcp/clientsocket.h
new file mode 100644
index 0000000..17a55c1
--- /dev/null
+++ b/networking/udhcp/clientsocket.h
@@ -0,0 +1,7 @@
+/* clientsocket.h */
+#ifndef _CLIENTSOCKET_H
+#define _CLIENTSOCKET_H
+
+int raw_socket(int ifindex);
+
+#endif
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index babd980..bfdc7ba 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -1,8 +1,9 @@
/* common.c
*
- * Functions to assist in the writing and removing of pidfiles.
+ * Functions for debugging and logging as well as some other
+ * simple helper functions.
*
- * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
+ * Russ Dill <Russ.Dill@asu.edu> 2001-2003
* Rewrited by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
*
* This program is free software; you can redistribute it and/or modify
@@ -26,18 +27,54 @@
#include <string.h>
#include <stdlib.h>
#include <signal.h>
+#include <paths.h>
#include <sys/socket.h>
+#include <stdarg.h>
#include "common.h"
+#include "pidfile.h"
static int daemonized;
-#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
+/*
+ * This function makes sure our first socket calls
+ * aren't going to fd 1 (printf badness...) and are
+ * not later closed by daemon()
+ */
+static inline void sanitize_fds(void)
+{
+ int zero;
+ if ((zero = open(_PATH_DEVNULL, O_RDWR, 0)) < 0) return;
+ while (zero < 3) zero = dup(zero);
+ close(zero);
+}
+
+
+void background(const char *pidfile)
+{
+#ifdef __uClinux__
+ LOG(LOG_ERR, "Cannot background in uclinux (yet)");
+#else /* __uClinux__ */
+ int pid_fd;
+
+ if (!pidfile) return;
+
+ pid_fd = pidfile_acquire(pidfile); /* hold lock during fork. */
+ if (daemon(0, 0) == -1) {
+ perror("fork");
+ exit(1);
+ }
+ daemonized++;
+ pidfile_write_release(pid_fd);
+#endif /* __uClinux__ */
+}
+
+
+#ifdef UDHCP_SYSLOG
void udhcp_logging(int level, const char *fmt, ...)
{
- int e = errno;
va_list p;
va_list p2;
@@ -46,21 +83,34 @@ void udhcp_logging(int level, const char *fmt, ...)
if(!daemonized) {
vprintf(fmt, p);
putchar('\n');
- fflush(stdout);
- errno = e;
}
vsyslog(level, fmt, p2);
va_end(p);
}
-void start_log(const char *client_server)
+
+void start_log_and_pid(const char *client_server, const char *pidfile)
{
- openlog(bb_applet_name, LOG_PID | LOG_CONS, LOG_LOCAL0);
+ int pid_fd;
+
+ /* Make sure our syslog fd isn't overwritten */
+ sanitize_fds();
+
+ /* 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 */
+ setlinebuf(stdout);
+
+ openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0);
udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
}
+
#else
+
static char *syslog_level_msg[] = {
[LOG_EMERG] = "EMERGENCY!",
[LOG_ALERT] = "ALERT!",
@@ -71,86 +121,36 @@ static char *syslog_level_msg[] = {
[LOG_DEBUG] = "debug"
};
+
void udhcp_logging(int level, const char *fmt, ...)
{
- int e = errno;
va_list p;
va_start(p, fmt);
if(!daemonized) {
printf("%s, ", syslog_level_msg[level]);
- errno = e;
vprintf(fmt, p);
putchar('\n');
- fflush(stdout);
}
va_end(p);
}
-void start_log(const char *client_server)
+
+void start_log_and_pid(const char *client_server, const char *pidfile)
{
- udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
-}
-#endif
+ int pid_fd;
-static const char *saved_pidfile;
+ /* Make sure our syslog fd isn't overwritten */
+ sanitize_fds();
-static void exit_fun(void)
-{
- if (saved_pidfile) unlink(saved_pidfile);
-}
+ /* do some other misc startup stuff while we are here to save bytes */
+ pid_fd = pidfile_acquire(pidfile);
+ pidfile_write_release(pid_fd);
-void background(const char *pidfile)
-{
-#ifdef __uClinux__
- LOG(LOG_ERR, "Cannot background in uclinux (yet)");
-#else /* __uClinux__ */
- int pid_fd = -1;
-
- if (pidfile) {
- pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
- if (pid_fd < 0) {
- LOG(LOG_ERR, "Unable to open pidfile %s: %m", pidfile);
- } else {
- lockf(pid_fd, F_LOCK, 0);
- if(!saved_pidfile)
- atexit(exit_fun); /* set atexit one only */
- saved_pidfile = pidfile; /* but may be rewrite */
- }
- }
- while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */
- if (daemon(0, 0) == -1) {
- perror("fork");
- exit(1);
- }
- daemonized++;
- if (pid_fd >= 0) {
- FILE *out;
-
- if ((out = fdopen(pid_fd, "w")) != NULL) {
- fprintf(out, "%d\n", getpid());
- fclose(out);
- }
- lockf(pid_fd, F_UNLCK, 0);
- close(pid_fd);
- }
-#endif /* __uClinux__ */
-}
+ /* equivelent of doing a fflush after every \n */
+ setlinebuf(stdout);
-/* Signal handler */
-int udhcp_signal_pipe[2];
-static void signal_handler(int sig)
-{
- if (send(udhcp_signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
- LOG(LOG_ERR, "Could not send signal: %m");
- }
+ udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
}
+#endif
-void udhcp_set_signal_pipe(int sig_add)
-{
- socketpair(AF_UNIX, SOCK_STREAM, 0, udhcp_signal_pipe);
- signal(SIGUSR1, signal_handler);
- signal(SIGTERM, signal_handler);
- if(sig_add)
- signal(sig_add, signal_handler);
-}
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 768f551..78eb1c1 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -18,10 +18,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifndef _COMMON_H
+#define _COMMON_H
+
#include "version.h"
-#include "busybox.h"
+#include "libbb_udhcp.h"
+
-#ifndef CONFIG_FEATURE_UDHCP_SYSLOG
+#ifndef UDHCP_SYSLOG
enum syslog_levels {
LOG_EMERG = 0,
LOG_ALERT,
@@ -35,18 +39,17 @@ enum syslog_levels {
#include <syslog.h>
#endif
-void start_log(const char *client_server);
+void background(const char *pidfile);
+void start_log_and_pid(const char *client_server, const char *pidfile);
void background(const char *pidfile);
void udhcp_logging(int level, const char *fmt, ...);
-
-extern int udhcp_signal_pipe[2];
-void udhcp_set_signal_pipe(int sig_add);
-
-
+
#define LOG(level, str, args...) udhcp_logging(level, str, ## args)
-#ifdef CONFIG_FEATURE_UDHCP_DEBUG
-# define DEBUG(level, str, args...) udhcp_logging(level, str, ## args)
+#ifdef UDHCP_DEBUG
+# define DEBUG(level, str, args...) LOG(level, str, ## args)
#else
# define DEBUG(level, str, args...) do {;} while(0)
#endif
+
+#endif
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 55664ab..a180cc5 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -38,9 +38,11 @@
#include "dhcpc.h"
#include "options.h"
#include "clientpacket.h"
+#include "clientsocket.h"
#include "script.h"
#include "socket.h"
#include "common.h"
+#include "signalpipe.h"
static int state;
static unsigned long requested_ip; /* = 0 */
@@ -54,12 +56,6 @@ static int fd = -1;
#define LISTEN_RAW 2
static int listen_mode;
-#ifdef CONFIG_INSTALL_NO_USR
-#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
-#else
-#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
-#endif
-
struct client_config_t client_config = {
/* Default options. */
abort_if_no_lease: 0,
@@ -78,7 +74,7 @@ struct client_config_t client_config = {
#ifndef IN_BUSYBOX
static void __attribute__ ((noreturn)) show_usage(void)
{
- printf(
+ printf(
"Usage: udhcpc [OPTIONS]\n\n"
" -c, --clientid=CLIENTID Client identifier\n"
" -H, --hostname=HOSTNAME Client hostname\n"
@@ -95,8 +91,8 @@ static void __attribute__ ((noreturn)) show_usage(void)
" -s, --script=file Run file at dhcp events (default:\n"
" " DEFAULT_SCRIPT ")\n"
" -v, --version Display version\n"
- );
- exit(0);
+ );
+ exit(0);
}
#else
#define show_usage bb_show_usage
@@ -177,7 +173,11 @@ static void client_background(void)
}
+#ifdef COMBINED_BINARY
int udhcpc_main(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
{
unsigned char *temp, *message;
unsigned long t1 = 0, t2 = 0, xid = 0;
@@ -258,18 +258,20 @@ int udhcpc_main(int argc, char *argv[])
client_config.script = optarg;
break;
case 'v':
- bb_error_msg("version %s\n", VERSION);
- return(0);
+ printf("udhcpcd, version %s\n\n", VERSION);
+ return 0;
break;
default:
show_usage();
}
}
- start_log("client");
+ /* Start the log, sanitize fd's, and write a pid file */
+ start_log_and_pid("udhcpc", client_config.pidfile);
+
if (read_interface(client_config.interface, &client_config.ifindex,
NULL, client_config.arp) < 0)
- return(1);
+ return 1;
if (!client_config.clientid) {
client_config.clientid = xmalloc(6 + 3);
@@ -279,8 +281,8 @@ int udhcpc_main(int argc, char *argv[])
memcpy(client_config.clientid + 3, client_config.arp, 6);
}
- /* setup signal handlers */
- udhcp_set_signal_pipe(SIGUSR2);
+ /* setup the signal pipe */
+ udhcp_sp_setup();
state = INIT_SELECTING;
run_script(NULL, "deconfig");
@@ -290,7 +292,6 @@ int udhcpc_main(int argc, char *argv[])
tv.tv_sec = timeout - time(0);
tv.tv_usec = 0;
- FD_ZERO(&rfds);
if (listen_mode != LISTEN_NONE && fd < 0) {
if (listen_mode == LISTEN_KERNEL)
@@ -299,15 +300,13 @@ int udhcpc_main(int argc, char *argv[])
fd = raw_socket(client_config.ifindex);
if (fd < 0) {
LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m");
- return(0);
+ return 0;
}
}
- if (fd >= 0) FD_SET(fd, &rfds);
- FD_SET(udhcp_signal_pipe[0], &rfds);
+ max_fd = udhcp_sp_fd_set(&rfds, fd);
if (tv.tv_sec > 0) {
DEBUG(LOG_INFO, "Waiting on select...");
- max_fd = udhcp_signal_pipe[0] > fd ? udhcp_signal_pipe[0] : fd;
retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
} else retval = 0; /* If we already timed out, fall through */
@@ -332,7 +331,7 @@ int udhcpc_main(int argc, char *argv[])
client_background();
} else if (client_config.abort_if_no_lease) {
LOG(LOG_INFO, "No lease, failing.");
- return(1);
+ return 1;
}
/* wait to try again */
packet_num = 0;
@@ -474,7 +473,7 @@ int udhcpc_main(int argc, char *argv[])
state = BOUND;
change_mode(LISTEN_NONE);
if (client_config.quit_after_lease)
- return(0);
+ return 0;
if (!client_config.foreground)
client_background();
@@ -494,11 +493,7 @@ int udhcpc_main(int argc, char *argv[])
break;
/* case BOUND, RELEASED: - ignore all packets */
}
- } else if (retval > 0 && FD_ISSET(udhcp_signal_pipe[0], &rfds)) {
- if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0) {
- DEBUG(LOG_ERR, "Could not read signal: %m");
- continue; /* probably just EINTR */
- }
+ } else if (retval > 0 && (sig = udhcp_sp_read(&rfds))) {
switch (sig) {
case SIGUSR1:
perform_renew();
@@ -508,7 +503,7 @@ int udhcpc_main(int argc, char *argv[])
break;
case SIGTERM:
LOG(LOG_INFO, "Received SIGTERM");
- return(0);
+ return 0;
}
} else if (retval == -1 && errno == EINTR) {
/* a signal was caught */
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index e23d9d4..7145cbd 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -2,6 +2,11 @@
#ifndef _DHCPC_H
#define _DHCPC_H
+#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
+
+/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */
+#include "libbb_udhcp.h"
+
#define INIT_SELECTING 0
#define REQUESTING 1
#define BOUND 2
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index c21cb72..aabab38 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -43,6 +43,7 @@
#include "files.h"
#include "serverpacket.h"
#include "common.h"
+#include "signalpipe.h"
/* globals */
@@ -50,7 +51,11 @@ struct dhcpOfferedAddr *leases;
struct server_config_t server_config;
+#ifdef COMBINED_BINARY
int udhcpd_main(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
{
fd_set rfds;
struct timeval tv;
@@ -64,16 +69,13 @@ int udhcpd_main(int argc, char *argv[])
struct option_set *option;
struct dhcpOfferedAddr *lease;
int max_sock;
- int sig;
unsigned long num_ips;
- start_log("server");
-
memset(&server_config, 0, sizeof(struct server_config_t));
-
- if (argc < 2)
- read_config(DHCPD_CONF_FILE);
- else read_config(argv[1]);
+ read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
+
+ /* Start the log, sanitize fd's, and write a pid file */
+ start_log_and_pid("udhcpd", server_config.pidfile);
if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
memcpy(&server_config.lease, option->data + 2, 4);
@@ -90,18 +92,19 @@ int udhcpd_main(int argc, char *argv[])
server_config.max_leases = num_ips;
}
- leases = xcalloc(sizeof(struct dhcpOfferedAddr), server_config.max_leases);
+ leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr));
read_leases(server_config.lease_file);
if (read_interface(server_config.interface, &server_config.ifindex,
&server_config.server, server_config.arp) < 0)
- return(1);
+ return 1;
-#ifndef CONFIG_FEATURE_UDHCP_DEBUG
- background(server_config.pidfile);
+#ifndef UDHCP_DEBUG
+ background(server_config.pidfile); /* hold lock during fork. */
#endif
- udhcp_set_signal_pipe(0);
+ /* Setup the signal pipe */
+ udhcp_sp_setup();
timeout_end = time(0) + server_config.auto_time;
while(1) { /* loop until universe collapses */
@@ -109,18 +112,15 @@ int udhcpd_main(int argc, char *argv[])
if (server_socket < 0)
if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
LOG(LOG_ERR, "FATAL: couldn't create server socket, %m");
- return(2);
+ return 2;
}
- FD_ZERO(&rfds);
- FD_SET(server_socket, &rfds);
- FD_SET(udhcp_signal_pipe[0], &rfds);
+ max_sock = udhcp_sp_fd_set(&rfds, server_socket);
if (server_config.auto_time) {
tv.tv_sec = timeout_end - time(0);
tv.tv_usec = 0;
}
if (!server_config.auto_time || tv.tv_sec > 0) {
- max_sock = server_socket > udhcp_signal_pipe[0] ? server_socket : udhcp_signal_pipe[0];
retval = select(max_sock + 1, &rfds, NULL, NULL,
server_config.auto_time ? &tv : NULL);
} else retval = 0; /* If we already timed out, fall through */
@@ -134,20 +134,18 @@ int udhcpd_main(int argc, char *argv[])
continue;
}
- if (FD_ISSET(udhcp_signal_pipe[0], &rfds)) {
- if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0)
- continue; /* probably just EINTR */
- switch (sig) {
- case SIGUSR1:
- LOG(LOG_INFO, "Received a SIGUSR1");
- write_leases();
- /* why not just reset the timeout, eh */
- timeout_end = time(0) + server_config.auto_time;
- continue;
- case SIGTERM:
- LOG(LOG_INFO, "Received a SIGTERM");
- return(0);
- }
+ switch (udhcp_sp_read(&rfds)) {
+ case SIGUSR1:
+ LOG(LOG_INFO, "Received a SIGUSR1");
+ write_leases();
+ /* why not just reset the timeout, eh */
+ timeout_end = time(0) + server_config.auto_time;
+ continue;
+ case SIGTERM:
+ LOG(LOG_INFO, "Received a SIGTERM");
+ return 0;
+ case 0: break; /* no signal */
+ default: continue; /* signal or error (probably EINTR) */
}
if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
@@ -251,3 +249,4 @@ int udhcpd_main(int argc, char *argv[])
return 0;
}
+
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index f24f01c..6d72863 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -16,6 +16,13 @@
#include "options.h"
#include "common.h"
+/*
+ * Domain names may have 254 chars, and string options can be 254
+ * chars long. However, 80 bytes will be enough for most, and won't
+ * hog up memory. If you have a special application, change it
+ */
+#define READ_CONFIG_BUF_SIZE 80
+
/* on these functions, make sure you datatype matches */
static int read_ip(const char *line, void *arg)
{
@@ -66,23 +73,23 @@ static int read_yn(const char *line, void *arg)
return retval;
}
-#define READ_CONFIG_BUF_SIZE 512 /* domainname may have 254 chars */
/* read a dhcp option and add it to opt_list */
static int read_opt(const char *const_line, void *arg)
{
- char line[READ_CONFIG_BUF_SIZE];
struct option_set **opt_list = arg;
char *opt, *val, *endptr;
struct dhcp_option *option;
int retval = 0, length;
- char buffer[256]; /* max opt length */
- u_int16_t result_u16;
- u_int32_t result_u32;
- void *valptr;
+ char buffer[8];
+ char *line;
+ u_int16_t *result_u16 = (u_int16_t *) buffer;
+ u_int32_t *result_u32 = (u_int32_t *) buffer;
+
+ /* Cheat, the only const line we'll actually get is "" */
+ line = (char *) const_line;
+ if (!(opt = strtok(line, " \t="))) return 0;
- if (!(opt = strtok(strcpy(line, const_line), " \t="))) return 0;
-
for (option = dhcp_options; option->code; option++)
if (!strcasecmp(option->name, opt))
break;
@@ -90,11 +97,10 @@ static int read_opt(const char *const_line, void *arg)
if (!option->code) return 0;
do {
- val = strtok(NULL, ", \t");
- if(!val)
- break;
+ if (!(val = strtok(NULL, ", \t"))) break;
length = option_lengths[option->flags & TYPE_MASK];
- valptr = NULL;
+ retval = 0;
+ opt = buffer; /* new meaning for variable opt */
switch (option->flags & TYPE_MASK) {
case OPTION_IP:
retval = read_ip(val, buffer);
@@ -108,9 +114,8 @@ static int read_opt(const char *const_line, void *arg)
length = strlen(val);
if (length > 0) {
if (length > 254) length = 254;
- endptr = buffer + length;
- endptr[0] = 0;
- valptr = val;
+ opt = val;
+ retval = 1;
}
break;
case OPTION_BOOLEAN:
@@ -118,43 +123,36 @@ static int read_opt(const char *const_line, void *arg)
break;
case OPTION_U8:
buffer[0] = strtoul(val, &endptr, 0);
- valptr = buffer;
+ retval = (endptr[0] == '\0');
break;
case OPTION_U16:
- result_u16 = htons(strtoul(val, &endptr, 0));
- valptr = &result_u16;
+ *result_u16 = htons(strtoul(val, &endptr, 0));
+ retval = (endptr[0] == '\0');
break;
case OPTION_S16:
- result_u16 = htons(strtol(val, &endptr, 0));
- valptr = &result_u16;
+ *result_u16 = htons(strtol(val, &endptr, 0));
+ retval = (endptr[0] == '\0');
break;
case OPTION_U32:
- result_u32 = htonl(strtoul(val, &endptr, 0));
- valptr = &result_u32;
+ *result_u32 = htonl(strtoul(val, &endptr, 0));
+ retval = (endptr[0] == '\0');
break;
case OPTION_S32:
- result_u32 = htonl(strtol(val, &endptr, 0));
- valptr = &result_u32;
+ *result_u32 = htonl(strtol(val, &endptr, 0));
+ retval = (endptr[0] == '\0');
break;
default:
- retval = 0;
break;
}
- if (valptr) {
- memcpy(buffer, valptr, length);
- retval = (endptr[0] == '\0');
- }
if (retval)
- attach_option(opt_list, option, buffer, length);
- else
- break;
- } while (option->flags & OPTION_LIST);
+ attach_option(opt_list, option, opt, length);
+ } while (retval && option->flags & OPTION_LIST);
return retval;
}
static const struct config_keyword keywords[] = {
- /* keyword handler variable address default */
+ /* keyword handler variable address default */
{"start", read_ip, &(server_config.start), "192.168.0.20"},
{"end", read_ip, &(server_config.end), "192.168.0.254"},
{"interface", read_str, &(server_config.interface), "eth0"},
@@ -167,7 +165,7 @@ static const struct config_keyword keywords[] = {
{"conflict_time",read_u32,&(server_config.conflict_time),"3600"},
{"offer_time", read_u32, &(server_config.offer_time), "60"},
{"min_lease", read_u32, &(server_config.min_lease), "60"},
- {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE},
+ {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE},
{"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
{"notify_file", read_str, &(server_config.notify_file), ""},
{"siaddr", read_ip, &(server_config.siaddr), "0.0.0.0"},
@@ -181,9 +179,11 @@ static const struct config_keyword keywords[] = {
int read_config(const char *file)
{
FILE *in;
- char buffer[READ_CONFIG_BUF_SIZE], orig[READ_CONFIG_BUF_SIZE];
- char *token, *line;
- int i;
+ char buffer[READ_CONFIG_BUF_SIZE], *token, *line;
+#ifdef UDHCP_DEBUG
+ char orig[READ_CONFIG_BUF_SIZE];
+#endif
+ int i, lm = 0;
for (i = 0; keywords[i].keyword[0]; i++)
if (keywords[i].def[0])
@@ -195,27 +195,27 @@ int read_config(const char *file)
}
while (fgets(buffer, READ_CONFIG_BUF_SIZE, in)) {
+ lm++;
if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0';
+#ifdef UDHCP_DEBUG
strcpy(orig, buffer);
+#endif
if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0';
- token = strtok(buffer, " \t");
- if(!token)
- continue;
- line = strtok(NULL, "");
- if(!line)
- continue;
- while(*line == '=' || isspace(*line))
- line++;
+
+ if (!(token = strtok(buffer, " \t"))) continue;
+ if (!(line = strtok(NULL, ""))) continue;
+
+ /* eat leading whitespace */
+ line = line + strspn(line, " \t=");
/* eat trailing whitespace */
for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--);
line[i] = '\0';
- if (*line == '\0')
- continue;
for (i = 0; keywords[i].keyword[0]; i++)
if (!strcasecmp(token, keywords[i].keyword))
if (!keywords[i].handler(line, keywords[i].var)) {
- LOG(LOG_ERR, "unable to parse '%s'", orig);
+ LOG(LOG_ERR, "Failure parsing line %d of %s", lm, file);
+ DEBUG(LOG_ERR, "unable to parse '%s'", orig);
/* reset back to the default value */
keywords[i].handler(keywords[i].def, keywords[i].var);
}
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index 341abab..add114f 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -117,6 +117,7 @@ static int check_ip(u_int32_t addr)
} else return 0;
}
+
/* find an assignable address, it check_expired is true, we check all the expired leases as well.
* Maybe this should try expired leases by age... */
u_int32_t find_address(int check_expired)
diff --git a/networking/udhcp/leases.h b/networking/udhcp/leases.h
index d54cd11..24d8608 100644
--- a/networking/udhcp/leases.h
+++ b/networking/udhcp/leases.h
@@ -9,8 +9,6 @@ struct dhcpOfferedAddr {
u_int32_t expires; /* host order */
};
-extern const char leases_file[];
-
extern unsigned char blank_chaddr[];
void clear_lease(u_int8_t *chaddr, u_int32_t yiaddr);
diff --git a/networking/udhcp/leases_file.c b/networking/udhcp/leases_file.c
deleted file mode 100644
index 96e2f2d..0000000
--- a/networking/udhcp/leases_file.c
+++ /dev/null
@@ -1 +0,0 @@
-const char leases_file[] = "/var/lib/misc/udhcpd.leases";
diff --git a/networking/udhcp/libbb_udhcp.h b/networking/udhcp/libbb_udhcp.h
index 73e2146..9b5d5a8 100644
--- a/networking/udhcp/libbb_udhcp.h
+++ b/networking/udhcp/libbb_udhcp.h
@@ -1,5 +1,13 @@
/* libbb_udhcp.h - busybox compatability wrapper */
+/* bit of a hack, do this no matter what the order of the includes.
+ * (for busybox) */
+
+#ifdef CONFIG_INSTALL_NO_USR
+#undef DEFUALT_SCRIPT
+#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
+#endif
+
#ifndef _LIBBB_UDHCP_H
#define _LIBBB_UDHCP_H
@@ -7,22 +15,16 @@
#include "busybox.h"
#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
-#define SYSLOG
+#define UDHCP_SYSLOG
#endif
#ifdef CONFIG_FEATURE_UDHCP_DEBUG
-#define DEBUG
+#define UDHCP_DEBUG
#endif
#define COMBINED_BINARY
#include "version.h"
-#ifdef CONFIG_INSTALL_NO_USR
-#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
-#else
-#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
-#endif
-
#define xfopen bb_xfopen
#else /* ! BB_VER */
@@ -36,8 +38,6 @@
#define xmalloc malloc
#define xcalloc calloc
-#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
-
static inline FILE *xfopen(const char *file, const char *mode)
{
FILE *fp;
diff --git a/networking/udhcp/pidfile.c b/networking/udhcp/pidfile.c
new file mode 100644
index 0000000..d656c7a
--- /dev/null
+++ b/networking/udhcp/pidfile.c
@@ -0,0 +1,75 @@
+/* pidfile.c
+ *
+ * Functions to assist in the writing and removing of pidfiles.
+ *
+ * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pidfile.h"
+#include "common.h"
+
+static char *saved_pidfile;
+
+static void pidfile_delete(void)
+{
+ if (saved_pidfile) unlink(saved_pidfile);
+}
+
+
+int pidfile_acquire(const char *pidfile)
+{
+ int pid_fd;
+ if (!pidfile) return -1;
+
+ pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
+ if (pid_fd < 0) {
+ LOG(LOG_ERR, "Unable to open pidfile %s: %m\n", pidfile);
+ } else {
+ lockf(pid_fd, F_LOCK, 0);
+ if (!saved_pidfile)
+ atexit(pidfile_delete);
+ saved_pidfile = (char *) pidfile;
+ }
+
+ return pid_fd;
+}
+
+
+void pidfile_write_release(int pid_fd)
+{
+ FILE *out;
+
+ if (pid_fd < 0) return;
+
+ if ((out = fdopen(pid_fd, "w")) != NULL) {
+ fprintf(out, "%d\n", getpid());
+ fclose(out);
+ }
+ lockf(pid_fd, F_UNLCK, 0);
+ close(pid_fd);
+}
+
+
+
+
diff --git a/networking/udhcp/pidfile.h b/networking/udhcp/pidfile.h
new file mode 100644
index 0000000..7f8e8ae
--- /dev/null
+++ b/networking/udhcp/pidfile.h
@@ -0,0 +1,25 @@
+/* pidfile.h
+ *
+ * Functions to assist in the writing and removing of pidfiles.
+ *
+ * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+int pidfile_acquire(const char *pidfile);
+void pidfile_write_release(int pid_fd);
+
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c
index 9c766a2..dcd2cad 100644
--- a/networking/udhcp/script.c
+++ b/networking/udhcp/script.c
@@ -32,7 +32,6 @@
#include "options.h"
#include "dhcpd.h"
#include "dhcpc.h"
-#include "script.h"
#include "common.h"
/* get a rough idea of how long an option will be (rounding up...) */
@@ -56,14 +55,9 @@ static inline int upper_length(int length, int opt_index)
}
-static int sprintip(char *dest, unsigned char *ip)
+static int sprintip(char *dest, char *pre, unsigned char *ip)
{
- return sprintf(dest, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
-}
-
-static void asprintip(char **dest, char *pre, unsigned char *ip)
-{
- asprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
+ return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
}
@@ -96,12 +90,12 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option *
for(;;) {
switch (type) {
case OPTION_IP_PAIR:
- dest += sprintip(dest, option);
+ dest += sprintip(dest, "", option);
*(dest++) = '/';
option += 4;
optlen = 4;
case OPTION_IP: /* Works regardless of host byte order. */
- dest += sprintip(dest, option);
+ dest += sprintip(dest, "", option);
break;
case OPTION_BOOLEAN:
dest += sprintf(dest, *option ? "yes" : "no");
@@ -138,15 +132,6 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option *
}
-static char *find_env(const char *prefix, char *defaultstr)
-{
- char *ptr;
-
- ptr = getenv(prefix);
- return ptr ? ptr : defaultstr;
-}
-
-
/* put all the paramaters into an environment */
static char **fill_envp(struct dhcpMessage *packet)
{
@@ -167,21 +152,20 @@ static char **fill_envp(struct dhcpMessage *packet)
if ((temp = get_option(packet, DHCP_OPTION_OVER)))
over = *temp;
if (!(over & FILE_FIELD) && packet->file[0]) num_options++;
- if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;
+ if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;
}
- envp = xmalloc((num_options + 5) * sizeof(char *));
+ envp = xcalloc(sizeof(char *), num_options + 5);
j = 0;
asprintf(&envp[j++], "interface=%s", client_config.interface);
- envp[j++] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin");
- envp[j++] = find_env("HOME", "HOME=/");
+ asprintf(&envp[j++], "%s=%s", "PATH",
+ getenv("PATH") ? : "/bin:/usr/bin:/sbin:/usr/sbin");
+ asprintf(&envp[j++], "%s=%s", "HOME", getenv("HOME") ? : "/");
- if (packet == NULL) {
- envp[j++] = NULL;
- return envp;
- }
+ if (packet == NULL) return envp;
- asprintip(&envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
+ envp[j] = xmalloc(sizeof("ip=255.255.255.255"));
+ sprintip(envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
for (i = 0; dhcp_options[i].code; i++) {
@@ -198,7 +182,8 @@ static char **fill_envp(struct dhcpMessage *packet)
}
}
if (packet->siaddr) {
- asprintip(&envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
+ envp[j] = xmalloc(sizeof("siaddr=255.255.255.255"));
+ sprintip(envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
}
if (!(over & FILE_FIELD) && packet->file[0]) {
/* watch out for invalid packets */
@@ -210,7 +195,6 @@ static char **fill_envp(struct dhcpMessage *packet)
packet->sname[sizeof(packet->sname) - 1] = '\0';
asprintf(&envp[j++], "sname=%s", packet->sname);
}
- envp[j] = NULL;
return envp;
}
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c
new file mode 100644
index 0000000..4f3292b
--- /dev/null
+++ b/networking/udhcp/signalpipe.c
@@ -0,0 +1,78 @@
+/* signalpipe.c
+ *
+ * Signal pipe infastructure. A reliable way of delivering signals.
+ *
+ * Russ Dill <Russ.Dill@asu.edu> Decemeber 2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+
+
+#include "signalpipe.h"
+#include "common.h"
+
+static int signal_pipe[2];
+
+static void signal_handler(int sig)
+{
+ if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0)
+ DEBUG(LOG_ERR, "Could not send signal: %m");
+}
+
+
+/* Call this before doing anything else. Sets up the socket pair
+ * and installs the signal handler */
+void udhcp_sp_setup(void)
+{
+ socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
+ signal(SIGUSR1, signal_handler);
+ signal(SIGUSR2, signal_handler);
+ signal(SIGTERM, signal_handler);
+}
+
+
+/* Quick little function to setup the rfds. Will return the
+ * max_fd for use with select. Limited in that you can only pass
+ * one extra fd */
+int udhcp_sp_fd_set(fd_set *rfds, int extra_fd)
+{
+ FD_ZERO(rfds);
+ FD_SET(signal_pipe[0], rfds);
+ if (extra_fd >= 0) FD_SET(extra_fd, rfds);
+ return signal_pipe[0] > extra_fd ? signal_pipe[0] : extra_fd;
+}
+
+
+/* Read a signal from the signal pipe. Returns 0 if there is
+ * no signal, -1 on error (and sets errno appropriately), and
+ * your signal on success */
+int udhcp_sp_read(fd_set *rfds)
+{
+ int sig;
+
+ if (!FD_ISSET(signal_pipe[0], rfds))
+ return 0;
+
+ if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
+ return -1;
+
+ return sig;
+}
diff --git a/networking/udhcp/signalpipe.h b/networking/udhcp/signalpipe.h
new file mode 100644
index 0000000..70c1e57
--- /dev/null
+++ b/networking/udhcp/signalpipe.h
@@ -0,0 +1,22 @@
+/* signalpipe.h
+ *
+ * Russ Dill <Russ.Dill@asu.edu> December 2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+void udhcp_sp_setup(void);
+int udhcp_sp_fd_set(fd_set *rfds, int extra_fd);
+int udhcp_sp_read(fd_set *rfds);
diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c
index 60190a0..c19838a 100644
--- a/networking/udhcp/socket.c
+++ b/networking/udhcp/socket.c
@@ -130,29 +130,3 @@ int listen_socket(unsigned int ip, int port, char *inf)
return fd;
}
-
-
-int raw_socket(int ifindex)
-{
- int fd;
- struct sockaddr_ll sock;
-
- DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex);
- if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
- DEBUG(LOG_ERR, "socket call failed: %m");
- return -1;
- }
-
- while (fd >= 0 && fd < 3) fd = dup(fd); /* don't let daemon close fds on us */
-
- sock.sll_family = AF_PACKET;
- sock.sll_protocol = htons(ETH_P_IP);
- sock.sll_ifindex = ifindex;
- if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
- DEBUG(LOG_ERR, "bind call failed: %m");
- close(fd);
- return -1;
- }
-
- return fd;
-}
diff --git a/networking/udhcp/socket.h b/networking/udhcp/socket.h
index 333994b..d259ef7 100644
--- a/networking/udhcp/socket.h
+++ b/networking/udhcp/socket.h
@@ -4,6 +4,5 @@
int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp);
int listen_socket(unsigned int ip, int port, char *inf);
-int raw_socket(int ifindex);
#endif