aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/leases.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/leases.c')
-rw-r--r--networking/udhcp/leases.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index 7aeb37bae..c5b60b108 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -137,21 +137,42 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
137 uint32_t addr; 137 uint32_t addr;
138 struct dyn_lease *oldest_lease = NULL; 138 struct dyn_lease *oldest_lease = NULL;
139 139
140 addr = server_config.start_ip; /* addr is in host order here */ 140#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC
141 for (; addr <= server_config.end_ip; addr++) { 141 uint32_t stop;
142 unsigned i, hash;
143
144 /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good
145 * dispersal even with similarly-valued "strings".
146 */
147 hash = 0;
148 for (i = 0; i < 6; i++)
149 hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash;
150
151 /* pick a seed based on hwaddr then iterate until we find a free address. */
152 addr = server_config.start_ip
153 + (hash % (1 + server_config.end_ip - server_config.start_ip));
154 stop = addr;
155#else
156 addr = server_config.start_ip;
157#define stop (server_config.end_ip + 1)
158#endif
159 do {
142 uint32_t nip; 160 uint32_t nip;
143 struct dyn_lease *lease; 161 struct dyn_lease *lease;
144 162
145 /* ie, 192.168.55.0 */ 163 /* ie, 192.168.55.0 */
146 if ((addr & 0xff) == 0) 164 if ((addr & 0xff) == 0)
147 continue; 165 goto next_addr;
148 /* ie, 192.168.55.255 */ 166 /* ie, 192.168.55.255 */
149 if ((addr & 0xff) == 0xff) 167 if ((addr & 0xff) == 0xff)
150 continue; 168 goto next_addr;
151 nip = htonl(addr); 169 nip = htonl(addr);
170 /* skip our own address */
171 if (nip == server_config.server_nip)
172 goto next_addr;
152 /* is this a static lease addr? */ 173 /* is this a static lease addr? */
153 if (is_nip_reserved(server_config.static_leases, nip)) 174 if (is_nip_reserved(server_config.static_leases, nip))
154 continue; 175 goto next_addr;
155 176
156 lease = find_lease_by_nip(nip); 177 lease = find_lease_by_nip(nip);
157 if (!lease) { 178 if (!lease) {
@@ -162,7 +183,14 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
162 if (!oldest_lease || lease->expires < oldest_lease->expires) 183 if (!oldest_lease || lease->expires < oldest_lease->expires)
163 oldest_lease = lease; 184 oldest_lease = lease;
164 } 185 }
165 } 186
187 next_addr:
188 addr++;
189#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC
190 if (addr > server_config.end_ip)
191 addr = server_config.start_ip;
192#endif
193 } while (addr != stop);
166 194
167 if (oldest_lease 195 if (oldest_lease
168 && is_expired_lease(oldest_lease) 196 && is_expired_lease(oldest_lease)