diff options
Diffstat (limited to 'networking/udhcp/dhcpc.c')
-rw-r--r-- | networking/udhcp/dhcpc.c | 120 |
1 files changed, 22 insertions, 98 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index c97e422e2..4612c4100 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -19,9 +19,7 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <stdio.h> | ||
23 | #include <sys/time.h> | 22 | #include <sys/time.h> |
24 | #include <sys/types.h> | ||
25 | #include <sys/file.h> | 23 | #include <sys/file.h> |
26 | #include <unistd.h> | 24 | #include <unistd.h> |
27 | #include <getopt.h> | 25 | #include <getopt.h> |
@@ -40,11 +38,9 @@ | |||
40 | #include "dhcpc.h" | 38 | #include "dhcpc.h" |
41 | #include "options.h" | 39 | #include "options.h" |
42 | #include "clientpacket.h" | 40 | #include "clientpacket.h" |
43 | #include "packet.h" | ||
44 | #include "script.h" | 41 | #include "script.h" |
45 | #include "socket.h" | 42 | #include "socket.h" |
46 | #include "debug.h" | 43 | #include "common.h" |
47 | #include "pidfile.h" | ||
48 | 44 | ||
49 | static int state; | 45 | static int state; |
50 | static unsigned long requested_ip; /* = 0 */ | 46 | static unsigned long requested_ip; /* = 0 */ |
@@ -52,7 +48,6 @@ static unsigned long server_addr; | |||
52 | static unsigned long timeout; | 48 | static unsigned long timeout; |
53 | static int packet_num; /* = 0 */ | 49 | static int packet_num; /* = 0 */ |
54 | static int fd = -1; | 50 | static int fd = -1; |
55 | static int signal_pipe[2]; | ||
56 | 51 | ||
57 | #define LISTEN_NONE 0 | 52 | #define LISTEN_NONE 0 |
58 | #define LISTEN_KERNEL 1 | 53 | #define LISTEN_KERNEL 1 |
@@ -80,34 +75,6 @@ struct client_config_t client_config = { | |||
80 | arp: "\0\0\0\0\0\0", /* appease gcc-3.0 */ | 75 | arp: "\0\0\0\0\0\0", /* appease gcc-3.0 */ |
81 | }; | 76 | }; |
82 | 77 | ||
83 | #ifndef IN_BUSYBOX | ||
84 | static void __attribute__ ((noreturn)) bb_show_usage(void) | ||
85 | { | ||
86 | printf( | ||
87 | "Usage: udhcpc [OPTIONS]\n\n" | ||
88 | " -c, --clientid=CLIENTID Client identifier\n" | ||
89 | " -H, --hostname=HOSTNAME Client hostname\n" | ||
90 | " -h Alias for -H\n" | ||
91 | " -f, --foreground Do not fork after getting lease\n" | ||
92 | " -b, --background Fork to background if lease cannot be\n" | ||
93 | " immediately negotiated.\n" | ||
94 | " -i, --interface=INTERFACE Interface to use (default: eth0)\n" | ||
95 | " -n, --now Exit with failure if lease cannot be\n" | ||
96 | " immediately negotiated.\n" | ||
97 | " -p, --pidfile=file Store process ID of daemon in file\n" | ||
98 | " -q, --quit Quit after obtaining lease\n" | ||
99 | " -r, --request=IP IP address to request (default: none)\n" | ||
100 | " -s, --script=file Run file at dhcp events (default:\n" | ||
101 | " " DEFAULT_SCRIPT ")\n" | ||
102 | " -v, --version Display version\n" | ||
103 | ); | ||
104 | exit(0); | ||
105 | } | ||
106 | #else | ||
107 | extern void bb_show_usage(void) __attribute__ ((noreturn)); | ||
108 | #endif | ||
109 | |||
110 | |||
111 | /* just a little helper */ | 78 | /* just a little helper */ |
112 | static void change_mode(int new_mode) | 79 | static void change_mode(int new_mode) |
113 | { | 80 | { |
@@ -172,46 +139,15 @@ static void perform_release(void) | |||
172 | } | 139 | } |
173 | 140 | ||
174 | 141 | ||
175 | /* Exit and cleanup */ | 142 | static void client_background(void) |
176 | static void exit_client(int retval) | ||
177 | { | ||
178 | pidfile_delete(client_config.pidfile); | ||
179 | CLOSE_LOG(); | ||
180 | exit(retval); | ||
181 | } | ||
182 | |||
183 | |||
184 | /* Signal handler */ | ||
185 | static void signal_handler(int sig) | ||
186 | { | ||
187 | if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) { | ||
188 | LOG(LOG_ERR, "Could not send signal: %s", | ||
189 | strerror(errno)); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | |||
194 | static void background(void) | ||
195 | { | 143 | { |
196 | int pid_fd; | 144 | background(client_config.pidfile); |
197 | |||
198 | pid_fd = pidfile_acquire(client_config.pidfile); /* hold lock during fork. */ | ||
199 | while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */ | ||
200 | if (daemon(0, 0) == -1) { | ||
201 | perror("fork"); | ||
202 | exit_client(1); | ||
203 | } | ||
204 | client_config.foreground = 1; /* Do not fork again. */ | 145 | client_config.foreground = 1; /* Do not fork again. */ |
205 | client_config.background_if_no_lease = 0; | 146 | client_config.background_if_no_lease = 0; |
206 | pidfile_write_release(pid_fd); | ||
207 | } | 147 | } |
208 | 148 | ||
209 | 149 | ||
210 | #ifdef COMBINED_BINARY | ||
211 | int udhcpc_main(int argc, char *argv[]) | 150 | int udhcpc_main(int argc, char *argv[]) |
212 | #else | ||
213 | int main(int argc, char *argv[]) | ||
214 | #endif | ||
215 | { | 151 | { |
216 | unsigned char *temp, *message; | 152 | unsigned char *temp, *message; |
217 | unsigned long t1 = 0, t2 = 0, xid = 0; | 153 | unsigned long t1 = 0, t2 = 0, xid = 0; |
@@ -222,12 +158,11 @@ int main(int argc, char *argv[]) | |||
222 | int c, len; | 158 | int c, len; |
223 | struct dhcpMessage packet; | 159 | struct dhcpMessage packet; |
224 | struct in_addr temp_addr; | 160 | struct in_addr temp_addr; |
225 | int pid_fd; | ||
226 | time_t now; | 161 | time_t now; |
227 | int max_fd; | 162 | int max_fd; |
228 | int sig; | 163 | int sig; |
229 | 164 | ||
230 | static struct option arg_options[] = { | 165 | static const struct option arg_options[] = { |
231 | {"clientid", required_argument, 0, 'c'}, | 166 | {"clientid", required_argument, 0, 'c'}, |
232 | {"foreground", no_argument, 0, 'f'}, | 167 | {"foreground", no_argument, 0, 'f'}, |
233 | {"background", no_argument, 0, 'b'}, | 168 | {"background", no_argument, 0, 'b'}, |
@@ -240,7 +175,6 @@ int main(int argc, char *argv[]) | |||
240 | {"request", required_argument, 0, 'r'}, | 175 | {"request", required_argument, 0, 'r'}, |
241 | {"script", required_argument, 0, 's'}, | 176 | {"script", required_argument, 0, 's'}, |
242 | {"version", no_argument, 0, 'v'}, | 177 | {"version", no_argument, 0, 'v'}, |
243 | {"help", no_argument, 0, '?'}, | ||
244 | {0, 0, 0, 0} | 178 | {0, 0, 0, 0} |
245 | }; | 179 | }; |
246 | 180 | ||
@@ -294,23 +228,18 @@ int main(int argc, char *argv[]) | |||
294 | client_config.script = optarg; | 228 | client_config.script = optarg; |
295 | break; | 229 | break; |
296 | case 'v': | 230 | case 'v': |
297 | printf("udhcpcd, version %s\n\n", VERSION); | 231 | bb_error_msg("version %s\n", VERSION); |
298 | exit_client(0); | 232 | return(0); |
299 | break; | 233 | break; |
300 | default: | 234 | default: |
301 | bb_show_usage(); | 235 | bb_show_usage(); |
302 | } | 236 | } |
303 | } | 237 | } |
304 | 238 | ||
305 | OPEN_LOG("udhcpc"); | 239 | start_log("client"); |
306 | LOG(LOG_INFO, "udhcp client (v%s) started", VERSION); | ||
307 | |||
308 | pid_fd = pidfile_acquire(client_config.pidfile); | ||
309 | pidfile_write_release(pid_fd); | ||
310 | |||
311 | if (read_interface(client_config.interface, &client_config.ifindex, | 240 | if (read_interface(client_config.interface, &client_config.ifindex, |
312 | NULL, client_config.arp) < 0) | 241 | NULL, client_config.arp) < 0) |
313 | exit_client(1); | 242 | return(1); |
314 | 243 | ||
315 | if (!client_config.clientid) { | 244 | if (!client_config.clientid) { |
316 | client_config.clientid = xmalloc(6 + 3); | 245 | client_config.clientid = xmalloc(6 + 3); |
@@ -321,10 +250,7 @@ int main(int argc, char *argv[]) | |||
321 | } | 250 | } |
322 | 251 | ||
323 | /* setup signal handlers */ | 252 | /* setup signal handlers */ |
324 | socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe); | 253 | udhcp_set_signal_pipe(SIGUSR2); |
325 | signal(SIGUSR1, signal_handler); | ||
326 | signal(SIGUSR2, signal_handler); | ||
327 | signal(SIGTERM, signal_handler); | ||
328 | 254 | ||
329 | state = INIT_SELECTING; | 255 | state = INIT_SELECTING; |
330 | run_script(NULL, "deconfig"); | 256 | run_script(NULL, "deconfig"); |
@@ -342,16 +268,16 @@ int main(int argc, char *argv[]) | |||
342 | else | 268 | else |
343 | fd = raw_socket(client_config.ifindex); | 269 | fd = raw_socket(client_config.ifindex); |
344 | if (fd < 0) { | 270 | if (fd < 0) { |
345 | LOG(LOG_ERR, "FATAL: couldn't listen on socket, %s", strerror(errno)); | 271 | LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m"); |
346 | exit_client(0); | 272 | return(0); |
347 | } | 273 | } |
348 | } | 274 | } |
349 | if (fd >= 0) FD_SET(fd, &rfds); | 275 | if (fd >= 0) FD_SET(fd, &rfds); |
350 | FD_SET(signal_pipe[0], &rfds); | 276 | FD_SET(udhcp_signal_pipe[0], &rfds); |
351 | 277 | ||
352 | if (tv.tv_sec > 0) { | 278 | if (tv.tv_sec > 0) { |
353 | DEBUG(LOG_INFO, "Waiting on select...\n"); | 279 | DEBUG(LOG_INFO, "Waiting on select...\n"); |
354 | max_fd = signal_pipe[0] > fd ? signal_pipe[0] : fd; | 280 | max_fd = udhcp_signal_pipe[0] > fd ? udhcp_signal_pipe[0] : fd; |
355 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); | 281 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); |
356 | } else retval = 0; /* If we already timed out, fall through */ | 282 | } else retval = 0; /* If we already timed out, fall through */ |
357 | 283 | ||
@@ -372,10 +298,10 @@ int main(int argc, char *argv[]) | |||
372 | } else { | 298 | } else { |
373 | if (client_config.background_if_no_lease) { | 299 | if (client_config.background_if_no_lease) { |
374 | LOG(LOG_INFO, "No lease, forking to background."); | 300 | LOG(LOG_INFO, "No lease, forking to background."); |
375 | background(); | 301 | client_background(); |
376 | } else if (client_config.abort_if_no_lease) { | 302 | } else if (client_config.abort_if_no_lease) { |
377 | LOG(LOG_INFO, "No lease, failing."); | 303 | LOG(LOG_INFO, "No lease, failing."); |
378 | exit_client(1); | 304 | return(1); |
379 | } | 305 | } |
380 | /* wait to try again */ | 306 | /* wait to try again */ |
381 | packet_num = 0; | 307 | packet_num = 0; |
@@ -453,7 +379,7 @@ int main(int argc, char *argv[]) | |||
453 | else len = get_raw_packet(&packet, fd); | 379 | else len = get_raw_packet(&packet, fd); |
454 | 380 | ||
455 | if (len == -1 && errno != EINTR) { | 381 | if (len == -1 && errno != EINTR) { |
456 | DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno)); | 382 | DEBUG(LOG_INFO, "error on read, %m, reopening socket"); |
457 | change_mode(listen_mode); /* just close and reopen */ | 383 | change_mode(listen_mode); /* just close and reopen */ |
458 | } | 384 | } |
459 | if (len < 0) continue; | 385 | if (len < 0) continue; |
@@ -517,9 +443,9 @@ int main(int argc, char *argv[]) | |||
517 | state = BOUND; | 443 | state = BOUND; |
518 | change_mode(LISTEN_NONE); | 444 | change_mode(LISTEN_NONE); |
519 | if (client_config.quit_after_lease) | 445 | if (client_config.quit_after_lease) |
520 | exit_client(0); | 446 | return(0); |
521 | if (!client_config.foreground) | 447 | if (!client_config.foreground) |
522 | background(); | 448 | client_background(); |
523 | 449 | ||
524 | } else if (*message == DHCPNAK) { | 450 | } else if (*message == DHCPNAK) { |
525 | /* return to init state */ | 451 | /* return to init state */ |
@@ -537,10 +463,9 @@ int main(int argc, char *argv[]) | |||
537 | break; | 463 | break; |
538 | /* case BOUND, RELEASED: - ignore all packets */ | 464 | /* case BOUND, RELEASED: - ignore all packets */ |
539 | } | 465 | } |
540 | } else if (retval > 0 && FD_ISSET(signal_pipe[0], &rfds)) { | 466 | } else if (retval > 0 && FD_ISSET(udhcp_signal_pipe[0], &rfds)) { |
541 | if (read(signal_pipe[0], &sig, sizeof(sig)) < 0) { | 467 | if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0) { |
542 | DEBUG(LOG_ERR, "Could not read signal: %s", | 468 | DEBUG(LOG_ERR, "Could not read signal: %m"); |
543 | strerror(errno)); | ||
544 | continue; /* probably just EINTR */ | 469 | continue; /* probably just EINTR */ |
545 | } | 470 | } |
546 | switch (sig) { | 471 | switch (sig) { |
@@ -552,7 +477,7 @@ int main(int argc, char *argv[]) | |||
552 | break; | 477 | break; |
553 | case SIGTERM: | 478 | case SIGTERM: |
554 | LOG(LOG_INFO, "Received SIGTERM"); | 479 | LOG(LOG_INFO, "Received SIGTERM"); |
555 | exit_client(0); | 480 | return(0); |
556 | } | 481 | } |
557 | } else if (retval == -1 && errno == EINTR) { | 482 | } else if (retval == -1 && errno == EINTR) { |
558 | /* a signal was caught */ | 483 | /* a signal was caught */ |
@@ -564,4 +489,3 @@ int main(int argc, char *argv[]) | |||
564 | } | 489 | } |
565 | return 0; | 490 | return 0; |
566 | } | 491 | } |
567 | |||