mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Preliminary implementation of IPv6CP and IPv6 for PPP (untested)
This commit is contained in:
parent
f627b64264
commit
f2fee4d32c
@ -2589,13 +2589,13 @@ void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size)
|
|||||||
|
|
||||||
if (p->BroadcastPacket || Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) == 0)
|
if (p->BroadcastPacket || Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) == 0)
|
||||||
{
|
{
|
||||||
if (IsValidUnicastMacAddress(p->MacAddressSrc))
|
if (IsMacUnicast(p->MacAddressSrc))
|
||||||
{
|
{
|
||||||
Copy(e->RawIpYourMacAddr, p->MacAddressSrc, 6);
|
Copy(e->RawIpYourMacAddr, p->MacAddressSrc, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsZero(e->RawIpYourMacAddr, 6) || IsValidUnicastMacAddress(p->MacAddressSrc) == false ||
|
if (IsZero(e->RawIpYourMacAddr, 6) || IsMacUnicast(p->MacAddressSrc) == false ||
|
||||||
(p->BroadcastPacket == false && Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) != 0))
|
(p->BroadcastPacket == false && Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) != 0))
|
||||||
{
|
{
|
||||||
Free(data);
|
Free(data);
|
||||||
|
@ -583,6 +583,7 @@ typedef struct IPC_DHCP_RELEASE_QUEUE IPC_DHCP_RELEASE_QUEUE;
|
|||||||
typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO;
|
typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO;
|
||||||
typedef struct IPC_SESSION_SHARED_BUFFER_DATA IPC_SESSION_SHARED_BUFFER_DATA;
|
typedef struct IPC_SESSION_SHARED_BUFFER_DATA IPC_SESSION_SHARED_BUFFER_DATA;
|
||||||
typedef struct IPC_IPV6_ROUTER_ADVERTISEMENT IPC_IPV6_ROUTER_ADVERTISEMENT;
|
typedef struct IPC_IPV6_ROUTER_ADVERTISEMENT IPC_IPV6_ROUTER_ADVERTISEMENT;
|
||||||
|
typedef struct IPC_DHCPV4_AWAIT IPC_DHCPV4_AWAIT;
|
||||||
|
|
||||||
|
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
175
src/Cedar/IPC.c
175
src/Cedar/IPC.c
@ -147,7 +147,7 @@ void IPCAsyncThreadProc(THREAD *thread, void *param)
|
|||||||
|
|
||||||
// Save the options list
|
// Save the options list
|
||||||
Copy(&a->L3ClientAddressOption, &cao, sizeof(DHCP_OPTION_LIST));
|
Copy(&a->L3ClientAddressOption, &cao, sizeof(DHCP_OPTION_LIST));
|
||||||
a->L3DhcpRenewInterval = t * 1000;
|
a->L3DhcpRenewInterval = (UINT64)t * (UINT64)1000;
|
||||||
|
|
||||||
// Set the obtained IP address parameters to the IPC virtual host
|
// Set the obtained IP address parameters to the IPC virtual host
|
||||||
UINTToIP(&ip, cao.ClientAddress);
|
UINTToIP(&ip, cao.ClientAddress);
|
||||||
@ -488,6 +488,10 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
|
|||||||
|
|
||||||
// Create an IPv4 reception queue
|
// Create an IPv4 reception queue
|
||||||
ipc->IPv4ReceivedQueue = NewQueue();
|
ipc->IPv4ReceivedQueue = NewQueue();
|
||||||
|
ipc->IPv4State = IPC_PROTO_STATUS_CLOSED;
|
||||||
|
|
||||||
|
ipc->DHCPv4Awaiter.IsAwaiting = false;
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
|
|
||||||
IPCIPv6Init(ipc);
|
IPCIPv6Init(ipc);
|
||||||
|
|
||||||
@ -530,6 +534,10 @@ IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address)
|
|||||||
|
|
||||||
// Create an IPv4 reception queue
|
// Create an IPv4 reception queue
|
||||||
ipc->IPv4ReceivedQueue = NewQueue();
|
ipc->IPv4ReceivedQueue = NewQueue();
|
||||||
|
ipc->IPv4State = IPC_PROTO_STATUS_CLOSED;
|
||||||
|
|
||||||
|
ipc->DHCPv4Awaiter.IsAwaiting = false;
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
|
|
||||||
ipc->FlushList = NewTubeFlushList();
|
ipc->FlushList = NewTubeFlushList();
|
||||||
|
|
||||||
@ -614,6 +622,8 @@ void FreeIPC(IPC *ipc)
|
|||||||
|
|
||||||
ReleaseSharedBuffer(ipc->IpcSessionSharedBuffer);
|
ReleaseSharedBuffer(ipc->IpcSessionSharedBuffer);
|
||||||
|
|
||||||
|
FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData);
|
||||||
|
|
||||||
IPCIPv6Free(ipc);
|
IPCIPv6Free(ipc);
|
||||||
|
|
||||||
Free(ipc);
|
Free(ipc);
|
||||||
@ -871,6 +881,9 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION
|
|||||||
// Time-out inspection
|
// Time-out inspection
|
||||||
if ((expecting_code != 0) && (now >= giveup_time))
|
if ((expecting_code != 0) && (now >= giveup_time))
|
||||||
{
|
{
|
||||||
|
ipc->DHCPv4Awaiter.IsAwaiting = false;
|
||||||
|
FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData);
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,6 +893,9 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION
|
|||||||
dhcp_packet = IPCBuildDhcpRequest(ipc, dest_ip, tran_id, opt);
|
dhcp_packet = IPCBuildDhcpRequest(ipc, dest_ip, tran_id, opt);
|
||||||
if (dhcp_packet == NULL)
|
if (dhcp_packet == NULL)
|
||||||
{
|
{
|
||||||
|
ipc->DHCPv4Awaiter.IsAwaiting = false;
|
||||||
|
FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData);
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,6 +905,9 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION
|
|||||||
|
|
||||||
if (expecting_code == 0)
|
if (expecting_code == 0)
|
||||||
{
|
{
|
||||||
|
ipc->DHCPv4Awaiter.IsAwaiting = false;
|
||||||
|
FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData);
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,48 +917,28 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Happy processing
|
// Happy processing
|
||||||
|
ipc->DHCPv4Awaiter.IsAwaiting = true;
|
||||||
|
FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData);
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
|
ipc->DHCPv4Awaiter.TransCode = tran_id;
|
||||||
|
ipc->DHCPv4Awaiter.OpCode = expecting_code;
|
||||||
IPCProcessL3Events(ipc);
|
IPCProcessL3Events(ipc);
|
||||||
|
|
||||||
while (true)
|
if (ipc->DHCPv4Awaiter.DhcpData != NULL)
|
||||||
{
|
{
|
||||||
// Receive a packet
|
DHCPV4_DATA *dhcp = ipc->DHCPv4Awaiter.DhcpData;
|
||||||
BLOCK *b = IPCRecvIPv4(ipc);
|
ipc->DHCPv4Awaiter.IsAwaiting = false;
|
||||||
PKT *pkt;
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
DHCPV4_DATA *dhcp;
|
|
||||||
|
|
||||||
if (b == NULL)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the packet
|
|
||||||
pkt = ParsePacketIPv4WithDummyMacHeader(b->Buf, b->Size);
|
|
||||||
|
|
||||||
dhcp = ParseDHCPv4Data(pkt);
|
|
||||||
|
|
||||||
if (dhcp != NULL)
|
|
||||||
{
|
|
||||||
if (Endian32(dhcp->Header->TransactionId) == tran_id && dhcp->OpCode == expecting_code)
|
|
||||||
{
|
|
||||||
// Expected operation code and transaction ID are returned
|
|
||||||
FreePacketWithData(pkt);
|
|
||||||
FreeBlock(b);
|
|
||||||
|
|
||||||
return dhcp;
|
return dhcp;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeDHCPv4Data(dhcp);
|
|
||||||
}
|
|
||||||
|
|
||||||
FreePacketWithData(pkt);
|
|
||||||
|
|
||||||
FreeBlock(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsTubeConnected(ipc->Sock->RecvTube) == false || IsTubeConnected(ipc->Sock->SendTube) == false ||
|
if (IsTubeConnected(ipc->Sock->RecvTube) == false || IsTubeConnected(ipc->Sock->SendTube) == false ||
|
||||||
(discon_poll_tube != NULL && IsTubeConnected(discon_poll_tube) == false))
|
(discon_poll_tube != NULL && IsTubeConnected(discon_poll_tube) == false))
|
||||||
{
|
{
|
||||||
// Session is disconnected
|
// Session is disconnected
|
||||||
|
ipc->DHCPv4Awaiter.IsAwaiting = false;
|
||||||
|
FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData);
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -947,6 +946,9 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION
|
|||||||
WaitForTubes(tubes, num_tubes, GetNextIntervalForInterrupt(ipc->Interrupt));
|
WaitForTubes(tubes, num_tubes, GetNextIntervalForInterrupt(ipc->Interrupt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipc->DHCPv4Awaiter.IsAwaiting = false;
|
||||||
|
FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData);
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1301,6 +1303,16 @@ void IPCProcessL3Events(IPC *ipc)
|
|||||||
{
|
{
|
||||||
IPCProcessL3EventsEx(ipc, 0);
|
IPCProcessL3EventsEx(ipc, 0);
|
||||||
}
|
}
|
||||||
|
void IPCProcessL3EventsIPv4Only(IPC *ipc)
|
||||||
|
{
|
||||||
|
UINT previousStatus4 = IPC_PROTO_GET_STATUS(ipc, IPv4State);
|
||||||
|
UINT previousStatus6 = IPC_PROTO_GET_STATUS(ipc, IPv6State);
|
||||||
|
IPC_PROTO_SET_STATUS(ipc, IPv4State, IPC_PROTO_STATUS_OPENED);
|
||||||
|
IPC_PROTO_SET_STATUS(ipc, IPv6State, IPC_PROTO_STATUS_CLOSED);
|
||||||
|
IPCProcessL3Events(ipc);
|
||||||
|
IPC_PROTO_SET_STATUS(ipc, IPv4State, previousStatus4);
|
||||||
|
IPC_PROTO_SET_STATUS(ipc, IPv6State, previousStatus6);
|
||||||
|
}
|
||||||
void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
|
void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
|
||||||
{
|
{
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
@ -1340,6 +1352,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
|
|||||||
// If the source MAC address is itselves or invalid address, ignore the packet
|
// If the source MAC address is itselves or invalid address, ignore the packet
|
||||||
if (Cmp(src_mac, ipc->MacAddress, 6) != 0 && !IsMacUnicast(src_mac))
|
if (Cmp(src_mac, ipc->MacAddress, 6) != 0 && !IsMacUnicast(src_mac))
|
||||||
{
|
{
|
||||||
|
Debug("Received packed for L3 parsing\n");
|
||||||
if (protocol == MAC_PROTO_ARPV4)
|
if (protocol == MAC_PROTO_ARPV4)
|
||||||
{
|
{
|
||||||
// ARP receiving process
|
// ARP receiving process
|
||||||
@ -1347,6 +1360,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
|
|||||||
}
|
}
|
||||||
else if (protocol == MAC_PROTO_IPV4)
|
else if (protocol == MAC_PROTO_IPV4)
|
||||||
{
|
{
|
||||||
|
Debug("MAC_PROTO_IPV4\n");
|
||||||
// IPv4 receiving process
|
// IPv4 receiving process
|
||||||
if (b->Size >= (14 + 20))
|
if (b->Size >= (14 + 20))
|
||||||
{
|
{
|
||||||
@ -1390,11 +1404,44 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
|
|||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
|
// Parse DHCP packets
|
||||||
|
bool packetConsumed = false;
|
||||||
|
if (ipc->DHCPv4Awaiter.IsAwaiting)
|
||||||
|
{
|
||||||
|
PKT *pkt;
|
||||||
|
DHCPV4_DATA *dhcp;
|
||||||
|
|
||||||
|
Debug("Parsing for DHCP awaiter\n");
|
||||||
|
pkt = ParsePacketIPv4WithDummyMacHeader(data, size);
|
||||||
|
dhcp = ParseDHCPv4Data(pkt);
|
||||||
|
|
||||||
|
if (dhcp != NULL)
|
||||||
|
{
|
||||||
|
if (Endian32(dhcp->Header->TransactionId) == ipc->DHCPv4Awaiter.TransCode &&
|
||||||
|
dhcp->OpCode == ipc->DHCPv4Awaiter.OpCode)
|
||||||
|
{
|
||||||
|
FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData);
|
||||||
|
ipc->DHCPv4Awaiter.DhcpData = dhcp;
|
||||||
|
packetConsumed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FreeDHCPv4Data(dhcp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePacket(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
IPCAssociateOnArpTable(ipc, &ip_src, src_mac);
|
IPCAssociateOnArpTable(ipc, &ip_src, src_mac);
|
||||||
|
|
||||||
|
if (ipc->IPv4State == IPC_PROTO_STATUS_OPENED && !packetConsumed)
|
||||||
|
{
|
||||||
// Place in the reception queue
|
// Place in the reception queue
|
||||||
InsertQueue(ipc->IPv4ReceivedQueue, NewBlock(data, size, 0));
|
InsertQueue(ipc->IPv4ReceivedQueue, NewBlock(data, size, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This packet is discarded because it is irrelevant for me
|
// This packet is discarded because it is irrelevant for me
|
||||||
@ -1409,8 +1456,9 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
|
|||||||
{
|
{
|
||||||
IP ip_src, ip_dst;
|
IP ip_src, ip_dst;
|
||||||
bool ndtProcessed = false;
|
bool ndtProcessed = false;
|
||||||
|
UINT size = p->L3.IPv6Header->PayloadLength + sizeof(IPV6_HEADER);
|
||||||
|
|
||||||
UCHAR *data = Clone(p->L3.IPv6Header, p->L3.IPv6Header->PayloadLength + sizeof(IPV6_HEADER));
|
UCHAR *data = Clone(p->L3.IPv6Header, size);
|
||||||
|
|
||||||
IPv6AddrToIP(&ip_src, &p->IPv6HeaderPacketInfo.IPv6Header->SrcAddress);
|
IPv6AddrToIP(&ip_src, &p->IPv6HeaderPacketInfo.IPv6Header->SrcAddress);
|
||||||
IPv6AddrToIP(&ip_dst, &p->IPv6HeaderPacketInfo.IPv6Header->DestAddress);
|
IPv6AddrToIP(&ip_dst, &p->IPv6HeaderPacketInfo.IPv6Header->DestAddress);
|
||||||
@ -1426,7 +1474,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
|
|||||||
// We save the router advertisement data for later use
|
// We save the router advertisement data for later use
|
||||||
IPCIPv6AddRouterPrefix(ipc, &p->ICMPv6HeaderPacketInfo.OptionList, src_mac, &ip_src);
|
IPCIPv6AddRouterPrefix(ipc, &p->ICMPv6HeaderPacketInfo.OptionList, src_mac, &ip_src);
|
||||||
IPCIPv6AssociateOnNDTEx(ipc, &ip_src, src_mac, true);
|
IPCIPv6AssociateOnNDTEx(ipc, &ip_src, src_mac, true);
|
||||||
IPCIPv6AssociateOnNDTEx(ipc, &ip_src, &p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer, true);
|
IPCIPv6AssociateOnNDTEx(ipc, &ip_src, &p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, true);
|
||||||
break;
|
break;
|
||||||
case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
|
case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
|
||||||
// We save the neighbor advertisements into NDT
|
// We save the neighbor advertisements into NDT
|
||||||
@ -1445,7 +1493,10 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: should we or not filter Neighbor Advertisements and/or Neighbor Solicitations?
|
/// TODO: should we or not filter Neighbor Advertisements and/or Neighbor Solicitations?
|
||||||
InsertQueue(ipc->IPv6ReceivedQueue, data);
|
if (ipc->IPv6State == IPC_PROTO_STATUS_OPENED)
|
||||||
|
{
|
||||||
|
InsertQueue(ipc->IPv6ReceivedQueue, NewBlock(data, size, 0));
|
||||||
|
}
|
||||||
|
|
||||||
FreePacket(p);
|
FreePacket(p);
|
||||||
}
|
}
|
||||||
@ -1948,6 +1999,8 @@ void IPCIPv6Init(IPC *ipc)
|
|||||||
|
|
||||||
ipc->IPv6ClientEUI = 0;
|
ipc->IPv6ClientEUI = 0;
|
||||||
ipc->IPv6ServerEUI = 0;
|
ipc->IPv6ServerEUI = 0;
|
||||||
|
|
||||||
|
ipc->IPv6State = IPC_PROTO_STATUS_CLOSED;
|
||||||
}
|
}
|
||||||
void IPCIPv6Free(IPC *ipc)
|
void IPCIPv6Free(IPC *ipc)
|
||||||
{
|
{
|
||||||
@ -2113,14 +2166,31 @@ void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, IP *addr)
|
// Scan the hub IP Table to try to find the EUI-based link-local address
|
||||||
|
bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui)
|
||||||
{
|
{
|
||||||
HUB t, *h;
|
HUB t, *h;
|
||||||
IP_TABLE_ENTRY t, *e;
|
IP_TABLE_ENTRY i, *e;
|
||||||
t.Name = ipc->HubName;
|
t.Name = ipc->HubName;
|
||||||
|
|
||||||
|
// Construct link local from eui
|
||||||
|
ZeroIP6(&i.Ip);
|
||||||
|
i.Ip.ipv6_addr[0] = 0xFE;
|
||||||
|
i.Ip.ipv6_addr[1] = 0x80;
|
||||||
|
WRITE_UINT64(&i.Ip.ipv6_addr[8], &eui);
|
||||||
|
|
||||||
h = Search(ipc->Cedar->HubList, &t);
|
h = Search(ipc->Cedar->HubList, &t);
|
||||||
|
|
||||||
//h->IpTable
|
if (h != NULL)
|
||||||
|
{
|
||||||
|
e = Search(h->IpTable, &i);
|
||||||
|
if (e != NULL)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RA
|
// RA
|
||||||
@ -2175,13 +2245,30 @@ bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVER
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send router solicitation and then eventually populate the info from Router Advertisements
|
// Send router solicitation and then eventually populate the info from Router Advertisements
|
||||||
void IPCIPv6SendRouterSolicitation(IPC *ipc)
|
UINT64 IPCIPv6GetServerEui(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LIST_NUM(ipc->IPv6RouterAdvs) == 0)
|
||||||
{
|
{
|
||||||
IP senderIP;
|
IP senderIP;
|
||||||
|
IPV6_ADDR senderV6;
|
||||||
IP destIP;
|
IP destIP;
|
||||||
|
IPV6_ADDR destV6;
|
||||||
UCHAR destMacAddress[6];
|
UCHAR destMacAddress[6];
|
||||||
IPV6_ADDR linkLocal;
|
IPV6_ADDR linkLocal;
|
||||||
BUF *packet;
|
BUF *packet;
|
||||||
|
|
||||||
Zero(&linkLocal, sizeof(IPV6_ADDR));
|
Zero(&linkLocal, sizeof(IPV6_ADDR));
|
||||||
|
|
||||||
// Generate link local from client's EUI
|
// Generate link local from client's EUI
|
||||||
@ -2196,7 +2283,10 @@ void IPCIPv6SendRouterSolicitation(IPC *ipc)
|
|||||||
destMacAddress[1] = 0x33;
|
destMacAddress[1] = 0x33;
|
||||||
WRITE_UINT(&destMacAddress[2], &destIP.ipv6_addr[12]);
|
WRITE_UINT(&destMacAddress[2], &destIP.ipv6_addr[12]);
|
||||||
|
|
||||||
packet = BuildICMPv6RouterSoliciation(senderIP.ipv6_addr, destIP.ipv6_addr, ipc->MacAddress, 0);
|
IPToIPv6Addr(&senderV6, &senderIP);
|
||||||
|
IPToIPv6Addr(&destV6, &destIP);
|
||||||
|
|
||||||
|
packet = BuildICMPv6RouterSoliciation(&senderV6, &destV6, ipc->MacAddress, 0);
|
||||||
|
|
||||||
while (LIST_NUM(ipc->IPv6RouterAdvs) == 0)
|
while (LIST_NUM(ipc->IPv6RouterAdvs) == 0)
|
||||||
{
|
{
|
||||||
@ -2215,6 +2305,7 @@ void IPCIPv6SendRouterSolicitation(IPC *ipc)
|
|||||||
// The processing should populate the received RAs by itself
|
// The processing should populate the received RAs by itself
|
||||||
IPCProcessL3Events(ipc);
|
IPCProcessL3Events(ipc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Populating the IPv6 Server EUI for IPV6CP
|
// Populating the IPv6 Server EUI for IPV6CP
|
||||||
if (LIST_NUM(ipc->IPv6RouterAdvs) > 0)
|
if (LIST_NUM(ipc->IPv6RouterAdvs) > 0)
|
||||||
@ -2222,6 +2313,8 @@ void IPCIPv6SendRouterSolicitation(IPC *ipc)
|
|||||||
IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, 0);
|
IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, 0);
|
||||||
ipc->IPv6ServerEUI = READ_UINT64(&ra->RouterAddress.ipv6_addr[8]);
|
ipc->IPv6ServerEUI = READ_UINT64(&ra->RouterAddress.ipv6_addr[8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ipc->IPv6ServerEUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data flow
|
// Data flow
|
||||||
|
@ -30,6 +30,16 @@
|
|||||||
#define IPC_IPV6_RA_INTERVAL (4 * 1000) // as per RTR_SOLICITATION_INTERVAL constant of RFC4861
|
#define IPC_IPV6_RA_INTERVAL (4 * 1000) // as per RTR_SOLICITATION_INTERVAL constant of RFC4861
|
||||||
#define IPC_IPV6_RA_MAX_RETRIES 3 // as per MAX_RTR_SOLICITATIONS constant of RFC4861
|
#define IPC_IPV6_RA_MAX_RETRIES 3 // as per MAX_RTR_SOLICITATIONS constant of RFC4861
|
||||||
|
|
||||||
|
// Protocol status
|
||||||
|
#define IPC_PROTO_STATUS_CLOSED 0x0
|
||||||
|
#define IPC_PROTO_STATUS_CONFIG 0x1
|
||||||
|
#define IPC_PROTO_STATUS_CONFIG_WAIT 0x2
|
||||||
|
#define IPC_PROTO_STATUS_OPENED 0x10
|
||||||
|
#define IPC_PROTO_STATUS_REJECTED 0x100
|
||||||
|
|
||||||
|
#define IPC_PROTO_SET_STATUS(ipc, proto, value) ((ipc) != NULL ? ((ipc->proto) = (value)) : 0)
|
||||||
|
#define IPC_PROTO_GET_STATUS(ipc, proto) ((ipc) != NULL ? (ipc->proto) : IPC_PROTO_STATUS_REJECTED)
|
||||||
|
|
||||||
// ARP table entry
|
// ARP table entry
|
||||||
struct IPC_ARP
|
struct IPC_ARP
|
||||||
{
|
{
|
||||||
@ -78,6 +88,15 @@ struct IPC_PARAM
|
|||||||
UINT Layer;
|
UINT Layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// DHCPv4 response awaiter
|
||||||
|
struct IPC_DHCPV4_AWAIT
|
||||||
|
{
|
||||||
|
bool IsAwaiting;
|
||||||
|
DHCPV4_DATA *DhcpData;
|
||||||
|
UINT TransCode;
|
||||||
|
UINT OpCode;
|
||||||
|
};
|
||||||
|
|
||||||
// IPC_ASYNC object
|
// IPC_ASYNC object
|
||||||
struct IPC_ASYNC
|
struct IPC_ASYNC
|
||||||
{
|
{
|
||||||
@ -117,6 +136,8 @@ struct IPC
|
|||||||
UCHAR Padding[2];
|
UCHAR Padding[2];
|
||||||
LIST *ArpTable; // ARP table
|
LIST *ArpTable; // ARP table
|
||||||
QUEUE *IPv4ReceivedQueue; // IPv4 reception queue
|
QUEUE *IPv4ReceivedQueue; // IPv4 reception queue
|
||||||
|
UINT IPv4State;
|
||||||
|
IPC_DHCPV4_AWAIT DHCPv4Awaiter;
|
||||||
TUBE_FLUSH_LIST *FlushList; // Tube Flush List
|
TUBE_FLUSH_LIST *FlushList; // Tube Flush List
|
||||||
UCHAR MsChapV2_ServerResponse[20]; // Server response
|
UCHAR MsChapV2_ServerResponse[20]; // Server response
|
||||||
DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table
|
DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table
|
||||||
@ -126,6 +147,7 @@ struct IPC
|
|||||||
|
|
||||||
// IPv6 stuff
|
// IPv6 stuff
|
||||||
QUEUE *IPv6ReceivedQueue; // IPv6 reception queue
|
QUEUE *IPv6ReceivedQueue; // IPv6 reception queue
|
||||||
|
UINT IPv6State;
|
||||||
LIST *IPv6NeighborTable; // Neighbor Discovery Table
|
LIST *IPv6NeighborTable; // Neighbor Discovery Table
|
||||||
LIST *IPv6RouterAdvs; // Router offered prefixes
|
LIST *IPv6RouterAdvs; // Router offered prefixes
|
||||||
UINT64 IPv6ClientEUI; // The EUI of the client (for the SLAAC autoconf)
|
UINT64 IPv6ClientEUI; // The EUI of the client (for the SLAAC autoconf)
|
||||||
@ -166,6 +188,7 @@ void IPCSendIPv4(IPC *ipc, void *data, UINT size);
|
|||||||
BLOCK *IPCRecvL2(IPC *ipc);
|
BLOCK *IPCRecvL2(IPC *ipc);
|
||||||
BLOCK *IPCRecvIPv4(IPC *ipc);
|
BLOCK *IPCRecvIPv4(IPC *ipc);
|
||||||
void IPCProcessInterrupts(IPC *ipc);
|
void IPCProcessInterrupts(IPC *ipc);
|
||||||
|
void IPCProcessL3EventsIPv4Only(IPC *ipc);
|
||||||
void IPCProcessL3Events(IPC *ipc);
|
void IPCProcessL3Events(IPC *ipc);
|
||||||
void IPCProcessL3EventsEx(IPC *ipc, UINT64 now);
|
void IPCProcessL3EventsEx(IPC *ipc, UINT64 now);
|
||||||
bool IPCSetIPv4Parameters(IPC *ipc, IP *ip, IP *subnet, IP *gw, DHCP_CLASSLESS_ROUTE_TABLE *rt);
|
bool IPCSetIPv4Parameters(IPC *ipc, IP *ip, IP *subnet, IP *gw, DHCP_CLASSLESS_ROUTE_TABLE *rt);
|
||||||
@ -202,11 +225,11 @@ void IPCIPv6AssociateOnNDT(IPC *ipc, IP *ip, UCHAR *mac_address);
|
|||||||
void IPCIPv6AssociateOnNDTEx(IPC *ipc, IP *ip, UCHAR *mac_address, bool isNeighborAdv);
|
void IPCIPv6AssociateOnNDTEx(IPC *ipc, IP *ip, UCHAR *mac_address, bool isNeighborAdv);
|
||||||
void IPCIPv6FlushNDT(IPC *ipc);
|
void IPCIPv6FlushNDT(IPC *ipc);
|
||||||
void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now);
|
void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now);
|
||||||
bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, IP *addr);
|
bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui);
|
||||||
// RA
|
// RA
|
||||||
void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip);
|
void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip);
|
||||||
bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA);
|
bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA);
|
||||||
void IPCIPv6SendRouterSolicitation(IPC *ipc);
|
UINT64 IPCIPv6GetServerEui(IPC *ipc);
|
||||||
// Data flow
|
// Data flow
|
||||||
BLOCK *IPCIPv6Recv(IPC *ipc);
|
BLOCK *IPCIPv6Recv(IPC *ipc);
|
||||||
void IPCIPv6Send(IPC *ipc, void *data, UINT size);
|
void IPCIPv6Send(IPC *ipc, void *data, UINT size);
|
||||||
|
@ -2159,7 +2159,8 @@ void OvsFreeSession(OPENVPN_SESSION *se)
|
|||||||
UINTToIP(&dhcp_ip, se->IpcAsync->L3ClientAddressOption.ServerAddress);
|
UINTToIP(&dhcp_ip, se->IpcAsync->L3ClientAddressOption.ServerAddress);
|
||||||
|
|
||||||
IPCDhcpFreeIP(se->Ipc, &dhcp_ip);
|
IPCDhcpFreeIP(se->Ipc, &dhcp_ip);
|
||||||
IPCProcessL3Events(se->Ipc);
|
IPC_PROTO_SET_STATUS(se->Ipc, IPv6State, IPC_PROTO_STATUS_CLOSED);
|
||||||
|
IPCProcessL3EventsIPv4Only(se->Ipc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2259,7 +2260,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
|
|||||||
{
|
{
|
||||||
if (se->Mode == OPENVPN_MODE_L3)
|
if (se->Mode == OPENVPN_MODE_L3)
|
||||||
{
|
{
|
||||||
IPCProcessL3Events(se->Ipc);
|
IPCProcessL3EventsIPv4Only(se->Ipc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2656,7 +2657,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCProcessL3Events(se->Ipc);
|
IPCProcessL3EventsIPv4Only(se->Ipc);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCProcessInterrupts(se->Ipc);
|
IPCProcessInterrupts(se->Ipc);
|
||||||
|
@ -12,9 +12,6 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
{
|
{
|
||||||
PPP_SESSION *p = (PPP_SESSION *)param;
|
PPP_SESSION *p = (PPP_SESSION *)param;
|
||||||
UINT i;
|
UINT i;
|
||||||
PPP_LCP *c;
|
|
||||||
USHORT us;
|
|
||||||
UINT ui;
|
|
||||||
USHORT next_protocol = 0;
|
USHORT next_protocol = 0;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
char ipstr1[128], ipstr2[128];
|
char ipstr1[128], ipstr2[128];
|
||||||
@ -32,8 +29,6 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
Debug("PPP Initialize");
|
Debug("PPP Initialize");
|
||||||
|
|
||||||
PPPSetStatus(p, PPP_STATUS_CONNECTED);
|
PPPSetStatus(p, PPP_STATUS_CONNECTED);
|
||||||
p->IPv4_State = PPP_PROTO_STATUS_CLOSED;
|
|
||||||
p->IPv6_State = PPP_PROTO_STATUS_CLOSED;
|
|
||||||
|
|
||||||
p->Eap_Protocol = PPP_UNSPECIFIED;
|
p->Eap_Protocol = PPP_UNSPECIFIED;
|
||||||
|
|
||||||
@ -181,7 +176,8 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
{
|
{
|
||||||
UINT64 nowL;
|
UINT64 nowL;
|
||||||
// Here client to server
|
// Here client to server
|
||||||
if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IP && p->IPv4_State == PPP_PROTO_STATUS_OPENED)
|
if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IP &&
|
||||||
|
IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED)
|
||||||
{
|
{
|
||||||
receivedPacketProcessed = true;
|
receivedPacketProcessed = true;
|
||||||
IPCSendIPv4(p->Ipc, p->CurrentPacket->Data, p->CurrentPacket->DataSize);
|
IPCSendIPv4(p->Ipc, p->CurrentPacket->Data, p->CurrentPacket->DataSize);
|
||||||
@ -190,10 +186,11 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
{
|
{
|
||||||
Debug("Got IPv4 packet before IPv4 ready!\n");
|
Debug("Got IPv4 packet before IPv4 ready!\n");
|
||||||
}
|
}
|
||||||
else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6 && p->IPv6_State == PPP_PROTO_STATUS_OPENED)
|
else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6 &&
|
||||||
|
IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_OPENED)
|
||||||
{
|
{
|
||||||
receivedPacketProcessed = true;
|
receivedPacketProcessed = true;
|
||||||
Debug("IPv6 to be implemented\n");
|
IPCIPv6Send(p->Ipc, p->CurrentPacket->Data, p->CurrentPacket->DataSize);
|
||||||
}
|
}
|
||||||
else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6)
|
else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6)
|
||||||
{
|
{
|
||||||
@ -318,6 +315,8 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
if (p->PPPStatus == PPP_STATUS_NETWORK_LAYER)
|
if (p->PPPStatus == PPP_STATUS_NETWORK_LAYER)
|
||||||
{
|
{
|
||||||
UINT64 timeBeforeLoop;
|
UINT64 timeBeforeLoop;
|
||||||
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED)
|
||||||
|
{
|
||||||
if (p->DhcpAllocated)
|
if (p->DhcpAllocated)
|
||||||
{
|
{
|
||||||
if (now >= p->DhcpNextRenewTime)
|
if (now >= p->DhcpNextRenewTime)
|
||||||
@ -332,6 +331,7 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
IPCDhcpRenewIP(p->Ipc, &ip);
|
IPCDhcpRenewIP(p->Ipc, &ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IPCProcessL3Events(p->Ipc);
|
IPCProcessL3Events(p->Ipc);
|
||||||
|
|
||||||
@ -340,13 +340,19 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
UINT64 nowL;
|
UINT64 nowL;
|
||||||
|
bool no4packets = false;
|
||||||
|
bool no6packets = false;
|
||||||
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED)
|
||||||
|
{
|
||||||
BLOCK *b = IPCRecvIPv4(p->Ipc);
|
BLOCK *b = IPCRecvIPv4(p->Ipc);
|
||||||
PPP_PACKET *pp;
|
|
||||||
PPP_PACKET tmp;
|
|
||||||
if (b == NULL)
|
if (b == NULL)
|
||||||
{
|
{
|
||||||
break;
|
no4packets = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PPP_PACKET *pp;
|
||||||
|
PPP_PACKET tmp;
|
||||||
|
|
||||||
// Since receiving the IP packet, send it to the client by PPP
|
// Since receiving the IP packet, send it to the client by PPP
|
||||||
pp = &tmp;
|
pp = &tmp;
|
||||||
@ -360,10 +366,47 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
|
|
||||||
FreePPPPacketEx(pp, true);
|
FreePPPPacketEx(pp, true);
|
||||||
Free(b);
|
Free(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
no4packets = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_OPENED)
|
||||||
|
{
|
||||||
|
BLOCK *b = IPCIPv6Recv(p->Ipc);
|
||||||
|
if (b == NULL)
|
||||||
|
{
|
||||||
|
no6packets = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PPP_PACKET *pp;
|
||||||
|
PPP_PACKET tmp;
|
||||||
|
|
||||||
|
// Since receiving the IP packet, send it to the client by PPP
|
||||||
|
pp = &tmp;
|
||||||
|
pp->IsControl = false;
|
||||||
|
pp->Protocol = PPP_PROTOCOL_IPV6;
|
||||||
|
pp->Lcp = NULL;
|
||||||
|
pp->Data = b->Buf;
|
||||||
|
pp->DataSize = b->Size;
|
||||||
|
|
||||||
|
PPPSendPacketEx(p, pp, true);
|
||||||
|
|
||||||
|
FreePPPPacketEx(pp, true);
|
||||||
|
Free(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
no6packets = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Let's break out of the loop once in a while so we don't get stuck here endlessly
|
// Let's break out of the loop once in a while so we don't get stuck here endlessly
|
||||||
nowL = Tick64();
|
nowL = Tick64();
|
||||||
if (nowL > timeBeforeLoop + PPP_PACKET_RESEND_INTERVAL)
|
if (nowL > timeBeforeLoop + PPP_PACKET_RESEND_INTERVAL || (no4packets && no6packets))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -743,7 +786,7 @@ bool PPPProcessResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
|
|||||||
return PPPProcessIPCPResponsePacket(p, pp, req);
|
return PPPProcessIPCPResponsePacket(p, pp, req);
|
||||||
break;
|
break;
|
||||||
case PPP_PROTOCOL_IPV6CP:
|
case PPP_PROTOCOL_IPV6CP:
|
||||||
Debug("IPv6CP to be implemented\n");
|
return PPPProcessIPv6CPResponsePacket(p, pp, req);
|
||||||
break;
|
break;
|
||||||
case PPP_PROTOCOL_EAP:
|
case PPP_PROTOCOL_EAP:
|
||||||
return PPPProcessEAPResponsePacket(p, pp, req);
|
return PPPProcessEAPResponsePacket(p, pp, req);
|
||||||
@ -786,11 +829,11 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
USHORT *protocol = pp->Lcp->Data;
|
USHORT *protocol = pp->Lcp->Data;
|
||||||
if (*protocol == PPP_PROTOCOL_IPCP || *protocol == PPP_PROTOCOL_IP)
|
if (*protocol == PPP_PROTOCOL_IPCP || *protocol == PPP_PROTOCOL_IP)
|
||||||
{
|
{
|
||||||
p->IPv4_State = PPP_PROTO_STATUS_REJECTED;
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED);
|
||||||
}
|
}
|
||||||
if (*protocol == PPP_PROTOCOL_IPV6CP || *protocol == PPP_PROTOCOL_IPV6)
|
if (*protocol == PPP_PROTOCOL_IPV6CP || *protocol == PPP_PROTOCOL_IPV6)
|
||||||
{
|
{
|
||||||
p->IPv6_State = PPP_PROTO_STATUS_REJECTED;
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_REJECTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1082,7 +1125,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
|
|||||||
if (!PPPGetIPAddressValueFromLCP(pp->Lcp, PPP_IPCP_OPTION_IP, &addrStruct) || pp->Lcp->Code == PPP_LCP_CODE_REJECT || pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT)
|
if (!PPPGetIPAddressValueFromLCP(pp->Lcp, PPP_IPCP_OPTION_IP, &addrStruct) || pp->Lcp->Code == PPP_LCP_CODE_REJECT || pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT)
|
||||||
{
|
{
|
||||||
Debug("Unsupported IPCP protocol");
|
Debug("Unsupported IPCP protocol");
|
||||||
p->IPv4_State = PPP_PROTO_STATUS_REJECTED;
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED);
|
||||||
PPPRejectUnsupportedPacketEx(p, pp, true);
|
PPPRejectUnsupportedPacketEx(p, pp, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1096,14 +1139,14 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
|
|||||||
Debug("Accepted server IP address of %s\n", addrStr);
|
Debug("Accepted server IP address of %s\n", addrStr);
|
||||||
|
|
||||||
// We already configured client address, now server address is also confirmed, ready for IPv4 data flow
|
// We already configured client address, now server address is also confirmed, ready for IPv4 data flow
|
||||||
if (p->IPv4_State == PPP_PROTO_STATUS_CONFIG)
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG)
|
||||||
{
|
{
|
||||||
p->IPv4_State = PPP_PROTO_STATUS_CONFIG_WAIT;
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG_WAIT);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->IPv4_State = PPP_PROTO_STATUS_CONFIG;
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG);
|
||||||
|
|
||||||
PPPGetIPAddressValueFromLCP(req->Lcp, PPP_IPCP_OPTION_IP, &prevAddrStruct);
|
PPPGetIPAddressValueFromLCP(req->Lcp, PPP_IPCP_OPTION_IP, &prevAddrStruct);
|
||||||
prevAddr = IPToUINT(&prevAddrStruct);
|
prevAddr = IPToUINT(&prevAddrStruct);
|
||||||
@ -1115,7 +1158,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
|
|||||||
if (prevAddr == Endian32(0xc0000008))
|
if (prevAddr == Endian32(0xc0000008))
|
||||||
{
|
{
|
||||||
Debug("We already tried the fallback IP of 192.0.0.8, giving up\n");
|
Debug("We already tried the fallback IP of 192.0.0.8, giving up\n");
|
||||||
p->IPv4_State = PPP_PROTO_STATUS_REJECTED;
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED);
|
||||||
PPPRejectUnsupportedPacketEx(p, pp, true);
|
PPPRejectUnsupportedPacketEx(p, pp, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1205,6 +1248,31 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process IPv6CP responses
|
||||||
|
bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
|
||||||
|
{
|
||||||
|
bool isAccepted = !PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code);
|
||||||
|
|
||||||
|
// If we got a reject or a NACK, we just reject the whole IPv6 configuration, there is no way we can recover even from a NACK as we can't change the link-local address of an already existing router
|
||||||
|
if (!isAccepted)
|
||||||
|
{
|
||||||
|
Debug("Unsupported IPv6CP protocol");
|
||||||
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_REJECTED);
|
||||||
|
PPPRejectUnsupportedPacketEx(p, pp, true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) != IPC_PROTO_STATUS_CONFIG)
|
||||||
|
{
|
||||||
|
Debug("We got an early IPv6CP response, ignoring for now...\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug("Accepted server IPv6CP handshake\n");
|
||||||
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_CONFIG_WAIT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Processes request packets
|
// Processes request packets
|
||||||
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
||||||
@ -1227,8 +1295,7 @@ bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
return PPPProcessIPCPRequestPacket(p, pp);
|
return PPPProcessIPCPRequestPacket(p, pp);
|
||||||
break;
|
break;
|
||||||
case PPP_PROTOCOL_IPV6CP:
|
case PPP_PROTOCOL_IPV6CP:
|
||||||
PPPRejectUnsupportedPacketEx(p, pp, true);
|
return PPPProcessIPv6CPRequestPacket(p, pp);
|
||||||
Debug("IPv6CP to be implemented\n");
|
|
||||||
break;
|
break;
|
||||||
case PPP_PROTOCOL_EAP:
|
case PPP_PROTOCOL_EAP:
|
||||||
return PPPProcessEAPRequestPacket(p, pp);
|
return PPPProcessEAPRequestPacket(p, pp);
|
||||||
@ -1547,9 +1614,8 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
bool ok = true;
|
bool ok = true;
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
bool isEmptyIpAddress = false;
|
bool isEmptyIpAddress = false;
|
||||||
PPP_LCP *c;
|
|
||||||
|
|
||||||
if (p->IPv4_State == PPP_PROTO_STATUS_REJECTED)
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_REJECTED)
|
||||||
{
|
{
|
||||||
Debug("We got an IPCP packet after we had it rejected\n");
|
Debug("We got an IPCP packet after we had it rejected\n");
|
||||||
return PPPRejectUnsupportedPacketEx(p, pp, true);
|
return PPPRejectUnsupportedPacketEx(p, pp, true);
|
||||||
@ -1823,7 +1889,7 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
|
|
||||||
// We will delay this packet ACK and send the server IP first, then wait for a reparse
|
// We will delay this packet ACK and send the server IP first, then wait for a reparse
|
||||||
// it is kind of dirty but fixes issues on some clients (namely VPN Client Pro on Android)
|
// it is kind of dirty but fixes issues on some clients (namely VPN Client Pro on Android)
|
||||||
if (p->IPv4_State == PPP_PROTO_STATUS_CLOSED && p->ClientAddressOption.ServerAddress != 0 && ok)
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CLOSED && p->ClientAddressOption.ServerAddress != 0 && ok)
|
||||||
{
|
{
|
||||||
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
|
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
|
||||||
UINT ui = p->ClientAddressOption.ServerAddress;
|
UINT ui = p->ClientAddressOption.ServerAddress;
|
||||||
@ -1834,7 +1900,7 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
WHERE;
|
WHERE;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
p->IPv4_State = PPP_PROTO_STATUS_CONFIG;
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG);
|
||||||
if (!processed)
|
if (!processed)
|
||||||
{
|
{
|
||||||
PPPAddNextPacket(p, pp, 1);
|
PPPAddNextPacket(p, pp, 1);
|
||||||
@ -1843,7 +1909,8 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We still haven't received any answer from client about server IP, keep waiting...
|
// We still haven't received any answer from client about server IP, keep waiting...
|
||||||
if ((p->IPv4_State == PPP_PROTO_STATUS_CONFIG || p->IPv4_State == PPP_PROTO_STATUS_CLOSED) && !processed)
|
if ((IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG ||
|
||||||
|
IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CLOSED) && !processed)
|
||||||
{
|
{
|
||||||
PPPAddNextPacket(p, pp, 1);
|
PPPAddNextPacket(p, pp, 1);
|
||||||
return false;
|
return false;
|
||||||
@ -1856,9 +1923,9 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
}
|
}
|
||||||
Debug("ACKed IPCP options ID = 0x%x\n", pp->Lcp->Id);
|
Debug("ACKed IPCP options ID = 0x%x\n", pp->Lcp->Id);
|
||||||
|
|
||||||
if (ok && p->IPv4_State == PPP_PROTO_STATUS_CONFIG_WAIT)
|
if (ok && IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG_WAIT)
|
||||||
{
|
{
|
||||||
p->IPv4_State = PPP_PROTO_STATUS_OPENED;
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_OPENED);
|
||||||
Debug("IPv4 OPENED\n");
|
Debug("IPv4 OPENED\n");
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
@ -1871,6 +1938,116 @@ bool PPPProcessEAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process IPv6CP request packets
|
||||||
|
bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
bool processed = false;
|
||||||
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_REJECTED)
|
||||||
|
{
|
||||||
|
Debug("We got an IPv6CP packet after we had it rejected\n");
|
||||||
|
return PPPRejectUnsupportedPacketEx(p, pp, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < LIST_NUM(pp->Lcp->OptionList); i++)
|
||||||
|
{
|
||||||
|
PPP_OPTION *t = LIST_DATA(pp->Lcp->OptionList, i);
|
||||||
|
|
||||||
|
switch (t->Type)
|
||||||
|
{
|
||||||
|
case PPP_IPV6CP_OPTION_EUI:
|
||||||
|
t->IsSupported = true;
|
||||||
|
if (t->DataSize == sizeof(UINT64))
|
||||||
|
{
|
||||||
|
UINT64 newValue = 0;
|
||||||
|
UINT64 value = READ_UINT64(t->Data);
|
||||||
|
if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, value))
|
||||||
|
{
|
||||||
|
t->IsAccepted = true;
|
||||||
|
p->Ipc->IPv6ClientEUI = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t->IsAccepted = false;
|
||||||
|
GenerateEui64Address6((UCHAR *)&newValue, p->Ipc->MacAddress);
|
||||||
|
if (newValue != value && !IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue))
|
||||||
|
{
|
||||||
|
WRITE_UINT64(t->AltData, newValue);
|
||||||
|
t->AltDataSize = sizeof(UINT64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
newValue = Rand64();
|
||||||
|
if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue))
|
||||||
|
{
|
||||||
|
WRITE_UINT64(t->AltData, newValue);
|
||||||
|
t->AltDataSize = sizeof(UINT64);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
t->IsSupported = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PPPRejectLCPOptionsEx(p, pp, processed))
|
||||||
|
{
|
||||||
|
Debug("Rejected IPv6CP options ID = 0x%x\n", pp->Lcp->Id);
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PPPNackLCPOptionsEx(p, pp, processed))
|
||||||
|
{
|
||||||
|
Debug("NACKed IPv6CP options ID = 0x%x\n", pp->Lcp->Id);
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c))
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CONFIG && !processed)
|
||||||
|
{
|
||||||
|
PPPAddNextPacket(p, pp, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PPPAckLCPOptionsEx(p, pp, processed))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Debug("ACKed IPv6CP options ID = 0x%x\n", pp->Lcp->Id);
|
||||||
|
|
||||||
|
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CONFIG_WAIT)
|
||||||
|
{
|
||||||
|
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_OPENED);
|
||||||
|
Debug("IPv6 OPENED\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// LCP option based packets utility
|
// LCP option based packets utility
|
||||||
bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp)
|
bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp)
|
||||||
{
|
{
|
||||||
@ -2128,7 +2305,7 @@ LABEL_LOOP:
|
|||||||
|
|
||||||
if (async == false)
|
if (async == false)
|
||||||
{
|
{
|
||||||
d = TubeRecvSync(p->TubeRecv, p->PacketRecvTimeout);
|
d = TubeRecvSync(p->TubeRecv, (UINT)p->PacketRecvTimeout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2241,7 +2418,6 @@ PPP_PACKET *PPPGetNextPacket(PPP_SESSION *p)
|
|||||||
void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay)
|
void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay)
|
||||||
{
|
{
|
||||||
PPP_DELAYED_PACKET *t = ZeroMalloc(sizeof(PPP_DELAYED_PACKET));
|
PPP_DELAYED_PACKET *t = ZeroMalloc(sizeof(PPP_DELAYED_PACKET));
|
||||||
UINT i;
|
|
||||||
if (p->CurrentPacket == pp)
|
if (p->CurrentPacket == pp)
|
||||||
{
|
{
|
||||||
p->CurrentPacket = NULL;
|
p->CurrentPacket = NULL;
|
||||||
@ -2262,7 +2438,7 @@ void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay)
|
|||||||
Debug("after sorting delayeds end\n");*/
|
Debug("after sorting delayeds end\n");*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int PPPDelayedPacketsComparator(const void *a, const void *b)
|
int PPPDelayedPacketsComparator(void *a, void *b)
|
||||||
{
|
{
|
||||||
PPP_DELAYED_PACKET *first = a;
|
PPP_DELAYED_PACKET *first = a;
|
||||||
PPP_DELAYED_PACKET *second = b;
|
PPP_DELAYED_PACKET *second = b;
|
||||||
@ -3009,12 +3185,11 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
UCHAR *dataBuffer;
|
UCHAR *dataBuffer;
|
||||||
UINT dataSize;
|
UINT dataSize;
|
||||||
UINT tlsLength = 0;
|
UINT tlsLength = 0;
|
||||||
UINT i;
|
|
||||||
bool isFragmented = false;
|
bool isFragmented = false;
|
||||||
PPP_LCP *lcp;
|
PPP_LCP *lcp;
|
||||||
PPP_EAP *eap;
|
PPP_EAP *eap;
|
||||||
UCHAR flags = PPP_EAP_TLS_FLAG_NONE;
|
UCHAR flags = PPP_EAP_TLS_FLAG_NONE;
|
||||||
UINT64 sizeLeft = 0;
|
UINT sizeLeft = 0;
|
||||||
Debug("Got EAP-TLS size=%i\n", eapTlsSize);
|
Debug("Got EAP-TLS size=%i\n", eapTlsSize);
|
||||||
if (eapTlsSize == 1)
|
if (eapTlsSize == 1)
|
||||||
{
|
{
|
||||||
@ -3024,7 +3199,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
// We got an ACK to transmit the next fragmented message
|
// We got an ACK to transmit the next fragmented message
|
||||||
dataSize = p->Mru1 - 8 - 1 - 1; // Calculating the maximum payload size (without TlsLength)
|
dataSize = p->Mru1 - 8 - 1 - 1; // Calculating the maximum payload size (without TlsLength)
|
||||||
sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferSend);
|
sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferSend);
|
||||||
sizeLeft -= p->Eap_TlsCtx.CachedBufferSendPntr - p->Eap_TlsCtx.CachedBufferSend;
|
sizeLeft -= (UINT)(p->Eap_TlsCtx.CachedBufferSendPntr - p->Eap_TlsCtx.CachedBufferSend);
|
||||||
|
|
||||||
flags = PPP_EAP_TLS_FLAG_FRAGMENTED; // M flag
|
flags = PPP_EAP_TLS_FLAG_FRAGMENTED; // M flag
|
||||||
if (dataSize > sizeLeft)
|
if (dataSize > sizeLeft)
|
||||||
@ -3035,7 +3210,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
lcp = BuildEAPTlsRequest(p->Eap_PacketId++, dataSize, flags);
|
lcp = BuildEAPTlsRequest(p->Eap_PacketId++, dataSize, flags);
|
||||||
eap = lcp->Data;
|
eap = lcp->Data;
|
||||||
Copy(eap->Tls.TlsDataWithoutLength, p->Eap_TlsCtx.CachedBufferSendPntr, dataSize);
|
Copy(eap->Tls.TlsDataWithoutLength, p->Eap_TlsCtx.CachedBufferSendPntr, dataSize);
|
||||||
p->Eap_TlsCtx.CachedBufferSendPntr += dataSize;
|
p->Eap_TlsCtx.CachedBufferSendPntr += (UINT64)dataSize;
|
||||||
|
|
||||||
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp))
|
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp))
|
||||||
{
|
{
|
||||||
@ -3192,7 +3367,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv;
|
p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv;
|
||||||
}
|
}
|
||||||
sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
|
sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
sizeLeft -= p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv;
|
sizeLeft -= (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
|
|
||||||
Copy(p->Eap_TlsCtx.CachedBufferRecvPntr, dataBuffer, MIN(sizeLeft, dataSize));
|
Copy(p->Eap_TlsCtx.CachedBufferRecvPntr, dataBuffer, MIN(sizeLeft, dataSize));
|
||||||
|
|
||||||
@ -3206,7 +3381,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
dataSize = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
|
dataSize = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
if (dataSize == MAX_BUFFERING_PACKET_SIZE)
|
if (dataSize == MAX_BUFFERING_PACKET_SIZE)
|
||||||
{
|
{
|
||||||
dataSize = p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv;
|
dataSize = (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
#define PPP_IPCP_OPTION_WINS2 132
|
#define PPP_IPCP_OPTION_WINS2 132
|
||||||
|
|
||||||
// IPV6CP option type
|
// IPV6CP option type
|
||||||
#define PPP_IPV6CP_OPTION_IID 1
|
#define PPP_IPV6CP_OPTION_EUI 1
|
||||||
|
|
||||||
// EAP codes
|
// EAP codes
|
||||||
#define PPP_EAP_CODE_REQUEST 1
|
#define PPP_EAP_CODE_REQUEST 1
|
||||||
@ -135,13 +135,6 @@
|
|||||||
#define PPP_STATUS_FAIL 0x1000
|
#define PPP_STATUS_FAIL 0x1000
|
||||||
#define PPP_STATUS_AUTH_FAIL 0x1010
|
#define PPP_STATUS_AUTH_FAIL 0x1010
|
||||||
|
|
||||||
// Protocol status
|
|
||||||
#define PPP_PROTO_STATUS_CLOSED 0x0
|
|
||||||
#define PPP_PROTO_STATUS_CONFIG 0x1
|
|
||||||
#define PPP_PROTO_STATUS_CONFIG_WAIT 0x2
|
|
||||||
#define PPP_PROTO_STATUS_OPENED 0x10
|
|
||||||
#define PPP_PROTO_STATUS_REJECTED 0x100
|
|
||||||
|
|
||||||
#define PPP_UNSPECIFIED 0xFFFF
|
#define PPP_UNSPECIFIED 0xFFFF
|
||||||
|
|
||||||
//// Type
|
//// Type
|
||||||
@ -301,8 +294,6 @@ struct PPP_SESSION
|
|||||||
UCHAR ClientInterfaceId[8]; // Client IPv6CP Interface Identifier
|
UCHAR ClientInterfaceId[8]; // Client IPv6CP Interface Identifier
|
||||||
|
|
||||||
UINT PPPStatus;
|
UINT PPPStatus;
|
||||||
UINT IPv4_State;
|
|
||||||
UINT IPv6_State;
|
|
||||||
|
|
||||||
// EAP contexts
|
// EAP contexts
|
||||||
UINT Eap_Protocol; // Current EAP Protocol used
|
UINT Eap_Protocol; // Current EAP Protocol used
|
||||||
@ -344,12 +335,14 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
|
bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
|
||||||
bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
|
bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
|
||||||
bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
|
bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
|
||||||
|
bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
|
||||||
// Request packets
|
// Request packets
|
||||||
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
bool PPPProcessEAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPProcessEAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
|
bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
|
|
||||||
// LCP option based packets utility
|
// LCP option based packets utility
|
||||||
bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
@ -369,7 +362,7 @@ PPP_PACKET *PPPRecvPacket(PPP_SESSION *p, bool async);
|
|||||||
// Helpers for delaying packets
|
// Helpers for delaying packets
|
||||||
PPP_PACKET *PPPGetNextPacket(PPP_SESSION *p);
|
PPP_PACKET *PPPGetNextPacket(PPP_SESSION *p);
|
||||||
void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay);
|
void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay);
|
||||||
int PPPDelayedPacketsComparator(const void *a, const void *b);
|
int PPPDelayedPacketsComparator(void *a, void *b);
|
||||||
char PPPRelatedPacketComparator(PPP_PACKET *a, PPP_PACKET *b);
|
char PPPRelatedPacketComparator(PPP_PACKET *a, PPP_PACKET *b);
|
||||||
|
|
||||||
// PPP utility functions
|
// PPP utility functions
|
||||||
|
@ -1753,7 +1753,7 @@ LABEL_RESTART:
|
|||||||
UnlockQueue(t->SendQueue);
|
UnlockQueue(t->SendQueue);
|
||||||
|
|
||||||
// Happy processing
|
// Happy processing
|
||||||
IPCProcessL3Events(ipc);
|
IPCProcessL3EventsIPv4Only(ipc);
|
||||||
|
|
||||||
LockQueue(t->RecvQueue);
|
LockQueue(t->RecvQueue);
|
||||||
{
|
{
|
||||||
@ -2370,7 +2370,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Happy processing
|
// Happy processing
|
||||||
IPCProcessL3Events(ipc);
|
IPCProcessL3EventsIPv4Only(ipc);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -2479,7 +2479,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Happy procedure
|
// Happy procedure
|
||||||
IPCProcessL3Events(ipc);
|
IPCProcessL3EventsIPv4Only(ipc);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -6141,67 +6141,128 @@ char *CharToNetBiosStr(char c)
|
|||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case '\0': return "AA";
|
case '\0':
|
||||||
case 'A': return "EB";
|
return "AA";
|
||||||
case 'B': return "EC";
|
case 'A':
|
||||||
case 'C': return "ED";
|
return "EB";
|
||||||
case 'D': return "EE";
|
case 'B':
|
||||||
case 'E': return "EF";
|
return "EC";
|
||||||
case 'F': return "EG";
|
case 'C':
|
||||||
case 'G': return "EH";
|
return "ED";
|
||||||
case 'H': return "EI";
|
case 'D':
|
||||||
case 'I': return "EJ";
|
return "EE";
|
||||||
case 'J': return "EK";
|
case 'E':
|
||||||
case 'K': return "EL";
|
return "EF";
|
||||||
case 'L': return "EM";
|
case 'F':
|
||||||
case 'M': return "EN";
|
return "EG";
|
||||||
case 'N': return "EO";
|
case 'G':
|
||||||
case 'O': return "EP";
|
return "EH";
|
||||||
case 'P': return "FA";
|
case 'H':
|
||||||
case 'Q': return "FB";
|
return "EI";
|
||||||
case 'R': return "FC";
|
case 'I':
|
||||||
case 'S': return "FD";
|
return "EJ";
|
||||||
case 'T': return "FE";
|
case 'J':
|
||||||
case 'U': return "FF";
|
return "EK";
|
||||||
case 'V': return "FG";
|
case 'K':
|
||||||
case 'W': return "FH";
|
return "EL";
|
||||||
case 'X': return "FI";
|
case 'L':
|
||||||
case 'Y': return "FJ";
|
return "EM";
|
||||||
case 'Z': return "FK";
|
case 'M':
|
||||||
case '0': return "DA";
|
return "EN";
|
||||||
case '1': return "DB";
|
case 'N':
|
||||||
case '2': return "DC";
|
return "EO";
|
||||||
case '3': return "DD";
|
case 'O':
|
||||||
case '4': return "DE";
|
return "EP";
|
||||||
case '5': return "DF";
|
case 'P':
|
||||||
case '6': return "DG";
|
return "FA";
|
||||||
case '7': return "DH";
|
case 'Q':
|
||||||
case '8': return "DI";
|
return "FB";
|
||||||
case '9': return "DJ";
|
case 'R':
|
||||||
case ' ': return "CA";
|
return "FC";
|
||||||
case '!': return "CB";
|
case 'S':
|
||||||
case '\"': return "CC";
|
return "FD";
|
||||||
case '#': return "CD";
|
case 'T':
|
||||||
case '$': return "CE";
|
return "FE";
|
||||||
case '%': return "CF";
|
case 'U':
|
||||||
case '&': return "CG";
|
return "FF";
|
||||||
case '\'': return "CH";
|
case 'V':
|
||||||
case '(': return "CI";
|
return "FG";
|
||||||
case ')': return "CJ";
|
case 'W':
|
||||||
case '*': return "CK";
|
return "FH";
|
||||||
case '+': return "CL";
|
case 'X':
|
||||||
case ',': return "CM";
|
return "FI";
|
||||||
case '-': return "CN";
|
case 'Y':
|
||||||
case '.': return "CO";
|
return "FJ";
|
||||||
case '=': return "DN";
|
case 'Z':
|
||||||
case ':': return "DK";
|
return "FK";
|
||||||
case ';': return "DL";
|
case '0':
|
||||||
case '@': return "EA";
|
return "DA";
|
||||||
case '^': return "FO";
|
case '1':
|
||||||
case '_': return "FP";
|
return "DB";
|
||||||
case '{': return "HL";
|
case '2':
|
||||||
case '}': return "HN";
|
return "DC";
|
||||||
case '~': return "HO";
|
case '3':
|
||||||
|
return "DD";
|
||||||
|
case '4':
|
||||||
|
return "DE";
|
||||||
|
case '5':
|
||||||
|
return "DF";
|
||||||
|
case '6':
|
||||||
|
return "DG";
|
||||||
|
case '7':
|
||||||
|
return "DH";
|
||||||
|
case '8':
|
||||||
|
return "DI";
|
||||||
|
case '9':
|
||||||
|
return "DJ";
|
||||||
|
case ' ':
|
||||||
|
return "CA";
|
||||||
|
case '!':
|
||||||
|
return "CB";
|
||||||
|
case '\"':
|
||||||
|
return "CC";
|
||||||
|
case '#':
|
||||||
|
return "CD";
|
||||||
|
case '$':
|
||||||
|
return "CE";
|
||||||
|
case '%':
|
||||||
|
return "CF";
|
||||||
|
case '&':
|
||||||
|
return "CG";
|
||||||
|
case '\'':
|
||||||
|
return "CH";
|
||||||
|
case '(':
|
||||||
|
return "CI";
|
||||||
|
case ')':
|
||||||
|
return "CJ";
|
||||||
|
case '*':
|
||||||
|
return "CK";
|
||||||
|
case '+':
|
||||||
|
return "CL";
|
||||||
|
case ',':
|
||||||
|
return "CM";
|
||||||
|
case '-':
|
||||||
|
return "CN";
|
||||||
|
case '.':
|
||||||
|
return "CO";
|
||||||
|
case '=':
|
||||||
|
return "DN";
|
||||||
|
case ':':
|
||||||
|
return "DK";
|
||||||
|
case ';':
|
||||||
|
return "DL";
|
||||||
|
case '@':
|
||||||
|
return "EA";
|
||||||
|
case '^':
|
||||||
|
return "FO";
|
||||||
|
case '_':
|
||||||
|
return "FP";
|
||||||
|
case '{':
|
||||||
|
return "HL";
|
||||||
|
case '}':
|
||||||
|
return "HN";
|
||||||
|
case '~':
|
||||||
|
return "HO";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "CA";
|
return "CA";
|
||||||
|
@ -2398,6 +2398,7 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
|
|||||||
{
|
{
|
||||||
UCHAR *buf;
|
UCHAR *buf;
|
||||||
UINT i, icmp_type, buf_size, padding_size;
|
UINT i, icmp_type, buf_size, padding_size;
|
||||||
|
icmp_type = 0;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (r == NULL || se == NULL || (data == NULL && data_size != 0))
|
if (r == NULL || se == NULL || (data == NULL && data_size != 0))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user