diff options
| author | David Härdeman | 2025-10-08 13:46:24 +0000 |
|---|---|---|
| committer | Álvaro Fernández Rojas | 2025-10-25 15:08:59 +0000 |
| commit | 3ad54baa4adc0d6d102ccdc82f8b1f7439059f6e (patch) | |
| tree | 97126843cad18276c0fa0d7176337e41cab45116 | |
| parent | fab8f67818e69c4400c67293d8240d5f93709673 (diff) | |
| download | odhcpd-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.c | 55 |
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; } } |