|
|
|
@@ -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);
|
|
|
|
|