aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/udhcp/Kbuild4
-rw-r--r--networking/udhcp/common.c60
-rw-r--r--networking/udhcp/common.h8
-rw-r--r--networking/udhcp/dhcpc.c21
-rw-r--r--networking/udhcp/dhcpd.c78
5 files changed, 105 insertions, 66 deletions
diff --git a/networking/udhcp/Kbuild b/networking/udhcp/Kbuild
index 57d2511f0..aed40b98c 100644
--- a/networking/udhcp/Kbuild
+++ b/networking/udhcp/Kbuild
@@ -6,9 +6,9 @@
6# 6#
7 7
8lib-y:= 8lib-y:=
9lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \ 9lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o \
10 signalpipe.o socket.o 10 signalpipe.o socket.o
11lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \ 11lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o \
12 signalpipe.o socket.o 12 signalpipe.o socket.o
13lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \ 13lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \
14 script.o 14 script.o
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index 3704ba71a..7b2e19c42 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -22,40 +22,56 @@ long uptime(void)
22 return info.uptime; 22 return info.uptime;
23} 23}
24 24
25void udhcp_background(const char *pidfile) 25
26static const char *saved_pidfile;
27
28static void pidfile_delete(void)
29{
30 if (saved_pidfile)
31 unlink(saved_pidfile);
32}
33
34static int pidfile_acquire(const char *pidfile)
26{ 35{
27#ifdef __uClinux__
28 bb_error_msg("cannot background in uclinux (yet)");
29#else /* __uClinux__ */
30 int pid_fd; 36 int pid_fd;
37 if (!pidfile) return -1;
31 38
32 /* hold lock during fork. */ 39 pid_fd = open(pidfile, O_CREAT|O_WRONLY|O_TRUNC, 0644);
33 pid_fd = pidfile_acquire(pidfile); 40 if (pid_fd < 0) {
34 setsid(); 41 bb_perror_msg("cannot open pidfile %s", pidfile);
35 xdaemon(0, 0); 42 } else {
36 logmode &= ~LOGMODE_STDIO; 43 /* lockf(pid_fd, F_LOCK, 0); */
37 pidfile_write_release(pid_fd); 44 if (!saved_pidfile)
38#endif /* __uClinux__ */ 45 atexit(pidfile_delete);
46 saved_pidfile = pidfile;
47 }
48
49 return pid_fd;
50}
51
52static void pidfile_write_release(int pid_fd)
53{
54 if (pid_fd < 0) return;
55
56 fdprintf(pid_fd, "%d\n", getpid());
57 /* lockf(pid_fd, F_UNLCK, 0); */
58 close(pid_fd);
39} 59}
40 60
41void udhcp_start_log_and_pid(const char *pidfile) 61
62void udhcp_make_pidfile(const char *pidfile)
42{ 63{
43 int pid_fd; 64 int pid_fd;
44 65
45 /* Make sure our syslog fd isn't overwritten */ 66 /* Make sure fd 0,1,2 are open */
46 bb_sanitize_stdio(); 67 bb_sanitize_stdio();
47 68
48 /* do some other misc startup stuff while we are here to save bytes */ 69 /* Equivalent of doing a fflush after every \n */
49 pid_fd = pidfile_acquire(pidfile);
50 pidfile_write_release(pid_fd);
51
52 /* equivelent of doing a fflush after every \n */
53 setlinebuf(stdout); 70 setlinebuf(stdout);
54 71
55 if (ENABLE_FEATURE_UDHCP_SYSLOG) { 72 /* Create pidfile */
56 openlog(applet_name, LOG_PID, LOG_LOCAL0); 73 pid_fd = pidfile_acquire(pidfile);
57 logmode |= LOGMODE_SYSLOG; 74 pidfile_write_release(pid_fd);
58 }
59 75
60 bb_info_msg("%s (v%s) started", applet_name, BB_VER); 76 bb_info_msg("%s (v%s) started", applet_name, BB_VER);
61} 77}
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index a80691b4a..00890ac1c 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -60,16 +60,12 @@ int udhcp_kernel_packet(struct dhcpMessage *payload,
60 60
61/**/ 61/**/
62 62
63void udhcp_background(const char *pidfile); 63void udhcp_make_pidfile(const char *pidfile);
64void udhcp_start_log_and_pid(const char *pidfile);
65 64
66void udhcp_run_script(struct dhcpMessage *packet, const char *name); 65void udhcp_run_script(struct dhcpMessage *packet, const char *name);
67 66
68// Still need to clean these up... 67// Still need to clean these up...
69 68
70/* from pidfile.h */
71#define pidfile_acquire udhcp_pidfile_acquire
72#define pidfile_write_release udhcp_pidfile_write_release
73/* from options.h */ 69/* from options.h */
74#define get_option udhcp_get_option 70#define get_option udhcp_get_option
75#define end_option udhcp_end_option 71#define end_option udhcp_end_option
@@ -91,8 +87,6 @@ int udhcp_sp_read(fd_set *rfds);
91int raw_socket(int ifindex); 87int raw_socket(int ifindex);
92int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t *arp); 88int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t *arp);
93int listen_socket(uint32_t ip, int port, const char *inf); 89int listen_socket(uint32_t ip, int port, const char *inf);
94int pidfile_acquire(const char *pidfile);
95void pidfile_write_release(int pid_fd);
96int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface); 90int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface);
97 91
98#if ENABLE_FEATURE_UDHCP_DEBUG 92#if ENABLE_FEATURE_UDHCP_DEBUG
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index a59c5db74..dc10386d5 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <getopt.h> 11#include <getopt.h>
12#include <syslog.h>
12 13
13#include "common.h" 14#include "common.h"
14#include "dhcpd.h" 15#include "dhcpd.h"
@@ -103,7 +104,16 @@ static void perform_release(void)
103 104
104static void client_background(void) 105static void client_background(void)
105{ 106{
106 udhcp_background(client_config.pidfile); 107#ifdef __uClinux__
108 bb_error_msg("cannot background in uclinux (yet)");
109/* ... mainly because udhcpc calls client_background()
110 * in _the _middle _of _udhcpc _run_, not at the start!
111 * If that will be properly disabled for NOMMU, client_background()
112 * will work on NOMMU too */
113#else
114 bb_daemonize(DAEMON_CHDIR_ROOT);
115 logmode &= ~LOGMODE_STDIO;
116#endif
107 client_config.foreground = 1; /* Do not fork again. */ 117 client_config.foreground = 1; /* Do not fork again. */
108 client_config.background_if_no_lease = 0; 118 client_config.background_if_no_lease = 0;
109} 119}
@@ -246,13 +256,18 @@ int udhcpc_main(int argc, char *argv[])
246 return 0; 256 return 0;
247 } 257 }
248 258
249 /* Start the log, sanitize fd's, and write a pid file */ 259 if (ENABLE_FEATURE_UDHCP_SYSLOG) {
250 udhcp_start_log_and_pid(client_config.pidfile); 260 openlog(applet_name, LOG_PID, LOG_LOCAL0);
261 logmode |= LOGMODE_SYSLOG;
262 }
251 263
252 if (read_interface(client_config.interface, &client_config.ifindex, 264 if (read_interface(client_config.interface, &client_config.ifindex,
253 NULL, client_config.arp) < 0) 265 NULL, client_config.arp) < 0)
254 return 1; 266 return 1;
255 267
268 /* Sanitize fd's and write pidfile */
269 udhcp_make_pidfile(client_config.pidfile);
270
256 /* if not set, and not suppressed, setup the default client ID */ 271 /* if not set, and not suppressed, setup the default client ID */
257 if (!client_config.clientid && !no_clientid) { 272 if (!client_config.clientid && !no_clientid) {
258 client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); 273 client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 90d8f0d17..ef9aa584e 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -10,6 +10,7 @@
10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
11 */ 11 */
12 12
13#include <syslog.h>
13#include "common.h" 14#include "common.h"
14#include "dhcpd.h" 15#include "dhcpd.h"
15#include "options.h" 16#include "options.h"
@@ -33,16 +34,30 @@ int udhcpd_main(int argc, char *argv[])
33 struct option_set *option; 34 struct option_set *option;
34 struct dhcpOfferedAddr *lease, static_lease; 35 struct dhcpOfferedAddr *lease, static_lease;
35 36
37//Huh, dhcpd don't have --foreground, --syslog options?? TODO
38
39 if (!ENABLE_FEATURE_UDHCP_DEBUG) {
40 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
41 logmode &= ~LOGMODE_STDIO;
42 }
43
44 if (ENABLE_FEATURE_UDHCP_SYSLOG) {
45 openlog(applet_name, LOG_PID, LOG_LOCAL0);
46 logmode |= LOGMODE_SYSLOG;
47 }
48
49 /* Would rather not do read_config before daemonization -
50 * otherwise NOMMU machines will parse config twice */
36 read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]); 51 read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
37 52
38 /* Start the log, sanitize fd's, and write a pid file */ 53 udhcp_make_pidfile(server_config.pidfile);
39 udhcp_start_log_and_pid(server_config.pidfile);
40 54
41 if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) { 55 option = find_option(server_config.options, DHCP_LEASE_TIME);
56 if (option) {
42 memcpy(&server_config.lease, option->data + 2, 4); 57 memcpy(&server_config.lease, option->data + 2, 4);
43 server_config.lease = ntohl(server_config.lease); 58 server_config.lease = ntohl(server_config.lease);
44 } 59 } else
45 else server_config.lease = LEASE_TIME; 60 server_config.lease = LEASE_TIME;
46 61
47 /* Sanity check */ 62 /* Sanity check */
48 num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1; 63 num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
@@ -60,9 +75,6 @@ int udhcpd_main(int argc, char *argv[])
60 &server_config.server, server_config.arp) < 0) 75 &server_config.server, server_config.arp) < 0)
61 return 1; 76 return 1;
62 77
63 if (!ENABLE_FEATURE_UDHCP_DEBUG)
64 udhcp_background(server_config.pidfile); /* hold lock during fork. */
65
66 /* Setup the signal pipe */ 78 /* Setup the signal pipe */
67 udhcp_sp_setup(); 79 udhcp_sp_setup();
68 80
@@ -106,7 +118,8 @@ int udhcpd_main(int argc, char *argv[])
106 default: continue; /* signal or error (probably EINTR) */ 118 default: continue; /* signal or error (probably EINTR) */
107 } 119 }
108 120
109 if ((bytes = udhcp_get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */ 121 bytes = udhcp_get_packet(&packet, server_socket); /* this waits for a packet - idle */
122 if (bytes < 0) {
110 if (bytes == -1 && errno != EINTR) { 123 if (bytes == -1 && errno != EINTR) {
111 DEBUG("error on read, %s, reopening socket", strerror(errno)); 124 DEBUG("error on read, %s, reopening socket", strerror(errno));
112 close(server_socket); 125 close(server_socket);
@@ -115,7 +128,8 @@ int udhcpd_main(int argc, char *argv[])
115 continue; 128 continue;
116 } 129 }
117 130
118 if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) { 131 state = get_option(&packet, DHCP_MESSAGE_TYPE);
132 if (state == NULL) {
119 bb_error_msg("cannot get option from packet, ignoring"); 133 bb_error_msg("cannot get option from packet, ignoring");
120 continue; 134 continue;
121 } 135 }
@@ -131,7 +145,6 @@ int udhcpd_main(int argc, char *argv[])
131 static_lease.expires = 0; 145 static_lease.expires = 0;
132 146
133 lease = &static_lease; 147 lease = &static_lease;
134
135 } else { 148 } else {
136 lease = find_lease_by_chaddr(packet.chaddr); 149 lease = find_lease_by_chaddr(packet.chaddr);
137 } 150 }
@@ -157,25 +170,23 @@ int udhcpd_main(int argc, char *argv[])
157 if (server_id) { 170 if (server_id) {
158 /* SELECTING State */ 171 /* SELECTING State */
159 DEBUG("server_id = %08x", ntohl(server_id_align)); 172 DEBUG("server_id = %08x", ntohl(server_id_align));
160 if (server_id_align == server_config.server && requested && 173 if (server_id_align == server_config.server && requested
161 requested_align == lease->yiaddr) { 174 && requested_align == lease->yiaddr
175 ) {
162 sendACK(&packet, lease->yiaddr); 176 sendACK(&packet, lease->yiaddr);
163 } 177 }
178 } else if (requested) {
179 /* INIT-REBOOT State */
180 if (lease->yiaddr == requested_align)
181 sendACK(&packet, lease->yiaddr);
182 else
183 sendNAK(&packet);
184 } else if (lease->yiaddr == packet.ciaddr) {
185 /* RENEWING or REBINDING State */
186 sendACK(&packet, lease->yiaddr);
164 } else { 187 } else {
165 if (requested) { 188 /* don't know what to do!!!! */
166 /* INIT-REBOOT State */ 189 sendNAK(&packet);
167 if (lease->yiaddr == requested_align)
168 sendACK(&packet, lease->yiaddr);
169 else sendNAK(&packet);
170 } else {
171 /* RENEWING or REBINDING State */
172 if (lease->yiaddr == packet.ciaddr)
173 sendACK(&packet, lease->yiaddr);
174 else {
175 /* don't know what to do!!!! */
176 sendNAK(&packet);
177 }
178 }
179 } 190 }
180 191
181 /* what to do if we have no record of the client */ 192 /* what to do if we have no record of the client */
@@ -184,19 +195,22 @@ int udhcpd_main(int argc, char *argv[])
184 195
185 } else if (requested) { 196 } else if (requested) {
186 /* INIT-REBOOT State */ 197 /* INIT-REBOOT State */
187 if ((lease = find_lease_by_yiaddr(requested_align))) { 198 lease = find_lease_by_yiaddr(requested_align);
199 if (lease) {
188 if (lease_expired(lease)) { 200 if (lease_expired(lease)) {
189 /* probably best if we drop this lease */ 201 /* probably best if we drop this lease */
190 memset(lease->chaddr, 0, 16); 202 memset(lease->chaddr, 0, 16);
191 /* make some contention for this address */ 203 /* make some contention for this address */
192 } else sendNAK(&packet); 204 } else
193 } else if (requested_align < server_config.start || 205 sendNAK(&packet);
194 requested_align > server_config.end) { 206 } else if (requested_align < server_config.start
207 || requested_align > server_config.end
208 ) {
195 sendNAK(&packet); 209 sendNAK(&packet);
196 } /* else remain silent */ 210 } /* else remain silent */
197 211
198 } else { 212 } else {
199 /* RENEWING or REBINDING State */ 213 /* RENEWING or REBINDING State */
200 } 214 }
201 break; 215 break;
202 case DHCPDECLINE: 216 case DHCPDECLINE: