[PATCH v31 0/2] MR6884: Iphlpapi.dll: Included SendARP
Returns MAC address by: - search local interfaces, or - send UDP packed that does not need linux privilege, then search local cache solve https://bugs.winehq.org/show_bug.cgi?id=9418 files updated - /dlls/iphlpapi/iphlpapi_main.c - /dlls/iphlpapi/tests/iphlpapi.c -- v31: update to standard heap allocation functions https://gitlab.winehq.org/wine/wine/-/merge_requests/6884
From: thi garlet <galet at gmail> Returns MAC address by: search local interfaces, or send UDP packed that does not need linux privilege, then search local cache solves https://bugs.winehq.org/show_bug.cgi?id=9418 files updated /dlls/iphlpapi/iphlpapi_main.c /dlls/iphlpapi/tests/iphlpapi.c --- dlls/iphlpapi/iphlpapi_main.c | 115 +++++++++++++++++++++++++++++++-- dlls/iphlpapi/tests/iphlpapi.c | 33 ++++++++++ 2 files changed, 142 insertions(+), 6 deletions(-) diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index b315490b1f2..7ca577f6742 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -4038,15 +4038,118 @@ DWORD WINAPI NotifyUnicastIpAddressChange(ADDRESS_FAMILY family, PUNICAST_IPADDR * RETURNS * Success: NO_ERROR * Failure: error code from winerror.h - * - * FIXME - * Stub, returns ERROR_NOT_SUPPORTED. */ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen) { - FIXME("(DestIP 0x%08lx, SrcIP 0x%08lx, pMacAddr %p, PhyAddrLen %p): stub\n", - DestIP, SrcIP, pMacAddr, PhyAddrLen); - return ERROR_NOT_SUPPORTED; + int i=3, time_out=420; + ULONG size=16000; + struct sockaddr_in dst, src; + struct WSAData wd; + SOCKET s; + MIB_IPNETTABLE *table = NULL; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; + PIP_ADAPTER_ADDRESSES pInterfaces = NULL, pCurrInterface = NULL; + + if( DestIP == 0 ) + return ERROR_INVALID_PARAMETER; + if( pMacAddr == NULL || PhyAddrLen == NULL ) + return ERROR_INVALID_USER_BUFFER; + if( (*PhyAddrLen) < 6 ) + return ERROR_BUFFER_OVERFLOW; + + /* copy DestIP to MAC, in case MAC cant be found */ + (*PhyAddrLen) = 6; + memcpy(pMacAddr, &DestIP, 4); + memcpy(pMacAddr+1, &DestIP, 2); + + + /* first, check if DestIP is a local adapter */ + do + { + pInterfaces = (IP_ADAPTER_ADDRESSES *) heap_alloc_zero(size); + if (pInterfaces == NULL) + { + ERR("Memory allocation failed for IP_ADAPTER_ADDRESSES struct"); + return ERROR_BUFFER_OVERFLOW; + } + + i = GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST + GAA_FLAG_SKIP_MULTICAST + + GAA_FLAG_SKIP_DNS_SERVER + GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, pInterfaces, &size); + + if (i == NO_ERROR ) + { + pCurrInterface = pInterfaces; + while ( pCurrInterface ) + { + + pUnicast = pCurrInterface->FirstUnicastAddress; + while ( pUnicast ) + { + if ( DestIP == ((struct sockaddr_in *) + pUnicast->Address.lpSockaddr)->sin_addr.s_addr ) + { + memcpy(pMacAddr, pCurrInterface->PhysicalAddress, 6); + heap_free(pInterfaces); + return NO_ERROR; + } + pUnicast = pUnicast->Next; + } + pCurrInterface = pCurrInterface->Next; + } + } + heap_free(pInterfaces); + + } while ( i == ERROR_BUFFER_OVERFLOW && i-- > 0 ); + + + /* prepare config, to send an UDP packed instead of privileged ARP */ + src.sin_family = AF_INET; + src.sin_addr.s_addr = SrcIP; + src.sin_port = 10123; + dst.sin_family = AF_INET; + dst.sin_addr.s_addr = DestIP; + dst.sin_port = 10123; + + /* send UDP */ + if( WSAStartup( MAKEWORD( 2, 2 ), &wd ) != 0 ) + return ERROR_NOT_SUPPORTED; + s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + bind( s, (SOCKADDR *) &src, sizeof(src) ); + i = sendto( s, (const char *) &time_out, 4, 0, (SOCKADDR *) &dst, sizeof(dst) ); + closesocket(s); + WSACleanup(); + if( i == SOCKET_ERROR ) + return ERROR_GEN_FAILURE; + + + /* search cached arp table */ + size = 16000; + while( time_out-- > 0 ) + { + table = heap_alloc_zero(size); + if( table == NULL ) + { + ERR("Memory allocation failed for IpNetTable struct"); + return ERROR_BUFFER_OVERFLOW; + } + + if( GetIpNetTable( table, &size, 0 ) == NO_ERROR ) + { + for (i = 0; i < table->dwNumEntries; ++i) + { + if( table->table[i].dwAddr == DestIP ) + { + memcpy(pMacAddr, table->table[i].bPhysAddr, 6); + heap_free(table); + return NO_ERROR; + } + } + } + Sleep(1); + heap_free(table); + } + + return ERROR_NOT_FOUND; } diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 982880fdb9d..151f05de664 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -2020,6 +2020,36 @@ static void testWin2KFunctions(void) testNotifyAddrChange(); } +static void test_SendARP(void) +{ + DWORD apiReturn; + ULONG dwSize = 0; + ULONG MacAddr[2]={0,0}; + + apiReturn = SendARP( 0, 0, MacAddr, &dwSize); + if (apiReturn == ERROR_NOT_SUPPORTED) { + skip("SendARP is not supported\n"); + return; + } + ok(apiReturn == ERROR_INVALID_PARAMETER, + "SendARP(inet_addr('255.255.255.255'), 0, MacAddr, &dwSize) returned %ld, expected ERROR_INVALID_PARAMETER\n", + apiReturn); + + apiReturn = SendARP( inet_addr("255.255.255.255"), 0, MacAddr, &dwSize); + ok(apiReturn == ERROR_BUFFER_OVERFLOW, + "SendARP(inet_addr('255.255.255.255'), 0, MacAddr, &dwSize=0) returned %ld, expected ERROR_BUFFER_OVERFLOW\n", + apiReturn); + + dwSize = 6; + apiReturn = SendARP( inet_addr("255.255.255.255"), 0, MacAddr, &dwSize); + if (apiReturn == ERROR_NOT_FOUND) { + trace( "SendARP(inet_addr('255.255.255.255'), 0, MacAddr, &dwSize) did not found a mac address\n" ); + } else { + trace( "SendARP(inet_addr('255.255.255.255'), 0, MacAddr, &dwSize) returned '%lu' backwarded mac: %lx%lX\n", + apiReturn, MacAddr[1], MacAddr[0] ); + } +} + static void test_GetAdaptersAddresses(void) { BOOL dns_eligible_found = FALSE; @@ -3570,6 +3600,7 @@ static void test_compartments(void) ok(id == NET_IF_COMPARTMENT_ID_PRIMARY, "got %u\n", id); } +<<<<<<< HEAD static void test_GetIpInterface(void) { MIB_IPINTERFACE_ROW entry_row; @@ -4153,6 +4184,7 @@ done: FreeMibTable( table ); } + START_TEST(iphlpapi) { WSADATA wsa_data; @@ -4171,6 +4203,7 @@ START_TEST(iphlpapi) WaitForSingleObject(thread, INFINITE); testWin2KFunctions(); + test_SendARP(); test_GetAdaptersAddresses(); test_GetExtendedTcpTable(); test_GetExtendedTcpTable_owner(AF_INET); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6884
From: thi garlet <garlet at gmail dot com> --- dlls/iphlpapi/iphlpapi_main.c | 12 ++++++------ dlls/iphlpapi/tests/iphlpapi.c | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 7ca577f6742..7a4fd9e955e 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -4066,7 +4066,7 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd /* first, check if DestIP is a local adapter */ do { - pInterfaces = (IP_ADAPTER_ADDRESSES *) heap_alloc_zero(size); + pInterfaces = (IP_ADAPTER_ADDRESSES *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); if (pInterfaces == NULL) { ERR("Memory allocation failed for IP_ADAPTER_ADDRESSES struct"); @@ -4089,7 +4089,7 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd pUnicast->Address.lpSockaddr)->sin_addr.s_addr ) { memcpy(pMacAddr, pCurrInterface->PhysicalAddress, 6); - heap_free(pInterfaces); + HeapFree(GetProcessHeap(), 0, pInterfaces); return NO_ERROR; } pUnicast = pUnicast->Next; @@ -4097,7 +4097,7 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd pCurrInterface = pCurrInterface->Next; } } - heap_free(pInterfaces); + HeapFree(GetProcessHeap(), 0, pInterfaces); } while ( i == ERROR_BUFFER_OVERFLOW && i-- > 0 ); @@ -4126,7 +4126,7 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd size = 16000; while( time_out-- > 0 ) { - table = heap_alloc_zero(size); + table = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); if( table == NULL ) { ERR("Memory allocation failed for IpNetTable struct"); @@ -4140,13 +4140,13 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd if( table->table[i].dwAddr == DestIP ) { memcpy(pMacAddr, table->table[i].bPhysAddr, 6); - heap_free(table); + HeapFree(GetProcessHeap(), 0, table); return NO_ERROR; } } } Sleep(1); - heap_free(table); + HeapFree(GetProcessHeap(), 0, table); } return ERROR_NOT_FOUND; diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 151f05de664..a1a74a633bb 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -3600,7 +3600,6 @@ static void test_compartments(void) ok(id == NET_IF_COMPARTMENT_ID_PRIMARY, "got %u\n", id); } -<<<<<<< HEAD static void test_GetIpInterface(void) { MIB_IPINTERFACE_ROW entry_row; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6884
participants (2)
-
thi garlet -
Thi Garlet (@garlett)