mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2025-07-12 02:34:59 +03:00
Cedar: DHCP server now assigns static IPv4 address, if present in user note
This works for all VPN protocols. In SessionMain(): for DHCPDISCOVER and DHCPREQUEST frames, write the static IP address (which is retrieved from the user notes) in the SIADDR field of DHCPHEADER. In VirtualDhcpServer(): for DHCPDISCOVER and DHCPREQUEST frames, read the static IP address from the SIADDR field of DHCPHEADER and assign it to the client.
This commit is contained in:
@ -33,6 +33,8 @@ void SessionMain(SESSION *s)
|
||||
SOCK *nicinfo_sock = NULL;
|
||||
bool is_server_session = false;
|
||||
bool lock_receive_blocks_queue = false;
|
||||
UINT static_ip = 0;
|
||||
|
||||
// Validate arguments
|
||||
if (s == NULL)
|
||||
{
|
||||
@ -300,6 +302,13 @@ void SessionMain(SESSION *s)
|
||||
|
||||
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 (is_server_session == false)
|
||||
@ -603,6 +612,9 @@ CLEANUP:
|
||||
// Update the user information
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2309,3 +2321,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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user