[PATCH 4/4] iphlpapi: Implement AllocateAndGetIpNetTableFromStack() on top of GetIpNetTable().
Huw Davies
huw at codeweavers.com
Tue Aug 10 03:20:50 CDT 2021
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/iphlpapi/iphlpapi_main.c | 23 ++++
dlls/iphlpapi/ipstats.c | 193 ----------------------------------
2 files changed, 23 insertions(+), 193 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 24cfedd2b02..fe2daa0f24d 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -2317,6 +2317,29 @@ err:
return err;
}
+/******************************************************************
+ * AllocateAndGetIpNetTableFromStack (IPHLPAPI.@)
+ */
+DWORD WINAPI AllocateAndGetIpNetTableFromStack( MIB_IPNETTABLE **table, BOOL sort, HANDLE heap, DWORD flags )
+{
+ DWORD err, size = FIELD_OFFSET(MIB_IPNETTABLE, table[2]), attempt;
+
+ TRACE( "table %p, sort %d, heap %p, flags 0x%08x\n", table, sort, heap, flags );
+
+ for (attempt = 0; attempt < 5; attempt++)
+ {
+ *table = HeapAlloc( heap, flags, size );
+ if (!*table) return ERROR_NOT_ENOUGH_MEMORY;
+
+ err = GetIpNetTable( *table, &size, sort );
+ if (!err) break;
+ HeapFree( heap, flags, *table );
+ if (err != ERROR_INSUFFICIENT_BUFFER) break;
+ }
+
+ return err;
+}
+
static void ipnet_row2_fill( MIB_IPNET_ROW2 *row, USHORT fam, void *key, struct nsi_ip_neighbour_rw *rw,
struct nsi_ip_neighbour_dynamic *dyn )
{
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index 7bb4ff0603e..115bafa6f8e 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -1220,199 +1220,6 @@ static void *append_table_row( HANDLE heap, DWORD flags, void *table, DWORD *tab
return table;
}
-static int compare_ipnet_rows(const void *a, const void *b)
-{
- const MIB_IPNETROW *rowA = a;
- const MIB_IPNETROW *rowB = b;
-
- return ntohl(rowA->dwAddr) - ntohl(rowB->dwAddr);
-}
-
-
-/******************************************************************
- * AllocateAndGetIpNetTableFromStack (IPHLPAPI.@)
- *
- * Get the IP-to-physical address mapping table.
- * Like GetIpNetTable(), but allocate the returned table from heap.
- *
- * PARAMS
- * ppIpNetTable [Out] pointer into which the MIB_IPNETTABLE is
- * allocated and returned.
- * bOrder [In] whether to sort the table
- * heap [In] heap from which the table is allocated
- * flags [In] flags to HeapAlloc
- *
- * RETURNS
- * ERROR_INVALID_PARAMETER if ppIpNetTable is NULL, other error codes
- * on failure, NO_ERROR on success.
- */
-DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable, BOOL bOrder,
- HANDLE heap, DWORD flags)
-{
- MIB_IPNETTABLE *table;
- MIB_IPNETROW row;
- DWORD ret = NO_ERROR, count = 16, table_size = FIELD_OFFSET( MIB_IPNETTABLE, table[count] );
-
- TRACE("table %p, bOrder %d, heap %p, flags 0x%08x\n", ppIpNetTable, bOrder, heap, flags);
-
- if (!ppIpNetTable) return ERROR_INVALID_PARAMETER;
-
- if (!(table = HeapAlloc( heap, flags, table_size )))
- return ERROR_OUTOFMEMORY;
-
- table->dwNumEntries = 0;
-
-#ifdef __linux__
- {
- FILE *fp;
-
- if ((fp = fopen("/proc/net/arp", "r")))
- {
- char buf[512], *ptr;
- DWORD atf_flags;
-
- /* skip header line */
- ptr = fgets(buf, sizeof(buf), fp);
- while ((ptr = fgets(buf, sizeof(buf), fp)))
- {
- memset( &row, 0, sizeof(row) );
-
- row.dwAddr = inet_addr(ptr);
- while (*ptr && !isspace(*ptr)) ptr++;
- strtoul(ptr + 1, &ptr, 16); /* hw type (skip) */
- atf_flags = strtoul(ptr + 1, &ptr, 16);
-
-#ifdef ATF_COM
- if (atf_flags & ATF_COM) row.u.Type = MIB_IPNET_TYPE_DYNAMIC;
- else
-#endif
-#ifdef ATF_PERM
- if (atf_flags & ATF_PERM) row.u.Type = MIB_IPNET_TYPE_STATIC;
- else
-#endif
- row.u.Type = MIB_IPNET_TYPE_OTHER;
-
- while (*ptr && isspace(*ptr)) ptr++;
- while (*ptr && !isspace(*ptr))
- {
- row.bPhysAddr[row.dwPhysAddrLen++] = strtoul(ptr, &ptr, 16);
- if (*ptr) ptr++;
- }
- while (*ptr && isspace(*ptr)) ptr++;
- while (*ptr && !isspace(*ptr)) ptr++; /* mask (skip) */
- while (*ptr && isspace(*ptr)) ptr++;
- getInterfaceIndexByName(ptr, &row.dwIndex);
-
- if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, sizeof(row) )))
- break;
- }
- fclose(fp);
- }
- else ret = ERROR_NOT_SUPPORTED;
- }
-#elif defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK)
- {
- void *data;
- int fd, len, namelen;
- mib2_ipNetToMediaEntry_t *entry;
- char name[64];
-
- if ((fd = open_streams_mib( NULL )) != -1)
- {
- if ((data = read_mib_entry( fd, MIB2_IP, MIB2_IP_MEDIA, &len )))
- {
- for (entry = data; (char *)(entry + 1) <= (char *)data + len; entry++)
- {
- row.dwPhysAddrLen = min( entry->ipNetToMediaPhysAddress.o_length, MAXLEN_PHYSADDR );
- memcpy( row.bPhysAddr, entry->ipNetToMediaPhysAddress.o_bytes, row.dwPhysAddrLen );
- row.dwAddr = entry->ipNetToMediaNetAddress;
- row.u.Type = entry->ipNetToMediaType;
- namelen = min( sizeof(name) - 1, entry->ipNetToMediaIfIndex.o_length );
- memcpy( name, entry->ipNetToMediaIfIndex.o_bytes, namelen );
- name[namelen] = 0;
- getInterfaceIndexByName( name, &row.dwIndex );
- if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, sizeof(row) )))
- break;
- }
- HeapFree( GetProcessHeap(), 0, data );
- }
- close( fd );
- }
- else ret = ERROR_NOT_SUPPORTED;
- }
-#elif defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP)
- {
- int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_LLINFO};
- size_t needed;
- char *buf = NULL, *lim, *next;
- struct rt_msghdr *rtm;
- struct sockaddr_inarp *sinarp;
- struct sockaddr_dl *sdl;
-
- if (sysctl (mib, ARRAY_SIZE(mib), NULL, &needed, NULL, 0) == -1)
- {
- ERR ("failed to get arp table\n");
- ret = ERROR_NOT_SUPPORTED;
- goto done;
- }
-
- buf = HeapAlloc (GetProcessHeap (), 0, needed);
- if (!buf)
- {
- ret = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- if (sysctl (mib, ARRAY_SIZE(mib), buf, &needed, NULL, 0) == -1)
- {
- ret = ERROR_NOT_SUPPORTED;
- goto done;
- }
-
- lim = buf + needed;
- next = buf;
- while(next < lim)
- {
- rtm = (struct rt_msghdr *)next;
- sinarp=(struct sockaddr_inarp *)(rtm + 1);
- sdl = (struct sockaddr_dl *)((char *)sinarp + ROUNDUP(sinarp->sin_len));
- if(sdl->sdl_alen) /* arp entry */
- {
- memset( &row, 0, sizeof(row) );
- row.dwAddr = sinarp->sin_addr.s_addr;
- row.dwIndex = sdl->sdl_index;
- row.dwPhysAddrLen = min( 8, sdl->sdl_alen );
- memcpy( row.bPhysAddr, &sdl->sdl_data[sdl->sdl_nlen], row.dwPhysAddrLen );
- if(rtm->rtm_rmx.rmx_expire == 0) row.u.Type = MIB_IPNET_TYPE_STATIC;
- else if(sinarp->sin_other & SIN_PROXY) row.u.Type = MIB_IPNET_TYPE_OTHER;
- else if(rtm->rtm_rmx.rmx_expire != 0) row.u.Type = MIB_IPNET_TYPE_DYNAMIC;
- else row.u.Type = MIB_IPNET_TYPE_INVALID;
-
- if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, sizeof(row) )))
- break;
- }
- next += rtm->rtm_msglen;
- }
-done:
- HeapFree( GetProcessHeap (), 0, buf );
- }
-#else
- FIXME( "not implemented\n" );
- ret = ERROR_NOT_SUPPORTED;
-#endif
-
- if (!table) return ERROR_OUTOFMEMORY;
- if (!ret)
- {
- if (bOrder && table->dwNumEntries)
- qsort( table->table, table->dwNumEntries, sizeof(row), compare_ipnet_rows );
- *ppIpNetTable = table;
- }
- else HeapFree( heap, flags, table );
- TRACE( "returning ret %u table %p\n", ret, table );
- return ret;
-}
-
static DWORD get_tcp_table_sizes( TCP_TABLE_CLASS class, DWORD row_count, DWORD *row_size )
{
DWORD table_size;
--
2.23.0
More information about the wine-devel
mailing list