iphlpapi: Add a partial implementation of CreateSortedAddressPairs.
This commit is contained in:
parent
f0dee09c52
commit
2ffb2f71e3
|
@ -278,26 +278,140 @@ DWORD WINAPI CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex)
|
|||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static char *debugstr_ipv6(const struct WS_sockaddr_in6 *sin, char *buf)
|
||||
{
|
||||
const IN6_ADDR *addr = &sin->sin6_addr;
|
||||
char *p = buf;
|
||||
int i;
|
||||
BOOL in_zero = FALSE;
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
if (!addr->u.Word[i])
|
||||
{
|
||||
if (i == 0)
|
||||
*p++ = ':';
|
||||
if (!in_zero)
|
||||
{
|
||||
*p++ = ':';
|
||||
in_zero = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p += sprintf(p, "%x:", ntohs(addr->u.Word[i]));
|
||||
in_zero = FALSE;
|
||||
}
|
||||
}
|
||||
sprintf(p, "%x", ntohs(addr->u.Word[7]));
|
||||
return buf;
|
||||
}
|
||||
|
||||
static BOOL map_address_6to4( SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if (addr6->sin6_family != WS_AF_INET6) return FALSE;
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
if (addr6->sin6_addr.u.Word[i]) return FALSE;
|
||||
|
||||
if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
|
||||
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = addr6->sin6_port;
|
||||
addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
|
||||
memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL find_src_address( MIB_IPADDRTABLE *table, SOCKADDR_IN *dst, SOCKADDR_IN6 *src )
|
||||
{
|
||||
MIB_IPFORWARDROW row;
|
||||
DWORD i, j;
|
||||
|
||||
if (GetBestRoute( dst->sin_addr.S_un.S_addr, 0, &row )) return FALSE;
|
||||
|
||||
for (i = 0; i < table->dwNumEntries; i++)
|
||||
{
|
||||
/* take the first address */
|
||||
if (table->table[i].dwIndex == row.dwForwardIfIndex)
|
||||
{
|
||||
src->sin6_family = WS_AF_INET6;
|
||||
src->sin6_port = 0;
|
||||
src->sin6_flowinfo = 0;
|
||||
for (j = 0; j < 5; j++) src->sin6_addr.u.Word[j] = 0;
|
||||
src->sin6_addr.u.Word[5] = 0xffff;
|
||||
src->sin6_addr.u.Word[6] = table->table[i].dwAddr & 0xffff;
|
||||
src->sin6_addr.u.Word[7] = table->table[i].dwAddr >> 16;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CreateSortedAddressPairs (IPHLPAPI.@)
|
||||
*/
|
||||
DWORD WINAPI CreateSortedAddressPairs(const PSOCKADDR_IN6 source, DWORD sourcecount,
|
||||
const PSOCKADDR_IN6 destination, DWORD destinationcount,
|
||||
DWORD sortoptions,
|
||||
PSOCKADDR_IN6_PAIR *sortedaddr, DWORD *sortedcount)
|
||||
DWORD WINAPI CreateSortedAddressPairs( const PSOCKADDR_IN6 src_list, DWORD src_count,
|
||||
const PSOCKADDR_IN6 dst_list, DWORD dst_count,
|
||||
DWORD options, PSOCKADDR_IN6_PAIR *pair_list,
|
||||
DWORD *pair_count )
|
||||
{
|
||||
FIXME("(source %p, sourcecount %d, destination %p, destcount %d, sortoptions %x,"
|
||||
" sortedaddr %p, sortedcount %p): stub\n", source, sourcecount, destination,
|
||||
destinationcount, sortoptions, sortedaddr, sortedcount);
|
||||
DWORD i, size, ret;
|
||||
SOCKADDR_IN6_PAIR *pairs;
|
||||
SOCKADDR_IN6 *ptr;
|
||||
SOCKADDR_IN addr4;
|
||||
MIB_IPADDRTABLE *table;
|
||||
|
||||
if (source || sourcecount || !destination || !sortedaddr || !sortedcount || destinationcount > 500)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
FIXME( "(src_list %p src_count %u dst_list %p dst_count %u options %x pair_list %p pair_count %p): stub\n",
|
||||
src_list, src_count, dst_list, dst_count, options, pair_list, pair_count );
|
||||
|
||||
/* Returning not supported tells the client we don't have IPv6 support
|
||||
* so applications can fallback to IPv4.
|
||||
*/
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
if (src_list || src_count || !dst_list || !pair_list || !pair_count || dst_count > 500)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
for (i = 0; i < dst_count; i++)
|
||||
{
|
||||
if (!map_address_6to4( &dst_list[i], &addr4 ))
|
||||
{
|
||||
FIXME("only mapped IPv4 addresses are supported\n");
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
size = dst_count * sizeof(*pairs);
|
||||
size += dst_count * sizeof(SOCKADDR_IN6) * 2; /* source address + destination address */
|
||||
if (!(pairs = HeapAlloc( GetProcessHeap(), 0, size ))) return ERROR_NOT_ENOUGH_MEMORY;
|
||||
ptr = (SOCKADDR_IN6 *)(char *)pairs + dst_count * sizeof(*pairs);
|
||||
|
||||
if ((ret = getIPAddrTable( &table, GetProcessHeap(), 0 )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, pairs );
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < dst_count; i++)
|
||||
{
|
||||
pairs[i].SourceAddress = ptr++;
|
||||
if (!map_address_6to4( &dst_list[i], &addr4 ) ||
|
||||
!find_src_address( table, &addr4, pairs[i].SourceAddress ))
|
||||
{
|
||||
char buf[46];
|
||||
FIXME( "source address for %s not found\n", debugstr_ipv6(&dst_list[i], buf) );
|
||||
memset( pairs[i].SourceAddress, 0, sizeof(*pairs[i].SourceAddress) );
|
||||
pairs[i].SourceAddress->sin6_family = WS_AF_INET6;
|
||||
}
|
||||
|
||||
pairs[i].DestinationAddress = ptr++;
|
||||
memcpy( pairs[i].DestinationAddress, &dst_list[i], sizeof(*pairs[i].DestinationAddress) );
|
||||
}
|
||||
*pair_list = pairs;
|
||||
*pair_count = dst_count;
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, table );
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -727,35 +841,6 @@ static char *debugstr_ipv4(const in_addr_t *in_addr, char *buf)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static char *debugstr_ipv6(const struct WS_sockaddr_in6 *sin, char *buf)
|
||||
{
|
||||
const IN6_ADDR *addr = &sin->sin6_addr;
|
||||
char *p = buf;
|
||||
int i;
|
||||
BOOL in_zero = FALSE;
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
if (!addr->u.Word[i])
|
||||
{
|
||||
if (i == 0)
|
||||
*p++ = ':';
|
||||
if (!in_zero)
|
||||
{
|
||||
*p++ = ':';
|
||||
in_zero = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p += sprintf(p, "%x:", ntohs(addr->u.Word[i]));
|
||||
in_zero = FALSE;
|
||||
}
|
||||
}
|
||||
sprintf(p, "%x", ntohs(addr->u.Word[7]));
|
||||
return buf;
|
||||
}
|
||||
|
||||
static ULONG count_v4_gateways(DWORD index, PMIB_IPFORWARDTABLE routeTable)
|
||||
{
|
||||
DWORD i, num_gateways = 0;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "winsock2.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "ws2tcpip.h"
|
||||
#include "iphlpapi.h"
|
||||
#include "iprtrmib.h"
|
||||
#include "wine/test.h"
|
||||
|
@ -77,6 +78,9 @@ static DWORD (WINAPI *pGetExtendedUdpTable)(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CL
|
|||
static DWORD (WINAPI *pSetTcpEntry)(PMIB_TCPROW);
|
||||
static HANDLE(WINAPI *pIcmpCreateFile)(VOID);
|
||||
static DWORD (WINAPI *pIcmpSendEcho)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD);
|
||||
static DWORD (WINAPI *pCreateSortedAddressPairs)(const PSOCKADDR_IN6,ULONG,const PSOCKADDR_IN6,ULONG,ULONG,
|
||||
PSOCKADDR_IN6_PAIR*,ULONG*);
|
||||
static void (WINAPI *pFreeMibTable)(void*);
|
||||
|
||||
static void loadIPHlpApi(void)
|
||||
{
|
||||
|
@ -111,6 +115,8 @@ static void loadIPHlpApi(void)
|
|||
pSetTcpEntry = (void *)GetProcAddress(hLibrary, "SetTcpEntry");
|
||||
pIcmpCreateFile = (void *)GetProcAddress(hLibrary, "IcmpCreateFile");
|
||||
pIcmpSendEcho = (void *)GetProcAddress(hLibrary, "IcmpSendEcho");
|
||||
pCreateSortedAddressPairs = (void *)GetProcAddress(hLibrary, "CreateSortedAddressPairs");
|
||||
pFreeMibTable = (void *)GetProcAddress(hLibrary, "FreeMibTable");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1562,6 +1568,65 @@ static void test_GetExtendedUdpTable(void)
|
|||
HeapFree( GetProcessHeap(), 0, table_module );
|
||||
}
|
||||
|
||||
static void test_CreateSortedAddressPairs(void)
|
||||
{
|
||||
SOCKADDR_IN6 dst[2];
|
||||
SOCKADDR_IN6_PAIR *pair;
|
||||
ULONG pair_count;
|
||||
DWORD ret;
|
||||
|
||||
if (!pCreateSortedAddressPairs)
|
||||
{
|
||||
win_skip( "CreateSortedAddressPairs not available\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
memset( dst, 0, sizeof(dst) );
|
||||
dst[0].sin6_family = AF_INET6;
|
||||
dst[0].sin6_addr.u.Word[5] = 0xffff;
|
||||
dst[0].sin6_addr.u.Word[6] = 0x0808;
|
||||
dst[0].sin6_addr.u.Word[7] = 0x0808;
|
||||
|
||||
pair_count = 0xdeadbeef;
|
||||
ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, NULL, &pair_count );
|
||||
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
|
||||
ok( pair_count == 0xdeadbeef, "got %u\n", pair_count );
|
||||
|
||||
pair = (SOCKADDR_IN6_PAIR *)0xdeadbeef;
|
||||
pair_count = 0xdeadbeef;
|
||||
ret = pCreateSortedAddressPairs( NULL, 0, NULL, 1, 0, &pair, &pair_count );
|
||||
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
|
||||
ok( pair == (SOCKADDR_IN6_PAIR *)0xdeadbeef, "got %p\n", pair );
|
||||
ok( pair_count == 0xdeadbeef, "got %u\n", pair_count );
|
||||
|
||||
pair = NULL;
|
||||
pair_count = 0xdeadbeef;
|
||||
ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, &pair, &pair_count );
|
||||
ok( ret == NO_ERROR, "got %u\n", ret );
|
||||
ok( pair != NULL, "pair not set\n" );
|
||||
ok( pair_count == 1, "got %u\n", pair_count );
|
||||
ok( pair[0].SourceAddress != NULL, "src address not set\n" );
|
||||
ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
|
||||
pFreeMibTable( pair );
|
||||
|
||||
dst[1].sin6_family = AF_INET6;
|
||||
dst[1].sin6_addr.u.Word[5] = 0xffff;
|
||||
dst[1].sin6_addr.u.Word[6] = 0x0404;
|
||||
dst[1].sin6_addr.u.Word[7] = 0x0808;
|
||||
|
||||
pair = NULL;
|
||||
pair_count = 0xdeadbeef;
|
||||
ret = pCreateSortedAddressPairs( NULL, 0, dst, 2, 0, &pair, &pair_count );
|
||||
ok( ret == NO_ERROR, "got %u\n", ret );
|
||||
ok( pair != NULL, "pair not set\n" );
|
||||
ok( pair_count == 2, "got %u\n", pair_count );
|
||||
ok( pair[0].SourceAddress != NULL, "src address not set\n" );
|
||||
ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
|
||||
ok( pair[1].SourceAddress != NULL, "src address not set\n" );
|
||||
ok( pair[1].DestinationAddress != NULL, "dst address not set\n" );
|
||||
pFreeMibTable( pair );
|
||||
}
|
||||
|
||||
START_TEST(iphlpapi)
|
||||
{
|
||||
|
||||
|
@ -1581,6 +1646,7 @@ START_TEST(iphlpapi)
|
|||
test_GetAdaptersAddresses();
|
||||
test_GetExtendedTcpTable();
|
||||
test_GetExtendedUdpTable();
|
||||
test_CreateSortedAddressPairs();
|
||||
freeIPHlpApi();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue