mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Merge PR #1218: Cedar: DHCP server now assigns static IPv4 address, if present in user note
This commit is contained in:
commit
3c140dde8d
@ -112,6 +112,7 @@ CONTRIBUTORS:
|
|||||||
- NV <nvsofts@gmail.com>
|
- NV <nvsofts@gmail.com>
|
||||||
- Olimjon <olim98@bk.ru>
|
- Olimjon <olim98@bk.ru>
|
||||||
- parly <https://github.com/parly>
|
- parly <https://github.com/parly>
|
||||||
|
- PeTeeR <tom2pet@gmail.com>
|
||||||
- Quantum <quantum2048@gmail.com>
|
- Quantum <quantum2048@gmail.com>
|
||||||
- Quintin <quintin@last.za.net>
|
- Quintin <quintin@last.za.net>
|
||||||
- Raymond Tau <raymondtau@gmail.com>
|
- Raymond Tau <raymondtau@gmail.com>
|
||||||
|
@ -1318,3 +1318,40 @@ bool GetUserMacAddressFromUserNote(UCHAR *mac, wchar_t *note)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the static IPv4 address from the user's note string
|
||||||
|
UINT GetUserIPv4AddressFromUserNote32(wchar_t *note)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
UINT ip32 = 0;
|
||||||
|
|
||||||
|
UINT i = UniSearchStrEx(note, USER_IPV4_STR_PREFIX, 0, false);
|
||||||
|
if (i != INFINITE)
|
||||||
|
{
|
||||||
|
wchar_t *ipv4str_start = ¬e[i + UniStrLen(USER_IPV4_STR_PREFIX)];
|
||||||
|
wchar_t ipv4str2[MAX_SIZE];
|
||||||
|
UNI_TOKEN_LIST *tokens;
|
||||||
|
|
||||||
|
UniStrCpy(ipv4str2, sizeof(ipv4str2), ipv4str_start);
|
||||||
|
UniTrim(ipv4str2);
|
||||||
|
|
||||||
|
tokens = UniParseToken(ipv4str2, L" ,/()[]");
|
||||||
|
if (tokens != NULL)
|
||||||
|
{
|
||||||
|
if (tokens->NumTokens >= 1)
|
||||||
|
{
|
||||||
|
wchar_t *ipv4str = tokens->Token[0];
|
||||||
|
if (UniIsEmptyStr(ipv4str) == false)
|
||||||
|
{
|
||||||
|
char ipv4str_a[MAX_SIZE];
|
||||||
|
UniToStr(ipv4str_a, sizeof(ipv4str_a), ipv4str);
|
||||||
|
ip32 = StrToIP32(ipv4str_a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UniFreeToken(tokens);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip32;
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define ACCOUNT_H
|
#define ACCOUNT_H
|
||||||
|
|
||||||
#define USER_MAC_STR_PREFIX L"MAC:"
|
#define USER_MAC_STR_PREFIX L"MAC:"
|
||||||
|
#define USER_IPV4_STR_PREFIX L"IPv4:"
|
||||||
|
|
||||||
// Policy item
|
// Policy item
|
||||||
struct POLICY_ITEM
|
struct POLICY_ITEM
|
||||||
@ -205,7 +206,6 @@ POLICY_ITEM *GetPolicyItem(UINT id);
|
|||||||
void GetPolicyValueRangeStr(wchar_t *str, UINT size, UINT id);
|
void GetPolicyValueRangeStr(wchar_t *str, UINT size, UINT id);
|
||||||
void FormatPolicyValue(wchar_t *str, UINT size, UINT id, UINT value);
|
void FormatPolicyValue(wchar_t *str, UINT size, UINT id, UINT value);
|
||||||
bool GetUserMacAddressFromUserNote(UCHAR *mac, wchar_t *note);
|
bool GetUserMacAddressFromUserNote(UCHAR *mac, wchar_t *note);
|
||||||
|
UINT GetUserIPv4AddressFromUserNote32(wchar_t *note);
|
||||||
|
|
||||||
#endif // ACCOUNT_H
|
#endif // ACCOUNT_H
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ void SessionMain(SESSION *s)
|
|||||||
SOCK *nicinfo_sock = NULL;
|
SOCK *nicinfo_sock = NULL;
|
||||||
bool is_server_session = false;
|
bool is_server_session = false;
|
||||||
bool lock_receive_blocks_queue = false;
|
bool lock_receive_blocks_queue = false;
|
||||||
|
UINT static_ip = 0;
|
||||||
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
{
|
{
|
||||||
@ -300,6 +302,13 @@ void SessionMain(SESSION *s)
|
|||||||
|
|
||||||
if (b->Size >= 14)
|
if (b->Size >= 14)
|
||||||
{
|
{
|
||||||
|
UINT ip;
|
||||||
|
if( (ip = PrepareDHCPRequestForStaticIPv4( s, b )) != 0 )
|
||||||
|
{
|
||||||
|
// Remember the static IP address to remove it from the leased IP address list later
|
||||||
|
static_ip = ip;
|
||||||
|
}
|
||||||
|
|
||||||
if (b->Buf[0] & 0x01)
|
if (b->Buf[0] & 0x01)
|
||||||
{
|
{
|
||||||
if (is_server_session == false)
|
if (is_server_session == false)
|
||||||
@ -603,6 +612,9 @@ CLEANUP:
|
|||||||
// Update the user information
|
// Update the user information
|
||||||
IncrementUserTraffic(s->Hub, s->UserNameReal, s);
|
IncrementUserTraffic(s->Hub, s->UserNameReal, s);
|
||||||
|
|
||||||
|
// Clear the DHCP lease record if assigned as a static client IP address
|
||||||
|
ClearDHCPLeaseRecordForIPv4(s, static_ip);
|
||||||
|
|
||||||
DelSession(s->Hub, s);
|
DelSession(s->Hub, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2316,3 +2328,140 @@ void Notify(SESSION *s, UINT code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UINT PrepareDHCPRequestForStaticIPv4(SESSION *s, BLOCK *b)
|
||||||
|
{
|
||||||
|
PKT *pkt = NULL;
|
||||||
|
DHCPV4_HEADER *dhcp = NULL;
|
||||||
|
UCHAR *data = NULL;
|
||||||
|
UINT size = 0;
|
||||||
|
UINT dhcp_header_size = 0;
|
||||||
|
UINT dhcp_data_offset = 0;
|
||||||
|
UINT magic_cookie = Endian32(DHCP_MAGIC_COOKIE);
|
||||||
|
DHCP_OPTION_LIST *opt = NULL;
|
||||||
|
USER *user = NULL;
|
||||||
|
UINT ret_ip = 0;
|
||||||
|
|
||||||
|
if ((s->Username == NULL) || (StrLen(s->Username) == 0) || (StrCmpi(s->Username, SNAT_USER_NAME_PRINT) == 0) ||
|
||||||
|
(StrCmpi( s->Username, BRIDGE_USER_NAME_PRINT) == 0) || (StrCmpi(s->Username, LINK_USER_NAME_PRINT) == 0))
|
||||||
|
{
|
||||||
|
return ret_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkt = ParsePacket(b->Buf, b->Size);
|
||||||
|
if (pkt == NULL)
|
||||||
|
{
|
||||||
|
return ret_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_UDP && pkt->TypeL7 == L7_DHCPV4)
|
||||||
|
{
|
||||||
|
if (pkt->L7.DHCPv4Header->OpCode != 1)
|
||||||
|
{
|
||||||
|
goto CLEANUP_TP;
|
||||||
|
}
|
||||||
|
|
||||||
|
dhcp = pkt->L7.DHCPv4Header;
|
||||||
|
dhcp_header_size = sizeof(DHCPV4_HEADER);
|
||||||
|
dhcp_data_offset = (UINT)(((UCHAR *)pkt->L7.DHCPv4Header) - ((UCHAR *)pkt->MacHeader) + dhcp_header_size);
|
||||||
|
data = ((UCHAR *)dhcp) + dhcp_header_size;
|
||||||
|
size = pkt->PacketSize - dhcp_data_offset;
|
||||||
|
|
||||||
|
if (dhcp_header_size < 5)
|
||||||
|
{
|
||||||
|
goto CLEANUP_TP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for Magic Cookie
|
||||||
|
while (size >= 5)
|
||||||
|
{
|
||||||
|
if (Cmp(data, &magic_cookie, sizeof(magic_cookie)) == 0)
|
||||||
|
{
|
||||||
|
// Found
|
||||||
|
data += 4;
|
||||||
|
size -= 4;
|
||||||
|
opt = ParseDhcpOptionList(data, size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++data;
|
||||||
|
--size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt == NULL)
|
||||||
|
{
|
||||||
|
goto CLEANUP_TP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt->Opcode == DHCP_DISCOVER || opt->Opcode == DHCP_REQUEST)
|
||||||
|
{
|
||||||
|
if (s->Hub != NULL)
|
||||||
|
{
|
||||||
|
user = AcGetUser( s->Hub, s->Username );
|
||||||
|
if (user != NULL)
|
||||||
|
{
|
||||||
|
dhcp->ServerIP = GetUserIPv4AddressFromUserNote32(user->Note);
|
||||||
|
ReleaseUser(user);
|
||||||
|
if (s->Hub->SecureNAT != NULL && s->Hub->SecureNAT->Nat != NULL)
|
||||||
|
{
|
||||||
|
VH *v = s->Hub->SecureNAT->Nat->Virtual;
|
||||||
|
if (v != NULL && v->UseDhcp == true && v->DhcpLeaseList != NULL)
|
||||||
|
{
|
||||||
|
DHCP_LEASE *d = SearchDhcpLeaseByIp(v, dhcp->ServerIP);
|
||||||
|
|
||||||
|
// The given static IP address is not used - it's OK
|
||||||
|
if (d == NULL)
|
||||||
|
{
|
||||||
|
ret_ip = dhcp->ServerIP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CLEANUP_TP:
|
||||||
|
if (opt != NULL)
|
||||||
|
{
|
||||||
|
Free(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkt != NULL)
|
||||||
|
{
|
||||||
|
FreePacket(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearDHCPLeaseRecordForIPv4(SESSION *s, UINT static_ip)
|
||||||
|
{
|
||||||
|
if (s == NULL || static_ip == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->Hub == NULL || s->Hub->SecureNAT == NULL || s->Hub->SecureNAT->Nat == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VH *v = s->Hub->SecureNAT->Nat->Virtual;
|
||||||
|
if (v == NULL || v->DhcpLeaseList == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DHCP_LEASE *d = SearchDhcpLeaseByIp(v, static_ip);
|
||||||
|
if (d == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LockList(v->DhcpLeaseList);
|
||||||
|
{
|
||||||
|
FreeDhcpLease(d);
|
||||||
|
Delete(v->DhcpLeaseList, d);
|
||||||
|
}
|
||||||
|
UnlockList( v->DhcpLeaseList);
|
||||||
|
}
|
||||||
|
@ -339,6 +339,9 @@ void CancelList(LIST *o);
|
|||||||
bool IsPriorityHighestPacketForQoS(void *data, UINT size);
|
bool IsPriorityHighestPacketForQoS(void *data, UINT size);
|
||||||
UINT GetNextDelayedPacketTickDiff(SESSION *s);
|
UINT GetNextDelayedPacketTickDiff(SESSION *s);
|
||||||
|
|
||||||
|
UINT PrepareDHCPRequestForStaticIPv4(SESSION *s, BLOCK *b);
|
||||||
|
void ClearDHCPLeaseRecordForIPv4(SESSION *s, UINT static_ip);
|
||||||
|
|
||||||
#endif // SESSION_H
|
#endif // SESSION_H
|
||||||
|
|
||||||
|
|
||||||
|
@ -9198,6 +9198,11 @@ PENDING_LIST_CLEANUP:
|
|||||||
|
|
||||||
// Correspond to the DHCP REQUEST
|
// Correspond to the DHCP REQUEST
|
||||||
UINT ServeDhcpRequest(VH *v, UCHAR *mac, UINT request_ip)
|
UINT ServeDhcpRequest(VH *v, UCHAR *mac, UINT request_ip)
|
||||||
|
{
|
||||||
|
return ServeDhcpRequestEx(v, mac, request_ip, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT ServeDhcpRequestEx(VH *v, UCHAR *mac, UINT request_ip, bool is_static_ip)
|
||||||
{
|
{
|
||||||
UINT ret;
|
UINT ret;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
@ -9206,7 +9211,7 @@ UINT ServeDhcpRequest(VH *v, UCHAR *mac, UINT request_ip)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ServeDhcpDiscover(v, mac, request_ip);
|
ret = ServeDhcpDiscoverEx(v, mac, request_ip, is_static_ip);
|
||||||
if (ret != request_ip)
|
if (ret != request_ip)
|
||||||
{
|
{
|
||||||
if (request_ip != 0)
|
if (request_ip != 0)
|
||||||
@ -9309,6 +9314,34 @@ UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT ServeDhcpDiscoverEx(VH *v, UCHAR *mac, UINT request_ip, bool is_static_ip)
|
||||||
|
{
|
||||||
|
if (is_static_ip == false)
|
||||||
|
{
|
||||||
|
return ServeDhcpDiscover(v, mac, request_ip );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v == NULL || mac == NULL || request_ip == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DHCP_LEASE *d = SearchDhcpLeaseByIp(v, request_ip);
|
||||||
|
if (d != NULL)
|
||||||
|
{
|
||||||
|
// The requested IP address is used already
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For static IP, the requested IP address must NOT be within the range of the DHCP pool
|
||||||
|
if (Endian32(request_ip) < Endian32(v->DhcpIpStart) || Endian32(request_ip) > Endian32(v->DhcpIpEnd))
|
||||||
|
{
|
||||||
|
return request_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Take an appropriate IP addresses that can be assigned newly
|
// Take an appropriate IP addresses that can be assigned newly
|
||||||
UINT GetFreeDhcpIpAddress(VH *v)
|
UINT GetFreeDhcpIpAddress(VH *v)
|
||||||
{
|
{
|
||||||
@ -9469,21 +9502,30 @@ void VirtualDhcpServer(VH *v, PKT *p)
|
|||||||
if (dhcp->OpCode == 1 && (opt->Opcode == DHCP_DISCOVER || opt->Opcode == DHCP_REQUEST || opt->Opcode == DHCP_INFORM))
|
if (dhcp->OpCode == 1 && (opt->Opcode == DHCP_DISCOVER || opt->Opcode == DHCP_REQUEST || opt->Opcode == DHCP_INFORM))
|
||||||
{
|
{
|
||||||
// Operate as the server
|
// Operate as the server
|
||||||
UINT ip = 0;
|
UINT ip = 0, ip_static = dhcp->ServerIP;
|
||||||
|
dhcp->ServerIP = 0;
|
||||||
|
|
||||||
if (opt->RequestedIp == 0)
|
if (opt->RequestedIp == 0)
|
||||||
{
|
{
|
||||||
opt->RequestedIp = p->L3.IPv4Header->SrcIP;
|
opt->RequestedIp = (ip_static ? ip_static : p->L3.IPv4Header->SrcIP);
|
||||||
}
|
}
|
||||||
if (opt->Opcode == DHCP_DISCOVER)
|
if (opt->Opcode == DHCP_DISCOVER)
|
||||||
{
|
{
|
||||||
// Return an IP address that can be used
|
// Return an IP address that can be used
|
||||||
ip = ServeDhcpDiscover(v, p->MacAddressSrc, opt->RequestedIp);
|
ip = ServeDhcpDiscoverEx(v, p->MacAddressSrc, opt->RequestedIp, ip_static);
|
||||||
}
|
}
|
||||||
else if (opt->Opcode == DHCP_REQUEST)
|
else if (opt->Opcode == DHCP_REQUEST)
|
||||||
{
|
{
|
||||||
// Determine the IP address
|
// Determine the IP address
|
||||||
ip = ServeDhcpRequest(v, p->MacAddressSrc, opt->RequestedIp);
|
if (ip_static && opt->RequestedIp != ip_static)
|
||||||
|
{
|
||||||
|
// Don't allow opt->RequestedIp other than the IP written in user's note
|
||||||
|
ip = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ip = ServeDhcpRequestEx(v, p->MacAddressSrc, opt->RequestedIp, ip_static);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip != 0 || opt->Opcode == DHCP_INFORM)
|
if (ip != 0 || opt->Opcode == DHCP_INFORM)
|
||||||
|
@ -514,9 +514,11 @@ DHCP_LEASE *SearchDhcpPendingLeaseByMac(VH *v, UCHAR *mac);
|
|||||||
DHCP_LEASE *SearchDhcpLeaseByIp(VH *v, UINT ip);
|
DHCP_LEASE *SearchDhcpLeaseByIp(VH *v, UINT ip);
|
||||||
DHCP_LEASE *SearchDhcpPendingLeaseByIp(VH *v, UINT ip);
|
DHCP_LEASE *SearchDhcpPendingLeaseByIp(VH *v, UINT ip);
|
||||||
UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip);
|
UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip);
|
||||||
|
UINT ServeDhcpDiscoverEx(VH *v, UCHAR *mac, UINT request_ip, bool is_static_ip);
|
||||||
UINT GetFreeDhcpIpAddress(VH *v);
|
UINT GetFreeDhcpIpAddress(VH *v);
|
||||||
UINT GetFreeDhcpIpAddressByRandom(VH *v, UCHAR *mac);
|
UINT GetFreeDhcpIpAddressByRandom(VH *v, UCHAR *mac);
|
||||||
UINT ServeDhcpRequest(VH *v, UCHAR *mac, UINT request_ip);
|
UINT ServeDhcpRequest(VH *v, UCHAR *mac, UINT request_ip);
|
||||||
|
UINT ServeDhcpRequestEx(VH *v, UCHAR *mac, UINT request_ip, bool is_static_ip);
|
||||||
void VirtualDhcpSend(VH *v, UINT tran_id, UINT dest_ip, UINT dest_port,
|
void VirtualDhcpSend(VH *v, UINT tran_id, UINT dest_ip, UINT dest_port,
|
||||||
UINT new_ip, UCHAR *client_mac, BUF *b, UINT hw_type, UINT hw_addr_size);
|
UINT new_ip, UCHAR *client_mac, BUF *b, UINT hw_type, UINT hw_addr_size);
|
||||||
void VLog(VH *v, char *str);
|
void VLog(VH *v, char *str);
|
||||||
@ -587,7 +589,4 @@ void NnDeleteOldestNatSessionIfNecessary(NATIVE_NAT *t, UINT ip, UINT protocol);
|
|||||||
|
|
||||||
void NnSetSecureNatTargetHostname(char *name);
|
void NnSetSecureNatTargetHostname(char *name);
|
||||||
|
|
||||||
|
|
||||||
#endif // VIRTUAL_H
|
#endif // VIRTUAL_H
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user