Implemented ICMPv6 on Windows.
This commit is contained in:
parent
ff42dfd3a4
commit
8b53b6e4d1
@ -19,7 +19,7 @@ namespace ehs
|
|||||||
class ICMP : public BaseICMP
|
class ICMP : public BaseICMP
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Int_32 hdl;
|
Socket hdl;
|
||||||
sockaddr_in6 src;
|
sockaddr_in6 src;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -17,7 +17,7 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
ICMP::~ICMP()
|
ICMP::~ICMP()
|
||||||
{
|
{
|
||||||
if (close(hdl) == -1)
|
if (closesocket(hdl) == -1)
|
||||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ namespace ehs
|
|||||||
|
|
||||||
void ICMP::Release()
|
void ICMP::Release()
|
||||||
{
|
{
|
||||||
if (close(hdl) == -1)
|
if (closesocket(hdl) == -1)
|
||||||
{
|
{
|
||||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
|
||||||
|
|
||||||
@ -118,33 +118,43 @@ namespace ehs
|
|||||||
|
|
||||||
sockaddr_in6 ICMP::RetrieveSrcAddress()
|
sockaddr_in6 ICMP::RetrieveSrcAddress()
|
||||||
{
|
{
|
||||||
ifaddrs *ifaddr;
|
|
||||||
sockaddr_in6 addr = {};
|
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) + ".");
|
buffer.Resize(outBufLen);
|
||||||
|
pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)&buffer[0];
|
||||||
return addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
for (PIP_ADAPTER_ADDRESSES adapter = pAdapterAddresses; adapter != nullptr; adapter = adapter->Next)
|
||||||
continue;
|
{
|
||||||
|
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;
|
sockaddr_in6 *ipv6Addr = (sockaddr_in6 *)sa;
|
||||||
if (!addr.sin6_addr.s6_addr32[0] || IsLinkLocal(addr.sin6_addr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
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();
|
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)
|
UInt_32 ICMP::CalculatePseudoHeaderChecksum(const PseudoICMPv6_Header &header)
|
||||||
@ -171,10 +181,10 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
UInt_32 checksum = 0;
|
UInt_32 checksum = 0;
|
||||||
|
|
||||||
if (!src.sin6_addr.s6_addr32[0])
|
if (!src.sin6_addr.u.Word[0])
|
||||||
{
|
{
|
||||||
src = RetrieveSrcAddress();
|
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.");
|
EHS_LOG_INT(LogType::ERR, 0, "Could not retrieve a suitable global address.");
|
||||||
return checksum;
|
return checksum;
|
||||||
@ -261,7 +271,7 @@ namespace ehs
|
|||||||
|
|
||||||
payload.SetOffset(payload.GetOffset() + size);
|
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.SetOffset(0);
|
||||||
payload.Write(header);
|
payload.Write(header);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user