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
-- v3: Returns MAC address by:
From: Thi Garlet garlet@gmail.com
- /dlls/iphlpapi/iphlpapi_main.c - /dlls/iphlpapi/tests/iphlpapi.c --- dlls/iphlpapi/iphlpapi_main.c | 117 +++++++++++++++++++++++++++++++-- dlls/iphlpapi/tests/iphlpapi.c | 40 +++++++++++ 2 files changed, 151 insertions(+), 6 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 172afbd62b8..8f92c488c8a 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -3964,15 +3964,120 @@ 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_BAD_NET_NAME; + if( pMacAddr == NULL ) + return ERROR_INVALID_PARAMETER; + if( 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); + // retunr NO_ERROR; + + + // 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; // 0 + } + 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; // del? + src.sin_port = 10123; // del? + dst.sin_family = AF_INET; + dst.sin_addr.s_addr = DestIP; + dst.sin_port = 10123; // del? + + // send UDP + if( WSAStartup( MAKEWORD( 2, 2 ), &wd ) != 0 ) + return ERROR_NOT_SUPPORTED; + s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); // SOCK_RAW, IPPROTO_ICMP + 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 ) // -1 + return ERROR_GEN_FAILURE; // 31 + + + // 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; // 0 + } + } + } + Sleep(1); + heap_free(table); + } + + return ERROR_NOT_FOUND; // 1168 }
diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index da3a06d54ca..7e14b2ad5d0 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -3098,6 +3098,45 @@ static void test_compartments(void) ok(id == NET_IF_COMPARTMENT_ID_PRIMARY, "got %u\n", id); }
+static void test_SendARP(void) +{ + DWORD apiReturn; + ULONG dwSize = 0; + ULONG MacAddr[2]={0,0}; + + apiReturn = SendARP(0, 0, NULL, NULL); + if (apiReturn == ERROR_NOT_SUPPORTED) { + skip("SendARP is not supported\n"); + return; + } + ok(apiReturn == ERROR_BAD_NET_NAME, + "SendARP(0, 0, NULL, NULL) returned %ld, expected ERROR_BAD_NET_NAME\n", + apiReturn); + + apiReturn = SendARP( inet_addr("127.0.0.1"), 0, NULL, NULL); + ok(apiReturn == ERROR_INVALID_PARAMETER, + "SendARP(inet_addr('127.0.0.1'), 0, NULL, NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n", + apiReturn); + + apiReturn = SendARP( inet_addr("127.0.0.1"), 0, (PULONG) &MacAddr, NULL); + ok(apiReturn == ERROR_INVALID_USER_BUFFER, + "SendARP(inet_addr('127.0.0.1'), 0, (PULONG) &MacAddr, NULL) returned %ld, expected ERROR_INVALID_USER_BUFFER\n", + apiReturn); + + apiReturn = SendARP( inet_addr("127.0.0.1"), 0, (PULONG) &MacAddr, &dwSize); + ok(apiReturn == ERROR_BUFFER_OVERFLOW, + "SendARP(inet_addr('127.0.0.1'), 0, (PULONG) &MacAddr, &dwSize=0) returned %ld, expected ERROR_BUFFER_OVERFLOW\n", + apiReturn); + + dwSize = 6; + apiReturn = SendARP( inet_addr("127.0.0.1"), 0, (PULONG) &MacAddr, &dwSize); + if (apiReturn == ERROR_NOT_FOUND) { + trace( "SendARP(inet_addr('127.0.0.1'), 0, (PULONG) &MacAddr, &dwSize) did not found a mac address\n" ); + } else { + trace( "SendARP(inet_addr('127.0.0.1'), 0, (PULONG) &MacAddr, &dwSize) returned %lu mac: %lu - %lu.\n", apiReturn, MacAddr[0], MacAddr[1] ); + } +} + START_TEST(iphlpapi) { WSADATA wsa_data; @@ -3139,6 +3178,7 @@ START_TEST(iphlpapi) test_NotifyUnicastIpAddressChange(); test_ConvertGuidToString(); test_compartments(); + test_SendARP(); freeIPHlpApi(); }
From: thi garlet <galet at gmail>
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 --- dlls/iphlpapi/iphlpapi_main.c | 11 ++++++----- dlls/iphlpapi/tests/iphlpapi.c | 15 ++++++++------- 2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 8f92c488c8a..5e6fbe4bec3 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -4014,7 +4014,8 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd pUnicast = pCurrInterface->FirstUnicastAddress; while ( pUnicast ) { - if ( DestIP == ((struct sockaddr_in *) pUnicast->Address.lpSockaddr)->sin_addr.s_addr ) + if ( DestIP == ((struct sockaddr_in *) + pUnicast->Address.lpSockaddr)->sin_addr.s_addr ) { memcpy(pMacAddr, pCurrInterface->PhysicalAddress, 6); heap_free(pInterfaces); @@ -4032,16 +4033,16 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd
// prepare config, to send an UDP packed instead of privileged ARP src.sin_family = AF_INET; - src.sin_addr.s_addr = SrcIP; // del? - src.sin_port = 10123; // del? + 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; // del? + 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 ); // SOCK_RAW, IPPROTO_ICMP + 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); diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 7e14b2ad5d0..73b913c616e 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -3118,22 +3118,23 @@ static void test_SendARP(void) "SendARP(inet_addr('127.0.0.1'), 0, NULL, NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
- apiReturn = SendARP( inet_addr("127.0.0.1"), 0, (PULONG) &MacAddr, NULL); + apiReturn = SendARP( inet_addr("127.0.0.1"), 0, MacAddr, NULL); ok(apiReturn == ERROR_INVALID_USER_BUFFER, - "SendARP(inet_addr('127.0.0.1'), 0, (PULONG) &MacAddr, NULL) returned %ld, expected ERROR_INVALID_USER_BUFFER\n", + "SendARP(inet_addr('127.0.0.1'), 0, MacAddr, NULL) returned %ld, expected ERROR_INVALID_USER_BUFFER\n", apiReturn);
- apiReturn = SendARP( inet_addr("127.0.0.1"), 0, (PULONG) &MacAddr, &dwSize); + apiReturn = SendARP( inet_addr("127.0.0.1"), 0, MacAddr, &dwSize); ok(apiReturn == ERROR_BUFFER_OVERFLOW, - "SendARP(inet_addr('127.0.0.1'), 0, (PULONG) &MacAddr, &dwSize=0) returned %ld, expected ERROR_BUFFER_OVERFLOW\n", + "SendARP(inet_addr('127.0.0.1'), 0, MacAddr, &dwSize=0) returned %ld, expected ERROR_BUFFER_OVERFLOW\n", apiReturn);
dwSize = 6; - apiReturn = SendARP( inet_addr("127.0.0.1"), 0, (PULONG) &MacAddr, &dwSize); + apiReturn = SendARP( inet_addr("127.0.0.1"), 0, MacAddr, &dwSize); if (apiReturn == ERROR_NOT_FOUND) { - trace( "SendARP(inet_addr('127.0.0.1'), 0, (PULONG) &MacAddr, &dwSize) did not found a mac address\n" ); + trace( "SendARP(inet_addr('127.0.0.1'), 0, MacAddr, &dwSize) did not found a mac address\n" ); } else { - trace( "SendARP(inet_addr('127.0.0.1'), 0, (PULONG) &MacAddr, &dwSize) returned %lu mac: %lu - %lu.\n", apiReturn, MacAddr[0], MacAddr[1] ); + trace( "SendARP(inet_addr('127.0.0.1'), 0, MacAddr, &dwSize) returned %lu mac: %lu - %lu.\n", + apiReturn, MacAddr[0], MacAddr[1] ); } }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149908
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
iphlpapi: 071c:iphlpapi: unhandled exception c0000005 at 7320F508
=== w7u_adm (32 bit report) ===
iphlpapi: 086c:iphlpapi: unhandled exception c0000005 at 7379F508
=== w7u_el (32 bit report) ===
iphlpapi: 0a60:iphlpapi: unhandled exception c0000005 at 7311F508
=== w8 (32 bit report) ===
iphlpapi: 0bf4:iphlpapi: unhandled exception c0000005 at 71C12AF6
=== w8adm (32 bit report) ===
iphlpapi: 0aa4:iphlpapi: unhandled exception c0000005 at 71DF2AF6
=== w864 (32 bit report) ===
iphlpapi: 093c:iphlpapi: unhandled exception c0000005 at 739E2AF6
=== w1064v1507 (32 bit report) ===
iphlpapi: 0638:iphlpapi: unhandled exception c0000005 at 7497FB64
=== w1064v1809 (32 bit report) ===
iphlpapi: 1eac:iphlpapi: unhandled exception c0000005 at 74B3F45C
=== w1064_tsign (32 bit report) ===
iphlpapi: 1dd4:iphlpapi: unhandled exception c0000005 at 750AEADC
=== w10pro64 (32 bit report) ===
iphlpapi: 20a8:iphlpapi: unhandled exception c0000005 at 73E3EADC
=== w10pro64_en_AE_u8 (32 bit report) ===
iphlpapi: 0eb4:iphlpapi: unhandled exception c0000005 at 7496EADC
=== w11pro64 (32 bit report) ===
iphlpapi: 067c:iphlpapi: unhandled exception c0000005 at 748508EC
=== w7pro64 (64 bit report) ===
iphlpapi: 08a4:iphlpapi: unhandled exception c0000005 at 000007FEFA36F44D
=== w864 (64 bit report) ===
iphlpapi: 0ae4:iphlpapi: unhandled exception c0000005 at 00007FFA43C4755B
=== w1064v1507 (64 bit report) ===
iphlpapi: 0b28:iphlpapi: unhandled exception c0000005 at 00007FFAD846F59B
=== w1064v1809 (64 bit report) ===
iphlpapi: 1dbc:iphlpapi: unhandled exception c0000005 at 00007FFFC130EA23
=== w1064_2qxl (64 bit report) ===
iphlpapi: 1dd8:iphlpapi: unhandled exception c0000005 at 00007FFFFA1EDD22
=== w1064_adm (64 bit report) ===
iphlpapi: 1c98:iphlpapi: unhandled exception c0000005 at 00007FFA535EDD22
=== w1064_tsign (64 bit report) ===
iphlpapi: 1de8:iphlpapi: unhandled exception c0000005 at 00007FFAA222DD22
=== w10pro64 (64 bit report) ===
iphlpapi: 20bc:iphlpapi: unhandled exception c0000005 at 00007FFF2B95DD22
=== w10pro64_ar (64 bit report) ===
iphlpapi: 2168:iphlpapi: unhandled exception c0000005 at 00007FFA063FDD22
=== w10pro64_ja (64 bit report) ===
iphlpapi: 1748:iphlpapi: unhandled exception c0000005 at 00007FF96D8FDD22
=== w10pro64_zh_CN (64 bit report) ===
iphlpapi: 2348:iphlpapi: unhandled exception c0000005 at 00007FF8B45DDD22
=== w11pro64_amd (64 bit report) ===
iphlpapi: 05ec:iphlpapi: unhandled exception c0000005 at 00007FFC52F62E22
=== debian11b (64 bit WoW report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000009400FC, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032