https://git.reactos.org/?p=reactos.git;a=commitdiff;h=63ad8a71c03cddea9e4d3f...
commit 63ad8a71c03cddea9e4d3f14243230d01da75087 Author: Stanislav Motylkov x86corez@gmail.com AuthorDate: Wed Jan 24 00:28:55 2018 +0300 Commit: Ged Murphy gedmurphy@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 {