Implemented ICMPv6 on Windows.
This commit is contained in:
parent
ff42dfd3a4
commit
8b53b6e4d1
@ -19,7 +19,7 @@ namespace ehs
|
||||
class ICMP : public BaseICMP
|
||||
{
|
||||
private:
|
||||
Int_32 hdl;
|
||||
Socket hdl;
|
||||
sockaddr_in6 src;
|
||||
|
||||
public:
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user