summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Härdeman2025-10-08 13:46:24 +0000
committerÁlvaro Fernández Rojas2025-10-25 15:08:59 +0000
commit3ad54baa4adc0d6d102ccdc82f8b1f7439059f6e (patch)
tree97126843cad18276c0fa0d7176337e41cab45116
parentfab8f67818e69c4400c67293d8240d5f93709673 (diff)
downloadodhcpd-3ad54baa4adc0d6d102ccdc82f8b1f7439059f6e.tar.gz
dhcpv4: dhcpv4_assign() - explain address assignment
Add some debug statements that also serve as comments explaining the logic of dhcpv4_assign() and which make it easier to understand why a requested address was not provided. Signed-off-by: David Härdeman <david@hardeman.nu> Link: https://github.com/openwrt/odhcpd/pull/286 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-rw-r--r--src/dhcpv4.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/src/dhcpv4.c b/src/dhcpv4.c
index 3fc1a3d..173457a 100644
--- a/src/dhcpv4.c
+++ b/src/dhcpv4.c
@@ -367,43 +367,48 @@ static bool dhcpv4_assign(struct interface *iface, struct dhcp_assignment *a,
uint32_t end = ntohl(iface->dhcpv4_end_ip.s_addr);
uint32_t count = end - start + 1;
uint32_t seed = 0;
- bool assigned;
char ipv4_str[INET_ADDRSTRLEN];
/* Preconfigured IP address by static lease */
if (a->addr) {
- assigned = dhcpv4_insert_assignment(&iface->dhcpv4_assignments,
- a, a->addr);
-
- if (assigned)
- debug("Assigning static IP: %s",
+ if (!dhcpv4_insert_assignment(&iface->dhcpv4_assignments, a, a->addr)) {
+ error("The static IP address is already assigned: %s",
inet_ntop(AF_INET, &a->addr, ipv4_str, sizeof(ipv4_str)));
+ return false;
+ }
- return assigned;
+ debug("Assigned static IP address: %s",
+ inet_ntop(AF_INET, &a->addr, ipv4_str, sizeof(ipv4_str)));
+ return true;
}
- /* try to assign the IP the client asked for */
- if (start <= ntohl(raddr) && ntohl(raddr) <= end &&
- !config_find_lease_by_ipaddr(raddr)) {
- assigned = dhcpv4_insert_assignment(&iface->dhcpv4_assignments,
- a, raddr);
-
- if (assigned) {
- debug("Assigning the IP the client asked for: %s",
- inet_ntop(AF_INET, &a->addr, ipv4_str, sizeof(ipv4_str)));
- return true;
- }
+ /* The client asked for a specific address, let's try... */
+ if (ntohl(raddr) < start || ntohl(raddr) > end) {
+ debug("The requested IP address is outside the pool: %s",
+ inet_ntop(AF_INET, &raddr, ipv4_str, sizeof(ipv4_str)));
+ } else if (config_find_lease_by_ipaddr(raddr)) {
+ debug("The requested IP address is statically assigned: %s",
+ inet_ntop(AF_INET, &raddr, ipv4_str, sizeof(ipv4_str)));
+ } else if (!dhcpv4_insert_assignment(&iface->dhcpv4_assignments, a, raddr)) {
+ debug("The requested IP address is already assigned: %s",
+ inet_ntop(AF_INET, &raddr, ipv4_str, sizeof(ipv4_str)));
+ } else {
+ debug("Assigned the requested IP address: %s",
+ inet_ntop(AF_INET, &a->addr, ipv4_str, sizeof(ipv4_str)));
+ return true;
}
- /* Seed RNG with checksum of hwaddress */
+ /* Ok, we'll have to pick an address for the client... */
for (size_t i = 0; i < sizeof(a->hwaddr); ++i) {
- /* Knuth's multiplicative method */
+ /* ...hash the hwaddr (Knuth's multiplicative method)... */
uint8_t o = a->hwaddr[i];
- seed += (o*2654435761) % UINT32_MAX;
+ seed += (o * 2654435761) % UINT32_MAX;
}
+ /* ...use it to seed the RNG... */
srand(seed);
+ /* ...and try a bunch of times to assign a randomly chosen address */
for (uint32_t i = 0, try = (((uint32_t)rand()) % count) + start; i < count;
++i, try = (((try - start) + 1) % count) + start) {
uint32_t n_try = htonl(try);
@@ -411,14 +416,10 @@ static bool dhcpv4_assign(struct interface *iface, struct dhcp_assignment *a,
if (config_find_lease_by_ipaddr(n_try))
continue;
- assigned = dhcpv4_insert_assignment(&iface->dhcpv4_assignments,
- a, n_try);
-
- if (assigned) {
- debug("Assigning mapped IP: %s (try %u of %u)",
+ if (dhcpv4_insert_assignment(&iface->dhcpv4_assignments, a, n_try)) {
+ debug("Assigned IP adress from pool: %s (succeeded on attempt %u of %u)",
inet_ntop(AF_INET, &a->addr, ipv4_str, sizeof(ipv4_str)),
i + 1, count);
-
return true;
}
}