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 { /* Returns 1 if no reply received */ -int FAST_FUNC arpping(uint32_t test_ip, +int FAST_FUNC arpping(uint32_t test_nip, const uint8_t *safe_mac, uint32_t from_ip, uint8_t *from_mac, @@ -78,7 +78,7 @@ int FAST_FUNC arpping(uint32_t test_ip, memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */ memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */ /* tHaddr is zero-filled */ /* target hardware address */ - memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */ + memcpy(arp.tInaddr, &test_nip, sizeof(test_nip));/* target IP address */ memset(&addr, 0, sizeof(addr)); safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data)); @@ -111,7 +111,7 @@ int FAST_FUNC arpping(uint32_t test_ip, && arp.operation == htons(ARPOP_REPLY) /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */ /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */ - && *((uint32_t *) arp.sInaddr) == test_ip + && *((uint32_t *) arp.sInaddr) == test_nip ) { /* if ARP source MAC matches safe_mac * (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 @@ #include "common.h" #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 -int dhcp_verbose; +unsigned dhcp_verbose; #endif const 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 int udhcp_raw_socket(int ifindex) FAST_FUNC; int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC; /* Returns 1 if no reply received */ -int arpping(uint32_t test_ip, +int arpping(uint32_t test_nip, const uint8_t *safe_mac, uint32_t from_ip, uint8_t *from_mac, const char *interface) FAST_FUNC; #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 -extern int dhcp_verbose; +extern unsigned dhcp_verbose; # define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) # if CONFIG_UDHCP_DEBUG >= 2 void 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 @@ /* globals */ -struct dyn_lease *leases; +struct dyn_lease *g_leases; /* struct server_config_t server_config is in bb_common_bufsiz1 */ @@ -28,15 +28,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) fd_set rfds; int server_socket = -1, retval, max_sock; struct dhcp_packet packet; - uint8_t *state, *server_id, *requested; - uint32_t server_id_aligned = server_id_aligned; /* for compiler */ - uint32_t requested_aligned = requested_aligned; + uint8_t *state; uint32_t static_lease_ip; unsigned timeout_end; unsigned num_ips; unsigned opt; struct option_set *option; - struct dyn_lease *lease, static_lease; + struct dyn_lease *lease, fake_lease; IF_FEATURE_UDHCP_PORT(char *str_P;) #if ENABLE_FEATURE_UDHCP_PORT @@ -84,10 +82,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) bb_info_msg("%s (v"BB_VER") started", applet_name); option = find_option(server_config.options, DHCP_LEASE_TIME); - server_config.lease = LEASE_TIME; + server_config.max_lease_sec = LEASE_TIME; if (option) { - move_from_unaligned32(server_config.lease, option->data + 2); - server_config.lease = ntohl(server_config.lease); + move_from_unaligned32(server_config.max_lease_sec, option->data + OPT_DATA); + server_config.max_lease_sec = ntohl(server_config.max_lease_sec); } /* Sanity check */ @@ -98,7 +96,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) server_config.max_leases = num_ips; } - leases = xzalloc(server_config.max_leases * sizeof(*leases)); + g_leases = xzalloc(server_config.max_leases * sizeof(g_leases[0])); read_leases(server_config.lease_file); if (udhcp_read_interface(server_config.interface, @@ -186,13 +184,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) if (static_lease_ip) { bb_info_msg("Found static lease: %x", static_lease_ip); - memcpy(&static_lease.lease_mac, &packet.chaddr, 6); - static_lease.lease_nip = static_lease_ip; - static_lease.expires = 0; + memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); + fake_lease.lease_nip = static_lease_ip; + fake_lease.expires = 0; - lease = &static_lease; + lease = &fake_lease; } else { - lease = find_lease_by_chaddr(packet.chaddr); + lease = find_lease_by_mac(packet.chaddr); } switch (state[0]) { @@ -203,29 +201,32 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) bb_error_msg("send OFFER failed"); } break; - case DHCPREQUEST: + case DHCPREQUEST: { + uint8_t *server_id_opt, *requested_opt; + uint32_t server_id_net = server_id_net; /* for compiler */ + uint32_t requested_nip = requested_nip; /* for compiler */ + log1("Received REQUEST"); - requested = get_option(&packet, DHCP_REQUESTED_IP); - server_id = get_option(&packet, DHCP_SERVER_ID); - - if (requested) - move_from_unaligned32(requested_aligned, requested); - if (server_id) - move_from_unaligned32(server_id_aligned, server_id); + requested_opt = get_option(&packet, DHCP_REQUESTED_IP); + server_id_opt = get_option(&packet, DHCP_SERVER_ID); + if (requested_opt) + move_from_unaligned32(requested_nip, requested_opt); + if (server_id_opt) + move_from_unaligned32(server_id_net, server_id_opt); if (lease) { - if (server_id) { + if (server_id_opt) { /* SELECTING State */ - if (server_id_aligned == server_config.server_nip - && requested - && requested_aligned == lease->lease_nip + if (server_id_net == server_config.server_nip + && requested_opt + && requested_nip == lease->lease_nip ) { send_ACK(&packet, lease->lease_nip); } - } else if (requested) { + } else if (requested_opt) { /* INIT-REBOOT State */ - if (lease->lease_nip == requested_aligned) + if (lease->lease_nip == requested_nip) send_ACK(&packet, lease->lease_nip); else send_NAK(&packet); @@ -237,14 +238,14 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) } /* what to do if we have no record of the client */ - } else if (server_id) { + } else if (server_id_opt) { /* SELECTING State */ - } else if (requested) { + } else if (requested_opt) { /* INIT-REBOOT State */ - lease = find_lease_by_yiaddr(requested_aligned); + lease = find_lease_by_nip(requested_nip); if (lease) { - if (lease_expired(lease)) { + if (is_expired_lease(lease)) { /* probably best if we drop this lease */ memset(lease->lease_mac, 0, sizeof(lease->lease_mac)); } else { @@ -252,7 +253,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) send_NAK(&packet); } } else { - uint32_t r = ntohl(requested_aligned); + uint32_t r = ntohl(requested_nip); if (r < server_config.start_ip || r > server_config.end_ip ) { @@ -265,6 +266,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) /* RENEWING or REBINDING State */ } break; + } case DHCPDECLINE: log1("Received DECLINE"); 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 { /* start,end are in host order: we need to compare start <= ip <= end */ uint32_t start_ip; /* start address of leases, in host order */ uint32_t end_ip; /* end of leases, in host order */ - uint32_t lease; /* lease time in seconds (host order) */ - uint32_t max_leases; /* maximum number of leases (including reserved address) */ + uint32_t max_lease_sec; /* maximum lease time (host order) */ + uint32_t min_lease_sec; /* minimum lease time a client can request */ + uint32_t max_leases; /* maximum number of leases (including reserved addresses) */ uint32_t auto_time; /* how long should udhcpd wait before writing a config file. * if this is zero, it will only write one on SIGUSR1 */ uint32_t decline_time; /* how long an address is reserved if a client returns a * decline message */ uint32_t conflict_time; /* how long an arp conflict offender is leased for */ uint32_t offer_time; /* how long an offered address is reserved */ - uint32_t min_lease; /* minimum lease time a client can request */ uint32_t siaddr_nip; /* "next server" bootp option */ char *lease_file; char *pidfile; @@ -89,24 +89,24 @@ struct dyn_lease { /* We use lease_mac[6], since e.g. ARP probing uses * only 6 first bytes anyway. We check received dhcp packets * that their hlen == 6 and thus chaddr has only 6 significant bytes - * (dhcp packet has chaddr[16]) + * (dhcp packet has chaddr[16], not [6]) */ uint8_t lease_mac[6]; uint8_t hostname[20]; uint8_t pad[2]; /* total size is a multiply of 4 */ -}; +} PACKED; -extern struct dyn_lease *leases; +extern struct dyn_lease *g_leases; struct dyn_lease *add_lease( const uint8_t *chaddr, uint32_t yiaddr, leasetime_t leasetime, uint8_t *hostname ) FAST_FUNC; -int lease_expired(struct dyn_lease *lease) FAST_FUNC; -struct dyn_lease *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC; -struct dyn_lease *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC; -uint32_t find_free_or_expired_address(const uint8_t *chaddr) FAST_FUNC; +int is_expired_lease(struct dyn_lease *lease) FAST_FUNC; +struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC; +struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC; +uint32_t find_free_or_expired_nip(const uint8_t *safe_mac) FAST_FUNC; /*** 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[] = { {"decline_time", read_u32, &(server_config.decline_time), "3600"}, {"conflict_time",read_u32, &(server_config.conflict_time),"3600"}, {"offer_time", read_u32, &(server_config.offer_time), "60"}, - {"min_lease", read_u32, &(server_config.min_lease), "60"}, + {"min_lease", read_u32, &(server_config.min_lease_sec),"60"}, {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE}, {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, {"siaddr", read_nip, &(server_config.siaddr_nip), "0.0.0.0"}, @@ -359,23 +359,23 @@ void FAST_FUNC write_leases(void) for (i = 0; i < server_config.max_leases; i++) { leasetime_t tmp_time; - if (leases[i].lease_nip == 0) + if (g_leases[i].lease_nip == 0) continue; /* Screw with the time in the struct, for easier writing */ - tmp_time = leases[i].expires; + tmp_time = g_leases[i].expires; - leases[i].expires -= curr; - if ((signed_leasetime_t) leases[i].expires < 0) - leases[i].expires = 0; - leases[i].expires = htonl(leases[i].expires); + g_leases[i].expires -= curr; + if ((signed_leasetime_t) g_leases[i].expires < 0) + g_leases[i].expires = 0; + g_leases[i].expires = htonl(g_leases[i].expires); /* No error check. If the file gets truncated, * we lose some leases on restart. Oh well. */ - full_write(fd, &leases[i], sizeof(leases[i])); + full_write(fd, &g_leases[i], sizeof(g_leases[i])); /* Then restore it when done */ - leases[i].expires = tmp_time; + g_leases[i].expires = tmp_time; } close(fd); 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) leasetime_t oldest_time = time(NULL); unsigned i; - /* Unexpired leases have leases[i].expires >= current time + /* Unexpired leases have g_leases[i].expires >= current time * and therefore can't ever match */ for (i = 0; i < server_config.max_leases; i++) { - if (leases[i].expires < oldest_time) { - oldest_time = leases[i].expires; - oldest_lease = &leases[i]; + if (g_leases[i].expires < oldest_time) { + oldest_time = g_leases[i].expires; + oldest_lease = &g_leases[i]; } } return oldest_lease; @@ -38,10 +38,10 @@ static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr) continue; for (i = 0; i < server_config.max_leases; i++) { - if ((j != 16 && memcmp(leases[i].lease_mac, chaddr, 6) == 0) - || (yiaddr && leases[i].lease_nip == yiaddr) + if ((j != 16 && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0) + || (yiaddr && g_leases[i].lease_nip == yiaddr) ) { - memset(&leases[i], 0, sizeof(leases[i])); + memset(&g_leases[i], 0, sizeof(g_leases[i])); } } } @@ -85,40 +85,40 @@ struct dyn_lease* FAST_FUNC add_lease( /* True if a lease has expired */ -int FAST_FUNC lease_expired(struct dyn_lease *lease) +int FAST_FUNC is_expired_lease(struct dyn_lease *lease) { return (lease->expires < (leasetime_t) time(NULL)); } -/* Find the first lease that matches chaddr, NULL if no match */ -struct dyn_lease* FAST_FUNC find_lease_by_chaddr(const uint8_t *chaddr) +/* Find the first lease that matches MAC, NULL if no match */ +struct dyn_lease* FAST_FUNC find_lease_by_mac(const uint8_t *mac) { unsigned i; for (i = 0; i < server_config.max_leases; i++) - if (memcmp(leases[i].lease_mac, chaddr, 6) == 0) - return &(leases[i]); + if (memcmp(g_leases[i].lease_mac, mac, 6) == 0) + return &g_leases[i]; return NULL; } -/* Find the first lease that matches yiaddr, NULL is no match */ -struct dyn_lease* FAST_FUNC find_lease_by_yiaddr(uint32_t yiaddr) +/* Find the first lease that matches IP, NULL is no match */ +struct dyn_lease* FAST_FUNC find_lease_by_nip(uint32_t nip) { unsigned i; for (i = 0; i < server_config.max_leases; i++) - if (leases[i].lease_nip == yiaddr) - return &leases[i]; + if (g_leases[i].lease_nip == nip) + return &g_leases[i]; return NULL; } /* Check if the IP is taken; if it is, add it to the lease table */ -static int nobody_responds_to_arp(uint32_t addr, const uint8_t *safe_mac) +static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac) { /* 16 zero bytes */ 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) struct in_addr temp; int r; - r = arpping(addr, safe_mac, + r = arpping(nip, safe_mac, server_config.server_nip, server_config.server_mac, server_config.interface); if (r) return r; - temp.s_addr = addr; + temp.s_addr = nip; bb_info_msg("%s belongs to someone, reserving it for %u seconds", inet_ntoa(temp), (unsigned)server_config.conflict_time); - add_lease(blank_chaddr, addr, server_config.conflict_time, NULL); + add_lease(blank_chaddr, nip, server_config.conflict_time, NULL); return 0; } /* Find a new usable (we think) address */ -uint32_t FAST_FUNC find_free_or_expired_address(const uint8_t *chaddr) +uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) { uint32_t addr; struct dyn_lease *oldest_lease = NULL; addr = server_config.start_ip; /* addr is in host order here */ for (; addr <= server_config.end_ip; addr++) { - uint32_t net_addr; + uint32_t nip; struct dyn_lease *lease; /* ie, 192.168.55.0 */ @@ -159,23 +159,23 @@ uint32_t FAST_FUNC find_free_or_expired_address(const uint8_t *chaddr) /* ie, 192.168.55.255 */ if ((addr & 0xff) == 0xff) continue; - net_addr = htonl(addr); + nip = htonl(addr); /* is this a static lease addr? */ - if (is_nip_reserved(server_config.static_leases, net_addr)) + if (is_nip_reserved(server_config.static_leases, nip)) continue; - lease = find_lease_by_yiaddr(net_addr); + lease = find_lease_by_nip(nip); if (!lease) { - if (nobody_responds_to_arp(net_addr, chaddr)) - return net_addr; + if (nobody_responds_to_arp(nip, safe_mac)) + return nip; } else { if (!oldest_lease || lease->expires < oldest_lease->expires) oldest_lease = lease; } } - if (oldest_lease && lease_expired(oldest_lease) - && nobody_responds_to_arp(oldest_lease->lease_nip, chaddr) + if (oldest_lease && is_expired_lease(oldest_lease) + && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac) ) { return oldest_lease->lease_nip; } 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 = { }; +#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 +static void log_option(const char *pfx, const uint8_t *opt) +{ + if (dhcp_verbose >= 2) { + char buf[256 * 2 + 2]; + *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; + bb_info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); + } +} +#else +# define log_option(pfx, opt) ((void)0) +#endif + + /* get an option with bounds checking (warning, result is not aligned). */ uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code) { @@ -167,11 +181,7 @@ uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code) continue; /* complain and return NULL */ if (optionptr[OPT_CODE] == code) { -#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 - char buf[256 * 2 + 2]; - *bin2hex(buf, (void*) (optionptr + OPT_DATA), optionptr[OPT_LEN]) = '\0'; - log2("Option 0x%02x found: %s", code, buf); -#endif + log_option("Option found", optionptr); return optionptr + OPT_DATA; } @@ -214,7 +224,7 @@ int FAST_FUNC add_option_string(uint8_t *optionptr, uint8_t *string) string[OPT_CODE]); return 0; } - log1("Adding option 0x%02x", string[OPT_CODE]); + log_option("Adding option", string); memcpy(optionptr + end, string, string[OPT_LEN] + 2); optionptr[end + string[OPT_LEN] + 2] = DHCP_END; 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) //, packet->cookie //, packet->options[] ); - bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)); + *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; bb_info_msg(" chaddr %s", buf); } #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) if (client_config.script == NULL) return; - log1("Executing %s", client_config.script); - envp = fill_envp(packet); /* call script */ + log1("Executing %s", client_config.script); argv[0] = (char*) client_config.script; argv[1] = (char*) name; argv[2] = NULL; wait4pid(spawn(argv)); for (curr = envp; *curr; curr++) { + log2(" %s", *curr); bb_unsetenv(*curr); free(*curr); } 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) } +static uint32_t select_lease_time(struct dhcp_packet *packet) +{ + uint32_t lease_time_sec = server_config.max_lease_sec; + uint8_t *lease_time_opt = get_option(packet, DHCP_LEASE_TIME); + if (lease_time_opt) { + move_from_unaligned32(lease_time_sec, lease_time_opt); + lease_time_sec = ntohl(lease_time_sec); + if (lease_time_sec > server_config.max_lease_sec) + lease_time_sec = server_config.max_lease_sec; + if (lease_time_sec < server_config.min_lease_sec) + lease_time_sec = server_config.min_lease_sec; + } + return lease_time_sec; +} + + /* send a DHCP OFFER to a DHCP DISCOVER */ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket) { struct dhcp_packet packet; - uint32_t req_align; - uint32_t lease_time_aligned = server_config.lease; + uint32_t req_nip; + uint32_t lease_time_sec = server_config.max_lease_sec; uint32_t static_lease_ip; - uint8_t *req, *lease_time, *p_host_name; + uint8_t *req_ip_opt, *p_host_name; struct option_set *curr; struct in_addr addr; @@ -126,31 +142,31 @@ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket) if (!static_lease_ip) { struct dyn_lease *lease; - lease = find_lease_by_chaddr(oldpacket->chaddr); + lease = find_lease_by_mac(oldpacket->chaddr); /* The client is in our lease/offered table */ if (lease) { signed_leasetime_t tmp = lease->expires - time(NULL); if (tmp >= 0) - lease_time_aligned = tmp; + lease_time_sec = tmp; packet.yiaddr = lease->lease_nip; } /* Or the client has requested an IP */ - else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL + else if ((req_ip_opt = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL /* (read IP) */ - && (move_from_unaligned32(req_align, req), 1) + && (move_from_unaligned32(req_nip, req_ip_opt), 1) /* and the IP is in the lease range */ - && ntohl(req_align) >= server_config.start_ip - && ntohl(req_align) <= server_config.end_ip + && ntohl(req_nip) >= server_config.start_ip + && ntohl(req_nip) <= server_config.end_ip /* and is not already taken/offered */ - && (!(lease = find_lease_by_yiaddr(req_align)) + && (!(lease = find_lease_by_nip(req_nip)) /* or its taken, but expired */ - || lease_expired(lease)) + || is_expired_lease(lease)) ) { - packet.yiaddr = req_align; + packet.yiaddr = req_nip; } /* Otherwise, find a free IP */ else { - packet.yiaddr = find_free_or_expired_address(oldpacket->chaddr); + packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr); } if (!packet.yiaddr) { @@ -162,23 +178,13 @@ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket) bb_error_msg("lease pool is full - OFFER abandoned"); return -1; } - lease_time = get_option(oldpacket, DHCP_LEASE_TIME); - if (lease_time) { - move_from_unaligned32(lease_time_aligned, lease_time); - lease_time_aligned = ntohl(lease_time_aligned); - if (lease_time_aligned > server_config.lease) - lease_time_aligned = server_config.lease; - } - - /* Make sure we aren't just using the lease time from the previous offer */ - if (lease_time_aligned < server_config.min_lease) - lease_time_aligned = server_config.min_lease; + lease_time_sec = select_lease_time(oldpacket); } else { /* It is a static lease... use it */ packet.yiaddr = static_lease_ip; } - add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned)); + add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); curr = server_config.options; while (curr) { @@ -210,25 +216,16 @@ int FAST_FUNC send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) { struct dhcp_packet packet; struct option_set *curr; - uint8_t *lease_time; - uint32_t lease_time_aligned = server_config.lease; + uint32_t lease_time_sec; struct in_addr addr; uint8_t *p_host_name; init_packet(&packet, oldpacket, DHCPACK); packet.yiaddr = yiaddr; - lease_time = get_option(oldpacket, DHCP_LEASE_TIME); - if (lease_time) { - move_from_unaligned32(lease_time_aligned, lease_time); - lease_time_aligned = ntohl(lease_time_aligned); - if (lease_time_aligned > server_config.lease) - lease_time_aligned = server_config.lease; - else if (lease_time_aligned < server_config.min_lease) - lease_time_aligned = server_config.min_lease; - } + lease_time_sec = select_lease_time(oldpacket); - add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned)); + add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); curr = server_config.options; while (curr) { @@ -246,7 +243,7 @@ int FAST_FUNC send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) return -1; p_host_name = get_option(oldpacket, DHCP_HOST_NAME); - add_lease(packet.chaddr, packet.yiaddr, lease_time_aligned, p_host_name); + add_lease(packet.chaddr, packet.yiaddr, lease_time_sec, p_host_name); if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) { /* rewrite the file with leases at every new acceptance */ write_leases();