diff options
-rw-r--r-- | networking/udhcp/AUTHORS | 2 | ||||
-rw-r--r-- | networking/udhcp/ChangeLog | 8 | ||||
-rw-r--r-- | networking/udhcp/Makefile.in | 20 | ||||
-rw-r--r-- | networking/udhcp/README | 13 | ||||
-rw-r--r-- | networking/udhcp/TODO | 2 | ||||
-rw-r--r-- | networking/udhcp/arpping.c | 4 | ||||
-rw-r--r-- | networking/udhcp/clientsocket.c | 62 | ||||
-rw-r--r-- | networking/udhcp/clientsocket.h | 7 | ||||
-rw-r--r-- | networking/udhcp/common.c | 142 | ||||
-rw-r--r-- | networking/udhcp/common.h | 23 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 51 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.h | 5 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 61 | ||||
-rw-r--r-- | networking/udhcp/files.c | 98 | ||||
-rw-r--r-- | networking/udhcp/leases.c | 1 | ||||
-rw-r--r-- | networking/udhcp/leases.h | 2 | ||||
-rw-r--r-- | networking/udhcp/leases_file.c | 1 | ||||
-rw-r--r-- | networking/udhcp/libbb_udhcp.h | 20 | ||||
-rw-r--r-- | networking/udhcp/pidfile.c | 75 | ||||
-rw-r--r-- | networking/udhcp/pidfile.h | 25 | ||||
-rw-r--r-- | networking/udhcp/script.c | 44 | ||||
-rw-r--r-- | networking/udhcp/signalpipe.c | 78 | ||||
-rw-r--r-- | networking/udhcp/signalpipe.h | 22 | ||||
-rw-r--r-- | networking/udhcp/socket.c | 26 | ||||
-rw-r--r-- | networking/udhcp/socket.h | 1 |
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 | -------------- |
10 | Moreton Bay (http://www.moretonbay.com/) | 10 | Moreton Bay (http://www.moretonbay.com/) |
11 | Lineo (http://opensource.lineo.com) | 11 | Lineo (http://opensource.lineo.com) |
12 | Vladimir Oleynik <dzo@simtrea.ru>, optimize and more integrate for busybox | 12 | Vladimir 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 @@ | |||
1 | 0.9.10 | ||
2 | Size optimization (over 3k), more busybox integration | ||
3 | (Vladimir Oleynik <dzo@simtreas.ru> | ||
4 | |||
5 | 0.9.9 (pending) | 1 | 0.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 | |||
33 | endif | 33 | endif |
34 | endif | 34 | endif |
35 | 35 | ||
36 | ifeq ($(CONFIG_UDHCPD), y) | ||
37 | CONFIG_UDHCP_LEASES_FILE=y | ||
38 | else | ||
39 | ifeq ($(CONFIG_UDHCPD), y) | ||
40 | CONFIG_UDHCP_LEASES_FILE=y | ||
41 | else | ||
42 | CONFIG_UDHCP_LEASES_FILE=n | ||
43 | endif | ||
44 | endif | ||
45 | |||
46 | UDHCP-y:= | 36 | UDHCP-y:= |
47 | UDHCP-$(CONFIG_UDHCP_SHARED) += options.c socket.c packet.c common.c | 37 | UDHCP-$(CONFIG_UDHCP_SHARED) += common.c options.c packet.c pidfile.c \ |
48 | UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c script.c | 38 | signalpipe.c socket.c |
49 | UDHCP-$(CONFIG_UDHCPD) += dhcpd.c arpping.c files.c leases.c serverpacket.c | 39 | UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c clientsocket.c \ |
40 | script.c | ||
41 | UDHCP-$(CONFIG_UDHCPD) += dhcpd.c arpping.c files.c leases.c \ | ||
42 | serverpacket.c | ||
50 | UDHCP-$(CONFIG_DUMPLEASES) += dumpleases.c | 43 | UDHCP-$(CONFIG_DUMPLEASES) += dumpleases.c |
51 | UDHCP-$(CONFIG_UDHCP_LEASES_FILE) += leases_file.c | ||
52 | UDHCP_OBJS=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y)) | 44 | UDHCP_OBJS=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y)) |
53 | 45 | ||
54 | libraries-y+=$(UDHCP_DIR)$(UDHCP_AR) | 46 | libraries-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 | ||
12 | The Makefile contains three of the compile time options: | 12 | The 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 | ||
23 | dhcpd.h contains the other two compile time options: | 24 | dhcpd.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 @@ | |||
1 | TODO | 1 | TODO |
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 | |||
41 | int 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 | |||
5 | int 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 | ||
34 | static int daemonized; | 38 | static 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 | */ | ||
46 | static 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 | |||
55 | void 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 | ||
38 | void udhcp_logging(int level, const char *fmt, ...) | 76 | void 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 | ||
56 | void start_log(const char *client_server) | 91 | |
92 | void 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 | |||
64 | static char *syslog_level_msg[] = { | 114 | static 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 | |||
74 | void udhcp_logging(int level, const char *fmt, ...) | 125 | void 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 | ||
90 | void start_log(const char *client_server) | 138 | |
139 | void 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 | ||
96 | static const char *saved_pidfile; | 143 | /* Make sure our syslog fd isn't overwritten */ |
144 | sanitize_fds(); | ||
97 | 145 | ||
98 | static 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 | ||
103 | void 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); |
141 | int udhcp_signal_pipe[2]; | ||
142 | static 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 | ||
149 | void 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 |
25 | enum syslog_levels { | 29 | enum 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 | ||
38 | void start_log(const char *client_server); | 42 | void background(const char *pidfile); |
43 | void start_log_and_pid(const char *client_server, const char *pidfile); | ||
39 | void background(const char *pidfile); | 44 | void background(const char *pidfile); |
40 | void udhcp_logging(int level, const char *fmt, ...); | 45 | void udhcp_logging(int level, const char *fmt, ...); |
41 | 46 | ||
42 | extern int udhcp_signal_pipe[2]; | ||
43 | void 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 | ||
45 | static int state; | 47 | static int state; |
46 | static unsigned long requested_ip; /* = 0 */ | 48 | static unsigned long requested_ip; /* = 0 */ |
@@ -54,12 +56,6 @@ static int fd = -1; | |||
54 | #define LISTEN_RAW 2 | 56 | #define LISTEN_RAW 2 |
55 | static int listen_mode; | 57 | static 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 | |||
63 | struct client_config_t client_config = { | 59 | struct 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 |
79 | static void __attribute__ ((noreturn)) show_usage(void) | 75 | static 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 | ||
180 | int udhcpc_main(int argc, char *argv[]) | 177 | int udhcpc_main(int argc, char *argv[]) |
178 | #else | ||
179 | int 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; | |||
50 | struct server_config_t server_config; | 51 | struct server_config_t server_config; |
51 | 52 | ||
52 | 53 | ||
54 | #ifdef COMBINED_BINARY | ||
53 | int udhcpd_main(int argc, char *argv[]) | 55 | int udhcpd_main(int argc, char *argv[]) |
56 | #else | ||
57 | int 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 */ |
20 | static int read_ip(const char *line, void *arg) | 27 | static 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 */ |
72 | static int read_opt(const char *const_line, void *arg) | 78 | static 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 | ||
156 | static const struct config_keyword keywords[] = { | 154 | static 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[] = { | |||
181 | int read_config(const char *file) | 179 | int 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... */ |
122 | u_int32_t find_address(int check_expired) | 123 | u_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 | ||
12 | extern const char leases_file[]; | ||
13 | |||
14 | extern unsigned char blank_chaddr[]; | 12 | extern unsigned char blank_chaddr[]; |
15 | 13 | ||
16 | void clear_lease(u_int8_t *chaddr, u_int32_t yiaddr); | 14 | void clear_lease(u_int8_t *chaddr, u_int32_t yiaddr); |
diff --git a/networking/udhcp/leases_file.c b/networking/udhcp/leases_file.c deleted file mode 100644 index 96e2f2d1b..000000000 --- a/networking/udhcp/leases_file.c +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | const 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 | |||
41 | static inline FILE *xfopen(const char *file, const char *mode) | 41 | static 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 | |||
32 | static char *saved_pidfile; | ||
33 | |||
34 | static void pidfile_delete(void) | ||
35 | { | ||
36 | if (saved_pidfile) unlink(saved_pidfile); | ||
37 | } | ||
38 | |||
39 | |||
40 | int 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 | |||
59 | void 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 | |||
23 | int pidfile_acquire(const char *pidfile); | ||
24 | void 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 | ||
59 | static int sprintip(char *dest, unsigned char *ip) | 58 | static 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 | |||
64 | static 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 | ||
141 | static 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 */ |
151 | static char **fill_envp(struct dhcpMessage *packet) | 136 | static 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 | |||
32 | static int signal_pipe[2]; | ||
33 | |||
34 | static 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 */ | ||
43 | void 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 */ | ||
55 | int 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 */ | ||
67 | int 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 | |||
20 | void udhcp_sp_setup(void); | ||
21 | int udhcp_sp_fd_set(fd_set *rfds, int extra_fd); | ||
22 | int 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 | |||
135 | int 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 | ||
5 | int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp); | 5 | int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp); |
6 | int listen_socket(unsigned int ip, int port, char *inf); | 6 | int listen_socket(unsigned int ip, int port, char *inf); |
7 | int raw_socket(int ifindex); | ||
8 | 7 | ||
9 | #endif | 8 | #endif |