diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-01-01 17:52:09 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-01-01 17:52:09 +0000 |
commit | 0416e3dde17ea9295635c52183b30fe3d7172333 (patch) | |
tree | 4eea1c401c74d6ec42f18c67090f73001103e0db | |
parent | b2ec03813c34bc3de2ddf9a0974be4e5b31ec757 (diff) | |
download | busybox-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.c | 15 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.h | 36 | ||||
-rw-r--r-- | networking/udhcp/dumpleases.c | 39 | ||||
-rw-r--r-- | networking/udhcp/files.c | 107 | ||||
-rw-r--r-- | networking/udhcp/leases.c | 79 | ||||
-rw-r--r-- | networking/udhcp/serverpacket.c | 37 | ||||
-rw-r--r-- | networking/udhcp/static_leases.c | 67 |
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; | |||
26 | int udhcpd_main(int argc UNUSED_PARAM, char **argv) | 26 | int 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 | ||
27 | struct static_lease { | 27 | struct 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 | ||
33 | struct server_config_t { | 33 | struct 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 | ||
82 | typedef uint32_t leasetime_t; | ||
83 | typedef int32_t signed_leasetime_t; | ||
84 | |||
79 | struct dhcpOfferedAddr { | 85 | struct 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 | ||
85 | struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) FAST_FUNC; | 97 | struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, leasetime_t leasetime) FAST_FUNC; |
86 | int lease_expired(struct dhcpOfferedAddr *lease) FAST_FUNC; | 98 | int lease_expired(struct dhcpOfferedAddr *lease) FAST_FUNC; |
87 | struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC; | 99 | struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC; |
88 | struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC; | 100 | struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC; |
89 | uint32_t find_address(int check_expired) FAST_FUNC; | 101 | uint32_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 */ |
96 | int addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip) FAST_FUNC; | 108 | void 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 */ |
98 | uint32_t getIpByMac(struct static_lease *lease_struct, void *arg) FAST_FUNC; | 110 | uint32_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 */ |
100 | uint32_t reservedIp(struct static_lease *lease_struct, uint32_t ip) FAST_FUNC; | 112 | int 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) */ |
102 | void printStaticLeases(struct static_lease **lease_struct) FAST_FUNC; | 114 | void 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 | ||
29 | static int read_mac(const char *line, void *arg) | 29 | static 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 | }; |
310 | enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; | 300 | enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; |
311 | 301 | ||
@@ -342,36 +332,42 @@ void FAST_FUNC read_config(const char *file) | |||
342 | 332 | ||
343 | void FAST_FUNC write_leases(void) | 333 | void 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 | ||
385 | void FAST_FUNC read_leases(const char *file) | 381 | void 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 */ |
14 | static struct dhcpOfferedAddr *oldest_expired_lease(void) | 14 | static 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 */ |
31 | static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr) | 33 | static 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 */ |
48 | struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) | 51 | struct 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 */ |
68 | int FAST_FUNC lease_expired(struct dhcpOfferedAddr *lease) | 71 | int 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... */ | 126 | uint32_t FAST_FUNC find_free_or_expired_address(void) |
124 | uint32_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) | |||
102 | int FAST_FUNC send_offer(struct dhcpMessage *oldpacket) | 102 | int 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 */ |
18 | int FAST_FUNC addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip) | 18 | void 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 */ |
45 | uint32_t FAST_FUNC getIpByMac(struct static_lease *lease_struct, void *arg) | 40 | uint32_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 */ |
66 | uint32_t FAST_FUNC reservedIp(struct static_lease *lease_struct, uint32_t ip) | 52 | int 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 */ |
86 | void FAST_FUNC printStaticLeases(struct static_lease **arg) | 66 | void 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 | } |