Commit beb84444 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

iphlpapi: Implement GetIpAddrTable() on top of nsi.

parent 3ef3166b
...@@ -148,19 +148,6 @@ static int IpAddrTableNumericSorter(const void *a, const void *b) ...@@ -148,19 +148,6 @@ static int IpAddrTableNumericSorter(const void *a, const void *b)
return ret; return ret;
} }
static int IpAddrTableLoopbackSorter(const void *a, const void *b)
{
const MIB_IPADDRROW *left = a, *right = b;
int ret = 0;
if (isIfIndexLoopback(left->dwIndex))
ret = 1;
else if (isIfIndexLoopback(right->dwIndex))
ret = -1;
return ret;
}
/****************************************************************** /******************************************************************
* AllocateAndGetIpAddrTableFromStack (IPHLPAPI.@) * AllocateAndGetIpAddrTableFromStack (IPHLPAPI.@)
* *
...@@ -2131,6 +2118,10 @@ DWORD WINAPI GetInterfaceInfo( IP_INTERFACE_INFO *table, ULONG *size ) ...@@ -2131,6 +2118,10 @@ DWORD WINAPI GetInterfaceInfo( IP_INTERFACE_INFO *table, ULONG *size )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static int ipaddrrow_cmp( const void *a, const void *b )
{
return ((const MIB_IPADDRROW*)a)->dwAddr - ((const MIB_IPADDRROW*)b)->dwAddr;
}
/****************************************************************** /******************************************************************
* GetIpAddrTable (IPHLPAPI.@) * GetIpAddrTable (IPHLPAPI.@)
...@@ -2138,59 +2129,63 @@ DWORD WINAPI GetInterfaceInfo( IP_INTERFACE_INFO *table, ULONG *size ) ...@@ -2138,59 +2129,63 @@ DWORD WINAPI GetInterfaceInfo( IP_INTERFACE_INFO *table, ULONG *size )
* Get interface-to-IP address mapping table. * Get interface-to-IP address mapping table.
* *
* PARAMS * PARAMS
* pIpAddrTable [Out] buffer for mapping table * table [Out] buffer for mapping table
* pdwSize [In/Out] length of output buffer * size [In/Out] length of output buffer
* bOrder [In] whether to sort the table * sort [In] whether to sort the table
* *
* RETURNS * RETURNS
* Success: NO_ERROR * Success: NO_ERROR
* Failure: error code from winerror.h * Failure: error code from winerror.h
* *
* NOTES
* If pdwSize is less than required, the function will return
* ERROR_INSUFFICIENT_BUFFER, and *pdwSize will be set to the required byte
* size.
* If bOrder is true, the returned table will be sorted by the next hop and
* an assortment of arbitrary parameters.
*/ */
DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder) DWORD WINAPI GetIpAddrTable( MIB_IPADDRTABLE *table, ULONG *size, BOOL sort )
{ {
DWORD ret; DWORD err, count, needed, i, loopback, row_num = 0;
struct nsi_ipv4_unicast_key *keys;
struct nsi_ip_unicast_rw *rw;
TRACE("pIpAddrTable %p, pdwSize %p, bOrder %d\n", pIpAddrTable, pdwSize, TRACE( "table %p, size %p, sort %d\n", table, size, sort );
(DWORD)bOrder); if (!size) return ERROR_INVALID_PARAMETER;
if (!pdwSize)
ret = ERROR_INVALID_PARAMETER; err = NsiAllocateAndGetTable( 1, &NPI_MS_IPV4_MODULEID, NSI_IP_UNICAST_TABLE, (void **)&keys, sizeof(*keys),
else { (void **)&rw, sizeof(*rw), NULL, 0, NULL, 0, &count, 0 );
PMIB_IPADDRTABLE table; if (err) return err;
ret = getIPAddrTable(&table, GetProcessHeap(), 0); needed = FIELD_OFFSET( MIB_IPADDRTABLE, table[count] );
if (ret == NO_ERROR)
if (!table || *size < needed)
{ {
ULONG size = FIELD_OFFSET(MIB_IPADDRTABLE, table[table->dwNumEntries]); *size = needed;
err = ERROR_INSUFFICIENT_BUFFER;
goto err;
}
if (!pIpAddrTable || *pdwSize < size) { table->dwNumEntries = count;
*pdwSize = size;
ret = ERROR_INSUFFICIENT_BUFFER; for (loopback = 0; loopback < 2; loopback++) /* Move the loopback addresses to the end */
} {
else { for (i = 0; i < count; i++)
*pdwSize = size; {
memcpy(pIpAddrTable, table, size); MIB_IPADDRROW *row = table->table + row_num;
/* sort by numeric IP value */
if (bOrder) if (!!loopback != (keys[i].luid.Info.IfType == MIB_IF_TYPE_LOOPBACK)) continue;
qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries,
sizeof(MIB_IPADDRROW), IpAddrTableNumericSorter); row->dwAddr = keys[i].addr.WS_s_addr;
/* sort ensuring loopback interfaces are in the end */ ConvertInterfaceLuidToIndex( &keys[i].luid, &row->dwIndex );
else ConvertLengthToIpv4Mask( rw[i].on_link_prefix, &row->dwMask );
qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries, row->dwBCastAddr = 1;
sizeof(MIB_IPADDRROW), IpAddrTableLoopbackSorter); row->dwReasmSize = 0xffff;
ret = NO_ERROR; row->unused1 = 0;
} row->wType = MIB_IPADDR_PRIMARY;
HeapFree(GetProcessHeap(), 0, table); row_num++;
}
} }
}
TRACE("returning %d\n", ret); if (sort) qsort( table->table, count, sizeof(MIB_IPADDRROW), ipaddrrow_cmp );
return ret; err:
NsiFreeTable( keys, rw, NULL, NULL );
return err;
} }
......
...@@ -203,6 +203,8 @@ static void testGetIpAddrTable(void) ...@@ -203,6 +203,8 @@ static void testGetIpAddrTable(void)
for (i = 0; i < buf->dwNumEntries; i++) for (i = 0; i < buf->dwNumEntries; i++)
{ {
ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i); ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i);
ok (buf->table[i].dwBCastAddr == 1, "Test[%d]: got %08x\n", i, buf->table[i].dwBCastAddr);
ok (buf->table[i].dwReasmSize == 0xffff, "Test[%d]: got %08x\n", i, buf->table[i].dwReasmSize);
trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i, trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i,
ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType); ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment