aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-06-17 13:24:03 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-06-17 13:24:03 +0200
commit6947d2c7e194e3be31eed1c75260e15fca1a2568 (patch)
treeff4d67b49e0e7e02e29ecc090db619a39b24498d
parent2b0e95780863da44f6a9244699ece8620a599e19 (diff)
downloadbusybox-w32-6947d2c7e194e3be31eed1c75260e15fca1a2568.tar.gz
busybox-w32-6947d2c7e194e3be31eed1c75260e15fca1a2568.tar.bz2
busybox-w32-6947d2c7e194e3be31eed1c75260e15fca1a2568.zip
udhcp: logging improvements, field and variable renames
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/arpping.c6
-rw-r--r--networking/udhcp/common.c2
-rw-r--r--networking/udhcp/common.h4
-rw-r--r--networking/udhcp/dhcpd.c68
-rw-r--r--networking/udhcp/dhcpd.h20
-rw-r--r--networking/udhcp/files.c18
-rw-r--r--networking/udhcp/leases.c58
-rw-r--r--networking/udhcp/options.c22
-rw-r--r--networking/udhcp/packet.c2
-rw-r--r--networking/udhcp/script.c4
-rw-r--r--networking/udhcp/serverpacket.c73
11 files changed, 143 insertions, 134 deletions
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c
index 47a7b1351..89400e296 100644
--- a/networking/udhcp/arpping.c
+++ b/networking/udhcp/arpping.c
@@ -41,7 +41,7 @@ enum {
41 41
42/* Returns 1 if no reply received */ 42/* Returns 1 if no reply received */
43 43
44int FAST_FUNC arpping(uint32_t test_ip, 44int FAST_FUNC arpping(uint32_t test_nip,
45 const uint8_t *safe_mac, 45 const uint8_t *safe_mac,
46 uint32_t from_ip, 46 uint32_t from_ip,
47 uint8_t *from_mac, 47 uint8_t *from_mac,
@@ -78,7 +78,7 @@ int FAST_FUNC arpping(uint32_t test_ip,
78 memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */ 78 memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */
79 memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */ 79 memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */
80 /* tHaddr is zero-filled */ /* target hardware address */ 80 /* tHaddr is zero-filled */ /* target hardware address */
81 memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */ 81 memcpy(arp.tInaddr, &test_nip, sizeof(test_nip));/* target IP address */
82 82
83 memset(&addr, 0, sizeof(addr)); 83 memset(&addr, 0, sizeof(addr));
84 safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data)); 84 safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));
@@ -111,7 +111,7 @@ int FAST_FUNC arpping(uint32_t test_ip,
111 && arp.operation == htons(ARPOP_REPLY) 111 && arp.operation == htons(ARPOP_REPLY)
112 /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */ 112 /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */
113 /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */ 113 /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */
114 && *((uint32_t *) arp.sInaddr) == test_ip 114 && *((uint32_t *) arp.sInaddr) == test_nip
115 ) { 115 ) {
116 /* if ARP source MAC matches safe_mac 116 /* if ARP source MAC matches safe_mac
117 * (which is client's MAC), then it's not a conflict 117 * (which is client's MAC), then it's not a conflict
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index c44f38239..4de29f258 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -6,7 +6,7 @@
6#include "common.h" 6#include "common.h"
7 7
8#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 8#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
9int dhcp_verbose; 9unsigned dhcp_verbose;
10#endif 10#endif
11 11
12const uint8_t MAC_BCAST_ADDR[6] ALIGN2 = { 12const uint8_t MAC_BCAST_ADDR[6] ALIGN2 = {
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index a01597f68..e88cfb1c7 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -93,14 +93,14 @@ int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uin
93int udhcp_raw_socket(int ifindex) FAST_FUNC; 93int udhcp_raw_socket(int ifindex) FAST_FUNC;
94int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC; 94int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC;
95/* Returns 1 if no reply received */ 95/* Returns 1 if no reply received */
96int arpping(uint32_t test_ip, 96int arpping(uint32_t test_nip,
97 const uint8_t *safe_mac, 97 const uint8_t *safe_mac,
98 uint32_t from_ip, 98 uint32_t from_ip,
99 uint8_t *from_mac, 99 uint8_t *from_mac,
100 const char *interface) FAST_FUNC; 100 const char *interface) FAST_FUNC;
101 101
102#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 102#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
103extern int dhcp_verbose; 103extern unsigned dhcp_verbose;
104# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) 104# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0)
105# if CONFIG_UDHCP_DEBUG >= 2 105# if CONFIG_UDHCP_DEBUG >= 2
106void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; 106void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 348246341..23292a55d 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -18,7 +18,7 @@
18 18
19 19
20/* globals */ 20/* globals */
21struct dyn_lease *leases; 21struct dyn_lease *g_leases;
22/* struct server_config_t server_config is in bb_common_bufsiz1 */ 22/* struct server_config_t server_config is in bb_common_bufsiz1 */
23 23
24 24
@@ -28,15 +28,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
28 fd_set rfds; 28 fd_set rfds;
29 int server_socket = -1, retval, max_sock; 29 int server_socket = -1, retval, max_sock;
30 struct dhcp_packet packet; 30 struct dhcp_packet packet;
31 uint8_t *state, *server_id, *requested; 31 uint8_t *state;
32 uint32_t server_id_aligned = server_id_aligned; /* for compiler */
33 uint32_t requested_aligned = requested_aligned;
34 uint32_t static_lease_ip; 32 uint32_t static_lease_ip;
35 unsigned timeout_end; 33 unsigned timeout_end;
36 unsigned num_ips; 34 unsigned num_ips;
37 unsigned opt; 35 unsigned opt;
38 struct option_set *option; 36 struct option_set *option;
39 struct dyn_lease *lease, static_lease; 37 struct dyn_lease *lease, fake_lease;
40 IF_FEATURE_UDHCP_PORT(char *str_P;) 38 IF_FEATURE_UDHCP_PORT(char *str_P;)
41 39
42#if ENABLE_FEATURE_UDHCP_PORT 40#if ENABLE_FEATURE_UDHCP_PORT
@@ -84,10 +82,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
84 bb_info_msg("%s (v"BB_VER") started", applet_name); 82 bb_info_msg("%s (v"BB_VER") started", applet_name);
85 83
86 option = find_option(server_config.options, DHCP_LEASE_TIME); 84 option = find_option(server_config.options, DHCP_LEASE_TIME);
87 server_config.lease = LEASE_TIME; 85 server_config.max_lease_sec = LEASE_TIME;
88 if (option) { 86 if (option) {
89 move_from_unaligned32(server_config.lease, option->data + 2); 87 move_from_unaligned32(server_config.max_lease_sec, option->data + OPT_DATA);
90 server_config.lease = ntohl(server_config.lease); 88 server_config.max_lease_sec = ntohl(server_config.max_lease_sec);
91 } 89 }
92 90
93 /* Sanity check */ 91 /* Sanity check */
@@ -98,7 +96,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
98 server_config.max_leases = num_ips; 96 server_config.max_leases = num_ips;
99 } 97 }
100 98
101 leases = xzalloc(server_config.max_leases * sizeof(*leases)); 99 g_leases = xzalloc(server_config.max_leases * sizeof(g_leases[0]));
102 read_leases(server_config.lease_file); 100 read_leases(server_config.lease_file);
103 101
104 if (udhcp_read_interface(server_config.interface, 102 if (udhcp_read_interface(server_config.interface,
@@ -186,13 +184,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
186 if (static_lease_ip) { 184 if (static_lease_ip) {
187 bb_info_msg("Found static lease: %x", static_lease_ip); 185 bb_info_msg("Found static lease: %x", static_lease_ip);
188 186
189 memcpy(&static_lease.lease_mac, &packet.chaddr, 6); 187 memcpy(&fake_lease.lease_mac, &packet.chaddr, 6);
190 static_lease.lease_nip = static_lease_ip; 188 fake_lease.lease_nip = static_lease_ip;
191 static_lease.expires = 0; 189 fake_lease.expires = 0;
192 190
193 lease = &static_lease; 191 lease = &fake_lease;
194 } else { 192 } else {
195 lease = find_lease_by_chaddr(packet.chaddr); 193 lease = find_lease_by_mac(packet.chaddr);
196 } 194 }
197 195
198 switch (state[0]) { 196 switch (state[0]) {
@@ -203,29 +201,32 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
203 bb_error_msg("send OFFER failed"); 201 bb_error_msg("send OFFER failed");
204 } 202 }
205 break; 203 break;
206 case DHCPREQUEST: 204 case DHCPREQUEST: {
207 log1("Received REQUEST"); 205 uint8_t *server_id_opt, *requested_opt;
206 uint32_t server_id_net = server_id_net; /* for compiler */
207 uint32_t requested_nip = requested_nip; /* for compiler */
208 208
209 requested = get_option(&packet, DHCP_REQUESTED_IP); 209 log1("Received REQUEST");
210 server_id = get_option(&packet, DHCP_SERVER_ID);
211 210
212 if (requested) 211 requested_opt = get_option(&packet, DHCP_REQUESTED_IP);
213 move_from_unaligned32(requested_aligned, requested); 212 server_id_opt = get_option(&packet, DHCP_SERVER_ID);
214 if (server_id) 213 if (requested_opt)
215 move_from_unaligned32(server_id_aligned, server_id); 214 move_from_unaligned32(requested_nip, requested_opt);
215 if (server_id_opt)
216 move_from_unaligned32(server_id_net, server_id_opt);
216 217
217 if (lease) { 218 if (lease) {
218 if (server_id) { 219 if (server_id_opt) {
219 /* SELECTING State */ 220 /* SELECTING State */
220 if (server_id_aligned == server_config.server_nip 221 if (server_id_net == server_config.server_nip
221 && requested 222 && requested_opt
222 && requested_aligned == lease->lease_nip 223 && requested_nip == lease->lease_nip
223 ) { 224 ) {
224 send_ACK(&packet, lease->lease_nip); 225 send_ACK(&packet, lease->lease_nip);
225 } 226 }
226 } else if (requested) { 227 } else if (requested_opt) {
227 /* INIT-REBOOT State */ 228 /* INIT-REBOOT State */
228 if (lease->lease_nip == requested_aligned) 229 if (lease->lease_nip == requested_nip)
229 send_ACK(&packet, lease->lease_nip); 230 send_ACK(&packet, lease->lease_nip);
230 else 231 else
231 send_NAK(&packet); 232 send_NAK(&packet);
@@ -237,14 +238,14 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
237 } 238 }
238 239
239 /* what to do if we have no record of the client */ 240 /* what to do if we have no record of the client */
240 } else if (server_id) { 241 } else if (server_id_opt) {
241 /* SELECTING State */ 242 /* SELECTING State */
242 243
243 } else if (requested) { 244 } else if (requested_opt) {
244 /* INIT-REBOOT State */ 245 /* INIT-REBOOT State */
245 lease = find_lease_by_yiaddr(requested_aligned); 246 lease = find_lease_by_nip(requested_nip);
246 if (lease) { 247 if (lease) {
247 if (lease_expired(lease)) { 248 if (is_expired_lease(lease)) {
248 /* probably best if we drop this lease */ 249 /* probably best if we drop this lease */
249 memset(lease->lease_mac, 0, sizeof(lease->lease_mac)); 250 memset(lease->lease_mac, 0, sizeof(lease->lease_mac));
250 } else { 251 } else {
@@ -252,7 +253,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
252 send_NAK(&packet); 253 send_NAK(&packet);
253 } 254 }
254 } else { 255 } else {
255 uint32_t r = ntohl(requested_aligned); 256 uint32_t r = ntohl(requested_nip);
256 if (r < server_config.start_ip 257 if (r < server_config.start_ip
257 || r > server_config.end_ip 258 || r > server_config.end_ip
258 ) { 259 ) {
@@ -265,6 +266,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
265 /* RENEWING or REBINDING State */ 266 /* RENEWING or REBINDING State */
266 } 267 }
267 break; 268 break;
269 }
268 case DHCPDECLINE: 270 case DHCPDECLINE:
269 log1("Received DECLINE"); 271 log1("Received DECLINE");
270 if (lease) { 272 if (lease) {
diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h
index 7776708cf..42a4b2782 100644
--- a/networking/udhcp/dhcpd.h
+++ b/networking/udhcp/dhcpd.h
@@ -46,15 +46,15 @@ struct server_config_t {
46 /* start,end are in host order: we need to compare start <= ip <= end */ 46 /* start,end are in host order: we need to compare start <= ip <= end */
47 uint32_t start_ip; /* start address of leases, in host order */ 47 uint32_t start_ip; /* start address of leases, in host order */
48 uint32_t end_ip; /* end of leases, in host order */ 48 uint32_t end_ip; /* end of leases, in host order */
49 uint32_t lease; /* lease time in seconds (host order) */ 49 uint32_t max_lease_sec; /* maximum lease time (host order) */
50 uint32_t max_leases; /* maximum number of leases (including reserved address) */ 50 uint32_t min_lease_sec; /* minimum lease time a client can request */
51 uint32_t max_leases; /* maximum number of leases (including reserved addresses) */
51 uint32_t auto_time; /* how long should udhcpd wait before writing a config file. 52 uint32_t auto_time; /* how long should udhcpd wait before writing a config file.
52 * if this is zero, it will only write one on SIGUSR1 */ 53 * if this is zero, it will only write one on SIGUSR1 */
53 uint32_t decline_time; /* how long an address is reserved if a client returns a 54 uint32_t decline_time; /* how long an address is reserved if a client returns a
54 * decline message */ 55 * decline message */
55 uint32_t conflict_time; /* how long an arp conflict offender is leased for */ 56 uint32_t conflict_time; /* how long an arp conflict offender is leased for */
56 uint32_t offer_time; /* how long an offered address is reserved */ 57 uint32_t offer_time; /* how long an offered address is reserved */
57 uint32_t min_lease; /* minimum lease time a client can request */
58 uint32_t siaddr_nip; /* "next server" bootp option */ 58 uint32_t siaddr_nip; /* "next server" bootp option */
59 char *lease_file; 59 char *lease_file;
60 char *pidfile; 60 char *pidfile;
@@ -89,24 +89,24 @@ struct dyn_lease {
89 /* We use lease_mac[6], since e.g. ARP probing uses 89 /* We use lease_mac[6], since e.g. ARP probing uses
90 * only 6 first bytes anyway. We check received dhcp packets 90 * only 6 first bytes anyway. We check received dhcp packets
91 * that their hlen == 6 and thus chaddr has only 6 significant bytes 91 * that their hlen == 6 and thus chaddr has only 6 significant bytes
92 * (dhcp packet has chaddr[16]) 92 * (dhcp packet has chaddr[16], not [6])
93 */ 93 */
94 uint8_t lease_mac[6]; 94 uint8_t lease_mac[6];
95 uint8_t hostname[20]; 95 uint8_t hostname[20];
96 uint8_t pad[2]; 96 uint8_t pad[2];
97 /* total size is a multiply of 4 */ 97 /* total size is a multiply of 4 */
98}; 98} PACKED;
99 99
100extern struct dyn_lease *leases; 100extern struct dyn_lease *g_leases;
101 101
102struct dyn_lease *add_lease( 102struct dyn_lease *add_lease(
103 const uint8_t *chaddr, uint32_t yiaddr, 103 const uint8_t *chaddr, uint32_t yiaddr,
104 leasetime_t leasetime, uint8_t *hostname 104 leasetime_t leasetime, uint8_t *hostname
105 ) FAST_FUNC; 105 ) FAST_FUNC;
106int lease_expired(struct dyn_lease *lease) FAST_FUNC; 106int is_expired_lease(struct dyn_lease *lease) FAST_FUNC;
107struct dyn_lease *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC; 107struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC;
108struct dyn_lease *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC; 108struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC;
109uint32_t find_free_or_expired_address(const uint8_t *chaddr) FAST_FUNC; 109uint32_t find_free_or_expired_nip(const uint8_t *safe_mac) FAST_FUNC;
110 110
111 111
112/*** static_leases.h ***/ 112/*** static_leases.h ***/
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index bddf3e141..c3cc2b0f5 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -295,7 +295,7 @@ static const struct config_keyword keywords[] = {
295 {"decline_time", read_u32, &(server_config.decline_time), "3600"}, 295 {"decline_time", read_u32, &(server_config.decline_time), "3600"},
296 {"conflict_time",read_u32, &(server_config.conflict_time),"3600"}, 296 {"conflict_time",read_u32, &(server_config.conflict_time),"3600"},
297 {"offer_time", read_u32, &(server_config.offer_time), "60"}, 297 {"offer_time", read_u32, &(server_config.offer_time), "60"},
298 {"min_lease", read_u32, &(server_config.min_lease), "60"}, 298 {"min_lease", read_u32, &(server_config.min_lease_sec),"60"},
299 {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE}, 299 {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE},
300 {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, 300 {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
301 {"siaddr", read_nip, &(server_config.siaddr_nip), "0.0.0.0"}, 301 {"siaddr", read_nip, &(server_config.siaddr_nip), "0.0.0.0"},
@@ -359,23 +359,23 @@ void FAST_FUNC write_leases(void)
359 for (i = 0; i < server_config.max_leases; i++) { 359 for (i = 0; i < server_config.max_leases; i++) {
360 leasetime_t tmp_time; 360 leasetime_t tmp_time;
361 361
362 if (leases[i].lease_nip == 0) 362 if (g_leases[i].lease_nip == 0)
363 continue; 363 continue;
364 364
365 /* Screw with the time in the struct, for easier writing */ 365 /* Screw with the time in the struct, for easier writing */
366 tmp_time = leases[i].expires; 366 tmp_time = g_leases[i].expires;
367 367
368 leases[i].expires -= curr; 368 g_leases[i].expires -= curr;
369 if ((signed_leasetime_t) leases[i].expires < 0) 369 if ((signed_leasetime_t) g_leases[i].expires < 0)
370 leases[i].expires = 0; 370 g_leases[i].expires = 0;
371 leases[i].expires = htonl(leases[i].expires); 371 g_leases[i].expires = htonl(g_leases[i].expires);
372 372
373 /* No error check. If the file gets truncated, 373 /* No error check. If the file gets truncated,
374 * we lose some leases on restart. Oh well. */ 374 * we lose some leases on restart. Oh well. */
375 full_write(fd, &leases[i], sizeof(leases[i])); 375 full_write(fd, &g_leases[i], sizeof(g_leases[i]));
376 376
377 /* Then restore it when done */ 377 /* Then restore it when done */
378 leases[i].expires = tmp_time; 378 g_leases[i].expires = tmp_time;
379 } 379 }
380 close(fd); 380 close(fd);
381 381
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index 4039f4dfb..68fba726e 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -17,12 +17,12 @@ static struct dyn_lease *oldest_expired_lease(void)
17 leasetime_t oldest_time = time(NULL); 17 leasetime_t oldest_time = time(NULL);
18 unsigned i; 18 unsigned i;
19 19
20 /* Unexpired leases have leases[i].expires >= current time 20 /* Unexpired leases have g_leases[i].expires >= current time
21 * and therefore can't ever match */ 21 * and therefore can't ever match */
22 for (i = 0; i < server_config.max_leases; i++) { 22 for (i = 0; i < server_config.max_leases; i++) {
23 if (leases[i].expires < oldest_time) { 23 if (g_leases[i].expires < oldest_time) {
24 oldest_time = leases[i].expires; 24 oldest_time = g_leases[i].expires;
25 oldest_lease = &leases[i]; 25 oldest_lease = &g_leases[i];
26 } 26 }
27 } 27 }
28 return oldest_lease; 28 return oldest_lease;
@@ -38,10 +38,10 @@ static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
38 continue; 38 continue;
39 39
40 for (i = 0; i < server_config.max_leases; i++) { 40 for (i = 0; i < server_config.max_leases; i++) {
41 if ((j != 16 && memcmp(leases[i].lease_mac, chaddr, 6) == 0) 41 if ((j != 16 && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0)
42 || (yiaddr && leases[i].lease_nip == yiaddr) 42 || (yiaddr && g_leases[i].lease_nip == yiaddr)
43 ) { 43 ) {
44 memset(&leases[i], 0, sizeof(leases[i])); 44 memset(&g_leases[i], 0, sizeof(g_leases[i]));
45 } 45 }
46 } 46 }
47} 47}
@@ -85,40 +85,40 @@ struct dyn_lease* FAST_FUNC add_lease(
85 85
86 86
87/* True if a lease has expired */ 87/* True if a lease has expired */
88int FAST_FUNC lease_expired(struct dyn_lease *lease) 88int FAST_FUNC is_expired_lease(struct dyn_lease *lease)
89{ 89{
90 return (lease->expires < (leasetime_t) time(NULL)); 90 return (lease->expires < (leasetime_t) time(NULL));
91} 91}
92 92
93 93
94/* Find the first lease that matches chaddr, NULL if no match */ 94/* Find the first lease that matches MAC, NULL if no match */
95struct dyn_lease* FAST_FUNC find_lease_by_chaddr(const uint8_t *chaddr) 95struct dyn_lease* FAST_FUNC find_lease_by_mac(const uint8_t *mac)
96{ 96{
97 unsigned i; 97 unsigned i;
98 98
99 for (i = 0; i < server_config.max_leases; i++) 99 for (i = 0; i < server_config.max_leases; i++)
100 if (memcmp(leases[i].lease_mac, chaddr, 6) == 0) 100 if (memcmp(g_leases[i].lease_mac, mac, 6) == 0)
101 return &(leases[i]); 101 return &g_leases[i];
102 102
103 return NULL; 103 return NULL;
104} 104}
105 105
106 106
107/* Find the first lease that matches yiaddr, NULL is no match */ 107/* Find the first lease that matches IP, NULL is no match */
108struct dyn_lease* FAST_FUNC find_lease_by_yiaddr(uint32_t yiaddr) 108struct dyn_lease* FAST_FUNC find_lease_by_nip(uint32_t nip)
109{ 109{
110 unsigned i; 110 unsigned i;
111 111
112 for (i = 0; i < server_config.max_leases; i++) 112 for (i = 0; i < server_config.max_leases; i++)
113 if (leases[i].lease_nip == yiaddr) 113 if (g_leases[i].lease_nip == nip)
114 return &leases[i]; 114 return &g_leases[i];
115 115
116 return NULL; 116 return NULL;
117} 117}
118 118
119 119
120/* Check if the IP is taken; if it is, add it to the lease table */ 120/* Check if the IP is taken; if it is, add it to the lease table */
121static int nobody_responds_to_arp(uint32_t addr, const uint8_t *safe_mac) 121static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac)
122{ 122{
123 /* 16 zero bytes */ 123 /* 16 zero bytes */
124 static const uint8_t blank_chaddr[16] = { 0 }; 124 static const uint8_t blank_chaddr[16] = { 0 };
@@ -127,30 +127,30 @@ static int nobody_responds_to_arp(uint32_t addr, const uint8_t *safe_mac)
127 struct in_addr temp; 127 struct in_addr temp;
128 int r; 128 int r;
129 129
130 r = arpping(addr, safe_mac, 130 r = arpping(nip, safe_mac,
131 server_config.server_nip, 131 server_config.server_nip,
132 server_config.server_mac, 132 server_config.server_mac,
133 server_config.interface); 133 server_config.interface);
134 if (r) 134 if (r)
135 return r; 135 return r;
136 136
137 temp.s_addr = addr; 137 temp.s_addr = nip;
138 bb_info_msg("%s belongs to someone, reserving it for %u seconds", 138 bb_info_msg("%s belongs to someone, reserving it for %u seconds",
139 inet_ntoa(temp), (unsigned)server_config.conflict_time); 139 inet_ntoa(temp), (unsigned)server_config.conflict_time);
140 add_lease(blank_chaddr, addr, server_config.conflict_time, NULL); 140 add_lease(blank_chaddr, nip, server_config.conflict_time, NULL);
141 return 0; 141 return 0;
142} 142}
143 143
144 144
145/* Find a new usable (we think) address */ 145/* Find a new usable (we think) address */
146uint32_t FAST_FUNC find_free_or_expired_address(const uint8_t *chaddr) 146uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
147{ 147{
148 uint32_t addr; 148 uint32_t addr;
149 struct dyn_lease *oldest_lease = NULL; 149 struct dyn_lease *oldest_lease = NULL;
150 150
151 addr = server_config.start_ip; /* addr is in host order here */ 151 addr = server_config.start_ip; /* addr is in host order here */
152 for (; addr <= server_config.end_ip; addr++) { 152 for (; addr <= server_config.end_ip; addr++) {
153 uint32_t net_addr; 153 uint32_t nip;
154 struct dyn_lease *lease; 154 struct dyn_lease *lease;
155 155
156 /* ie, 192.168.55.0 */ 156 /* ie, 192.168.55.0 */
@@ -159,23 +159,23 @@ uint32_t FAST_FUNC find_free_or_expired_address(const uint8_t *chaddr)
159 /* ie, 192.168.55.255 */ 159 /* ie, 192.168.55.255 */
160 if ((addr & 0xff) == 0xff) 160 if ((addr & 0xff) == 0xff)
161 continue; 161 continue;
162 net_addr = htonl(addr); 162 nip = htonl(addr);
163 /* is this a static lease addr? */ 163 /* is this a static lease addr? */
164 if (is_nip_reserved(server_config.static_leases, net_addr)) 164 if (is_nip_reserved(server_config.static_leases, nip))
165 continue; 165 continue;
166 166
167 lease = find_lease_by_yiaddr(net_addr); 167 lease = find_lease_by_nip(nip);
168 if (!lease) { 168 if (!lease) {
169 if (nobody_responds_to_arp(net_addr, chaddr)) 169 if (nobody_responds_to_arp(nip, safe_mac))
170 return net_addr; 170 return nip;
171 } else { 171 } else {
172 if (!oldest_lease || lease->expires < oldest_lease->expires) 172 if (!oldest_lease || lease->expires < oldest_lease->expires)
173 oldest_lease = lease; 173 oldest_lease = lease;
174 } 174 }
175 } 175 }
176 176
177 if (oldest_lease && lease_expired(oldest_lease) 177 if (oldest_lease && is_expired_lease(oldest_lease)
178 && nobody_responds_to_arp(oldest_lease->lease_nip, chaddr) 178 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac)
179 ) { 179 ) {
180 return oldest_lease->lease_nip; 180 return oldest_lease->lease_nip;
181 } 181 }
diff --git a/networking/udhcp/options.c b/networking/udhcp/options.c
index b86b3135d..0f17feb2a 100644
--- a/networking/udhcp/options.c
+++ b/networking/udhcp/options.c
@@ -119,6 +119,20 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = {
119}; 119};
120 120
121 121
122#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
123static void log_option(const char *pfx, const uint8_t *opt)
124{
125 if (dhcp_verbose >= 2) {
126 char buf[256 * 2 + 2];
127 *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0';
128 bb_info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf);
129 }
130}
131#else
132# define log_option(pfx, opt) ((void)0)
133#endif
134
135
122/* get an option with bounds checking (warning, result is not aligned). */ 136/* get an option with bounds checking (warning, result is not aligned). */
123uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code) 137uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code)
124{ 138{
@@ -167,11 +181,7 @@ uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code)
167 continue; /* complain and return NULL */ 181 continue; /* complain and return NULL */
168 182
169 if (optionptr[OPT_CODE] == code) { 183 if (optionptr[OPT_CODE] == code) {
170#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 184 log_option("Option found", optionptr);
171 char buf[256 * 2 + 2];
172 *bin2hex(buf, (void*) (optionptr + OPT_DATA), optionptr[OPT_LEN]) = '\0';
173 log2("Option 0x%02x found: %s", code, buf);
174#endif
175 return optionptr + OPT_DATA; 185 return optionptr + OPT_DATA;
176 } 186 }
177 187
@@ -214,7 +224,7 @@ int FAST_FUNC add_option_string(uint8_t *optionptr, uint8_t *string)
214 string[OPT_CODE]); 224 string[OPT_CODE]);
215 return 0; 225 return 0;
216 } 226 }
217 log1("Adding option 0x%02x", string[OPT_CODE]); 227 log_option("Adding option", string);
218 memcpy(optionptr + end, string, string[OPT_LEN] + 2); 228 memcpy(optionptr + end, string, string[OPT_LEN] + 2);
219 optionptr[end + string[OPT_LEN] + 2] = DHCP_END; 229 optionptr[end + string[OPT_LEN] + 2] = DHCP_END;
220 return string[OPT_LEN] + 2; 230 return string[OPT_LEN] + 2;
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 911bd3b37..d53c02dd5 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -78,7 +78,7 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet)
78 //, packet->cookie 78 //, packet->cookie
79 //, packet->options[] 79 //, packet->options[]
80 ); 80 );
81 bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)); 81 *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0';
82 bb_info_msg(" chaddr %s", buf); 82 bb_info_msg(" chaddr %s", buf);
83} 83}
84#endif 84#endif
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c
index 794e3ca8d..7ebef3553 100644
--- a/networking/udhcp/script.c
+++ b/networking/udhcp/script.c
@@ -218,17 +218,17 @@ void FAST_FUNC udhcp_run_script(struct dhcp_packet *packet, const char *name)
218 if (client_config.script == NULL) 218 if (client_config.script == NULL)
219 return; 219 return;
220 220
221 log1("Executing %s", client_config.script);
222
223 envp = fill_envp(packet); 221 envp = fill_envp(packet);
224 222
225 /* call script */ 223 /* call script */
224 log1("Executing %s", client_config.script);
226 argv[0] = (char*) client_config.script; 225 argv[0] = (char*) client_config.script;
227 argv[1] = (char*) name; 226 argv[1] = (char*) name;
228 argv[2] = NULL; 227 argv[2] = NULL;
229 wait4pid(spawn(argv)); 228 wait4pid(spawn(argv));
230 229
231 for (curr = envp; *curr; curr++) { 230 for (curr = envp; *curr; curr++) {
231 log2(" %s", *curr);
232 bb_unsetenv(*curr); 232 bb_unsetenv(*curr);
233 free(*curr); 233 free(*curr);
234 } 234 }
diff --git a/networking/udhcp/serverpacket.c b/networking/udhcp/serverpacket.c
index 209d3c8f3..c3724e0e2 100644
--- a/networking/udhcp/serverpacket.c
+++ b/networking/udhcp/serverpacket.c
@@ -107,14 +107,30 @@ static void add_bootp_options(struct dhcp_packet *packet)
107} 107}
108 108
109 109
110static uint32_t select_lease_time(struct dhcp_packet *packet)
111{
112 uint32_t lease_time_sec = server_config.max_lease_sec;
113 uint8_t *lease_time_opt = get_option(packet, DHCP_LEASE_TIME);
114 if (lease_time_opt) {
115 move_from_unaligned32(lease_time_sec, lease_time_opt);
116 lease_time_sec = ntohl(lease_time_sec);
117 if (lease_time_sec > server_config.max_lease_sec)
118 lease_time_sec = server_config.max_lease_sec;
119 if (lease_time_sec < server_config.min_lease_sec)
120 lease_time_sec = server_config.min_lease_sec;
121 }
122 return lease_time_sec;
123}
124
125
110/* send a DHCP OFFER to a DHCP DISCOVER */ 126/* send a DHCP OFFER to a DHCP DISCOVER */
111int FAST_FUNC send_offer(struct dhcp_packet *oldpacket) 127int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
112{ 128{
113 struct dhcp_packet packet; 129 struct dhcp_packet packet;
114 uint32_t req_align; 130 uint32_t req_nip;
115 uint32_t lease_time_aligned = server_config.lease; 131 uint32_t lease_time_sec = server_config.max_lease_sec;
116 uint32_t static_lease_ip; 132 uint32_t static_lease_ip;
117 uint8_t *req, *lease_time, *p_host_name; 133 uint8_t *req_ip_opt, *p_host_name;
118 struct option_set *curr; 134 struct option_set *curr;
119 struct in_addr addr; 135 struct in_addr addr;
120 136
@@ -126,31 +142,31 @@ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
126 if (!static_lease_ip) { 142 if (!static_lease_ip) {
127 struct dyn_lease *lease; 143 struct dyn_lease *lease;
128 144
129 lease = find_lease_by_chaddr(oldpacket->chaddr); 145 lease = find_lease_by_mac(oldpacket->chaddr);
130 /* The client is in our lease/offered table */ 146 /* The client is in our lease/offered table */
131 if (lease) { 147 if (lease) {
132 signed_leasetime_t tmp = lease->expires - time(NULL); 148 signed_leasetime_t tmp = lease->expires - time(NULL);
133 if (tmp >= 0) 149 if (tmp >= 0)
134 lease_time_aligned = tmp; 150 lease_time_sec = tmp;
135 packet.yiaddr = lease->lease_nip; 151 packet.yiaddr = lease->lease_nip;
136 } 152 }
137 /* Or the client has requested an IP */ 153 /* Or the client has requested an IP */
138 else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL 154 else if ((req_ip_opt = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL
139 /* (read IP) */ 155 /* (read IP) */
140 && (move_from_unaligned32(req_align, req), 1) 156 && (move_from_unaligned32(req_nip, req_ip_opt), 1)
141 /* and the IP is in the lease range */ 157 /* and the IP is in the lease range */
142 && ntohl(req_align) >= server_config.start_ip 158 && ntohl(req_nip) >= server_config.start_ip
143 && ntohl(req_align) <= server_config.end_ip 159 && ntohl(req_nip) <= server_config.end_ip
144 /* and is not already taken/offered */ 160 /* and is not already taken/offered */
145 && (!(lease = find_lease_by_yiaddr(req_align)) 161 && (!(lease = find_lease_by_nip(req_nip))
146 /* or its taken, but expired */ 162 /* or its taken, but expired */
147 || lease_expired(lease)) 163 || is_expired_lease(lease))
148 ) { 164 ) {
149 packet.yiaddr = req_align; 165 packet.yiaddr = req_nip;
150 } 166 }
151 /* Otherwise, find a free IP */ 167 /* Otherwise, find a free IP */
152 else { 168 else {
153 packet.yiaddr = find_free_or_expired_address(oldpacket->chaddr); 169 packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr);
154 } 170 }
155 171
156 if (!packet.yiaddr) { 172 if (!packet.yiaddr) {
@@ -162,23 +178,13 @@ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
162 bb_error_msg("lease pool is full - OFFER abandoned"); 178 bb_error_msg("lease pool is full - OFFER abandoned");
163 return -1; 179 return -1;
164 } 180 }
165 lease_time = get_option(oldpacket, DHCP_LEASE_TIME); 181 lease_time_sec = select_lease_time(oldpacket);
166 if (lease_time) {
167 move_from_unaligned32(lease_time_aligned, lease_time);
168 lease_time_aligned = ntohl(lease_time_aligned);
169 if (lease_time_aligned > server_config.lease)
170 lease_time_aligned = server_config.lease;
171 }
172
173 /* Make sure we aren't just using the lease time from the previous offer */
174 if (lease_time_aligned < server_config.min_lease)
175 lease_time_aligned = server_config.min_lease;
176 } else { 182 } else {
177 /* It is a static lease... use it */ 183 /* It is a static lease... use it */
178 packet.yiaddr = static_lease_ip; 184 packet.yiaddr = static_lease_ip;
179 } 185 }
180 186
181 add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned)); 187 add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec));
182 188
183 curr = server_config.options; 189 curr = server_config.options;
184 while (curr) { 190 while (curr) {
@@ -210,25 +216,16 @@ int FAST_FUNC send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
210{ 216{
211 struct dhcp_packet packet; 217 struct dhcp_packet packet;
212 struct option_set *curr; 218 struct option_set *curr;
213 uint8_t *lease_time; 219 uint32_t lease_time_sec;
214 uint32_t lease_time_aligned = server_config.lease;
215 struct in_addr addr; 220 struct in_addr addr;
216 uint8_t *p_host_name; 221 uint8_t *p_host_name;
217 222
218 init_packet(&packet, oldpacket, DHCPACK); 223 init_packet(&packet, oldpacket, DHCPACK);
219 packet.yiaddr = yiaddr; 224 packet.yiaddr = yiaddr;
220 225
221 lease_time = get_option(oldpacket, DHCP_LEASE_TIME); 226 lease_time_sec = select_lease_time(oldpacket);
222 if (lease_time) {
223 move_from_unaligned32(lease_time_aligned, lease_time);
224 lease_time_aligned = ntohl(lease_time_aligned);
225 if (lease_time_aligned > server_config.lease)
226 lease_time_aligned = server_config.lease;
227 else if (lease_time_aligned < server_config.min_lease)
228 lease_time_aligned = server_config.min_lease;
229 }
230 227
231 add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned)); 228 add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec));
232 229
233 curr = server_config.options; 230 curr = server_config.options;
234 while (curr) { 231 while (curr) {
@@ -246,7 +243,7 @@ int FAST_FUNC send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
246 return -1; 243 return -1;
247 244
248 p_host_name = get_option(oldpacket, DHCP_HOST_NAME); 245 p_host_name = get_option(oldpacket, DHCP_HOST_NAME);
249 add_lease(packet.chaddr, packet.yiaddr, lease_time_aligned, p_host_name); 246 add_lease(packet.chaddr, packet.yiaddr, lease_time_sec, p_host_name);
250 if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) { 247 if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) {
251 /* rewrite the file with leases at every new acceptance */ 248 /* rewrite the file with leases at every new acceptance */
252 write_leases(); 249 write_leases();