aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-01-01 17:52:09 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-01-01 17:52:09 +0000
commit0416e3dde17ea9295635c52183b30fe3d7172333 (patch)
tree4eea1c401c74d6ec42f18c67090f73001103e0db
parentb2ec03813c34bc3de2ddf9a0974be4e5b31ec757 (diff)
downloadbusybox-w32-0416e3dde17ea9295635c52183b30fe3d7172333.tar.gz
busybox-w32-0416e3dde17ea9295635c52183b30fe3d7172333.tar.bz2
busybox-w32-0416e3dde17ea9295635c52183b30fe3d7172333.zip
udhcpd: disable opton to have absolute lease times in lease file
(that does not work with dumpleases) dumpleases: fix -a option. networking/udhcp/*: code shrink, more compact static leases struture, better comments, etc function old new delta find_free_or_expired_address - 147 +147 nobody_responds_to_arp - 84 +84 read_opt 781 830 +49 dumpleases_main 435 447 +12 send_ACK 229 232 +3 read_staticlease 90 93 +3 addStaticLease 60 61 +1 getIpByMac 46 43 -3 reservedIp 31 20 -11 keywords 304 288 -16 send_offer 428 403 -25 write_leases 225 193 -32 read_leases 184 143 -41 read_yn 64 - -64 find_address 191 - -191 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 5/6 up/down: 299/-383) Total: -84 bytes
-rw-r--r--networking/udhcp/dhcpd.c15
-rw-r--r--networking/udhcp/dhcpd.h36
-rw-r--r--networking/udhcp/dumpleases.c39
-rw-r--r--networking/udhcp/files.c107
-rw-r--r--networking/udhcp/leases.c79
-rw-r--r--networking/udhcp/serverpacket.c37
-rw-r--r--networking/udhcp/static_leases.c67
7 files changed, 194 insertions, 186 deletions
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 7b4596895..d0a1eba81 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -26,8 +26,7 @@ int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
26int udhcpd_main(int argc UNUSED_PARAM, char **argv) 26int udhcpd_main(int argc UNUSED_PARAM, char **argv)
27{ 27{
28 fd_set rfds; 28 fd_set rfds;
29 struct timeval tv; 29 int server_socket = -1, retval, max_sock;
30 int server_socket = -1, bytes, retval, max_sock;
31 struct dhcpMessage packet; 30 struct dhcpMessage packet;
32 uint8_t *state, *server_id, *requested; 31 uint8_t *state, *server_id, *requested;
33 uint32_t server_id_aligned = server_id_aligned; /* for compiler */ 32 uint32_t server_id_aligned = server_id_aligned; /* for compiler */
@@ -107,6 +106,8 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
107 106
108 timeout_end = monotonic_sec() + server_config.auto_time; 107 timeout_end = monotonic_sec() + server_config.auto_time;
109 while (1) { /* loop until universe collapses */ 108 while (1) { /* loop until universe collapses */
109 int bytes;
110 struct timeval tv;
110 111
111 if (server_socket < 0) { 112 if (server_socket < 0) {
112 server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT, 113 server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT,
@@ -143,12 +144,15 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
143 case SIGTERM: 144 case SIGTERM:
144 bb_info_msg("Received a SIGTERM"); 145 bb_info_msg("Received a SIGTERM");
145 goto ret0; 146 goto ret0;
146 case 0: break; /* no signal */ 147 case 0: /* no signal: read a packet */
147 default: continue; /* signal or error (probably EINTR) */ 148 break;
149 default: /* signal or error (probably EINTR): back to select */
150 continue;
148 } 151 }
149 152
150 bytes = udhcp_recv_kernel_packet(&packet, server_socket); /* this waits for a packet - idle */ 153 bytes = udhcp_recv_kernel_packet(&packet, server_socket);
151 if (bytes < 0) { 154 if (bytes < 0) {
155 /* bytes can also be -2 ("bad packet data") */
152 if (bytes == -1 && errno != EINTR) { 156 if (bytes == -1 && errno != EINTR) {
153 DEBUG("error on read, %s, reopening socket", strerror(errno)); 157 DEBUG("error on read, %s, reopening socket", strerror(errno));
154 close(server_socket); 158 close(server_socket);
@@ -165,7 +169,6 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
165 169
166 /* Look for a static lease */ 170 /* Look for a static lease */
167 static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr); 171 static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr);
168
169 if (static_lease_ip) { 172 if (static_lease_ip) {
170 bb_info_msg("Found static lease: %x", static_lease_ip); 173 bb_info_msg("Found static lease: %x", static_lease_ip);
171 174
diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h
index 2d9752845..02e392aaf 100644
--- a/networking/udhcp/dhcpd.h
+++ b/networking/udhcp/dhcpd.h
@@ -26,8 +26,8 @@ struct option_set {
26 26
27struct static_lease { 27struct static_lease {
28 struct static_lease *next; 28 struct static_lease *next;
29 uint8_t *mac; 29 uint32_t ip;
30 uint32_t *ip; 30 uint8_t mac[6];
31}; 31};
32 32
33struct server_config_t { 33struct server_config_t {
@@ -42,8 +42,11 @@ struct server_config_t {
42 char *interface; /* The name of the interface to use */ 42 char *interface; /* The name of the interface to use */
43 int ifindex; /* Index number of the interface to use */ 43 int ifindex; /* Index number of the interface to use */
44 uint8_t arp[6]; /* Our arp address */ 44 uint8_t arp[6]; /* Our arp address */
45 char remaining; /* should the lease file be interpreted as lease time remaining, or 45// disabled: dumpleases has no way of knowing this value,
46 * as the time the lease expires */ 46// and will break if it's off. Now it's on always.
47// char remaining; /* Should the lease time in lease file
48// * be written as lease time remaining, or
49// * as the absolute time the lease expires */
47 uint32_t lease; /* lease time in seconds (host order) */ 50 uint32_t lease; /* lease time in seconds (host order) */
48 uint32_t max_leases; /* maximum number of leases (including reserved address) */ 51 uint32_t max_leases; /* maximum number of leases (including reserved address) */
49 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,11 +55,11 @@ struct server_config_t {
52 * decline message */ 55 * decline message */
53 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 */
54 uint32_t offer_time; /* how long an offered address is reserved */ 57 uint32_t offer_time; /* how long an offered address is reserved */
55 uint32_t min_lease; /* minimum lease a client can request */ 58 uint32_t min_lease; /* minimum lease time a client can request */
59 uint32_t siaddr; /* next server bootp option */
56 char *lease_file; 60 char *lease_file;
57 char *pidfile; 61 char *pidfile;
58 char *notify_file; /* What to run whenever leases are written */ 62 char *notify_file; /* What to run whenever leases are written */
59 uint32_t siaddr; /* next server bootp option */
60 char *sname; /* bootp server name */ 63 char *sname; /* bootp server name */
61 char *boot_file; /* bootp boot file option */ 64 char *boot_file; /* bootp boot file option */
62 struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */ 65 struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */
@@ -76,28 +79,37 @@ extern struct dhcpOfferedAddr *leases;
76 79
77/*** leases.h ***/ 80/*** leases.h ***/
78 81
82typedef uint32_t leasetime_t;
83typedef int32_t signed_leasetime_t;
84
79struct dhcpOfferedAddr { 85struct dhcpOfferedAddr {
80 uint8_t chaddr[16]; 86 uint8_t chaddr[16];
81 uint32_t yiaddr; /* network order */ 87 /* In network order */
82 uint32_t expires; /* host order */ 88 uint32_t yiaddr;
89 /* Unix time when lease expires, regardless of value of
90 * server_config.remaining. Kept in memory in host order.
91 * When written to file, converted to network order
92 * and optionally adjusted (current time subtracted)
93 * if server_config.remaining = 1 */
94 leasetime_t expires;
83}; 95};
84 96
85struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) FAST_FUNC; 97struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, leasetime_t leasetime) FAST_FUNC;
86int lease_expired(struct dhcpOfferedAddr *lease) FAST_FUNC; 98int lease_expired(struct dhcpOfferedAddr *lease) FAST_FUNC;
87struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC; 99struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC;
88struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC; 100struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC;
89uint32_t find_address(int check_expired) FAST_FUNC; 101uint32_t find_free_or_expired_address(void) FAST_FUNC;
90 102
91 103
92/*** static_leases.h ***/ 104/*** static_leases.h ***/
93 105
94/* Config file will pass static lease info to this function which will add it 106/* Config file will pass static lease info to this function which will add it
95 * to a data structure that can be searched later */ 107 * to a data structure that can be searched later */
96int addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip) FAST_FUNC; 108void addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t ip) FAST_FUNC;
97/* Check to see if a mac has an associated static lease */ 109/* Check to see if a mac has an associated static lease */
98uint32_t getIpByMac(struct static_lease *lease_struct, void *arg) FAST_FUNC; 110uint32_t getIpByMac(struct static_lease *lease_struct, void *arg) FAST_FUNC;
99/* Check to see if an ip is reserved as a static ip */ 111/* Check to see if an ip is reserved as a static ip */
100uint32_t reservedIp(struct static_lease *lease_struct, uint32_t ip) FAST_FUNC; 112int reservedIp(struct static_lease *lease_struct, uint32_t ip) FAST_FUNC;
101/* Print out static leases just to check what's going on (debug code) */ 113/* Print out static leases just to check what's going on (debug code) */
102void printStaticLeases(struct static_lease **lease_struct) FAST_FUNC; 114void printStaticLeases(struct static_lease **lease_struct) FAST_FUNC;
103 115
diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c
index 3e193903d..2d16ec160 100644
--- a/networking/udhcp/dumpleases.c
+++ b/networking/udhcp/dumpleases.c
@@ -12,7 +12,8 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv)
12 int fd; 12 int fd;
13 int i; 13 int i;
14 unsigned opt; 14 unsigned opt;
15 time_t expires; 15 leasetime_t expires;
16 leasetime_t curr;
16 const char *file = LEASES_FILE; 17 const char *file = LEASES_FILE;
17 struct dhcpOfferedAddr lease; 18 struct dhcpOfferedAddr lease;
18 struct in_addr addr; 19 struct in_addr addr;
@@ -38,27 +39,33 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv)
38 39
39 printf("Mac Address IP-Address Expires %s\n", (opt & OPT_a) ? "at" : "in"); 40 printf("Mac Address IP-Address Expires %s\n", (opt & OPT_a) ? "at" : "in");
40 /* "00:00:00:00:00:00 255.255.255.255 Wed Jun 30 21:49:08 1993" */ 41 /* "00:00:00:00:00:00 255.255.255.255 Wed Jun 30 21:49:08 1993" */
42
43 curr = time(NULL);
41 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { 44 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) {
42 printf(":%02x"+1, lease.chaddr[0]); 45 const char *fmt = ":%02x" + 1;
43 for (i = 1; i < 6; i++) { 46 for (i = 0; i < 6; i++) {
44 printf(":%02x", lease.chaddr[i]); 47 printf(fmt, lease.chaddr[i]);
48 fmt = ":%02x";
45 } 49 }
46 addr.s_addr = lease.yiaddr; 50 addr.s_addr = lease.yiaddr;
47 printf(" %-15s ", inet_ntoa(addr)); 51 printf(" %-15s ", inet_ntoa(addr));
52 if (lease.expires == 0) {
53 puts("expired");
54 continue;
55 }
48 expires = ntohl(lease.expires); 56 expires = ntohl(lease.expires);
49 if (!(opt & OPT_a)) { /* no -a */ 57 if (!(opt & OPT_a)) { /* no -a */
50 if (!expires) 58 unsigned d, h, m;
51 puts("expired"); 59 d = expires / (24*60*60); expires %= (24*60*60);
52 else { 60 h = expires / (60*60); expires %= (60*60);
53 unsigned d, h, m; 61 m = expires / 60; expires %= 60;
54 d = expires / (24*60*60); expires %= (24*60*60); 62 if (d)
55 h = expires / (60*60); expires %= (60*60); 63 printf("%u days ", d);
56 m = expires / 60; expires %= 60; 64 printf("%02u:%02u:%02u\n", h, m, (unsigned)expires);
57 if (d) printf("%u days ", d); 65 } else { /* -a */
58 printf("%02u:%02u:%02u\n", h, m, (unsigned)expires); 66 time_t t = expires + curr;
59 } 67 fputs(ctime(&t), stdout);
60 } else /* -a */ 68 }
61 fputs(ctime(&expires), stdout);
62 } 69 }
63 /* close(fd); */ 70 /* close(fd); */
64 71
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index 4f7b52056..76b42f0af 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -28,12 +28,7 @@ static int read_ip(const char *line, void *arg)
28 28
29static int read_mac(const char *line, void *arg) 29static int read_mac(const char *line, void *arg)
30{ 30{
31 struct ether_addr *temp_ether_addr; 31 return NULL == ether_aton_r(line, (struct ether_addr *)arg);
32
33 temp_ether_addr = ether_aton_r(line, (struct ether_addr *)arg);
34 if (temp_ether_addr == NULL)
35 return 0;
36 return 1;
37} 32}
38 33
39 34
@@ -250,23 +245,19 @@ static int read_staticlease(const char *const_line, void *arg)
250 char *line; 245 char *line;
251 char *mac_string; 246 char *mac_string;
252 char *ip_string; 247 char *ip_string;
253 uint8_t *mac_bytes; 248 struct ether_addr mac_bytes;
254 uint32_t *ip; 249 uint32_t ip;
255
256 /* Allocate memory for addresses */
257 mac_bytes = xmalloc(sizeof(unsigned char) * 8);
258 ip = xmalloc(sizeof(uint32_t));
259 250
260 /* Read mac */ 251 /* Read mac */
261 line = (char *) const_line; 252 line = (char *) const_line;
262 mac_string = strtok(line, " \t"); 253 mac_string = strtok_r(line, " \t", &line);
263 read_mac(mac_string, mac_bytes); 254 read_mac(mac_string, &mac_bytes);
264 255
265 /* Read ip */ 256 /* Read ip */
266 ip_string = strtok(NULL, " \t"); 257 ip_string = strtok_r(NULL, " \t", &line);
267 read_ip(ip_string, ip); 258 read_ip(ip_string, &ip);
268 259
269 addStaticLease(arg, mac_bytes, ip); 260 addStaticLease(arg, (uint8_t*) &mac_bytes, ip);
270 261
271 if (ENABLE_UDHCP_DEBUG) printStaticLeases(arg); 262 if (ENABLE_UDHCP_DEBUG) printStaticLeases(arg);
272 263
@@ -289,7 +280,7 @@ static const struct config_keyword keywords[] = {
289 /* Avoid "max_leases value not sane" warning by setting default 280 /* Avoid "max_leases value not sane" warning by setting default
290 * to default_end_ip - default_start_ip + 1: */ 281 * to default_end_ip - default_start_ip + 1: */
291 {"max_leases", read_u32, &(server_config.max_leases), "235"}, 282 {"max_leases", read_u32, &(server_config.max_leases), "235"},
292 {"remaining", read_yn, &(server_config.remaining), "yes"}, 283// {"remaining", read_yn, &(server_config.remaining), "yes"},
293 {"auto_time", read_u32, &(server_config.auto_time), "7200"}, 284 {"auto_time", read_u32, &(server_config.auto_time), "7200"},
294 {"decline_time", read_u32, &(server_config.decline_time), "3600"}, 285 {"decline_time", read_u32, &(server_config.decline_time), "3600"},
295 {"conflict_time",read_u32, &(server_config.conflict_time),"3600"}, 286 {"conflict_time",read_u32, &(server_config.conflict_time),"3600"},
@@ -305,7 +296,6 @@ static const struct config_keyword keywords[] = {
305 {"sname", read_str, &(server_config.sname), ""}, 296 {"sname", read_str, &(server_config.sname), ""},
306 {"boot_file", read_str, &(server_config.boot_file), ""}, 297 {"boot_file", read_str, &(server_config.boot_file), ""},
307 {"static_lease", read_staticlease, &(server_config.static_leases), ""}, 298 {"static_lease", read_staticlease, &(server_config.static_leases), ""},
308 /* ADDME: static lease */
309}; 299};
310enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; 300enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 };
311 301
@@ -342,36 +332,42 @@ void FAST_FUNC read_config(const char *file)
342 332
343void FAST_FUNC write_leases(void) 333void FAST_FUNC write_leases(void)
344{ 334{
345 int fp; 335 int fd;
346 unsigned i; 336 unsigned i;
347 time_t curr = time(0); 337 leasetime_t curr;
348 unsigned long tmp_time;
349 338
350 fp = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC); 339 fd = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC);
351 if (fp < 0) { 340 if (fd < 0)
352 return; 341 return;
353 } 342
343 curr = time(NULL);
344//TODO: write out current time? Readers need to adjust .expires field
345// to account for time between file was written and when it was read back.
354 346
355 for (i = 0; i < server_config.max_leases; i++) { 347 for (i = 0; i < server_config.max_leases; i++) {
356 if (leases[i].yiaddr != 0) { 348 leasetime_t tmp_time;
357 349
358 /* screw with the time in the struct, for easier writing */ 350 if (leases[i].yiaddr == 0)
359 tmp_time = leases[i].expires; 351 continue;
360 352
361 if (server_config.remaining) { 353 /* screw with the time in the struct, for easier writing */
362 if (lease_expired(&(leases[i]))) 354 tmp_time = leases[i].expires;
363 leases[i].expires = 0; 355
364 else leases[i].expires -= curr; 356 //if (server_config.remaining) {
365 } /* else stick with the time we got */ 357 leases[i].expires -= curr;
366 leases[i].expires = htonl(leases[i].expires); 358 if ((signed_leasetime_t) leases[i].expires < 0)
367 // FIXME: error check?? 359 leases[i].expires = 0;
368 full_write(fp, &leases[i], sizeof(leases[i])); 360 //} /* else stick with the time we got */
369 361 leases[i].expires = htonl(leases[i].expires);
370 /* then restore it when done */ 362
371 leases[i].expires = tmp_time; 363 /* No error check. If the file gets truncated,
372 } 364 * we lose some leases on restart. Oh well. */
365 full_write(fd, &leases[i], sizeof(leases[i]));
366
367 /* then restore it when done */
368 leases[i].expires = tmp_time;
373 } 369 }
374 close(fp); 370 close(fd);
375 371
376 if (server_config.notify_file) { 372 if (server_config.notify_file) {
377// TODO: vfork-based child creation 373// TODO: vfork-based child creation
@@ -384,26 +380,29 @@ void FAST_FUNC write_leases(void)
384 380
385void FAST_FUNC read_leases(const char *file) 381void FAST_FUNC read_leases(const char *file)
386{ 382{
387 int fp; 383 int fd;
388 unsigned i; 384 unsigned i;
385// leasetime_t curr;
389 struct dhcpOfferedAddr lease; 386 struct dhcpOfferedAddr lease;
390 387
391 fp = open_or_warn(file, O_RDONLY); 388 fd = open_or_warn(file, O_RDONLY);
392 if (fp < 0) { 389 if (fd < 0)
393 return; 390 return;
394 }
395 391
392// curr = time(NULL);
396 i = 0; 393 i = 0;
397 while (i < server_config.max_leases 394 while (i < server_config.max_leases
398 && full_read(fp, &lease, sizeof(lease)) == sizeof(lease) 395 && full_read(fd, &lease, sizeof(lease)) == sizeof(lease)
399 ) { 396 ) {
400 /* ADDME: is it a static lease */ 397 /* ADDME: what if it matches some static lease? */
401 uint32_t y = ntohl(lease.yiaddr); 398 uint32_t y = ntohl(lease.yiaddr);
402 if (y >= server_config.start_ip && y <= server_config.end_ip) { 399 if (y >= server_config.start_ip && y <= server_config.end_ip) {
403 lease.expires = ntohl(lease.expires); 400 leasetime_t expires = ntohl(lease.expires);
404 if (!server_config.remaining) 401// if (!server_config.remaining)
405 lease.expires -= time(NULL); 402// expires -= curr;
406 if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) { 403 /* NB: add_lease takes "relative time", IOW,
404 * lease duration, not lease deadline. */
405 if (!(add_lease(lease.chaddr, lease.yiaddr, expires))) {
407 bb_error_msg("too many leases while loading %s", file); 406 bb_error_msg("too many leases while loading %s", file);
408 break; 407 break;
409 } 408 }
@@ -411,5 +410,5 @@ void FAST_FUNC read_leases(const char *file)
411 } 410 }
412 } 411 }
413 DEBUG("Read %d leases", i); 412 DEBUG("Read %d leases", i);
414 close(fp); 413 close(fd);
415} 414}
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index a981db0d7..3044c2040 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -13,21 +13,23 @@
13/* Find the oldest expired lease, NULL if there are no expired leases */ 13/* Find the oldest expired lease, NULL if there are no expired leases */
14static struct dhcpOfferedAddr *oldest_expired_lease(void) 14static struct dhcpOfferedAddr *oldest_expired_lease(void)
15{ 15{
16 struct dhcpOfferedAddr *oldest = NULL; 16 struct dhcpOfferedAddr *oldest_lease = NULL;
17// TODO: use monotonic_sec() 17 leasetime_t oldest_time = time(NULL);
18 unsigned long oldest_lease = time(0);
19 unsigned i; 18 unsigned i;
20 19
21 for (i = 0; i < server_config.max_leases; i++) 20 /* Unexpired leases have leases[i].expires >= current time
22 if (oldest_lease > leases[i].expires) { 21 * and therefore can't ever match */
23 oldest_lease = leases[i].expires; 22 for (i = 0; i < server_config.max_leases; i++) {
24 oldest = &(leases[i]); 23 if (leases[i].expires < oldest_time) {
24 oldest_time = leases[i].expires;
25 oldest_lease = &(leases[i]);
25 } 26 }
26 return oldest; 27 }
28 return oldest_lease;
27} 29}
28 30
29 31
30/* clear every lease out that chaddr OR yiaddr matches and is nonzero */ 32/* Clear every lease out that chaddr OR yiaddr matches and is nonzero */
31static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr) 33static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
32{ 34{
33 unsigned i, j; 35 unsigned i, j;
@@ -35,17 +37,18 @@ static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
35 for (j = 0; j < 16 && !chaddr[j]; j++) 37 for (j = 0; j < 16 && !chaddr[j]; j++)
36 continue; 38 continue;
37 39
38 for (i = 0; i < server_config.max_leases; i++) 40 for (i = 0; i < server_config.max_leases; i++) {
39 if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) == 0) 41 if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) == 0)
40 || (yiaddr && leases[i].yiaddr == yiaddr) 42 || (yiaddr && leases[i].yiaddr == yiaddr)
41 ) { 43 ) {
42 memset(&(leases[i]), 0, sizeof(leases[i])); 44 memset(&(leases[i]), 0, sizeof(leases[i]));
43 } 45 }
46 }
44} 47}
45 48
46 49
47/* add a lease into the table, clearing out any old ones */ 50/* Add a lease into the table, clearing out any old ones */
48struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) 51struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiaddr, leasetime_t leasetime)
49{ 52{
50 struct dhcpOfferedAddr *oldest; 53 struct dhcpOfferedAddr *oldest;
51 54
@@ -57,17 +60,17 @@ struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiad
57 if (oldest) { 60 if (oldest) {
58 memcpy(oldest->chaddr, chaddr, 16); 61 memcpy(oldest->chaddr, chaddr, 16);
59 oldest->yiaddr = yiaddr; 62 oldest->yiaddr = yiaddr;
60 oldest->expires = time(0) + lease; 63 oldest->expires = time(NULL) + leasetime;
61 } 64 }
62 65
63 return oldest; 66 return oldest;
64} 67}
65 68
66 69
67/* true if a lease has expired */ 70/* True if a lease has expired */
68int FAST_FUNC lease_expired(struct dhcpOfferedAddr *lease) 71int FAST_FUNC lease_expired(struct dhcpOfferedAddr *lease)
69{ 72{
70 return (lease->expires < (unsigned long) time(0)); 73 return (lease->expires < (leasetime_t) time(NULL));
71} 74}
72 75
73 76
@@ -119,33 +122,43 @@ static int nobody_responds_to_arp(uint32_t addr)
119} 122}
120 123
121 124
122/* find an assignable address, if check_expired is true, we check all the expired leases as well. 125/* Find a new usable (we think) address. */
123 * Maybe this should try expired leases by age... */ 126uint32_t FAST_FUNC find_free_or_expired_address(void)
124uint32_t FAST_FUNC find_address(int check_expired)
125{ 127{
126 uint32_t addr, ret; 128 uint32_t addr;
127 struct dhcpOfferedAddr *lease = NULL; 129 struct dhcpOfferedAddr *oldest_lease = NULL;
128 130
129 addr = server_config.start_ip; /* addr is in host order here */ 131 addr = server_config.start_ip; /* addr is in host order here */
130 for (; addr <= server_config.end_ip; addr++) { 132 for (; addr <= server_config.end_ip; addr++) {
133 uint32_t net_addr;
134 struct dhcpOfferedAddr *lease;
135
131 /* ie, 192.168.55.0 */ 136 /* ie, 192.168.55.0 */
132 if (!(addr & 0xFF)) 137 if ((addr & 0xff) == 0)
133 continue; 138 continue;
134 /* ie, 192.168.55.255 */ 139 /* ie, 192.168.55.255 */
135 if ((addr & 0xFF) == 0xFF) 140 if ((addr & 0xff) == 0xff)
136 continue; 141 continue;
137 /* Only do if it isn't assigned as a static lease */ 142 net_addr = htonl(addr);
138 ret = htonl(addr); 143 /* addr has a static lease? */
139 if (!reservedIp(server_config.static_leases, ret)) { 144 if (reservedIp(server_config.static_leases, net_addr))
140 /* lease is not taken */ 145 continue;
141 lease = find_lease_by_yiaddr(ret); 146
142 /* no lease or it expired and we are checking for expired leases */ 147 lease = find_lease_by_yiaddr(net_addr);
143 if ((!lease || (check_expired && lease_expired(lease))) 148 if (!lease) {
144 && nobody_responds_to_arp(ret) /* it isn't used on the network */ 149 if (nobody_responds_to_arp(net_addr))
145 ) { 150 return net_addr;
146 return ret; 151 } else {
147 } 152 if (!oldest_lease || lease->expires < oldest_lease->expires)
153 oldest_lease = lease;
148 } 154 }
149 } 155 }
156
157 if (oldest_lease && lease_expired(oldest_lease)
158 && nobody_responds_to_arp(oldest_lease->yiaddr)
159 ) {
160 return oldest_lease->yiaddr;
161 }
162
150 return 0; 163 return 0;
151} 164}
diff --git a/networking/udhcp/serverpacket.c b/networking/udhcp/serverpacket.c
index fca685dd1..afc0fb40d 100644
--- a/networking/udhcp/serverpacket.c
+++ b/networking/udhcp/serverpacket.c
@@ -102,48 +102,44 @@ static void add_bootp_options(struct dhcpMessage *packet)
102int FAST_FUNC send_offer(struct dhcpMessage *oldpacket) 102int FAST_FUNC send_offer(struct dhcpMessage *oldpacket)
103{ 103{
104 struct dhcpMessage packet; 104 struct dhcpMessage packet;
105 struct dhcpOfferedAddr *lease = NULL;
106 uint32_t req_align; 105 uint32_t req_align;
107 uint32_t lease_time_aligned = server_config.lease; 106 uint32_t lease_time_aligned = server_config.lease;
107 uint32_t static_lease_ip;
108 uint8_t *req, *lease_time; 108 uint8_t *req, *lease_time;
109 struct option_set *curr; 109 struct option_set *curr;
110 struct in_addr addr; 110 struct in_addr addr;
111 111
112 uint32_t static_lease_ip;
113
114 init_packet(&packet, oldpacket, DHCPOFFER); 112 init_packet(&packet, oldpacket, DHCPOFFER);
115 113
116 static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr); 114 static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr);
117 115
118 /* ADDME: if static, short circuit */ 116 /* ADDME: if static, short circuit */
119 if (!static_lease_ip) { 117 if (!static_lease_ip) {
120 /* the client is in our lease/offered table */ 118 struct dhcpOfferedAddr *lease;
119
121 lease = find_lease_by_chaddr(oldpacket->chaddr); 120 lease = find_lease_by_chaddr(oldpacket->chaddr);
121 /* the client is in our lease/offered table */
122 if (lease) { 122 if (lease) {
123 if (!lease_expired(lease)) 123 signed_leasetime_t tmp = lease->expires - time(NULL);
124 lease_time_aligned = lease->expires - time(0); 124 if (tmp >= 0)
125 lease_time_aligned = tmp;
125 packet.yiaddr = lease->yiaddr; 126 packet.yiaddr = lease->yiaddr;
126 /* Or the client has a requested ip */ 127 /* Or the client has requested an ip */
127 } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) 128 } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL
128 /* Don't look here (ugly hackish thing to do) */ 129 /* Don't look here (ugly hackish thing to do) */
129 && memcpy(&req_align, req, 4) 130 && (move_from_unaligned32(req_align, req), 1)
130 /* and the ip is in the lease range */ 131 /* and the ip is in the lease range */
131 && ntohl(req_align) >= server_config.start_ip 132 && ntohl(req_align) >= server_config.start_ip
132 && ntohl(req_align) <= server_config.end_ip 133 && ntohl(req_align) <= server_config.end_ip
133 && !static_lease_ip /* Check that its not a static lease */
134 /* and is not already taken/offered */ 134 /* and is not already taken/offered */
135 && (!(lease = find_lease_by_yiaddr(req_align)) 135 && (!(lease = find_lease_by_yiaddr(req_align))
136 /* or its taken, but expired */ /* ADDME: or maybe in here */ 136 /* or its taken, but expired */
137 || lease_expired(lease)) 137 || lease_expired(lease))
138 ) { 138 ) {
139 packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */ 139 packet.yiaddr = req_align;
140 /* otherwise, find a free IP */ 140 /* otherwise, find a free IP */
141 } else { 141 } else {
142 /* Is it a static lease? (No, because find_address skips static lease) */ 142 packet.yiaddr = find_free_or_expired_address();
143 packet.yiaddr = find_address(0);
144 /* try for an expired lease */
145 if (!packet.yiaddr)
146 packet.yiaddr = find_address(1);
147 } 143 }
148 144
149 if (!packet.yiaddr) { 145 if (!packet.yiaddr) {
@@ -164,8 +160,7 @@ int FAST_FUNC send_offer(struct dhcpMessage *oldpacket)
164 160
165 /* Make sure we aren't just using the lease time from the previous offer */ 161 /* Make sure we aren't just using the lease time from the previous offer */
166 if (lease_time_aligned < server_config.min_lease) 162 if (lease_time_aligned < server_config.min_lease)
167 lease_time_aligned = server_config.lease; 163 lease_time_aligned = server_config.min_lease;
168 /* ADDME: end of short circuit */
169 } else { 164 } else {
170 /* It is a static lease... use it */ 165 /* It is a static lease... use it */
171 packet.yiaddr = static_lease_ip; 166 packet.yiaddr = static_lease_ip;
@@ -217,7 +212,7 @@ int FAST_FUNC send_ACK(struct dhcpMessage *oldpacket, uint32_t yiaddr)
217 if (lease_time_aligned > server_config.lease) 212 if (lease_time_aligned > server_config.lease)
218 lease_time_aligned = server_config.lease; 213 lease_time_aligned = server_config.lease;
219 else if (lease_time_aligned < server_config.min_lease) 214 else if (lease_time_aligned < server_config.min_lease)
220 lease_time_aligned = server_config.lease; 215 lease_time_aligned = server_config.min_lease;
221 } 216 }
222 217
223 add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned)); 218 add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned));
diff --git a/networking/udhcp/static_leases.c b/networking/udhcp/static_leases.c
index 7540f7f5e..1e77a58f9 100644
--- a/networking/udhcp/static_leases.c
+++ b/networking/udhcp/static_leases.c
@@ -15,69 +15,49 @@
15/* Takes the address of the pointer to the static_leases linked list, 15/* Takes the address of the pointer to the static_leases linked list,
16 * Address to a 6 byte mac address 16 * Address to a 6 byte mac address
17 * Address to a 4 byte ip address */ 17 * Address to a 4 byte ip address */
18int FAST_FUNC addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip) 18void FAST_FUNC addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t ip)
19{ 19{
20 struct static_lease *cur;
21 struct static_lease *new_static_lease; 20 struct static_lease *new_static_lease;
22 21
23 /* Build new node */ 22 /* Build new node */
24 new_static_lease = xmalloc(sizeof(struct static_lease)); 23 new_static_lease = xzalloc(sizeof(struct static_lease));
25 new_static_lease->mac = mac; 24 memcpy(new_static_lease->mac, mac, 6);
26 new_static_lease->ip = ip; 25 new_static_lease->ip = ip;
27 new_static_lease->next = NULL; 26 /*new_static_lease->next = NULL;*/
28 27
29 /* If it's the first node to be added... */ 28 /* If it's the first node to be added... */
30 if (*lease_struct == NULL) { 29 if (*lease_struct == NULL) {
31 *lease_struct = new_static_lease; 30 *lease_struct = new_static_lease;
32 } else { 31 } else {
33 cur = *lease_struct; 32 struct static_lease *cur = *lease_struct;
34 while (cur->next) { 33 while (cur->next)
35 cur = cur->next; 34 cur = cur->next;
36 }
37
38 cur->next = new_static_lease; 35 cur->next = new_static_lease;
39 } 36 }
40
41 return 1;
42} 37}
43 38
44/* Check to see if a mac has an associated static lease */ 39/* Check to see if a mac has an associated static lease */
45uint32_t FAST_FUNC getIpByMac(struct static_lease *lease_struct, void *arg) 40uint32_t FAST_FUNC getIpByMac(struct static_lease *lease_struct, void *mac)
46{ 41{
47 uint32_t return_ip; 42 while (lease_struct) {
48 struct static_lease *cur = lease_struct; 43 if (memcmp(lease_struct->mac, mac, 6) == 0)
49 uint8_t *mac = arg; 44 return lease_struct->ip;
50 45 lease_struct = lease_struct->next;
51 return_ip = 0;
52
53 while (cur) {
54 /* If the client has the correct mac */
55 if (memcmp(cur->mac, mac, 6) == 0) {
56 return_ip = *(cur->ip);
57 }
58
59 cur = cur->next;
60 } 46 }
61 47
62 return return_ip; 48 return 0;
63} 49}
64 50
65/* Check to see if an ip is reserved as a static ip */ 51/* Check to see if an ip is reserved as a static ip */
66uint32_t FAST_FUNC reservedIp(struct static_lease *lease_struct, uint32_t ip) 52int FAST_FUNC reservedIp(struct static_lease *lease_struct, uint32_t ip)
67{ 53{
68 struct static_lease *cur = lease_struct; 54 while (lease_struct) {
69 55 if (lease_struct->ip == ip)
70 uint32_t return_val = 0; 56 return 1;
71 57 lease_struct = lease_struct->next;
72 while (cur) {
73 /* If the client has the correct ip */
74 if (*cur->ip == ip)
75 return_val = 1;
76
77 cur = cur->next;
78 } 58 }
79 59
80 return return_val; 60 return 0;
81} 61}
82 62
83#if ENABLE_UDHCP_DEBUG 63#if ENABLE_UDHCP_DEBUG
@@ -85,15 +65,14 @@ uint32_t FAST_FUNC reservedIp(struct static_lease *lease_struct, uint32_t ip)
85/* Takes the address of the pointer to the static_leases linked list */ 65/* Takes the address of the pointer to the static_leases linked list */
86void FAST_FUNC printStaticLeases(struct static_lease **arg) 66void FAST_FUNC printStaticLeases(struct static_lease **arg)
87{ 67{
88 /* Get a pointer to the linked list */
89 struct static_lease *cur = *arg; 68 struct static_lease *cur = *arg;
90 69
91 while (cur) { 70 while (cur) {
92 /* printf("PrintStaticLeases: Lease mac Address: %x\n", cur->mac); */ 71 printf("PrintStaticLeases: Lease mac Value: %02x:%02x:%02x:%02x:%02x:%02x\n",
93 printf("PrintStaticLeases: Lease mac Value: %x\n", *(cur->mac)); 72 cur->mac[0], cur->mac[1], cur->mac[2],
94 /* printf("PrintStaticLeases: Lease ip Address: %x\n", cur->ip); */ 73 cur->mac[3], cur->mac[4], cur->mac[5]
95 printf("PrintStaticLeases: Lease ip Value: %x\n", *(cur->ip)); 74 );
96 75 printf("PrintStaticLeases: Lease ip Value: %x\n", cur->ip);
97 cur = cur->next; 76 cur = cur->next;
98 } 77 }
99} 78}