https://git.reactos.org/?p=reactos.git;a=commitdiff;h=63ad8a71c03cddea9e4d3…
commit 63ad8a71c03cddea9e4d3f14243230d01da75087
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Wed Jan 24 00:28:55 2018 +0300
Commit: Ged Murphy <gedmurphy(a)reactos.org>
CommitDate: Wed Jan 31 17:28:21 2018 +0000
[IPHLPAPI] Fix IcmpSendEcho output when host is not reachable
- Add missing error code to DDK/NDIS
- Fix error code in IP driver
- Patch MSAFD to reply correct WSA error code
- Fix IcmpSendEcho function
- Fix returning error code in ICMP_ECHO_REPLY (see MSDN)
- Fix returning host address (using GetBestInterface and GetIpAddrTable functions)
- Fix GetBestRoute function (it is used by GetBestInterface)
Relates to #318 and CORE-14241
---
dll/win32/iphlpapi/icmp.c | 59 ++++++++++++++++++++++++++++++++---
dll/win32/iphlpapi/iphlpapi_main.c | 17 +++++-----
dll/win32/msafd/misc/dllmain.c | 3 ++
sdk/include/ddk/ndis.h | 1 +
sdk/lib/drivers/ip/network/neighbor.c | 2 +-
5 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/dll/win32/iphlpapi/icmp.c b/dll/win32/iphlpapi/icmp.c
index ab0245a2dc..95fbe1bdca 100644
--- a/dll/win32/iphlpapi/icmp.c
+++ b/dll/win32/iphlpapi/icmp.c
@@ -496,6 +496,40 @@ static DWORD system_icmp(
}
#endif
+BOOL
+GetIPv4ByIndex(
+ _In_ DWORD Index,
+ _Out_ IPAddr * Address
+)
+{
+ PMIB_IPADDRTABLE pIpAddrTable;
+ ULONG dwSize = 0;
+ BOOL result = FALSE;
+
+ if (GetIpAddrTable(NULL, &dwSize, FALSE) != ERROR_INSUFFICIENT_BUFFER)
+ {
+ return result;
+ }
+ pIpAddrTable = HeapAlloc(GetProcessHeap(), 0, dwSize);
+
+ if (GetIpAddrTable(pIpAddrTable, &dwSize, FALSE) == NO_ERROR)
+ {
+ INT i;
+
+ for (i = 0; i < (*pIpAddrTable).dwNumEntries; i++)
+ {
+ if ((*pIpAddrTable).table[i].dwIndex == Index)
+ {
+ *Address = (IPAddr)(*pIpAddrTable).table[i].dwAddr;
+ result = TRUE;
+ break;
+ }
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, pIpAddrTable);
+ return result;
+}
+
/***********************************************************************
* IcmpSendEcho (IPHLPAPI.@)
*/
@@ -671,22 +705,34 @@ DWORD WINAPI IcmpSendEcho(
res=sendto(icp->sid, (const char*)reqbuf, reqsize, 0, (struct sockaddr*)&addr,
sizeof(addr));
HeapFree(GetProcessHeap (), 0, reqbuf);
if (res<0) {
+ DWORD dwBestIfIndex;
+ IPAddr IP4Addr;
+
+ ZeroMemory(&ier->Address, sizeof(ier->Address));
+
+ if (GetBestInterface(addr.sin_addr.s_addr, &dwBestIfIndex) == NO_ERROR
&&
+ GetIPv4ByIndex(dwBestIfIndex, &IP4Addr))
+ {
+ memcpy(&ier->Address, &IP4Addr, sizeof(IP4Addr));
+ }
+
if (WSAGetLastError()==WSAEMSGSIZE)
- SetLastError(IP_PACKET_TOO_BIG);
+ ier->Status = IP_PACKET_TOO_BIG;
else {
switch (WSAGetLastError()) {
case WSAENETUNREACH:
- SetLastError(IP_DEST_NET_UNREACHABLE);
+ ier->Status = IP_DEST_NET_UNREACHABLE;
break;
case WSAEHOSTUNREACH:
- SetLastError(IP_DEST_HOST_UNREACHABLE);
+ ier->Status = IP_DEST_HOST_UNREACHABLE;
break;
default:
TRACE("unknown error: errno=%d\n",WSAGetLastError());
- SetLastError(IP_GENERAL_FAILURE);
+ ier->Status = IP_GENERAL_FAILURE;
+ ZeroMemory(&ier->Address, sizeof(ier->Address));
}
}
- return 0;
+ return 1;
}
/* Get the reply */
@@ -848,7 +894,10 @@ DWORD WINAPI IcmpSendEcho(
HeapFree(GetProcessHeap(), 0, ip_header);
res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer;
if (res==0)
+ {
+ ier->Status = IP_REQ_TIMED_OUT;
SetLastError(IP_REQ_TIMED_OUT);
+ }
TRACE("received %d replies\n",res);
return res;
}
diff --git a/dll/win32/iphlpapi/iphlpapi_main.c b/dll/win32/iphlpapi/iphlpapi_main.c
index af8cbd1805..c06796f6d8 100644
--- a/dll/win32/iphlpapi/iphlpapi_main.c
+++ b/dll/win32/iphlpapi/iphlpapi_main.c
@@ -767,18 +767,19 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr,
PMIB_IPFORWARDRO
AllocateAndGetIpForwardTableFromStack(&table, FALSE, GetProcessHeap(), 0);
if (table) {
- DWORD ndx, matchedBits, matchedNdx = 0;
+ DWORD ndx, minMaskSize, matchedNdx = 0;
- for (ndx = 0, matchedBits = 0; ndx < table->dwNumEntries; ndx++) {
+ for (ndx = 0, minMaskSize = 255; ndx < table->dwNumEntries; ndx++) {
if ((dwDestAddr & table->table[ndx].dwForwardMask) ==
(table->table[ndx].dwForwardDest & table->table[ndx].dwForwardMask)) {
- DWORD numShifts, mask;
+ DWORD hostMaskSize;
- for (numShifts = 0, mask = table->table[ndx].dwForwardMask;
- mask && !(mask & 1); mask >>= 1, numShifts++)
- ;
- if (numShifts > matchedBits) {
- matchedBits = numShifts;
+ if (!_BitScanForward(&hostMaskSize,
ntohl(table->table[ndx].dwForwardMask)))
+ {
+ hostMaskSize = 32;
+ }
+ if (hostMaskSize < minMaskSize) {
+ minMaskSize = hostMaskSize;
matchedNdx = ndx;
}
}
diff --git a/dll/win32/msafd/misc/dllmain.c b/dll/win32/msafd/misc/dllmain.c
index c0de49ba28..f6e04ae5fc 100644
--- a/dll/win32/msafd/misc/dllmain.c
+++ b/dll/win32/msafd/misc/dllmain.c
@@ -579,6 +579,9 @@ TranslateNtStatusError(NTSTATUS Status)
case STATUS_NETWORK_UNREACHABLE:
return WSAENETUNREACH;
+ case STATUS_HOST_UNREACHABLE:
+ return WSAEHOSTUNREACH;
+
case STATUS_INVALID_PARAMETER:
return WSAEINVAL;
diff --git a/sdk/include/ddk/ndis.h b/sdk/include/ddk/ndis.h
index fef3b2e0f9..028dd1f49b 100644
--- a/sdk/include/ddk/ndis.h
+++ b/sdk/include/ddk/ndis.h
@@ -509,6 +509,7 @@ typedef MDL NDIS_BUFFER, *PNDIS_BUFFER;
#define NDIS_STATUS_TOKEN_RING_OPEN_ERROR ((NDIS_STATUS)0xC0011000L)
#define NDIS_STATUS_INVALID_DEVICE_REQUEST
((NDIS_STATUS)STATUS_INVALID_DEVICE_REQUEST)
#define NDIS_STATUS_NETWORK_UNREACHABLE
((NDIS_STATUS)STATUS_NETWORK_UNREACHABLE)
+#define NDIS_STATUS_HOST_UNREACHABLE ((NDIS_STATUS)STATUS_HOST_UNREACHABLE)
#if NDIS_SUPPORT_NDIS6
diff --git a/sdk/lib/drivers/ip/network/neighbor.c
b/sdk/lib/drivers/ip/network/neighbor.c
index a7c1d35eea..7477a8f9f3 100644
--- a/sdk/lib/drivers/ip/network/neighbor.c
+++ b/sdk/lib/drivers/ip/network/neighbor.c
@@ -144,7 +144,7 @@ VOID NBTimeout(VOID)
if (NCE->State & NUD_INCOMPLETE)
{
/* We couldn't get an address to this IP at all */
- Status = NDIS_STATUS_NETWORK_UNREACHABLE;
+ Status = NDIS_STATUS_HOST_UNREACHABLE;
}
else
{