diff options
-rw-r--r-- | networking/udhcp/Kbuild | 4 | ||||
-rw-r--r-- | networking/udhcp/common.c | 60 | ||||
-rw-r--r-- | networking/udhcp/common.h | 8 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 21 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 78 |
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 | ||
8 | lib-y:= | 8 | lib-y:= |
9 | lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \ | 9 | lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o \ |
10 | signalpipe.o socket.o | 10 | signalpipe.o socket.o |
11 | lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \ | 11 | lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o \ |
12 | signalpipe.o socket.o | 12 | signalpipe.o socket.o |
13 | lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \ | 13 | lib-$(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 | ||
25 | void udhcp_background(const char *pidfile) | 25 | |
26 | static const char *saved_pidfile; | ||
27 | |||
28 | static void pidfile_delete(void) | ||
29 | { | ||
30 | if (saved_pidfile) | ||
31 | unlink(saved_pidfile); | ||
32 | } | ||
33 | |||
34 | static 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 | |||
52 | static 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 | ||
41 | void udhcp_start_log_and_pid(const char *pidfile) | 61 | |
62 | void 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 | ||
63 | void udhcp_background(const char *pidfile); | 63 | void udhcp_make_pidfile(const char *pidfile); |
64 | void udhcp_start_log_and_pid(const char *pidfile); | ||
65 | 64 | ||
66 | void udhcp_run_script(struct dhcpMessage *packet, const char *name); | 65 | void 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); | |||
91 | int raw_socket(int ifindex); | 87 | int raw_socket(int ifindex); |
92 | int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t *arp); | 88 | int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t *arp); |
93 | int listen_socket(uint32_t ip, int port, const char *inf); | 89 | int listen_socket(uint32_t ip, int port, const char *inf); |
94 | int pidfile_acquire(const char *pidfile); | ||
95 | void pidfile_write_release(int pid_fd); | ||
96 | int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface); | 90 | int 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 | ||
104 | static void client_background(void) | 105 | static 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: |