Implemented ICMPv6 on Windows.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 3m34s
Build & Release / Linux-AMD64-Build (push) Successful in 14m39s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m40s

This commit is contained in:
Karutoh 2025-03-28 21:24:13 -07:00
parent ff42dfd3a4
commit 8b53b6e4d1
2 changed files with 31 additions and 21 deletions

View File

@ -19,7 +19,7 @@ namespace ehs
class ICMP : public BaseICMP
{
private:
Int_32 hdl;
Socket hdl;
sockaddr_in6 src;
public:

View File

@ -17,7 +17,7 @@ namespace ehs
{
ICMP::~ICMP()
{
if (close(hdl) == -1)
if (closesocket(hdl) == -1)
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
}
@ -78,7 +78,7 @@ namespace ehs
void ICMP::Release()
{
if (close(hdl) == -1)
if (closesocket(hdl) == -1)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
@ -118,33 +118,43 @@ namespace ehs
sockaddr_in6 ICMP::RetrieveSrcAddress()
{
ifaddrs *ifaddr;
sockaddr_in6 addr = {};
UInt_32 outBufLen = 15000;
Array<Byte> buffer(outBufLen);
PIP_ADAPTER_ADDRESSES pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)&buffer[0];
if (getifaddrs(&ifaddr) == -1)
if (GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAdapterAddresses, (PULONG)&outBufLen) == ERROR_BUFFER_OVERFLOW)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve public address with error #" + Str_8::FromNum(errno) + ".");
return addr;
buffer.Resize(outBufLen);
pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)&buffer[0];
}
for (ifaddrs *ifa = ifaddr; ifa; ifa = ifa->ifa_next)
if (GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAdapterAddresses, (PULONG)&outBufLen) == NO_ERROR)
{
if (ifa->ifa_addr == nullptr || ifa->ifa_addr->sa_family != AF_INET6)
continue;
for (PIP_ADAPTER_ADDRESSES adapter = pAdapterAddresses; adapter != nullptr; adapter = adapter->Next)
{
for (PIP_ADAPTER_UNICAST_ADDRESS addrInfo = adapter->FirstUnicastAddress; addrInfo != nullptr; addrInfo = addrInfo->Next)
{
SOCKADDR *sa = addrInfo->Address.lpSockaddr;
if (sa->sa_family != AF_INET6)
continue;
addr = *(sockaddr_in6 *)ifa->ifa_addr;
if (!addr.sin6_addr.s6_addr32[0] || IsLinkLocal(addr.sin6_addr))
continue;
sockaddr_in6 *ipv6Addr = (sockaddr_in6 *)sa;
break;
// Skip link-local addresses
if (IN6_IS_ADDR_LINKLOCAL(&ipv6Addr->sin6_addr))
continue;
addr = *ipv6Addr;
return addr; // Return the first suitable address
}
}
}
freeifaddrs(ifaddr);
EHS_LOG_SUCCESS();
return addr;
return addr; // Return an empty sockaddr_in6 if no valid address was found
}
UInt_32 ICMP::CalculatePseudoHeaderChecksum(const PseudoICMPv6_Header &header)
@ -171,10 +181,10 @@ namespace ehs
{
UInt_32 checksum = 0;
if (!src.sin6_addr.s6_addr32[0])
if (!src.sin6_addr.u.Word[0])
{
src = RetrieveSrcAddress();
if (!src.sin6_addr.s6_addr32[0])
if (!src.sin6_addr.u.Word[0])
{
EHS_LOG_INT(LogType::ERR, 0, "Could not retrieve a suitable global address.");
return checksum;
@ -261,7 +271,7 @@ namespace ehs
payload.SetOffset(payload.GetOffset() + size);
header.checksum = ComputeChecksum((UInt_16 *)&payload[0], payload.Size());
header.checksum = ComputeChecksumV4((UInt_16 *)&payload[0], payload.Size());
payload.SetOffset(0);
payload.Write(header);