mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:05:42 +00:00
[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
This commit is contained in:
parent
3624c5d6fd
commit
63ad8a71c0
5 changed files with 68 additions and 14 deletions
|
@ -496,6 +496,40 @@ static DWORD system_icmp(
|
||||||
}
|
}
|
||||||
#endif
|
#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.@)
|
* IcmpSendEcho (IPHLPAPI.@)
|
||||||
*/
|
*/
|
||||||
|
@ -671,22 +705,34 @@ DWORD WINAPI IcmpSendEcho(
|
||||||
res=sendto(icp->sid, (const char*)reqbuf, reqsize, 0, (struct sockaddr*)&addr, sizeof(addr));
|
res=sendto(icp->sid, (const char*)reqbuf, reqsize, 0, (struct sockaddr*)&addr, sizeof(addr));
|
||||||
HeapFree(GetProcessHeap (), 0, reqbuf);
|
HeapFree(GetProcessHeap (), 0, reqbuf);
|
||||||
if (res<0) {
|
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)
|
if (WSAGetLastError()==WSAEMSGSIZE)
|
||||||
SetLastError(IP_PACKET_TOO_BIG);
|
ier->Status = IP_PACKET_TOO_BIG;
|
||||||
else {
|
else {
|
||||||
switch (WSAGetLastError()) {
|
switch (WSAGetLastError()) {
|
||||||
case WSAENETUNREACH:
|
case WSAENETUNREACH:
|
||||||
SetLastError(IP_DEST_NET_UNREACHABLE);
|
ier->Status = IP_DEST_NET_UNREACHABLE;
|
||||||
break;
|
break;
|
||||||
case WSAEHOSTUNREACH:
|
case WSAEHOSTUNREACH:
|
||||||
SetLastError(IP_DEST_HOST_UNREACHABLE);
|
ier->Status = IP_DEST_HOST_UNREACHABLE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("unknown error: errno=%d\n",WSAGetLastError());
|
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 */
|
/* Get the reply */
|
||||||
|
@ -848,7 +894,10 @@ DWORD WINAPI IcmpSendEcho(
|
||||||
HeapFree(GetProcessHeap(), 0, ip_header);
|
HeapFree(GetProcessHeap(), 0, ip_header);
|
||||||
res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer;
|
res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer;
|
||||||
if (res==0)
|
if (res==0)
|
||||||
|
{
|
||||||
|
ier->Status = IP_REQ_TIMED_OUT;
|
||||||
SetLastError(IP_REQ_TIMED_OUT);
|
SetLastError(IP_REQ_TIMED_OUT);
|
||||||
|
}
|
||||||
TRACE("received %d replies\n",res);
|
TRACE("received %d replies\n",res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -767,18 +767,19 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDRO
|
||||||
|
|
||||||
AllocateAndGetIpForwardTableFromStack(&table, FALSE, GetProcessHeap(), 0);
|
AllocateAndGetIpForwardTableFromStack(&table, FALSE, GetProcessHeap(), 0);
|
||||||
if (table) {
|
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) ==
|
if ((dwDestAddr & table->table[ndx].dwForwardMask) ==
|
||||||
(table->table[ndx].dwForwardDest & 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;
|
if (!_BitScanForward(&hostMaskSize, ntohl(table->table[ndx].dwForwardMask)))
|
||||||
mask && !(mask & 1); mask >>= 1, numShifts++)
|
{
|
||||||
;
|
hostMaskSize = 32;
|
||||||
if (numShifts > matchedBits) {
|
}
|
||||||
matchedBits = numShifts;
|
if (hostMaskSize < minMaskSize) {
|
||||||
|
minMaskSize = hostMaskSize;
|
||||||
matchedNdx = ndx;
|
matchedNdx = ndx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -579,6 +579,9 @@ TranslateNtStatusError(NTSTATUS Status)
|
||||||
case STATUS_NETWORK_UNREACHABLE:
|
case STATUS_NETWORK_UNREACHABLE:
|
||||||
return WSAENETUNREACH;
|
return WSAENETUNREACH;
|
||||||
|
|
||||||
|
case STATUS_HOST_UNREACHABLE:
|
||||||
|
return WSAEHOSTUNREACH;
|
||||||
|
|
||||||
case STATUS_INVALID_PARAMETER:
|
case STATUS_INVALID_PARAMETER:
|
||||||
return WSAEINVAL;
|
return WSAEINVAL;
|
||||||
|
|
||||||
|
|
|
@ -509,6 +509,7 @@ typedef MDL NDIS_BUFFER, *PNDIS_BUFFER;
|
||||||
#define NDIS_STATUS_TOKEN_RING_OPEN_ERROR ((NDIS_STATUS)0xC0011000L)
|
#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_INVALID_DEVICE_REQUEST ((NDIS_STATUS)STATUS_INVALID_DEVICE_REQUEST)
|
||||||
#define NDIS_STATUS_NETWORK_UNREACHABLE ((NDIS_STATUS)STATUS_NETWORK_UNREACHABLE)
|
#define NDIS_STATUS_NETWORK_UNREACHABLE ((NDIS_STATUS)STATUS_NETWORK_UNREACHABLE)
|
||||||
|
#define NDIS_STATUS_HOST_UNREACHABLE ((NDIS_STATUS)STATUS_HOST_UNREACHABLE)
|
||||||
|
|
||||||
#if NDIS_SUPPORT_NDIS6
|
#if NDIS_SUPPORT_NDIS6
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ VOID NBTimeout(VOID)
|
||||||
if (NCE->State & NUD_INCOMPLETE)
|
if (NCE->State & NUD_INCOMPLETE)
|
||||||
{
|
{
|
||||||
/* We couldn't get an address to this IP at all */
|
/* We couldn't get an address to this IP at all */
|
||||||
Status = NDIS_STATUS_NETWORK_UNREACHABLE;
|
Status = NDIS_STATUS_HOST_UNREACHABLE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue