aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruss <russ@69ca8d6d-28ef-0310-b511-8ec308f3f277>2003-12-18 22:25:38 +0000
committerruss <russ@69ca8d6d-28ef-0310-b511-8ec308f3f277>2003-12-18 22:25:38 +0000
commit6664296f009660a416208c69fcd86fff16138e4b (patch)
tree6582084290de4bead010f5fb8ff0a0a6d2b573fd
parentaa32f3591b34736256e312db6b8f7e54b70c7733 (diff)
downloadbusybox-w32-6664296f009660a416208c69fcd86fff16138e4b.tar.gz
busybox-w32-6664296f009660a416208c69fcd86fff16138e4b.tar.bz2
busybox-w32-6664296f009660a416208c69fcd86fff16138e4b.zip
Finish remerging busybox udhcp and udhcp. Some cleanups as well.
git-svn-id: svn://busybox.net/trunk/busybox@8115 69ca8d6d-28ef-0310-b511-8ec308f3f277
-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 3772aedb3..bb58de13e 100644
--- a/networking/udhcp/AUTHORS
+++ b/networking/udhcp/AUTHORS
@@ -9,6 +9,6 @@ Other Credits:
9-------------- 9--------------
10Moreton Bay (http://www.moretonbay.com/) 10Moreton Bay (http://www.moretonbay.com/)
11Lineo (http://opensource.lineo.com) 11Lineo (http://opensource.lineo.com)
12Vladimir Oleynik <dzo@simtrea.ru>, optimize and more integrate for busybox 12Vladimir Oleynik <dzo@simtrea.ru> Size optimizations
13 13
14 14
diff --git a/networking/udhcp/ChangeLog b/networking/udhcp/ChangeLog
index 9ee97534f..f1aac060e 100644
--- a/networking/udhcp/ChangeLog
+++ b/networking/udhcp/ChangeLog
@@ -1,8 +1,6 @@
10.9.10
2 Size optimization (over 3k), more busybox integration
3 (Vladimir Oleynik <dzo@simtreas.ru>
4
50.9.9 (pending) 10.9.9 (pending)
2+ Various other size optimizations (Vladimir)
3+ Change strerror(errno) to %m (Vladimir N. Oleynik <dzo@simtreas.ru>)
6+ Fixed a little endian problem in mton (Bastian Blank <waldi@debian.org>) 4+ Fixed a little endian problem in mton (Bastian Blank <waldi@debian.org>)
7+ Fixed a arpping alignment problem (Rui He <rhe@3eti.com>) 5+ Fixed a arpping alignment problem (Rui He <rhe@3eti.com>)
8+ Added sanity check for max_leases (udhcp bug #1285) (me) 6+ Added sanity check for max_leases (udhcp bug #1285) (me)
@@ -36,7 +34,7 @@
36 udhcp bug#1256 34 udhcp bug#1256
37+ Fixed reading of client id (David Poole <davep@portsmith.com>) 35+ Fixed reading of client id (David Poole <davep@portsmith.com>)
38+ change sys_errlist[] to strerror() as it aparently doesn't exist 36+ change sys_errlist[] to strerror() as it aparently doesn't exist
39 (Erik Andersen <andersen@codepoet.org>) 37 (Erik Andersen <andersee@codepoet.org>)
40+ fixed get_raw_packet so it returns -2 on non fatal errors 38+ fixed get_raw_packet so it returns -2 on non fatal errors
41 (Ted Lemon <Ted.Lemon@nominum.com>) 39 (Ted Lemon <Ted.Lemon@nominum.com>)
42+ Improved (hopefully) NAKing behavior (me) 40+ Improved (hopefully) NAKing behavior (me)
diff --git a/networking/udhcp/Makefile.in b/networking/udhcp/Makefile.in
index d06e809c9..4d3f27093 100644
--- a/networking/udhcp/Makefile.in
+++ b/networking/udhcp/Makefile.in
@@ -33,22 +33,14 @@ CONFIG_UDHCP_SHARED=n
33endif 33endif
34endif 34endif
35 35
36ifeq ($(CONFIG_UDHCPD), y)
37CONFIG_UDHCP_LEASES_FILE=y
38else
39ifeq ($(CONFIG_UDHCPD), y)
40CONFIG_UDHCP_LEASES_FILE=y
41else
42CONFIG_UDHCP_LEASES_FILE=n
43endif
44endif
45
46UDHCP-y:= 36UDHCP-y:=
47UDHCP-$(CONFIG_UDHCP_SHARED) += options.c socket.c packet.c common.c 37UDHCP-$(CONFIG_UDHCP_SHARED) += common.c options.c packet.c pidfile.c \
48UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c script.c 38 signalpipe.c socket.c
49UDHCP-$(CONFIG_UDHCPD) += dhcpd.c arpping.c files.c leases.c serverpacket.c 39UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c clientsocket.c \
40 script.c
41UDHCP-$(CONFIG_UDHCPD) += dhcpd.c arpping.c files.c leases.c \
42 serverpacket.c
50UDHCP-$(CONFIG_DUMPLEASES) += dumpleases.c 43UDHCP-$(CONFIG_DUMPLEASES) += dumpleases.c
51UDHCP-$(CONFIG_UDHCP_LEASES_FILE) += leases_file.c
52UDHCP_OBJS=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y)) 44UDHCP_OBJS=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y))
53 45
54libraries-y+=$(UDHCP_DIR)$(UDHCP_AR) 46libraries-y+=$(UDHCP_DIR)$(UDHCP_AR)
diff --git a/networking/udhcp/README b/networking/udhcp/README
index 5f4bb78a8..eddb24be7 100644
--- a/networking/udhcp/README
+++ b/networking/udhcp/README
@@ -11,19 +11,22 @@ compile time options
11 11
12The Makefile contains three of the compile time options: 12The Makefile contains three of the compile time options:
13 13
14 DEBUG: If DEBUG is defined, udhcpd will output extra debugging 14 UDHCP_DEBUG: If UDHCP_DEBUG is defined, udhcpd will output extra
15 output, compile with -g, and not fork to the background when run. 15 debugging output, compile with -g, and not fork to the background when
16 SYSLOG: If SYSLOG is defined, udhcpd will log all its messages 16 run.
17 syslog, otherwise, it will attempt to log them to stdout. 17 UDHCP_SYSLOG: If UDHCP_SYSLOG is defined, udhcpd will log all its
18 messages syslog, otherwise, it will attempt to log them to stdout.
18 19
19 COMBINED_BINARY: If COMBINED_BINARY is define, one binary, udhcpd, 20 COMBINED_BINARY: If COMBINED_BINARY is define, one binary, udhcpd,
20 is created. If called as udhcpd, the dhcp server will be started. 21 is created. If called as udhcpd, the dhcp server will be started.
21 If called as udhcpc, the dhcp client will be started. 22 If called as udhcpc, the dhcp client will be started.
22 23
23dhcpd.h contains the other two compile time options: 24dhcpd.h contains the other three compile time options:
24 25
25 LEASE_TIME: The default lease time if not specified in the config 26 LEASE_TIME: The default lease time if not specified in the config
26 file. 27 file.
28
29 LEASES_FILE: The default file for storing leases.
27 30
28 DHCPD_CONFIG_FILE: The defualt config file to use. 31 DHCPD_CONFIG_FILE: The defualt config file to use.
29 32
diff --git a/networking/udhcp/TODO b/networking/udhcp/TODO
index f88694a86..6febe5ab4 100644
--- a/networking/udhcp/TODO
+++ b/networking/udhcp/TODO
@@ -1,5 +1,6 @@
1TODO 1TODO
2---- 2----
3+ Check for valid IP, netmask, hostname, paths, strings, etc
3+ Integrade README.*'s with manpages 4+ Integrade README.*'s with manpages
4+ using time(0) breaks if the system clock changes, find a portable solution 5+ using time(0) breaks if the system clock changes, find a portable solution
5+ make failure of reading functions revert to previous value, not the default 6+ make failure of reading functions revert to previous value, not the default
@@ -9,6 +10,7 @@ TODO
9+ make sure packet generation works on a wide varitey of arches 10+ make sure packet generation works on a wide varitey of arches
10+ Interoperability testing 11+ Interoperability testing
11+ Hooks within the DHCP server 12+ Hooks within the DHCP server
13 * Server notification when a lease is added/removed
12+ Additional bootp support in client/server 14+ Additional bootp support in client/server
13+ Make serverid option in server configurable 15+ Make serverid option in server configurable
14+ Possibly add failure message to DHCP NAK 16+ Possibly add failure message to DHCP NAK
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c
index e20395a9e..363408d6e 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)
44 44
45 45
46 if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) { 46 if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) {
47#ifdef IN_BUSYBOX
47 LOG(LOG_ERR, bb_msg_can_not_create_raw_socket); 48 LOG(LOG_ERR, bb_msg_can_not_create_raw_socket);
49#else
50 LOG(LOG_ERR, "Could not open raw socket");
51#endif
48 return -1; 52 return -1;
49 } 53 }
50 54
diff --git a/networking/udhcp/clientsocket.c b/networking/udhcp/clientsocket.c
new file mode 100644
index 000000000..7c1b6e87c
--- /dev/null
+++ b/networking/udhcp/clientsocket.c
@@ -0,0 +1,62 @@
1/*
2 * clientsocket.c -- DHCP client socket creation
3 *
4 * udhcp client
5 *
6 * Russ Dill <Russ.Dill@asu.edu> July 2001
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <sys/types.h>
24#include <sys/socket.h>
25#include <unistd.h>
26#include <netinet/in.h>
27#include <features.h>
28#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
29#include <netpacket/packet.h>
30#include <net/ethernet.h>
31#else
32#include <asm/types.h>
33#include <linux/if_packet.h>
34#include <linux/if_ether.h>
35#endif
36
37#include "clientsocket.h"
38#include "common.h"
39
40
41int raw_socket(int ifindex)
42{
43 int fd;
44 struct sockaddr_ll sock;
45
46 DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex);
47 if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
48 DEBUG(LOG_ERR, "socket call failed: %m");
49 return -1;
50 }
51
52 sock.sll_family = AF_PACKET;
53 sock.sll_protocol = htons(ETH_P_IP);
54 sock.sll_ifindex = ifindex;
55 if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
56 DEBUG(LOG_ERR, "bind call failed: %m");
57 close(fd);
58 return -1;
59 }
60
61 return fd;
62}
diff --git a/networking/udhcp/clientsocket.h b/networking/udhcp/clientsocket.h
new file mode 100644
index 000000000..17a55c154
--- /dev/null
+++ b/networking/udhcp/clientsocket.h
@@ -0,0 +1,7 @@
1/* clientsocket.h */
2#ifndef _CLIENTSOCKET_H
3#define _CLIENTSOCKET_H
4
5int raw_socket(int ifindex);
6
7#endif
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index babd980e3..bfdc7ba8d 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -1,8 +1,9 @@
1/* common.c 1/* common.c
2 * 2 *
3 * Functions to assist in the writing and removing of pidfiles. 3 * Functions for debugging and logging as well as some other
4 * simple helper functions.
4 * 5 *
5 * Russ Dill <Russ.Dill@asu.edu> Soptember 2001 6 * Russ Dill <Russ.Dill@asu.edu> 2001-2003
6 * Rewrited by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003 7 * Rewrited by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -26,18 +27,54 @@
26#include <string.h> 27#include <string.h>
27#include <stdlib.h> 28#include <stdlib.h>
28#include <signal.h> 29#include <signal.h>
30#include <paths.h>
29#include <sys/socket.h> 31#include <sys/socket.h>
32#include <stdarg.h>
30 33
31#include "common.h" 34#include "common.h"
35#include "pidfile.h"
32 36
33 37
34static int daemonized; 38static int daemonized;
35 39
36#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
37 40
41/*
42 * This function makes sure our first socket calls
43 * aren't going to fd 1 (printf badness...) and are
44 * not later closed by daemon()
45 */
46static inline void sanitize_fds(void)
47{
48 int zero;
49 if ((zero = open(_PATH_DEVNULL, O_RDWR, 0)) < 0) return;
50 while (zero < 3) zero = dup(zero);
51 close(zero);
52}
53
54
55void background(const char *pidfile)
56{
57#ifdef __uClinux__
58 LOG(LOG_ERR, "Cannot background in uclinux (yet)");
59#else /* __uClinux__ */
60 int pid_fd;
61
62 if (!pidfile) return;
63
64 pid_fd = pidfile_acquire(pidfile); /* hold lock during fork. */
65 if (daemon(0, 0) == -1) {
66 perror("fork");
67 exit(1);
68 }
69 daemonized++;
70 pidfile_write_release(pid_fd);
71#endif /* __uClinux__ */
72}
73
74
75#ifdef UDHCP_SYSLOG
38void udhcp_logging(int level, const char *fmt, ...) 76void udhcp_logging(int level, const char *fmt, ...)
39{ 77{
40 int e = errno;
41 va_list p; 78 va_list p;
42 va_list p2; 79 va_list p2;
43 80
@@ -46,21 +83,34 @@ void udhcp_logging(int level, const char *fmt, ...)
46 if(!daemonized) { 83 if(!daemonized) {
47 vprintf(fmt, p); 84 vprintf(fmt, p);
48 putchar('\n'); 85 putchar('\n');
49 fflush(stdout);
50 errno = e;
51 } 86 }
52 vsyslog(level, fmt, p2); 87 vsyslog(level, fmt, p2);
53 va_end(p); 88 va_end(p);
54} 89}
55 90
56void start_log(const char *client_server) 91
92void start_log_and_pid(const char *client_server, const char *pidfile)
57{ 93{
58 openlog(bb_applet_name, LOG_PID | LOG_CONS, LOG_LOCAL0); 94 int pid_fd;
95
96 /* Make sure our syslog fd isn't overwritten */
97 sanitize_fds();
98
99 /* do some other misc startup stuff while we are here to save bytes */
100 pid_fd = pidfile_acquire(pidfile);
101 pidfile_write_release(pid_fd);
102
103 /* equivelent of doing a fflush after every \n */
104 setlinebuf(stdout);
105
106 openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0);
59 udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION); 107 udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
60} 108}
61 109
110
62#else 111#else
63 112
113
64static char *syslog_level_msg[] = { 114static char *syslog_level_msg[] = {
65 [LOG_EMERG] = "EMERGENCY!", 115 [LOG_EMERG] = "EMERGENCY!",
66 [LOG_ALERT] = "ALERT!", 116 [LOG_ALERT] = "ALERT!",
@@ -71,86 +121,36 @@ static char *syslog_level_msg[] = {
71 [LOG_DEBUG] = "debug" 121 [LOG_DEBUG] = "debug"
72}; 122};
73 123
124
74void udhcp_logging(int level, const char *fmt, ...) 125void udhcp_logging(int level, const char *fmt, ...)
75{ 126{
76 int e = errno;
77 va_list p; 127 va_list p;
78 128
79 va_start(p, fmt); 129 va_start(p, fmt);
80 if(!daemonized) { 130 if(!daemonized) {
81 printf("%s, ", syslog_level_msg[level]); 131 printf("%s, ", syslog_level_msg[level]);
82 errno = e;
83 vprintf(fmt, p); 132 vprintf(fmt, p);
84 putchar('\n'); 133 putchar('\n');
85 fflush(stdout);
86 } 134 }
87 va_end(p); 135 va_end(p);
88} 136}
89 137
90void start_log(const char *client_server) 138
139void start_log_and_pid(const char *client_server, const char *pidfile)
91{ 140{
92 udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION); 141 int pid_fd;
93}
94#endif
95 142
96static const char *saved_pidfile; 143 /* Make sure our syslog fd isn't overwritten */
144 sanitize_fds();
97 145
98static void exit_fun(void) 146 /* do some other misc startup stuff while we are here to save bytes */
99{ 147 pid_fd = pidfile_acquire(pidfile);
100 if (saved_pidfile) unlink(saved_pidfile); 148 pidfile_write_release(pid_fd);
101}
102 149
103void background(const char *pidfile) 150 /* equivelent of doing a fflush after every \n */
104{ 151 setlinebuf(stdout);
105#ifdef __uClinux__
106 LOG(LOG_ERR, "Cannot background in uclinux (yet)");
107#else /* __uClinux__ */
108 int pid_fd = -1;
109
110 if (pidfile) {
111 pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
112 if (pid_fd < 0) {
113 LOG(LOG_ERR, "Unable to open pidfile %s: %m", pidfile);
114 } else {
115 lockf(pid_fd, F_LOCK, 0);
116 if(!saved_pidfile)
117 atexit(exit_fun); /* set atexit one only */
118 saved_pidfile = pidfile; /* but may be rewrite */
119 }
120 }
121 while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */
122 if (daemon(0, 0) == -1) {
123 perror("fork");
124 exit(1);
125 }
126 daemonized++;
127 if (pid_fd >= 0) {
128 FILE *out;
129
130 if ((out = fdopen(pid_fd, "w")) != NULL) {
131 fprintf(out, "%d\n", getpid());
132 fclose(out);
133 }
134 lockf(pid_fd, F_UNLCK, 0);
135 close(pid_fd);
136 }
137#endif /* __uClinux__ */
138}
139 152
140/* Signal handler */ 153 udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
141int udhcp_signal_pipe[2];
142static void signal_handler(int sig)
143{
144 if (send(udhcp_signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
145 LOG(LOG_ERR, "Could not send signal: %m");
146 }
147} 154}
155#endif
148 156
149void udhcp_set_signal_pipe(int sig_add)
150{
151 socketpair(AF_UNIX, SOCK_STREAM, 0, udhcp_signal_pipe);
152 signal(SIGUSR1, signal_handler);
153 signal(SIGTERM, signal_handler);
154 if(sig_add)
155 signal(sig_add, signal_handler);
156}
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 768f551b0..78eb1c147 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -18,10 +18,14 @@
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */ 19 */
20 20
21#ifndef _COMMON_H
22#define _COMMON_H
23
21#include "version.h" 24#include "version.h"
22#include "busybox.h" 25#include "libbb_udhcp.h"
26
23 27
24#ifndef CONFIG_FEATURE_UDHCP_SYSLOG 28#ifndef UDHCP_SYSLOG
25enum syslog_levels { 29enum syslog_levels {
26 LOG_EMERG = 0, 30 LOG_EMERG = 0,
27 LOG_ALERT, 31 LOG_ALERT,
@@ -35,18 +39,17 @@ enum syslog_levels {
35#include <syslog.h> 39#include <syslog.h>
36#endif 40#endif
37 41
38void start_log(const char *client_server); 42void background(const char *pidfile);
43void start_log_and_pid(const char *client_server, const char *pidfile);
39void background(const char *pidfile); 44void background(const char *pidfile);
40void udhcp_logging(int level, const char *fmt, ...); 45void udhcp_logging(int level, const char *fmt, ...);
41 46
42extern int udhcp_signal_pipe[2];
43void udhcp_set_signal_pipe(int sig_add);
44
45
46#define LOG(level, str, args...) udhcp_logging(level, str, ## args) 47#define LOG(level, str, args...) udhcp_logging(level, str, ## args)
47 48
48#ifdef CONFIG_FEATURE_UDHCP_DEBUG 49#ifdef UDHCP_DEBUG
49# define DEBUG(level, str, args...) udhcp_logging(level, str, ## args) 50# define DEBUG(level, str, args...) LOG(level, str, ## args)
50#else 51#else
51# define DEBUG(level, str, args...) do {;} while(0) 52# define DEBUG(level, str, args...) do {;} while(0)
52#endif 53#endif
54
55#endif
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 55664abf9..a180cc514 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -38,9 +38,11 @@
38#include "dhcpc.h" 38#include "dhcpc.h"
39#include "options.h" 39#include "options.h"
40#include "clientpacket.h" 40#include "clientpacket.h"
41#include "clientsocket.h"
41#include "script.h" 42#include "script.h"
42#include "socket.h" 43#include "socket.h"
43#include "common.h" 44#include "common.h"
45#include "signalpipe.h"
44 46
45static int state; 47static int state;
46static unsigned long requested_ip; /* = 0 */ 48static unsigned long requested_ip; /* = 0 */
@@ -54,12 +56,6 @@ static int fd = -1;
54#define LISTEN_RAW 2 56#define LISTEN_RAW 2
55static int listen_mode; 57static int listen_mode;
56 58
57#ifdef CONFIG_INSTALL_NO_USR
58#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
59#else
60#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
61#endif
62
63struct client_config_t client_config = { 59struct client_config_t client_config = {
64 /* Default options. */ 60 /* Default options. */
65 abort_if_no_lease: 0, 61 abort_if_no_lease: 0,
@@ -78,7 +74,7 @@ struct client_config_t client_config = {
78#ifndef IN_BUSYBOX 74#ifndef IN_BUSYBOX
79static void __attribute__ ((noreturn)) show_usage(void) 75static void __attribute__ ((noreturn)) show_usage(void)
80{ 76{
81 printf( 77 printf(
82"Usage: udhcpc [OPTIONS]\n\n" 78"Usage: udhcpc [OPTIONS]\n\n"
83" -c, --clientid=CLIENTID Client identifier\n" 79" -c, --clientid=CLIENTID Client identifier\n"
84" -H, --hostname=HOSTNAME Client hostname\n" 80" -H, --hostname=HOSTNAME Client hostname\n"
@@ -95,8 +91,8 @@ static void __attribute__ ((noreturn)) show_usage(void)
95" -s, --script=file Run file at dhcp events (default:\n" 91" -s, --script=file Run file at dhcp events (default:\n"
96" " DEFAULT_SCRIPT ")\n" 92" " DEFAULT_SCRIPT ")\n"
97" -v, --version Display version\n" 93" -v, --version Display version\n"
98 ); 94 );
99 exit(0); 95 exit(0);
100} 96}
101#else 97#else
102#define show_usage bb_show_usage 98#define show_usage bb_show_usage
@@ -177,7 +173,11 @@ static void client_background(void)
177} 173}
178 174
179 175
176#ifdef COMBINED_BINARY
180int udhcpc_main(int argc, char *argv[]) 177int udhcpc_main(int argc, char *argv[])
178#else
179int main(int argc, char *argv[])
180#endif
181{ 181{
182 unsigned char *temp, *message; 182 unsigned char *temp, *message;
183 unsigned long t1 = 0, t2 = 0, xid = 0; 183 unsigned long t1 = 0, t2 = 0, xid = 0;
@@ -258,18 +258,20 @@ int udhcpc_main(int argc, char *argv[])
258 client_config.script = optarg; 258 client_config.script = optarg;
259 break; 259 break;
260 case 'v': 260 case 'v':
261 bb_error_msg("version %s\n", VERSION); 261 printf("udhcpcd, version %s\n\n", VERSION);
262 return(0); 262 return 0;
263 break; 263 break;
264 default: 264 default:
265 show_usage(); 265 show_usage();
266 } 266 }
267 } 267 }
268 268
269 start_log("client"); 269 /* Start the log, sanitize fd's, and write a pid file */
270 start_log_and_pid("udhcpc", client_config.pidfile);
271
270 if (read_interface(client_config.interface, &client_config.ifindex, 272 if (read_interface(client_config.interface, &client_config.ifindex,
271 NULL, client_config.arp) < 0) 273 NULL, client_config.arp) < 0)
272 return(1); 274 return 1;
273 275
274 if (!client_config.clientid) { 276 if (!client_config.clientid) {
275 client_config.clientid = xmalloc(6 + 3); 277 client_config.clientid = xmalloc(6 + 3);
@@ -279,8 +281,8 @@ int udhcpc_main(int argc, char *argv[])
279 memcpy(client_config.clientid + 3, client_config.arp, 6); 281 memcpy(client_config.clientid + 3, client_config.arp, 6);
280 } 282 }
281 283
282 /* setup signal handlers */ 284 /* setup the signal pipe */
283 udhcp_set_signal_pipe(SIGUSR2); 285 udhcp_sp_setup();
284 286
285 state = INIT_SELECTING; 287 state = INIT_SELECTING;
286 run_script(NULL, "deconfig"); 288 run_script(NULL, "deconfig");
@@ -290,7 +292,6 @@ int udhcpc_main(int argc, char *argv[])
290 292
291 tv.tv_sec = timeout - time(0); 293 tv.tv_sec = timeout - time(0);
292 tv.tv_usec = 0; 294 tv.tv_usec = 0;
293 FD_ZERO(&rfds);
294 295
295 if (listen_mode != LISTEN_NONE && fd < 0) { 296 if (listen_mode != LISTEN_NONE && fd < 0) {
296 if (listen_mode == LISTEN_KERNEL) 297 if (listen_mode == LISTEN_KERNEL)
@@ -299,15 +300,13 @@ int udhcpc_main(int argc, char *argv[])
299 fd = raw_socket(client_config.ifindex); 300 fd = raw_socket(client_config.ifindex);
300 if (fd < 0) { 301 if (fd < 0) {
301 LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m"); 302 LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m");
302 return(0); 303 return 0;
303 } 304 }
304 } 305 }
305 if (fd >= 0) FD_SET(fd, &rfds); 306 max_fd = udhcp_sp_fd_set(&rfds, fd);
306 FD_SET(udhcp_signal_pipe[0], &rfds);
307 307
308 if (tv.tv_sec > 0) { 308 if (tv.tv_sec > 0) {
309 DEBUG(LOG_INFO, "Waiting on select..."); 309 DEBUG(LOG_INFO, "Waiting on select...");
310 max_fd = udhcp_signal_pipe[0] > fd ? udhcp_signal_pipe[0] : fd;
311 retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); 310 retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
312 } else retval = 0; /* If we already timed out, fall through */ 311 } else retval = 0; /* If we already timed out, fall through */
313 312
@@ -332,7 +331,7 @@ int udhcpc_main(int argc, char *argv[])
332 client_background(); 331 client_background();
333 } else if (client_config.abort_if_no_lease) { 332 } else if (client_config.abort_if_no_lease) {
334 LOG(LOG_INFO, "No lease, failing."); 333 LOG(LOG_INFO, "No lease, failing.");
335 return(1); 334 return 1;
336 } 335 }
337 /* wait to try again */ 336 /* wait to try again */
338 packet_num = 0; 337 packet_num = 0;
@@ -474,7 +473,7 @@ int udhcpc_main(int argc, char *argv[])
474 state = BOUND; 473 state = BOUND;
475 change_mode(LISTEN_NONE); 474 change_mode(LISTEN_NONE);
476 if (client_config.quit_after_lease) 475 if (client_config.quit_after_lease)
477 return(0); 476 return 0;
478 if (!client_config.foreground) 477 if (!client_config.foreground)
479 client_background(); 478 client_background();
480 479
@@ -494,11 +493,7 @@ int udhcpc_main(int argc, char *argv[])
494 break; 493 break;
495 /* case BOUND, RELEASED: - ignore all packets */ 494 /* case BOUND, RELEASED: - ignore all packets */
496 } 495 }
497 } else if (retval > 0 && FD_ISSET(udhcp_signal_pipe[0], &rfds)) { 496 } else if (retval > 0 && (sig = udhcp_sp_read(&rfds))) {
498 if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0) {
499 DEBUG(LOG_ERR, "Could not read signal: %m");
500 continue; /* probably just EINTR */
501 }
502 switch (sig) { 497 switch (sig) {
503 case SIGUSR1: 498 case SIGUSR1:
504 perform_renew(); 499 perform_renew();
@@ -508,7 +503,7 @@ int udhcpc_main(int argc, char *argv[])
508 break; 503 break;
509 case SIGTERM: 504 case SIGTERM:
510 LOG(LOG_INFO, "Received SIGTERM"); 505 LOG(LOG_INFO, "Received SIGTERM");
511 return(0); 506 return 0;
512 } 507 }
513 } else if (retval == -1 && errno == EINTR) { 508 } else if (retval == -1 && errno == EINTR) {
514 /* a signal was caught */ 509 /* a signal was caught */
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index e23d9d4fe..7145cbd8b 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -2,6 +2,11 @@
2#ifndef _DHCPC_H 2#ifndef _DHCPC_H
3#define _DHCPC_H 3#define _DHCPC_H
4 4
5#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
6
7/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */
8#include "libbb_udhcp.h"
9
5#define INIT_SELECTING 0 10#define INIT_SELECTING 0
6#define REQUESTING 1 11#define REQUESTING 1
7#define BOUND 2 12#define BOUND 2
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index c21cb72a2..aabab38b0 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -43,6 +43,7 @@
43#include "files.h" 43#include "files.h"
44#include "serverpacket.h" 44#include "serverpacket.h"
45#include "common.h" 45#include "common.h"
46#include "signalpipe.h"
46 47
47 48
48/* globals */ 49/* globals */
@@ -50,7 +51,11 @@ struct dhcpOfferedAddr *leases;
50struct server_config_t server_config; 51struct server_config_t server_config;
51 52
52 53
54#ifdef COMBINED_BINARY
53int udhcpd_main(int argc, char *argv[]) 55int udhcpd_main(int argc, char *argv[])
56#else
57int main(int argc, char *argv[])
58#endif
54{ 59{
55 fd_set rfds; 60 fd_set rfds;
56 struct timeval tv; 61 struct timeval tv;
@@ -64,16 +69,13 @@ int udhcpd_main(int argc, char *argv[])
64 struct option_set *option; 69 struct option_set *option;
65 struct dhcpOfferedAddr *lease; 70 struct dhcpOfferedAddr *lease;
66 int max_sock; 71 int max_sock;
67 int sig;
68 unsigned long num_ips; 72 unsigned long num_ips;
69 73
70 start_log("server");
71
72 memset(&server_config, 0, sizeof(struct server_config_t)); 74 memset(&server_config, 0, sizeof(struct server_config_t));
73 75 read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
74 if (argc < 2) 76
75 read_config(DHCPD_CONF_FILE); 77 /* Start the log, sanitize fd's, and write a pid file */
76 else read_config(argv[1]); 78 start_log_and_pid("udhcpd", server_config.pidfile);
77 79
78 if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) { 80 if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
79 memcpy(&server_config.lease, option->data + 2, 4); 81 memcpy(&server_config.lease, option->data + 2, 4);
@@ -90,18 +92,19 @@ int udhcpd_main(int argc, char *argv[])
90 server_config.max_leases = num_ips; 92 server_config.max_leases = num_ips;
91 } 93 }
92 94
93 leases = xcalloc(sizeof(struct dhcpOfferedAddr), server_config.max_leases); 95 leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr));
94 read_leases(server_config.lease_file); 96 read_leases(server_config.lease_file);
95 97
96 if (read_interface(server_config.interface, &server_config.ifindex, 98 if (read_interface(server_config.interface, &server_config.ifindex,
97 &server_config.server, server_config.arp) < 0) 99 &server_config.server, server_config.arp) < 0)
98 return(1); 100 return 1;
99 101
100#ifndef CONFIG_FEATURE_UDHCP_DEBUG 102#ifndef UDHCP_DEBUG
101 background(server_config.pidfile); 103 background(server_config.pidfile); /* hold lock during fork. */
102#endif 104#endif
103 105
104 udhcp_set_signal_pipe(0); 106 /* Setup the signal pipe */
107 udhcp_sp_setup();
105 108
106 timeout_end = time(0) + server_config.auto_time; 109 timeout_end = time(0) + server_config.auto_time;
107 while(1) { /* loop until universe collapses */ 110 while(1) { /* loop until universe collapses */
@@ -109,18 +112,15 @@ int udhcpd_main(int argc, char *argv[])
109 if (server_socket < 0) 112 if (server_socket < 0)
110 if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) { 113 if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
111 LOG(LOG_ERR, "FATAL: couldn't create server socket, %m"); 114 LOG(LOG_ERR, "FATAL: couldn't create server socket, %m");
112 return(2); 115 return 2;
113 } 116 }
114 117
115 FD_ZERO(&rfds); 118 max_sock = udhcp_sp_fd_set(&rfds, server_socket);
116 FD_SET(server_socket, &rfds);
117 FD_SET(udhcp_signal_pipe[0], &rfds);
118 if (server_config.auto_time) { 119 if (server_config.auto_time) {
119 tv.tv_sec = timeout_end - time(0); 120 tv.tv_sec = timeout_end - time(0);
120 tv.tv_usec = 0; 121 tv.tv_usec = 0;
121 } 122 }
122 if (!server_config.auto_time || tv.tv_sec > 0) { 123 if (!server_config.auto_time || tv.tv_sec > 0) {
123 max_sock = server_socket > udhcp_signal_pipe[0] ? server_socket : udhcp_signal_pipe[0];
124 retval = select(max_sock + 1, &rfds, NULL, NULL, 124 retval = select(max_sock + 1, &rfds, NULL, NULL,
125 server_config.auto_time ? &tv : NULL); 125 server_config.auto_time ? &tv : NULL);
126 } else retval = 0; /* If we already timed out, fall through */ 126 } else retval = 0; /* If we already timed out, fall through */
@@ -134,20 +134,18 @@ int udhcpd_main(int argc, char *argv[])
134 continue; 134 continue;
135 } 135 }
136 136
137 if (FD_ISSET(udhcp_signal_pipe[0], &rfds)) { 137 switch (udhcp_sp_read(&rfds)) {
138 if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0) 138 case SIGUSR1:
139 continue; /* probably just EINTR */ 139 LOG(LOG_INFO, "Received a SIGUSR1");
140 switch (sig) { 140 write_leases();
141 case SIGUSR1: 141 /* why not just reset the timeout, eh */
142 LOG(LOG_INFO, "Received a SIGUSR1"); 142 timeout_end = time(0) + server_config.auto_time;
143 write_leases(); 143 continue;
144 /* why not just reset the timeout, eh */ 144 case SIGTERM:
145 timeout_end = time(0) + server_config.auto_time; 145 LOG(LOG_INFO, "Received a SIGTERM");
146 continue; 146 return 0;
147 case SIGTERM: 147 case 0: break; /* no signal */
148 LOG(LOG_INFO, "Received a SIGTERM"); 148 default: continue; /* signal or error (probably EINTR) */
149 return(0);
150 }
151 } 149 }
152 150
153 if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */ 151 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[])
251 249
252 return 0; 250 return 0;
253} 251}
252
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index f24f01cb6..6d72863ee 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -16,6 +16,13 @@
16#include "options.h" 16#include "options.h"
17#include "common.h" 17#include "common.h"
18 18
19/*
20 * Domain names may have 254 chars, and string options can be 254
21 * chars long. However, 80 bytes will be enough for most, and won't
22 * hog up memory. If you have a special application, change it
23 */
24#define READ_CONFIG_BUF_SIZE 80
25
19/* on these functions, make sure you datatype matches */ 26/* on these functions, make sure you datatype matches */
20static int read_ip(const char *line, void *arg) 27static int read_ip(const char *line, void *arg)
21{ 28{
@@ -66,23 +73,23 @@ static int read_yn(const char *line, void *arg)
66 return retval; 73 return retval;
67} 74}
68 75
69#define READ_CONFIG_BUF_SIZE 512 /* domainname may have 254 chars */
70 76
71/* read a dhcp option and add it to opt_list */ 77/* read a dhcp option and add it to opt_list */
72static int read_opt(const char *const_line, void *arg) 78static int read_opt(const char *const_line, void *arg)
73{ 79{
74 char line[READ_CONFIG_BUF_SIZE];
75 struct option_set **opt_list = arg; 80 struct option_set **opt_list = arg;
76 char *opt, *val, *endptr; 81 char *opt, *val, *endptr;
77 struct dhcp_option *option; 82 struct dhcp_option *option;
78 int retval = 0, length; 83 int retval = 0, length;
79 char buffer[256]; /* max opt length */ 84 char buffer[8];
80 u_int16_t result_u16; 85 char *line;
81 u_int32_t result_u32; 86 u_int16_t *result_u16 = (u_int16_t *) buffer;
82 void *valptr; 87 u_int32_t *result_u32 = (u_int32_t *) buffer;
88
89 /* Cheat, the only const line we'll actually get is "" */
90 line = (char *) const_line;
91 if (!(opt = strtok(line, " \t="))) return 0;
83 92
84 if (!(opt = strtok(strcpy(line, const_line), " \t="))) return 0;
85
86 for (option = dhcp_options; option->code; option++) 93 for (option = dhcp_options; option->code; option++)
87 if (!strcasecmp(option->name, opt)) 94 if (!strcasecmp(option->name, opt))
88 break; 95 break;
@@ -90,11 +97,10 @@ static int read_opt(const char *const_line, void *arg)
90 if (!option->code) return 0; 97 if (!option->code) return 0;
91 98
92 do { 99 do {
93 val = strtok(NULL, ", \t"); 100 if (!(val = strtok(NULL, ", \t"))) break;
94 if(!val)
95 break;
96 length = option_lengths[option->flags & TYPE_MASK]; 101 length = option_lengths[option->flags & TYPE_MASK];
97 valptr = NULL; 102 retval = 0;
103 opt = buffer; /* new meaning for variable opt */
98 switch (option->flags & TYPE_MASK) { 104 switch (option->flags & TYPE_MASK) {
99 case OPTION_IP: 105 case OPTION_IP:
100 retval = read_ip(val, buffer); 106 retval = read_ip(val, buffer);
@@ -108,9 +114,8 @@ static int read_opt(const char *const_line, void *arg)
108 length = strlen(val); 114 length = strlen(val);
109 if (length > 0) { 115 if (length > 0) {
110 if (length > 254) length = 254; 116 if (length > 254) length = 254;
111 endptr = buffer + length; 117 opt = val;
112 endptr[0] = 0; 118 retval = 1;
113 valptr = val;
114 } 119 }
115 break; 120 break;
116 case OPTION_BOOLEAN: 121 case OPTION_BOOLEAN:
@@ -118,43 +123,36 @@ static int read_opt(const char *const_line, void *arg)
118 break; 123 break;
119 case OPTION_U8: 124 case OPTION_U8:
120 buffer[0] = strtoul(val, &endptr, 0); 125 buffer[0] = strtoul(val, &endptr, 0);
121 valptr = buffer; 126 retval = (endptr[0] == '\0');
122 break; 127 break;
123 case OPTION_U16: 128 case OPTION_U16:
124 result_u16 = htons(strtoul(val, &endptr, 0)); 129 *result_u16 = htons(strtoul(val, &endptr, 0));
125 valptr = &result_u16; 130 retval = (endptr[0] == '\0');
126 break; 131 break;
127 case OPTION_S16: 132 case OPTION_S16:
128 result_u16 = htons(strtol(val, &endptr, 0)); 133 *result_u16 = htons(strtol(val, &endptr, 0));
129 valptr = &result_u16; 134 retval = (endptr[0] == '\0');
130 break; 135 break;
131 case OPTION_U32: 136 case OPTION_U32:
132 result_u32 = htonl(strtoul(val, &endptr, 0)); 137 *result_u32 = htonl(strtoul(val, &endptr, 0));
133 valptr = &result_u32; 138 retval = (endptr[0] == '\0');
134 break; 139 break;
135 case OPTION_S32: 140 case OPTION_S32:
136 result_u32 = htonl(strtol(val, &endptr, 0)); 141 *result_u32 = htonl(strtol(val, &endptr, 0));
137 valptr = &result_u32; 142 retval = (endptr[0] == '\0');
138 break; 143 break;
139 default: 144 default:
140 retval = 0;
141 break; 145 break;
142 } 146 }
143 if (valptr) {
144 memcpy(buffer, valptr, length);
145 retval = (endptr[0] == '\0');
146 }
147 if (retval) 147 if (retval)
148 attach_option(opt_list, option, buffer, length); 148 attach_option(opt_list, option, opt, length);
149 else 149 } while (retval && option->flags & OPTION_LIST);
150 break;
151 } while (option->flags & OPTION_LIST);
152 return retval; 150 return retval;
153} 151}
154 152
155 153
156static const struct config_keyword keywords[] = { 154static const struct config_keyword keywords[] = {
157 /* keyword handler variable address default */ 155 /* keyword handler variable address default */
158 {"start", read_ip, &(server_config.start), "192.168.0.20"}, 156 {"start", read_ip, &(server_config.start), "192.168.0.20"},
159 {"end", read_ip, &(server_config.end), "192.168.0.254"}, 157 {"end", read_ip, &(server_config.end), "192.168.0.254"},
160 {"interface", read_str, &(server_config.interface), "eth0"}, 158 {"interface", read_str, &(server_config.interface), "eth0"},
@@ -167,7 +165,7 @@ static const struct config_keyword keywords[] = {
167 {"conflict_time",read_u32,&(server_config.conflict_time),"3600"}, 165 {"conflict_time",read_u32,&(server_config.conflict_time),"3600"},
168 {"offer_time", read_u32, &(server_config.offer_time), "60"}, 166 {"offer_time", read_u32, &(server_config.offer_time), "60"},
169 {"min_lease", read_u32, &(server_config.min_lease), "60"}, 167 {"min_lease", read_u32, &(server_config.min_lease), "60"},
170 {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE}, 168 {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE},
171 {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, 169 {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
172 {"notify_file", read_str, &(server_config.notify_file), ""}, 170 {"notify_file", read_str, &(server_config.notify_file), ""},
173 {"siaddr", read_ip, &(server_config.siaddr), "0.0.0.0"}, 171 {"siaddr", read_ip, &(server_config.siaddr), "0.0.0.0"},
@@ -181,9 +179,11 @@ static const struct config_keyword keywords[] = {
181int read_config(const char *file) 179int read_config(const char *file)
182{ 180{
183 FILE *in; 181 FILE *in;
184 char buffer[READ_CONFIG_BUF_SIZE], orig[READ_CONFIG_BUF_SIZE]; 182 char buffer[READ_CONFIG_BUF_SIZE], *token, *line;
185 char *token, *line; 183#ifdef UDHCP_DEBUG
186 int i; 184 char orig[READ_CONFIG_BUF_SIZE];
185#endif
186 int i, lm = 0;
187 187
188 for (i = 0; keywords[i].keyword[0]; i++) 188 for (i = 0; keywords[i].keyword[0]; i++)
189 if (keywords[i].def[0]) 189 if (keywords[i].def[0])
@@ -195,27 +195,27 @@ int read_config(const char *file)
195 } 195 }
196 196
197 while (fgets(buffer, READ_CONFIG_BUF_SIZE, in)) { 197 while (fgets(buffer, READ_CONFIG_BUF_SIZE, in)) {
198 lm++;
198 if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0'; 199 if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0';
200#ifdef UDHCP_DEBUG
199 strcpy(orig, buffer); 201 strcpy(orig, buffer);
202#endif
200 if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0'; 203 if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0';
201 token = strtok(buffer, " \t"); 204
202 if(!token) 205 if (!(token = strtok(buffer, " \t"))) continue;
203 continue; 206 if (!(line = strtok(NULL, ""))) continue;
204 line = strtok(NULL, ""); 207
205 if(!line) 208 /* eat leading whitespace */
206 continue; 209 line = line + strspn(line, " \t=");
207 while(*line == '=' || isspace(*line))
208 line++;
209 /* eat trailing whitespace */ 210 /* eat trailing whitespace */
210 for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--); 211 for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--);
211 line[i] = '\0'; 212 line[i] = '\0';
212 if (*line == '\0')
213 continue;
214 213
215 for (i = 0; keywords[i].keyword[0]; i++) 214 for (i = 0; keywords[i].keyword[0]; i++)
216 if (!strcasecmp(token, keywords[i].keyword)) 215 if (!strcasecmp(token, keywords[i].keyword))
217 if (!keywords[i].handler(line, keywords[i].var)) { 216 if (!keywords[i].handler(line, keywords[i].var)) {
218 LOG(LOG_ERR, "unable to parse '%s'", orig); 217 LOG(LOG_ERR, "Failure parsing line %d of %s", lm, file);
218 DEBUG(LOG_ERR, "unable to parse '%s'", orig);
219 /* reset back to the default value */ 219 /* reset back to the default value */
220 keywords[i].handler(keywords[i].def, keywords[i].var); 220 keywords[i].handler(keywords[i].def, keywords[i].var);
221 } 221 }
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index 341abab49..add114f6c 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -117,6 +117,7 @@ static int check_ip(u_int32_t addr)
117 } else return 0; 117 } else return 0;
118} 118}
119 119
120
120/* find an assignable address, it check_expired is true, we check all the expired leases as well. 121/* find an assignable address, it check_expired is true, we check all the expired leases as well.
121 * Maybe this should try expired leases by age... */ 122 * Maybe this should try expired leases by age... */
122u_int32_t find_address(int check_expired) 123u_int32_t find_address(int check_expired)
diff --git a/networking/udhcp/leases.h b/networking/udhcp/leases.h
index d54cd11cc..24d860867 100644
--- a/networking/udhcp/leases.h
+++ b/networking/udhcp/leases.h
@@ -9,8 +9,6 @@ struct dhcpOfferedAddr {
9 u_int32_t expires; /* host order */ 9 u_int32_t expires; /* host order */
10}; 10};
11 11
12extern const char leases_file[];
13
14extern unsigned char blank_chaddr[]; 12extern unsigned char blank_chaddr[];
15 13
16void clear_lease(u_int8_t *chaddr, u_int32_t yiaddr); 14void 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 96e2f2d1b..000000000
--- a/networking/udhcp/leases_file.c
+++ /dev/null
@@ -1 +0,0 @@
1const char leases_file[] = "/var/lib/misc/udhcpd.leases";
diff --git a/networking/udhcp/libbb_udhcp.h b/networking/udhcp/libbb_udhcp.h
index 73e21464f..9b5d5a846 100644
--- a/networking/udhcp/libbb_udhcp.h
+++ b/networking/udhcp/libbb_udhcp.h
@@ -1,5 +1,13 @@
1/* libbb_udhcp.h - busybox compatability wrapper */ 1/* libbb_udhcp.h - busybox compatability wrapper */
2 2
3/* bit of a hack, do this no matter what the order of the includes.
4 * (for busybox) */
5
6#ifdef CONFIG_INSTALL_NO_USR
7#undef DEFUALT_SCRIPT
8#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
9#endif
10
3#ifndef _LIBBB_UDHCP_H 11#ifndef _LIBBB_UDHCP_H
4#define _LIBBB_UDHCP_H 12#define _LIBBB_UDHCP_H
5 13
@@ -7,22 +15,16 @@
7#include "busybox.h" 15#include "busybox.h"
8 16
9#ifdef CONFIG_FEATURE_UDHCP_SYSLOG 17#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
10#define SYSLOG 18#define UDHCP_SYSLOG
11#endif 19#endif
12 20
13#ifdef CONFIG_FEATURE_UDHCP_DEBUG 21#ifdef CONFIG_FEATURE_UDHCP_DEBUG
14#define DEBUG 22#define UDHCP_DEBUG
15#endif 23#endif
16 24
17#define COMBINED_BINARY 25#define COMBINED_BINARY
18#include "version.h" 26#include "version.h"
19 27
20#ifdef CONFIG_INSTALL_NO_USR
21#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
22#else
23#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
24#endif
25
26#define xfopen bb_xfopen 28#define xfopen bb_xfopen
27 29
28#else /* ! BB_VER */ 30#else /* ! BB_VER */
@@ -36,8 +38,6 @@
36#define xmalloc malloc 38#define xmalloc malloc
37#define xcalloc calloc 39#define xcalloc calloc
38 40
39#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
40
41static inline FILE *xfopen(const char *file, const char *mode) 41static inline FILE *xfopen(const char *file, const char *mode)
42{ 42{
43 FILE *fp; 43 FILE *fp;
diff --git a/networking/udhcp/pidfile.c b/networking/udhcp/pidfile.c
new file mode 100644
index 000000000..d656c7ad0
--- /dev/null
+++ b/networking/udhcp/pidfile.c
@@ -0,0 +1,75 @@
1/* pidfile.c
2 *
3 * Functions to assist in the writing and removing of pidfiles.
4 *
5 * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <fcntl.h>
25#include <unistd.h>
26#include <stdio.h>
27#include <stdlib.h>
28
29#include "pidfile.h"
30#include "common.h"
31
32static char *saved_pidfile;
33
34static void pidfile_delete(void)
35{
36 if (saved_pidfile) unlink(saved_pidfile);
37}
38
39
40int pidfile_acquire(const char *pidfile)
41{
42 int pid_fd;
43 if (!pidfile) return -1;
44
45 pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
46 if (pid_fd < 0) {
47 LOG(LOG_ERR, "Unable to open pidfile %s: %m\n", pidfile);
48 } else {
49 lockf(pid_fd, F_LOCK, 0);
50 if (!saved_pidfile)
51 atexit(pidfile_delete);
52 saved_pidfile = (char *) pidfile;
53 }
54
55 return pid_fd;
56}
57
58
59void pidfile_write_release(int pid_fd)
60{
61 FILE *out;
62
63 if (pid_fd < 0) return;
64
65 if ((out = fdopen(pid_fd, "w")) != NULL) {
66 fprintf(out, "%d\n", getpid());
67 fclose(out);
68 }
69 lockf(pid_fd, F_UNLCK, 0);
70 close(pid_fd);
71}
72
73
74
75
diff --git a/networking/udhcp/pidfile.h b/networking/udhcp/pidfile.h
new file mode 100644
index 000000000..7f8e8aedc
--- /dev/null
+++ b/networking/udhcp/pidfile.h
@@ -0,0 +1,25 @@
1/* pidfile.h
2 *
3 * Functions to assist in the writing and removing of pidfiles.
4 *
5 * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23int pidfile_acquire(const char *pidfile);
24void pidfile_write_release(int pid_fd);
25
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c
index 9c766a2e2..dcd2cad2d 100644
--- a/networking/udhcp/script.c
+++ b/networking/udhcp/script.c
@@ -32,7 +32,6 @@
32#include "options.h" 32#include "options.h"
33#include "dhcpd.h" 33#include "dhcpd.h"
34#include "dhcpc.h" 34#include "dhcpc.h"
35#include "script.h"
36#include "common.h" 35#include "common.h"
37 36
38/* get a rough idea of how long an option will be (rounding up...) */ 37/* 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)
56} 55}
57 56
58 57
59static int sprintip(char *dest, unsigned char *ip) 58static int sprintip(char *dest, char *pre, unsigned char *ip)
60{ 59{
61 return sprintf(dest, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); 60 return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
62}
63
64static void asprintip(char **dest, char *pre, unsigned char *ip)
65{
66 asprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
67} 61}
68 62
69 63
@@ -96,12 +90,12 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option *
96 for(;;) { 90 for(;;) {
97 switch (type) { 91 switch (type) {
98 case OPTION_IP_PAIR: 92 case OPTION_IP_PAIR:
99 dest += sprintip(dest, option); 93 dest += sprintip(dest, "", option);
100 *(dest++) = '/'; 94 *(dest++) = '/';
101 option += 4; 95 option += 4;
102 optlen = 4; 96 optlen = 4;
103 case OPTION_IP: /* Works regardless of host byte order. */ 97 case OPTION_IP: /* Works regardless of host byte order. */
104 dest += sprintip(dest, option); 98 dest += sprintip(dest, "", option);
105 break; 99 break;
106 case OPTION_BOOLEAN: 100 case OPTION_BOOLEAN:
107 dest += sprintf(dest, *option ? "yes" : "no"); 101 dest += sprintf(dest, *option ? "yes" : "no");
@@ -138,15 +132,6 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option *
138} 132}
139 133
140 134
141static char *find_env(const char *prefix, char *defaultstr)
142{
143 char *ptr;
144
145 ptr = getenv(prefix);
146 return ptr ? ptr : defaultstr;
147}
148
149
150/* put all the paramaters into an environment */ 135/* put all the paramaters into an environment */
151static char **fill_envp(struct dhcpMessage *packet) 136static char **fill_envp(struct dhcpMessage *packet)
152{ 137{
@@ -167,21 +152,20 @@ static char **fill_envp(struct dhcpMessage *packet)
167 if ((temp = get_option(packet, DHCP_OPTION_OVER))) 152 if ((temp = get_option(packet, DHCP_OPTION_OVER)))
168 over = *temp; 153 over = *temp;
169 if (!(over & FILE_FIELD) && packet->file[0]) num_options++; 154 if (!(over & FILE_FIELD) && packet->file[0]) num_options++;
170 if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++; 155 if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;
171 } 156 }
172 157
173 envp = xmalloc((num_options + 5) * sizeof(char *)); 158 envp = xcalloc(sizeof(char *), num_options + 5);
174 j = 0; 159 j = 0;
175 asprintf(&envp[j++], "interface=%s", client_config.interface); 160 asprintf(&envp[j++], "interface=%s", client_config.interface);
176 envp[j++] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin"); 161 asprintf(&envp[j++], "%s=%s", "PATH",
177 envp[j++] = find_env("HOME", "HOME=/"); 162 getenv("PATH") ? : "/bin:/usr/bin:/sbin:/usr/sbin");
163 asprintf(&envp[j++], "%s=%s", "HOME", getenv("HOME") ? : "/");
178 164
179 if (packet == NULL) { 165 if (packet == NULL) return envp;
180 envp[j++] = NULL;
181 return envp;
182 }
183 166
184 asprintip(&envp[j++], "ip=", (unsigned char *) &packet->yiaddr); 167 envp[j] = xmalloc(sizeof("ip=255.255.255.255"));
168 sprintip(envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
185 169
186 170
187 for (i = 0; dhcp_options[i].code; i++) { 171 for (i = 0; dhcp_options[i].code; i++) {
@@ -198,7 +182,8 @@ static char **fill_envp(struct dhcpMessage *packet)
198 } 182 }
199 } 183 }
200 if (packet->siaddr) { 184 if (packet->siaddr) {
201 asprintip(&envp[j++], "siaddr=", (unsigned char *) &packet->siaddr); 185 envp[j] = xmalloc(sizeof("siaddr=255.255.255.255"));
186 sprintip(envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
202 } 187 }
203 if (!(over & FILE_FIELD) && packet->file[0]) { 188 if (!(over & FILE_FIELD) && packet->file[0]) {
204 /* watch out for invalid packets */ 189 /* watch out for invalid packets */
@@ -210,7 +195,6 @@ static char **fill_envp(struct dhcpMessage *packet)
210 packet->sname[sizeof(packet->sname) - 1] = '\0'; 195 packet->sname[sizeof(packet->sname) - 1] = '\0';
211 asprintf(&envp[j++], "sname=%s", packet->sname); 196 asprintf(&envp[j++], "sname=%s", packet->sname);
212 } 197 }
213 envp[j] = NULL;
214 return envp; 198 return envp;
215} 199}
216 200
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c
new file mode 100644
index 000000000..4f3292b9d
--- /dev/null
+++ b/networking/udhcp/signalpipe.c
@@ -0,0 +1,78 @@
1/* signalpipe.c
2 *
3 * Signal pipe infastructure. A reliable way of delivering signals.
4 *
5 * Russ Dill <Russ.Dill@asu.edu> Decemeber 2003
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <unistd.h>
23#include <signal.h>
24#include <sys/types.h>
25#include <sys/socket.h>
26#include <sys/select.h>
27
28
29#include "signalpipe.h"
30#include "common.h"
31
32static int signal_pipe[2];
33
34static void signal_handler(int sig)
35{
36 if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0)
37 DEBUG(LOG_ERR, "Could not send signal: %m");
38}
39
40
41/* Call this before doing anything else. Sets up the socket pair
42 * and installs the signal handler */
43void udhcp_sp_setup(void)
44{
45 socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
46 signal(SIGUSR1, signal_handler);
47 signal(SIGUSR2, signal_handler);
48 signal(SIGTERM, signal_handler);
49}
50
51
52/* Quick little function to setup the rfds. Will return the
53 * max_fd for use with select. Limited in that you can only pass
54 * one extra fd */
55int udhcp_sp_fd_set(fd_set *rfds, int extra_fd)
56{
57 FD_ZERO(rfds);
58 FD_SET(signal_pipe[0], rfds);
59 if (extra_fd >= 0) FD_SET(extra_fd, rfds);
60 return signal_pipe[0] > extra_fd ? signal_pipe[0] : extra_fd;
61}
62
63
64/* Read a signal from the signal pipe. Returns 0 if there is
65 * no signal, -1 on error (and sets errno appropriately), and
66 * your signal on success */
67int udhcp_sp_read(fd_set *rfds)
68{
69 int sig;
70
71 if (!FD_ISSET(signal_pipe[0], rfds))
72 return 0;
73
74 if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
75 return -1;
76
77 return sig;
78}
diff --git a/networking/udhcp/signalpipe.h b/networking/udhcp/signalpipe.h
new file mode 100644
index 000000000..70c1e5715
--- /dev/null
+++ b/networking/udhcp/signalpipe.h
@@ -0,0 +1,22 @@
1/* signalpipe.h
2 *
3 * Russ Dill <Russ.Dill@asu.edu> December 2003
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20void udhcp_sp_setup(void);
21int udhcp_sp_fd_set(fd_set *rfds, int extra_fd);
22int udhcp_sp_read(fd_set *rfds);
diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c
index 60190a044..c19838a7b 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)
130 130
131 return fd; 131 return fd;
132} 132}
133
134
135int raw_socket(int ifindex)
136{
137 int fd;
138 struct sockaddr_ll sock;
139
140 DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex);
141 if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
142 DEBUG(LOG_ERR, "socket call failed: %m");
143 return -1;
144 }
145
146 while (fd >= 0 && fd < 3) fd = dup(fd); /* don't let daemon close fds on us */
147
148 sock.sll_family = AF_PACKET;
149 sock.sll_protocol = htons(ETH_P_IP);
150 sock.sll_ifindex = ifindex;
151 if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
152 DEBUG(LOG_ERR, "bind call failed: %m");
153 close(fd);
154 return -1;
155 }
156
157 return fd;
158}
diff --git a/networking/udhcp/socket.h b/networking/udhcp/socket.h
index 333994b8f..d259ef770 100644
--- a/networking/udhcp/socket.h
+++ b/networking/udhcp/socket.h
@@ -4,6 +4,5 @@
4 4
5int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp); 5int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp);
6int listen_socket(unsigned int ip, int port, char *inf); 6int listen_socket(unsigned int ip, int port, char *inf);
7int raw_socket(int ifindex);
8 7
9#endif 8#endif