diff options
author | dnobori <da.git@softether.co.jp> | 2015-01-30 16:30:34 +0300 |
---|---|---|
committer | dnobori <da.git@softether.co.jp> | 2015-01-30 16:30:34 +0300 |
commit | 06a72040a347e567bec560e3426e5ccddcf785c5 (patch) | |
tree | 4f6c27e5ee5ab118621b78bc583ac15110a681fa /src/Cedar/Virtual.c | |
parent | 75f9836ce5f0a1dea2c3fe304bbc26c962ee64bf (diff) |
v4.13-9522-beta
Diffstat (limited to 'src/Cedar/Virtual.c')
-rw-r--r-- | src/Cedar/Virtual.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/Cedar/Virtual.c b/src/Cedar/Virtual.c index 44e35e55..444c7f9d 100644 --- a/src/Cedar/Virtual.c +++ b/src/Cedar/Virtual.c @@ -9282,7 +9282,16 @@ UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip) if (ret == 0)
{
// Take an appropriate IP addresses that can be assigned newly
- ret = GetFreeDhcpIpAddress(v);
+ HUB_OPTION *opt = NatGetHubOption(v);
+
+ if (opt != NULL && opt->SecureNAT_RandomizeAssignIp)
+ {
+ ret = GetFreeDhcpIpAddressByRandom(v, mac);
+ }
+ else
+ {
+ ret = GetFreeDhcpIpAddress(v);
+ }
}
return ret;
@@ -9316,6 +9325,56 @@ UINT GetFreeDhcpIpAddress(VH *v) return 0;
}
+// Take an appropriate IP addresses that can be assigned newly (random)
+UINT GetFreeDhcpIpAddressByRandom(VH *v, UCHAR *mac)
+{
+ UINT ip_start, ip_end;
+ UINT i;
+ UINT num_retry;
+ // Validate arguments
+ if (v == NULL || mac == NULL)
+ {
+ return 0;
+ }
+
+ ip_start = Endian32(v->DhcpIpStart);
+ ip_end = Endian32(v->DhcpIpEnd);
+
+ if (ip_start > ip_end)
+ {
+ return 0;
+ }
+
+ num_retry = (ip_end - ip_start + 1) * 2;
+ num_retry = MIN(num_retry, 65536 * 2);
+
+ for (i = 0;i < num_retry;i++)
+ {
+ UCHAR rand_seed[sizeof(UINT) + 6];
+ UCHAR hash[16];
+ UINT rand_int;
+ UINT new_ip;
+
+ WRITE_UINT(&rand_seed[0], i);
+ Copy(rand_seed + sizeof(UINT), mac, 6);
+
+ Hash(hash, rand_seed, sizeof(rand_seed), false);
+
+ rand_int = READ_UINT(hash);
+
+ new_ip = Endian32(ip_start + (rand_int % (ip_end - ip_start + 1)));
+
+ if (SearchDhcpLeaseByIp(v, new_ip) == NULL)
+ {
+ // A free IP address is found
+ return new_ip;
+ }
+ }
+
+ // There is no free address
+ return 0;
+}
+
// Virtual DHCP Server
void VirtualDhcpServer(VH *v, PKT *p)
{
|