1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-22 17:39:53 +03:00

Fixing most errors, the link on Windows is working and is stable

This commit is contained in:
Evengard 2020-05-12 03:30:59 +03:00
parent a2a6502ab9
commit 2cfe031398
6 changed files with 384 additions and 247 deletions

View File

@ -1428,7 +1428,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
} }
} }
FreePacket(pkt); FreePacketWithData(pkt);
} }
IPCAssociateOnArpTable(ipc, &ip_src, src_mac); IPCAssociateOnArpTable(ipc, &ip_src, src_mac);
@ -1438,6 +1438,10 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
// 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
{
Free(data); // We need to free the packet if we don't save it
}
} }
else else
@ -1470,9 +1474,9 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
{ {
case ICMPV6_TYPE_ROUTER_ADVERTISEMENT: case ICMPV6_TYPE_ROUTER_ADVERTISEMENT:
// 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); IPCIPv6AddRouterPrefixes(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->Address, 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
@ -1495,6 +1499,10 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
{ {
InsertQueue(ipc->IPv6ReceivedQueue, NewBlock(data, size, 0)); InsertQueue(ipc->IPv6ReceivedQueue, NewBlock(data, size, 0));
} }
else
{
Free(data); // We need to free the packet if we don't save it
}
FreePacket(p); FreePacket(p);
} }
@ -2192,14 +2200,18 @@ bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui)
} }
// RA // RA
void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip) void IPCIPv6AddRouterPrefixes(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip)
{ {
UINT i; UINT i, j;
bool foundPrefix = false; for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
for (i = 0; i < LIST_NUM(ipc->IPv6RouterAdvs); i++)
{ {
IPC_IPV6_ROUTER_ADVERTISEMENT *existingRA = LIST_DATA(ipc->IPv6RouterAdvs, i); if (recvPrefix->Prefix[i] != NULL)
if (Cmp(&recvPrefix->Prefix->Prefix, &existingRA->RoutedPrefix.ipv6_addr, sizeof(IPV6_ADDR)) == 0) {
bool foundPrefix = false;
for (j = 0; j < LIST_NUM(ipc->IPv6RouterAdvs); j++)
{
IPC_IPV6_ROUTER_ADVERTISEMENT *existingRA = LIST_DATA(ipc->IPv6RouterAdvs, j);
if (Cmp(&recvPrefix->Prefix[i]->Prefix, &existingRA->RoutedPrefix.ipv6_addr, sizeof(IPV6_ADDR)) == 0)
{ {
foundPrefix = true; foundPrefix = true;
break; break;
@ -2209,13 +2221,19 @@ void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *mac
if (!foundPrefix) if (!foundPrefix)
{ {
IPC_IPV6_ROUTER_ADVERTISEMENT *newRA = Malloc(sizeof(IPC_IPV6_ROUTER_ADVERTISEMENT)); IPC_IPV6_ROUTER_ADVERTISEMENT *newRA = Malloc(sizeof(IPC_IPV6_ROUTER_ADVERTISEMENT));
IPv6AddrToIP(&newRA->RoutedPrefix, &recvPrefix->Prefix->Prefix); IPv6AddrToIP(&newRA->RoutedPrefix, &recvPrefix->Prefix[i]->Prefix);
IntToSubnetMask6(&newRA->RoutedMask, recvPrefix->Prefix->SubnetLength); IntToSubnetMask6(&newRA->RoutedMask, recvPrefix->Prefix[i]->SubnetLength);
CopyIP(&newRA->RouterAddress, ip); CopyIP(&newRA->RouterAddress, ip);
Copy(newRA->RouterMacAddress, macAddress, 6); Copy(newRA->RouterMacAddress, macAddress, 6);
Copy(newRA->RouterLinkLayerAddress, recvPrefix->SourceLinkLayer->Address, 6); Copy(newRA->RouterLinkLayerAddress, recvPrefix->SourceLinkLayer->Address, 6);
Add(ipc->IPv6RouterAdvs, newRA); Add(ipc->IPv6RouterAdvs, newRA);
} }
}
else
{
break;
}
}
} }
bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA) bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA)
@ -2287,11 +2305,16 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc)
packet = BuildICMPv6RouterSoliciation(&senderV6, &destV6, ipc->MacAddress, 0); packet = BuildICMPv6RouterSoliciation(&senderV6, &destV6, ipc->MacAddress, 0);
UINT64 giveup_time = Tick64() + (UINT64)(IPC_IPV6_RA_MAX_RETRIES * IPC_IPV6_RA_INTERVAL); UINT64 giveup_time = Tick64() + (UINT64)(IPC_IPV6_RA_MAX_RETRIES * IPC_IPV6_RA_INTERVAL);
UINT64 timeout_retry = 0;
while (LIST_NUM(ipc->IPv6RouterAdvs) == 0) while (LIST_NUM(ipc->IPv6RouterAdvs) == 0)
{ {
UINT64 timeout_retry = Tick64() + (UINT64)IPC_IPV6_RA_INTERVAL; UINT64 now = Tick64();
if (now >= timeout_retry)
{
timeout_retry = now + (UINT64)IPC_IPV6_RA_INTERVAL;
IPCIPv6SendWithDestMacAddr(ipc, packet->Buf, packet->Size, destMacAddress); IPCIPv6SendWithDestMacAddr(ipc, packet->Buf, packet->Size, destMacAddress);
}
AddInterrupt(ipc->Interrupt, timeout_retry); AddInterrupt(ipc->Interrupt, timeout_retry);
@ -2304,6 +2327,8 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc)
// The processing should populate the received RAs by itself // The processing should populate the received RAs by itself
IPCProcessL3Events(ipc); IPCProcessL3Events(ipc);
} }
FreeBuf(packet);
} }
// Populating the IPv6 Server EUI for IPV6CP // Populating the IPv6 Server EUI for IPV6CP
@ -2379,6 +2404,10 @@ void IPCIPv6Send(IPC *ipc, void *data, UINT size)
void IPCIPv6SendWithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac_addr) void IPCIPv6SendWithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac_addr)
{ {
UCHAR tmp[1514]; UCHAR tmp[1514];
IPV6_HEADER *header = data;
// Validate arguments // Validate arguments
if (ipc == NULL || data == NULL || size < 40 || size > 1500 || dest_mac_addr == NULL) if (ipc == NULL || data == NULL || size < 40 || size > 1500 || dest_mac_addr == NULL)
{ {
@ -2397,6 +2426,60 @@ void IPCIPv6SendWithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac
// Data // Data
Copy(tmp + 14, data, size); Copy(tmp + 14, data, size);
// Parse the packet for ND ICMPv6 fixup
if (header->NextHeader == IP_PROTO_ICMPV6)
{
PKT *p = ParsePacketUpToICMPv6(tmp, size + 14);
if (p != NULL)
{
ICMPV6_OPTION_LINK_LAYER linkLayer;
BUF *buf;
BUF *optBuf;
BUF *packet;
// We need to rebuild the packet to
switch (p->ICMPv6HeaderPacketInfo.Type)
{
case ICMPV6_TYPE_NEIGHBOR_SOLICIATION:
if (p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer == NULL)
{
p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer = &linkLayer;
}
Copy(p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, ipc->MacAddress, 6);
case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
if (p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer == NULL)
{
p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer = &linkLayer;
}
Copy(p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer->Address, ipc->MacAddress, 6);
}
switch (p->ICMPv6HeaderPacketInfo.Type)
{
case ICMPV6_TYPE_NEIGHBOR_SOLICIATION:
case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
optBuf = BuildICMPv6Options(&p->ICMPv6HeaderPacketInfo.OptionList);
buf = NewBuf();
WriteBuf(buf, p->ICMPv6HeaderPacketInfo.Headers.HeaderPointer,
p->ICMPv6HeaderPacketInfo.Type == ICMPV6_TYPE_NEIGHBOR_SOLICIATION ? sizeof(ICMPV6_NEIGHBOR_SOLICIATION_HEADER) : sizeof(ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER));
WriteBufBuf(buf, optBuf);
packet = BuildICMPv6(&p->IPv6HeaderPacketInfo.IPv6Header->SrcAddress,
&p->IPv6HeaderPacketInfo.IPv6Header->DestAddress,
p->IPv6HeaderPacketInfo.IPv6Header->HopLimit,
p->ICMPv6HeaderPacketInfo.Type,
p->ICMPv6HeaderPacketInfo.Code,
buf->Buf,
buf->Size,
0);
Copy(tmp + 14, packet->Buf, packet->Size);
size = packet->Size;
FreeBuf(optBuf);
FreeBuf(buf);
FreeBuf(packet);
break;
}
}
FreePacket(p);
}
// Send // Send
IPCSendL2(ipc, tmp, size + 14); IPCSendL2(ipc, tmp, size + 14);
} }
@ -2484,13 +2567,24 @@ void IPCIPv6SendUnicast(IPC *ipc, void *data, UINT size, IP *next_ip)
{ {
// We need to send the Neighbor Solicitation and save the packet for sending later // We need to send the Neighbor Solicitation and save the packet for sending later
// Generate the MAC address from the multicast address // Generate the MAC address from the multicast address
BUF *neighborSolicit;
UCHAR destMacAddress[6]; UCHAR destMacAddress[6];
BUF *neighborSolicit = BuildICMPv6NeighborSoliciation(&header->SrcAddress, &header->DestAddress, ipc->MacAddress, 0); IPV6_ADDR solicitAddress;
Zero(&solicitAddress, sizeof(IPV6_ADDR));
Copy(&solicitAddress.Value[13], &header->DestAddress.Value[13], 3);
solicitAddress.Value[0] = 0xFF;
solicitAddress.Value[1] = 0x02;
solicitAddress.Value[11] = 0x01;
solicitAddress.Value[12] = 0xFF;
neighborSolicit = BuildICMPv6NeighborSoliciation(&header->SrcAddress, &solicitAddress, ipc->MacAddress, 0);
destMacAddress[0] = 0x33; destMacAddress[0] = 0x33;
destMacAddress[1] = 0x33; destMacAddress[1] = 0x33;
Copy(&destMacAddress[2], &next_ip->ipv6_addr[12], sizeof(UINT)); Copy(&destMacAddress[2], &solicitAddress.Value[12], sizeof(UINT));
IPCIPv6SendWithDestMacAddr(ipc, neighborSolicit->Buf, neighborSolicit->Size, destMacAddress); IPCIPv6SendWithDestMacAddr(ipc, neighborSolicit->Buf, neighborSolicit->Size, destMacAddress);
FreeBuf(neighborSolicit);
CHAR tmp[MAX_SIZE]; CHAR tmp[MAX_SIZE];
UCHAR *copy = Clone(data, size); UCHAR *copy = Clone(data, size);
BLOCK *blk = NewBlock(copy, size, 0); BLOCK *blk = NewBlock(copy, size, 0);

View File

@ -227,7 +227,7 @@ void IPCIPv6FlushNDT(IPC *ipc);
void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now); void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now);
bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui); bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui);
// RA // RA
void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip); void IPCIPv6AddRouterPrefixes(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);
UINT64 IPCIPv6GetServerEui(IPC *ipc); UINT64 IPCIPv6GetServerEui(IPC *ipc);
// Data flow // Data flow

View File

@ -175,7 +175,7 @@ void FreeEraseFileList(LIST *o)
return; return;
} }
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
ERASE_FILE *f = LIST_DATA(o, i); ERASE_FILE *f = LIST_DATA(o, i);
Free(f->FullPath); Free(f->FullPath);
@ -200,7 +200,7 @@ void EnumEraseFile(LIST *o, char *dirname)
// Enumeration // Enumeration
dir = EnumDir(dirname); dir = EnumDir(dirname);
for (i = 0;i < dir->NumFiles;i++) for (i = 0; i < dir->NumFiles; i++)
{ {
DIRENT *e = dir->File[i]; DIRENT *e = dir->File[i];
Format(tmp, sizeof(tmp), "%s/%s", dirname, e->FileName); Format(tmp, sizeof(tmp), "%s/%s", dirname, e->FileName);
@ -245,7 +245,7 @@ LIST *GenerateEraseFileList(ERASER *e)
o = NewListFast(CompareEraseFile); o = NewListFast(CompareEraseFile);
// Scan for each directory // Scan for each directory
for (i = 0;i < sizeof(delete_targets) / sizeof(delete_targets[0]);i++) for (i = 0; i < sizeof(delete_targets) / sizeof(delete_targets[0]); i++)
{ {
char dirname[MAX_PATH]; char dirname[MAX_PATH];
Format(dirname, sizeof(dirname), "%s/%s", e->DirName, delete_targets[i]); Format(dirname, sizeof(dirname), "%s/%s", e->DirName, delete_targets[i]);
@ -285,7 +285,7 @@ void EraserMain(ERASER *e)
o = GenerateEraseFileList(e); o = GenerateEraseFileList(e);
// Try to delete one by one in order from oldest file // Try to delete one by one in order from oldest file
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
ERASE_FILE *f = LIST_DATA(o, i); ERASE_FILE *f = LIST_DATA(o, i);
@ -1259,7 +1259,7 @@ void MakeSafeLogStr(char *str)
EnPrintableAsciiStr(str, '?'); EnPrintableAsciiStr(str, '?');
len = StrLen(str); len = StrLen(str);
for (i = 0;i < len;i++) for (i = 0; i < len; i++)
{ {
if (str[i] == ',') if (str[i] == ',')
{ {
@ -1284,6 +1284,7 @@ char *PacketLogParseProc(RECORD *rec)
TOKEN_LIST *t; TOKEN_LIST *t;
char tmp[MAX_SIZE]; char tmp[MAX_SIZE];
bool tcp_conn; bool tcp_conn;
UINT i;
// Validate arguments // Validate arguments
if (rec == NULL) if (rec == NULL)
{ {
@ -1686,14 +1687,21 @@ char *PacketLogParseProc(RECORD *rec)
snprintf(tmp, sizeof(tmp), "TargetLinkLayer=%s ", tmp2); snprintf(tmp, sizeof(tmp), "TargetLinkLayer=%s ", tmp2);
StrCat(info, sizeof(info), tmp); StrCat(info, sizeof(info), tmp);
} }
if (ol->Prefix != NULL) for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (ol->Prefix[i] != NULL)
{ {
char tmp2[MAX_SIZE]; char tmp2[MAX_SIZE];
IP6AddrToStr(tmp2, sizeof(tmp2), &ol->Prefix->Prefix); IP6AddrToStr(tmp2, sizeof(tmp2), &ol->Prefix[i]->Prefix);
snprintf(tmp, sizeof(tmp), "Prefix=%s/%u PrefixFlag=0x%02X ", tmp2, snprintf(tmp, sizeof(tmp), "Prefix=%s/%u PrefixFlag=0x%02X ", tmp2,
ol->Prefix->SubnetLength, ol->Prefix->Flags); ol->Prefix[i]->SubnetLength, ol->Prefix[i]->Flags);
StrCat(info, sizeof(info), tmp); StrCat(info, sizeof(info), tmp);
} }
else
{
break;
}
}
if (ol->Mtu != NULL) if (ol->Mtu != NULL)
{ {
snprintf(tmp, sizeof(tmp), "Mtu=%u ", Endian32(ol->Mtu->Mtu)); snprintf(tmp, sizeof(tmp), "Mtu=%u ", Endian32(ol->Mtu->Mtu));
@ -1975,7 +1983,7 @@ char *GenCsvLine(TOKEN_LIST *t)
} }
b = NewBuf(); b = NewBuf();
for (i = 0;i < t->NumTokens;i++) for (i = 0; i < t->NumTokens; i++)
{ {
if (t->Token[i] != NULL) if (t->Token[i] != NULL)
{ {
@ -2019,7 +2027,7 @@ void ReplaceForCsv(char *str)
len = StrLen(str); len = StrLen(str);
for (i = 0;i < len;i++) for (i = 0; i < len; i++)
{ {
// Convert the comma to underscore // Convert the comma to underscore
if (str[i] == ',') if (str[i] == ',')
@ -2542,7 +2550,7 @@ static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *l
log_object->CurrentLogNumber = 0; log_object->CurrentLogNumber = 0;
MakeLogFileName(log_object, file_name, sizeof(file_name), MakeLogFileName(log_object, file_name, sizeof(file_name),
log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, 0, current_logfile_datename); log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, 0, current_logfile_datename);
for (i = 0;;i++) for (i = 0;; i++)
{ {
char tmp[MAX_SIZE]; char tmp[MAX_SIZE];
MakeLogFileName(log_object, tmp, sizeof(tmp), MakeLogFileName(log_object, tmp, sizeof(tmp),

View File

@ -365,7 +365,7 @@ void PPPThread(THREAD *thread, void *param)
PPPSendPacketEx(p, pp, true); PPPSendPacketEx(p, pp, true);
FreePPPPacketEx(pp, true); FreePPPPacketEx(pp, true);
Free(b); Free(b); // Not FreeBlock because freed in FreePPPPacketEx
} }
} }
else else
@ -396,7 +396,7 @@ void PPPThread(THREAD *thread, void *param)
PPPSendPacketEx(p, pp, true); PPPSendPacketEx(p, pp, true);
FreePPPPacketEx(pp, true); FreePPPPacketEx(pp, true);
Free(b); Free(b); // Not FreeBlock because freed in FreePPPPacketEx
} }
} }
else else
@ -1961,7 +1961,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{ {
UINT64 newValue = 0; UINT64 newValue = 0;
UINT64 value = READ_UINT64(t->Data); UINT64 value = READ_UINT64(t->Data);
if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, value)) if (value != 0 && !IPCIPv6CheckExistingLinkLocal(p->Ipc, value))
{ {
t->IsAccepted = true; t->IsAccepted = true;
p->Ipc->IPv6ClientEUI = value; p->Ipc->IPv6ClientEUI = value;

View File

@ -1140,6 +1140,7 @@ void BuildICMPv6OptionValue(BUF *b, UCHAR type, void *header_pointer, UINT total
BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o) BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o)
{ {
BUF *b; BUF *b;
UINT i;
// Validate arguments // Validate arguments
if (o == NULL) if (o == NULL)
{ {
@ -1156,9 +1157,16 @@ BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o)
{ {
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_TARGET_LINK_LAYER, o->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER)); BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_TARGET_LINK_LAYER, o->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
} }
if (o->Prefix != NULL) for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{ {
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_PREFIX, o->Prefix, sizeof(ICMPV6_OPTION_PREFIX)); if (o->Prefix[i] != NULL)
{
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_PREFIX, o->Prefix[i], sizeof(ICMPV6_OPTION_PREFIX));
}
else
{
break;
}
} }
if (o->Mtu != NULL) if (o->Mtu != NULL)
{ {
@ -2402,7 +2410,15 @@ bool ParseICMPv6Options(ICMPV6_OPTION_LIST *o, UCHAR *buf, UINT size)
// Prefix Information // Prefix Information
if (header_total_size >= sizeof(ICMPV6_OPTION_PREFIX)) if (header_total_size >= sizeof(ICMPV6_OPTION_PREFIX))
{ {
o->Prefix = (ICMPV6_OPTION_PREFIX *)header_pointer; UINT i;
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (o->Prefix[i] == NULL)
{
o->Prefix[i] = (ICMPV6_OPTION_PREFIX *)header_pointer;
break;
}
}
} }
else else
{ {
@ -2556,6 +2572,7 @@ bool ParseICMPv6(PKT *p, UCHAR *buf, UINT size)
// Release of the ICMPv6 options // Release of the ICMPv6 options
void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o) void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o)
{ {
UINT i;
// Validate arguments // Validate arguments
if (o == NULL) if (o == NULL)
{ {
@ -2564,13 +2581,19 @@ void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o)
Free(o->SourceLinkLayer); Free(o->SourceLinkLayer);
Free(o->TargetLinkLayer); Free(o->TargetLinkLayer);
Free(o->Prefix);
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
Free(o->Prefix[i]);
o->Prefix[i] = NULL;
}
Free(o->Mtu); Free(o->Mtu);
} }
// Clone of the ICMPv6 options // Clone of the ICMPv6 options
void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src) void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src)
{ {
UINT i;
// Validate arguments // Validate arguments
if (dst == NULL || src == NULL) if (dst == NULL || src == NULL)
{ {
@ -2581,7 +2604,17 @@ void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src)
dst->SourceLinkLayer = Clone(src->SourceLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER)); dst->SourceLinkLayer = Clone(src->SourceLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
dst->TargetLinkLayer = Clone(src->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER)); dst->TargetLinkLayer = Clone(src->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
dst->Prefix = Clone(src->Prefix, sizeof(ICMPV6_OPTION_PREFIX)); for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (src->Prefix[i] != NULL)
{
dst->Prefix[i] = Clone(src->Prefix[i], sizeof(ICMPV6_OPTION_PREFIX));
}
else
{
break;
}
}
dst->Mtu = Clone(src->Mtu, sizeof(ICMPV6_OPTION_MTU)); dst->Mtu = Clone(src->Mtu, sizeof(ICMPV6_OPTION_MTU));
} }

View File

@ -399,12 +399,14 @@ struct ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER
#define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED 0x40 // Solicited flag #define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED 0x40 // Solicited flag
#define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERWRITE 0x20 // Overwrite flag #define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERWRITE 0x20 // Overwrite flag
#define ICMPV6_OPTION_PREFIXES_MAX_COUNT 10
// ICMPv6 option list // ICMPv6 option list
struct ICMPV6_OPTION_LIST struct ICMPV6_OPTION_LIST
{ {
ICMPV6_OPTION_LINK_LAYER *SourceLinkLayer; // Source link-layer address ICMPV6_OPTION_LINK_LAYER *SourceLinkLayer; // Source link-layer address
ICMPV6_OPTION_LINK_LAYER *TargetLinkLayer; // Target link-layer address ICMPV6_OPTION_LINK_LAYER *TargetLinkLayer; // Target link-layer address
ICMPV6_OPTION_PREFIX *Prefix; // Prefix Information ICMPV6_OPTION_PREFIX *Prefix[ICMPV6_OPTION_PREFIXES_MAX_COUNT]; // Prefix Information - may be multiple in one request
ICMPV6_OPTION_MTU *Mtu; // MTU ICMPV6_OPTION_MTU *Mtu; // MTU
} GCC_PACKED; } GCC_PACKED;