Finish remerging busybox udhcp and udhcp. Some cleanups as well.
authorRuss Dill <Russ.Dill@asu.edu>
Thu, 18 Dec 2003 22:25:38 +0000 (22:25 -0000)
committerRuss Dill <Russ.Dill@asu.edu>
Thu, 18 Dec 2003 22:25:38 +0000 (22:25 -0000)
25 files changed:
networking/udhcp/AUTHORS
networking/udhcp/ChangeLog
networking/udhcp/Makefile.in
networking/udhcp/README
networking/udhcp/TODO
networking/udhcp/arpping.c
networking/udhcp/clientsocket.c [new file with mode: 0644]
networking/udhcp/clientsocket.h [new file with mode: 0644]
networking/udhcp/common.c
networking/udhcp/common.h
networking/udhcp/dhcpc.c
networking/udhcp/dhcpc.h
networking/udhcp/dhcpd.c
networking/udhcp/files.c
networking/udhcp/leases.c
networking/udhcp/leases.h
networking/udhcp/leases_file.c [deleted file]
networking/udhcp/libbb_udhcp.h
networking/udhcp/pidfile.c [new file with mode: 0644]
networking/udhcp/pidfile.h [new file with mode: 0644]
networking/udhcp/script.c
networking/udhcp/signalpipe.c [new file with mode: 0644]
networking/udhcp/signalpipe.h [new file with mode: 0644]
networking/udhcp/socket.c
networking/udhcp/socket.h

index 3772aedb3fdf1db016b43548214970a31a84a35a..bb58de13e5bf57eb485d8606297c8f8b4b64bdc2 100644 (file)
@@ -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
 
 
index 9ee97534f5c11c9d4bc81bd7b1a179a6b2b0f42e..f1aac060e0b4888815e95c055304c02978dd1c00 100644 (file)
@@ -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)
index d06e809c9301983eacba9e43b9c5359a2caf8e89..4d3f27093b17a2fc7454f8731645ff50e5b6859c 100644 (file)
@@ -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)
index 5f4bb78a84b2a0b055c46442ed66d76b4160ead2..eddb24be7ccbf381263321f6852e645f48140040 100644 (file)
@@ -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.
        
index f88694a866ac965a00d4d76ecef019cdacb20dd4..6febe5ab4c914c4232890dd0316ac51a23f4e039 100644 (file)
@@ -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
index e20395a9e874d573d8c9685f17b520c9fa3d540b..363408d6e60ac8110158acd8449961c57f099404 100644 (file)
@@ -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 (file)
index 0000000..7c1b6e8
--- /dev/null
@@ -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 (file)
index 0000000..17a55c1
--- /dev/null
@@ -0,0 +1,7 @@
+/* clientsocket.h */
+#ifndef _CLIENTSOCKET_H
+#define _CLIENTSOCKET_H
+
+int raw_socket(int ifindex);
+
+#endif
index babd980e334f341dffda72f563a38e5d11d400c1..bfdc7ba8d7b32e87b118f049d0a1238310dd263d 100644 (file)
@@ -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
 #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);
-}
index 768f551b05cc91c158ae0bf4d3b01750167d204d..78eb1c147f8006281826d6d7163f559eda4e336d 100644 (file)
  * 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
index 55664abf958f6c4eefef4663e63b806bbabdeba5..a180cc5144f9e7795683d7a9883b82010bd3afc5 100644 (file)
 #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 */               
index e23d9d4fee90fdbfe2fd6503fd7205574c9a01d6..7145cbd8b826cb2e02db46ff9e114a2886e696be 100644 (file)
@@ -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
index c21cb72a2c56d2e544d41793142de81352c27386..aabab38b00d58a3f3577369bffd243d480f25a7b 100644 (file)
@@ -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;
 }
+
index f24f01cb66254a3e40a9223333506b846de2588e..6d72863eefa97ac3a9381045acb08a18205da837 100644 (file)
 #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);
                                }
index 341abab49f21e9a49b61bedb126989c94f511827..add114f6c41f03aa6b2cf6dbeb65a6dce3f874ce 100644 (file)
@@ -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) 
index d54cd11cc4d475084b0b97cb76d7db3bc39e4784..24d860867d4e2bf3ce3adceb9c1e43bdcdef5c21 100644 (file)
@@ -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 (file)
index 96e2f2d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-const char leases_file[] = "/var/lib/misc/udhcpd.leases";
index 73e21464f708c534f4b09954bcd86f1d1e716ba1..9b5d5a84680354cbbb3b586273dd29206eeb7560 100644 (file)
@@ -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
 
 #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 (file)
index 0000000..d656c7a
--- /dev/null
@@ -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 (file)
index 0000000..7f8e8ae
--- /dev/null
@@ -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);
+
index 9c766a2e287d67c8c15dbfc19958a4ff1894a771..dcd2cad2d6358f3f1c88663ba603233183ab6aab 100644 (file)
@@ -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 (file)
index 0000000..4f3292b
--- /dev/null
@@ -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 (file)
index 0000000..70c1e57
--- /dev/null
@@ -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);
index 60190a044d4cf07e19b4bb4848df40b71f53a345..c19838a7bd49538c7af85a1ea55f32e885e46993 100644 (file)
@@ -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;
-}
index 333994b8f7b5aea738cfbb57d6ded8fc8446b020..d259ef77050b62f1841a342d95a32de548d91b54 100644 (file)
@@ -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