1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-12-26 01:59:53 +03:00

Cedar/IPC: Improve IPv6CP configuration

This commit is contained in:
Yihong Wu 2023-01-28 09:05:28 +00:00
parent 0e8174c6cf
commit 0cdf0eacbf
3 changed files with 23 additions and 52 deletions

View File

@ -2128,7 +2128,7 @@ void IPCIPv6Init(IPC *ipc)
ipc->IPv6RouterAdvs = NewList(NULL);
ipc->IPv6ClientEUI = 0;
ipc->IPv6ServerEUI = 0;
GenerateEui64Address6((UCHAR *)&ipc->IPv6ServerEUI, ipc->MacAddress);
ipc->IPv6State = IPC_PROTO_STATUS_CLOSED;
}
@ -2364,6 +2364,12 @@ bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVER
UINT i;
IPC_IPV6_ROUTER_ADVERTISEMENT *matchingRA = NULL;
bool isInPrefix = false;
if (LIST_NUM(ipc->IPv6RouterAdvs) == 0 && IPCSendIPv6RouterSoliciation(ipc) == false)
{
return false;
}
for (i = 0; i < LIST_NUM(ipc->IPv6RouterAdvs); i++)
{
IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, i);
@ -2383,19 +2389,13 @@ bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVER
return isInPrefix;
}
// Send router solicitation and then eventually populate the info from Router Advertisements
UINT64 IPCIPv6GetServerEui(IPC *ipc)
// Send router solicitation to find a router
bool IPCSendIPv6RouterSoliciation(IPC *ipc)
{
// It is already configured, nothing to do here
if (ipc->IPv6ServerEUI != 0)
{
return ipc->IPv6ServerEUI;
}
// If we don't have a valid client EUI, we can't generate a correct link local
if (ipc->IPv6ClientEUI == 0)
{
return ipc->IPv6ServerEUI;
return false;
}
if (LIST_NUM(ipc->IPv6RouterAdvs) == 0)
@ -2440,7 +2440,8 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc)
if (Tick64() >= giveup_time)
{
// We failed to receive any router advertisements
break;
FreeBuf(packet);
return false;
}
// The processing should populate the received RAs by itself
@ -2450,24 +2451,7 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc)
FreeBuf(packet);
}
// Populating the IPv6 Server EUI for IPV6CP
if (LIST_NUM(ipc->IPv6RouterAdvs) > 0)
{
IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, 0);
Copy(&ipc->IPv6ServerEUI, &ra->RouterAddress.address[8], sizeof(ipc->IPv6ServerEUI));
}
// If it is still not defined, let's just generate something random
while (ipc->IPv6ServerEUI == 0)
{
ipc->IPv6ServerEUI = Rand64();
if (ipc->IPv6ClientEUI == ipc->IPv6ServerEUI)
{
ipc->IPv6ServerEUI = 0;
}
}
return ipc->IPv6ServerEUI;
return true;
}
// Data flow

View File

@ -155,7 +155,7 @@ struct IPC
LIST *IPv6NeighborTable; // Neighbor Discovery Table
LIST *IPv6RouterAdvs; // Router offered prefixes
UINT64 IPv6ClientEUI; // The EUI of the client (for the SLAAC autoconf)
UINT64 IPv6ServerEUI; // The EUI of the server (from the RA discovery)
UINT64 IPv6ServerEUI; // The EUI of the server (from the IPC Mac address)
};
// MS-CHAPv2 authentication information
@ -233,7 +233,7 @@ bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui);
// RA
void IPCIPv6AddRouterPrefixes(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip);
bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA);
UINT64 IPCIPv6GetServerEui(IPC *ipc);
bool IPCSendIPv6RouterSoliciation(IPC *ipc);
// Data flow
BLOCK *IPCIPv6Recv(IPC *ipc);
void IPCIPv6Send(IPC *ipc, void *data, UINT size);

View File

@ -2191,7 +2191,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{
UINT64 newValue = 0;
UINT64 value = READ_UINT64(t->Data);
if (value != 0 && IPCIPv6CheckExistingLinkLocal(p->Ipc, value) == false)
if (value != 0 && value != p->Ipc->IPv6ServerEUI && IPCIPv6CheckExistingLinkLocal(p->Ipc, value) == false)
{
t->IsAccepted = true;
p->Ipc->IPv6ClientEUI = value;
@ -2199,23 +2199,14 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
else
{
t->IsAccepted = false;
GenerateEui64Address6((UCHAR *)&newValue, p->Ipc->MacAddress);
if (newValue != value && IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false)
while (true)
{
WRITE_UINT64(t->AltData, newValue);
t->AltDataSize = sizeof(UINT64);
}
else
{
while (true)
newValue = Rand64();
if (newValue != 0 && newValue != p->Ipc->IPv6ServerEUI && IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false)
{
newValue = Rand64();
if (IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false)
{
WRITE_UINT64(t->AltData, newValue);
t->AltDataSize = sizeof(UINT64);
break;
}
WRITE_UINT64(t->AltData, newValue);
t->AltDataSize = sizeof(UINT64);
break;
}
}
}
@ -2242,11 +2233,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
if (p->Ipc->IPv6ClientEUI != 0 && IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CLOSED)
{
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
UINT64 serverEui = IPCIPv6GetServerEui(p->Ipc);
if (serverEui != 0 && serverEui != p->Ipc->IPv6ClientEUI)
{
Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &serverEui, sizeof(UINT64)));
}
Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &p->Ipc->IPv6ServerEUI, sizeof(UINT64)));
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);