Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/iphlpapi/iphlpapi_main.c | 43 +++ dlls/iphlpapi/ipstats.c | 644 ---------------------------------- dlls/iphlpapi/ipstats.h | 2 - 3 files changed, 43 insertions(+), 646 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 65a72379e60..e78689d8f11 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -3240,6 +3240,49 @@ ULONG WINAPI GetTcp6Table2( MIB_TCP6TABLE2 *table, ULONG *size, BOOL sort ) return get_extended_tcp_table( table, size, sort, WS_AF_INET6, TCP_TABLE2 ); }
+static DWORD allocate_tcp_table( void **table, BOOL sort, HANDLE heap, DWORD flags, + ULONG family, ULONG table_class ) +{ + DWORD err, size = 0x100, attempt; + + for (attempt = 0; attempt < 5; attempt++) + { + *table = HeapAlloc( heap, flags, size ); + if (!*table) return ERROR_NOT_ENOUGH_MEMORY; + err = get_extended_tcp_table( *table, &size, sort, family, table_class ); + if (!err) break; + HeapFree( heap, flags, *table ); + *table = NULL; + if (err != ERROR_INSUFFICIENT_BUFFER) break; + } + return err; +} + +/****************************************************************** + * AllocateAndGetTcpTableFromStack (IPHLPAPI.@) + */ +DWORD WINAPI AllocateAndGetTcpTableFromStack( MIB_TCPTABLE **table, BOOL sort, HANDLE heap, DWORD flags ) +{ + TRACE( "table %p, sort %d, heap %p, flags 0x%08x\n", table, sort, heap, flags ); + + if (!table) return ERROR_INVALID_PARAMETER; + + return allocate_tcp_table( (void **)table, sort, heap, flags, WS_AF_INET, TCP_TABLE_BASIC_ALL ); +} + +/****************************************************************** + * AllocateAndGetTcpExTableFromStack (IPHLPAPI.@) + */ +DWORD WINAPI AllocateAndGetTcpExTableFromStack( void **table, BOOL sort, HANDLE heap, DWORD flags, DWORD family ) +{ + TRACE( "table %p, sort %d, heap %p, flags 0x%08x, family %u\n", table, sort, heap, flags, family ); + + if (!table || !ip_module_id( family )) return ERROR_INVALID_PARAMETER; + if (family == WS_AF_INET6) return ERROR_NOT_SUPPORTED; + + return allocate_tcp_table( table, sort, heap, flags, family, TCP_TABLE_OWNER_PID_ALL ); +} + /****************************************************************** * GetUdpTable (IPHLPAPI.@) * diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index af14cddb0ca..326db56f5bc 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -466,77 +466,6 @@ static void *append_table_row( HANDLE heap, DWORD flags, void *table, DWORD *tab return table; }
-static DWORD get_tcp_table_sizes( TCP_TABLE_CLASS class, DWORD row_count, DWORD *row_size ) -{ - DWORD table_size; - - switch (class) - { - case TCP_TABLE_BASIC_LISTENER: - case TCP_TABLE_BASIC_CONNECTIONS: - case TCP_TABLE_BASIC_ALL: - { - table_size = FIELD_OFFSET(MIB_TCPTABLE, table[row_count]); - if (row_size) *row_size = sizeof(MIB_TCPROW); - break; - } - case TCP_TABLE_OWNER_PID_LISTENER: - case TCP_TABLE_OWNER_PID_CONNECTIONS: - case TCP_TABLE_OWNER_PID_ALL: - { - table_size = FIELD_OFFSET(MIB_TCPTABLE_OWNER_PID, table[row_count]); - if (row_size) *row_size = sizeof(MIB_TCPROW_OWNER_PID); - break; - } - case TCP_TABLE_OWNER_MODULE_LISTENER: - case TCP_TABLE_OWNER_MODULE_CONNECTIONS: - case TCP_TABLE_OWNER_MODULE_ALL: - { - table_size = FIELD_OFFSET(MIB_TCPTABLE_OWNER_MODULE, table[row_count]); - if (row_size) *row_size = sizeof(MIB_TCPROW_OWNER_MODULE); - break; - } - default: - ERR("unhandled class %u\n", class); - return 0; - } - return table_size; -} - -/* Why not a lookup table? Because the TCPS_* constants are different - on different platforms */ -static inline MIB_TCP_STATE TCPStateToMIBState (int state) -{ - switch (state) - { - case TCPS_ESTABLISHED: return MIB_TCP_STATE_ESTAB; - case TCPS_SYN_SENT: return MIB_TCP_STATE_SYN_SENT; - case TCPS_SYN_RECEIVED: return MIB_TCP_STATE_SYN_RCVD; - case TCPS_FIN_WAIT_1: return MIB_TCP_STATE_FIN_WAIT1; - case TCPS_FIN_WAIT_2: return MIB_TCP_STATE_FIN_WAIT2; - case TCPS_TIME_WAIT: return MIB_TCP_STATE_TIME_WAIT; - case TCPS_CLOSE_WAIT: return MIB_TCP_STATE_CLOSE_WAIT; - case TCPS_LAST_ACK: return MIB_TCP_STATE_LAST_ACK; - case TCPS_LISTEN: return MIB_TCP_STATE_LISTEN; - case TCPS_CLOSING: return MIB_TCP_STATE_CLOSING; - default: - case TCPS_CLOSED: return MIB_TCP_STATE_CLOSED; - } -} - -static int compare_tcp_rows(const void *a, const void *b) -{ - const MIB_TCPROW *rowA = a; - const MIB_TCPROW *rowB = b; - int ret; - - if ((ret = ntohl (rowA->dwLocalAddr) - ntohl (rowB->dwLocalAddr)) != 0) return ret; - if ((ret = ntohs ((unsigned short)rowA->dwLocalPort) - - ntohs ((unsigned short)rowB->dwLocalPort)) != 0) return ret; - if ((ret = ntohl (rowA->dwRemoteAddr) - ntohl (rowB->dwRemoteAddr)) != 0) return ret; - return ntohs ((unsigned short)rowA->dwRemotePort) - ntohs ((unsigned short)rowB->dwRemotePort); -} - struct pid_map { unsigned int pid; @@ -715,289 +644,6 @@ static unsigned int find_owning_pid( struct pid_map *map, unsigned int num_entri #endif }
-static BOOL match_class( TCP_TABLE_CLASS class, MIB_TCP_STATE state ) -{ - switch (class) - { - case TCP_TABLE_BASIC_ALL: - case TCP_TABLE_OWNER_PID_ALL: - case TCP_TABLE_OWNER_MODULE_ALL: - return TRUE; - - case TCP_TABLE_BASIC_LISTENER: - case TCP_TABLE_OWNER_PID_LISTENER: - case TCP_TABLE_OWNER_MODULE_LISTENER: - if (state == MIB_TCP_STATE_LISTEN) return TRUE; - return FALSE; - - case TCP_TABLE_BASIC_CONNECTIONS: - case TCP_TABLE_OWNER_PID_CONNECTIONS: - case TCP_TABLE_OWNER_MODULE_CONNECTIONS: - if (state == MIB_TCP_STATE_ESTAB) return TRUE; - return FALSE; - - default: - ERR( "unhandled class %u\n", class ); - return FALSE; - } -} - -DWORD build_tcp_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE heap, DWORD flags, - DWORD *size ) -{ - MIB_TCPTABLE *table; - MIB_TCPROW_OWNER_MODULE row; - DWORD ret = NO_ERROR, count = 16, table_size, row_size; - - if (!(table_size = get_tcp_table_sizes( class, count, &row_size ))) - 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/tcp", "r"))) - { - char buf[512], *ptr; - struct pid_map *map = NULL; - unsigned int num_entries = 0; - int inode; - - if (class >= TCP_TABLE_OWNER_PID_LISTENER) map = get_pid_map( &num_entries ); - - /* skip header line */ - ptr = fgets(buf, sizeof(buf), fp); - while ((ptr = fgets(buf, sizeof(buf), fp))) - { - if (sscanf( ptr, "%*x: %x:%x %x:%x %x %*s %*s %*s %*s %*s %d", - &row.dwLocalAddr, &row.dwLocalPort, &row.dwRemoteAddr, - &row.dwRemotePort, &row.dwState, &inode ) != 6) - continue; - row.dwLocalPort = htons( row.dwLocalPort ); - row.dwRemotePort = htons( row.dwRemotePort ); - row.dwState = TCPStateToMIBState( row.dwState ); - if (!match_class( class, row.dwState )) continue; - - if (class >= TCP_TABLE_OWNER_PID_LISTENER) - row.dwOwningPid = find_owning_pid( map, num_entries, inode ); - if (class >= TCP_TABLE_OWNER_MODULE_LISTENER) - { - row.liCreateTimestamp.QuadPart = 0; /* FIXME */ - memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) ); - } - if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, row_size ))) - break; - } - HeapFree( GetProcessHeap(), 0, map ); - fclose( fp ); - } - else ret = ERROR_NOT_SUPPORTED; - } -#elif defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK) - { - void *data; - int fd, len; - mib2_tcpConnEntry_t *entry; - - if ((fd = open_streams_mib( "tcp" )) != -1) - { - if ((data = read_mib_entry( fd, MIB2_TCP, MIB2_TCP_CONN, &len ))) - { - for (entry = data; (char *)(entry + 1) <= (char *)data + len; entry++) - { - row.dwLocalAddr = entry->tcpConnLocalAddress; - row.dwLocalPort = htons( entry->tcpConnLocalPort ); - row.dwRemoteAddr = entry->tcpConnRemAddress; - row.dwRemotePort = htons( entry->tcpConnRemPort ); - row.dwState = entry->tcpConnState; - if (!match_class( class, row.dwState )) continue; - if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, row_size ))) - break; - } - HeapFree( GetProcessHeap(), 0, data ); - } - close( fd ); - } - else ret = ERROR_NOT_SUPPORTED; - } -#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN) - { - size_t Len = 0; - char *Buf = NULL; - struct xinpgen *pXIG, *pOrigXIG; - struct pid_map *pMap = NULL; - unsigned NumEntries; - - if (sysctlbyname ("net.inet.tcp.pcblist", NULL, &Len, NULL, 0) < 0) - { - ERR ("Failure to read net.inet.tcp.pcblist via sysctlbyname!\n"); - ret = ERROR_NOT_SUPPORTED; - goto done; - } - - Buf = HeapAlloc (GetProcessHeap (), 0, Len); - if (!Buf) - { - ret = ERROR_OUTOFMEMORY; - goto done; - } - - if (sysctlbyname ("net.inet.tcp.pcblist", Buf, &Len, NULL, 0) < 0) - { - ERR ("Failure to read net.inet.tcp.pcblist via sysctlbyname!\n"); - ret = ERROR_NOT_SUPPORTED; - goto done; - } - - if (class >= TCP_TABLE_OWNER_PID_LISTENER) pMap = get_pid_map( &NumEntries ); - - /* Might be nothing here; first entry is just a header it seems */ - if (Len <= sizeof (struct xinpgen)) goto done; - - pOrigXIG = (struct xinpgen *)Buf; - pXIG = pOrigXIG; - - for (pXIG = (struct xinpgen *)((char *)pXIG + pXIG->xig_len); - pXIG->xig_len > sizeof (struct xinpgen); - pXIG = (struct xinpgen *)((char *)pXIG + pXIG->xig_len)) - { -#if __FreeBSD_version >= 1200026 - struct xtcpcb *pTCPData = (struct xtcpcb *)pXIG; - struct xinpcb *pINData = &pTCPData->xt_inp; - struct xsocket *pSockData = &pINData->xi_socket; -#else - struct tcpcb *pTCPData = &((struct xtcpcb *)pXIG)->xt_tp; - struct inpcb *pINData = &((struct xtcpcb *)pXIG)->xt_inp; - struct xsocket *pSockData = &((struct xtcpcb *)pXIG)->xt_socket; -#endif - - /* Ignore sockets for other protocols */ - if (pSockData->xso_protocol != IPPROTO_TCP) - continue; - - /* Ignore PCBs that were freed while generating the data */ - if (pINData->inp_gencnt > pOrigXIG->xig_gen) - continue; - - /* we're only interested in IPv4 addresses */ - if (!(pINData->inp_vflag & INP_IPV4) || - (pINData->inp_vflag & INP_IPV6)) - continue; - - /* If all 0's, skip it */ - if (!pINData->inp_laddr.s_addr && - !pINData->inp_lport && - !pINData->inp_faddr.s_addr && - !pINData->inp_fport) - continue; - - /* Fill in structure details */ - row.dwLocalAddr = pINData->inp_laddr.s_addr; - row.dwLocalPort = pINData->inp_lport; - row.dwRemoteAddr = pINData->inp_faddr.s_addr; - row.dwRemotePort = pINData->inp_fport; - row.dwState = TCPStateToMIBState (pTCPData->t_state); - if (!match_class( class, row.dwState )) continue; - if (class >= TCP_TABLE_OWNER_PID_LISTENER) - row.dwOwningPid = find_owning_pid( pMap, NumEntries, (UINT_PTR)pSockData->so_pcb ); - if (class >= TCP_TABLE_OWNER_MODULE_LISTENER) - { - row.liCreateTimestamp.QuadPart = 0; /* FIXME */ - memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) ); - } - if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, row_size ))) - break; - } - - done: - HeapFree( GetProcessHeap(), 0, pMap ); - HeapFree (GetProcessHeap (), 0, Buf); - } -#else - FIXME( "not implemented\n" ); - ret = ERROR_NOT_SUPPORTED; -#endif - - if (!table) return ERROR_OUTOFMEMORY; - if (!ret) - { - if (order && table->dwNumEntries) - qsort( table->table, table->dwNumEntries, row_size, compare_tcp_rows ); - *tablep = table; - } - else HeapFree( heap, flags, table ); - if (size) *size = get_tcp_table_sizes( class, count, NULL ); - TRACE( "returning ret %u table %p\n", ret, table ); - return ret; -} - -/****************************************************************** - * AllocateAndGetTcpTableFromStack (IPHLPAPI.@) - * - * Get the TCP connection table. - * Like GetTcpTable(), but allocate the returned table from heap. - * - * PARAMS - * ppTcpTable [Out] pointer into which the MIB_TCPTABLE 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 ppTcpTable is NULL, whatever GetTcpTable() - * returns otherwise. - */ -DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bOrder, - HANDLE heap, DWORD flags ) -{ - TRACE("table %p, bOrder %d, heap %p, flags 0x%08x\n", ppTcpTable, bOrder, heap, flags); - - if (!ppTcpTable) return ERROR_INVALID_PARAMETER; - return build_tcp_table( TCP_TABLE_BASIC_ALL, (void **)ppTcpTable, bOrder, heap, flags, NULL ); -} - -/****************************************************************** - * AllocateAndGetTcpExTableFromStack (IPHLPAPI.@) - * - * Get the TCP connection table. - * Like GetTcpTable(), but allocate the returned table from heap. - * - * PARAMS - * ppTcpTable [Out] pointer into which the MIB_TCPTABLE_EX 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 - * family [In] address family [AF_INET|AF_INET6] - * - * RETURNS - * ERROR_INVALID_PARAMETER if ppTcpTable is NULL, whatever GetTcpTable() - * returns otherwise. - */ -DWORD WINAPI AllocateAndGetTcpExTableFromStack( VOID **ppTcpTable, BOOL bOrder, - HANDLE heap, DWORD flags, DWORD family ) -{ - TRACE("table %p, bOrder %d, heap %p, flags 0x%08x, family %u\n", - ppTcpTable, bOrder, heap, flags, family); - - if (!ppTcpTable || !family) - return ERROR_INVALID_PARAMETER; - - if (family != WS_AF_INET) - { - FIXME( "family = %u not supported\n", family ); - return ERROR_NOT_SUPPORTED; - } - - return build_tcp_table( TCP_TABLE_OWNER_PID_ALL, ppTcpTable, bOrder, heap, flags, NULL ); -} - static DWORD get_udp_table_sizes( UDP_TABLE_CLASS class, DWORD row_count, DWORD *row_size ) { DWORD table_size; @@ -1222,71 +868,6 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE return ret; }
-static DWORD get_tcp6_table_sizes( TCP_TABLE_CLASS class, DWORD row_count, DWORD *row_size ) -{ - DWORD table_size; - - switch (class) - { - case TCP_TABLE_BASIC_LISTENER: - case TCP_TABLE_BASIC_CONNECTIONS: - case TCP_TABLE_BASIC_ALL: - { - table_size = FIELD_OFFSET(MIB_TCP6TABLE, table[row_count]); - if (row_size) *row_size = sizeof(MIB_TCP6ROW); - break; - } - case TCP_TABLE_OWNER_PID_LISTENER: - case TCP_TABLE_OWNER_PID_CONNECTIONS: - case TCP_TABLE_OWNER_PID_ALL: - { - table_size = FIELD_OFFSET(MIB_TCP6TABLE_OWNER_PID, table[row_count]); - if (row_size) *row_size = sizeof(MIB_TCP6ROW_OWNER_PID); - break; - } - case TCP_TABLE_OWNER_MODULE_LISTENER: - case TCP_TABLE_OWNER_MODULE_CONNECTIONS: - case TCP_TABLE_OWNER_MODULE_ALL: - { - table_size = FIELD_OFFSET(MIB_TCP6TABLE_OWNER_MODULE, table[row_count]); - if (row_size) *row_size = sizeof(MIB_TCP6ROW_OWNER_MODULE); - break; - } - default: - ERR("unhandled class %u\n", class); - return 0; - } - return table_size; -} - -static int compare_tcp6_basic_rows(const void *a, const void *b) -{ - const MIB_TCP6ROW *rowA = a; - const MIB_TCP6ROW *rowB = b; - int ret; - - if ((ret = memcmp(&rowA->LocalAddr, &rowB->LocalAddr, sizeof(rowA->LocalAddr))) != 0) return ret; - if ((ret = rowA->dwLocalScopeId - rowB->dwLocalScopeId) != 0) return ret; - if ((ret = rowA->dwLocalPort - rowB->dwLocalPort) != 0) return ret; - if ((ret = memcmp(&rowA->RemoteAddr, &rowB->RemoteAddr, sizeof(rowA->RemoteAddr))) != 0) return ret; - if ((ret = rowA->dwRemoteScopeId - rowB->dwRemoteScopeId) != 0) return ret; - return rowA->dwRemotePort - rowB->dwRemotePort; -} - -static int compare_tcp6_owner_rows(const void *a, const void *b) -{ - const MIB_TCP6ROW_OWNER_PID *rowA = a; - const MIB_TCP6ROW_OWNER_PID *rowB = b; - int ret; - - if ((ret = memcmp(&rowA->ucLocalAddr, &rowB->ucLocalAddr, sizeof(rowA->ucLocalAddr))) != 0) return ret; - if ((ret = rowA->dwLocalScopeId - rowB->dwLocalScopeId) != 0) return ret; - if ((ret = rowA->dwLocalPort - rowB->dwLocalPort) != 0) return ret; - if ((ret = memcmp(&rowA->ucRemoteAddr, &rowB->ucRemoteAddr, sizeof(rowA->ucRemoteAddr))) != 0) return ret; - if ((ret = rowA->dwRemoteScopeId - rowB->dwRemoteScopeId) != 0) return ret; - return rowA->dwRemotePort - rowB->dwRemotePort; -} - static DWORD get_udp6_table_sizes( UDP_TABLE_CLASS class, DWORD row_count, DWORD *row_size ) { DWORD table_size; @@ -1456,231 +1037,6 @@ static DWORD find_ipv6_addr_scope(const IN6_ADDR *addr, const struct ipv6_addr_s } #endif
-DWORD build_tcp6_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE heap, DWORD flags, - DWORD *size ) -{ - MIB_TCP6TABLE *table; - DWORD ret = NO_ERROR, count = 16, table_size, row_size; - - if (!(table_size = get_tcp6_table_sizes( class, count, &row_size ))) - return ERROR_INVALID_PARAMETER; - - if (!(table = HeapAlloc( heap, flags, table_size ))) - return ERROR_OUTOFMEMORY; - - table->dwNumEntries = 0; - -#ifdef __linux__ - { - MIB_TCP6ROW_OWNER_MODULE row; - FILE *fp; - - if ((fp = fopen( "/proc/net/tcp6", "r" ))) - { - char buf[512], *ptr; - struct pid_map *map = NULL; - unsigned int num_entries = 0; - struct ipv6_addr_scope *addr_scopes; - unsigned int addr_scopes_size = 0; - int inode; - - addr_scopes = get_ipv6_addr_scope_table(&addr_scopes_size); - - if (class >= TCP_TABLE_OWNER_PID_LISTENER) map = get_pid_map( &num_entries ); - - /* skip header line */ - ptr = fgets( buf, sizeof(buf), fp ); - while ((ptr = fgets( buf, sizeof(buf), fp ))) - { - DWORD *local_addr = (DWORD *)&row.ucLocalAddr; - DWORD *remote_addr = (DWORD *)&row.ucRemoteAddr; - - if (sscanf( ptr, "%*u: %8x%8x%8x%8x:%x %8x%8x%8x%8x:%x %x %*s %*s %*s %*s %*s %*s %*s %d", - &local_addr[0], &local_addr[1], &local_addr[2], &local_addr[3], &row.dwLocalPort, - &remote_addr[0], &remote_addr[1], &remote_addr[2], &remote_addr[3], &row.dwRemotePort, - &row.dwState, &inode ) != 12) - continue; - row.dwState = TCPStateToMIBState( row.dwState ); - if (!match_class( class, row.dwState )) continue; - row.dwLocalScopeId = find_ipv6_addr_scope((const IN6_ADDR *)&row.ucLocalAddr, addr_scopes, addr_scopes_size); - row.dwLocalPort = htons( row.dwLocalPort ); - row.dwRemoteScopeId = find_ipv6_addr_scope((const IN6_ADDR *)&row.ucRemoteAddr, addr_scopes, addr_scopes_size); - row.dwRemotePort = htons( row.dwRemotePort ); - - if (class <= TCP_TABLE_BASIC_ALL) - { - /* MIB_TCP6ROW has a different field order */ - MIB_TCP6ROW basic_row; - basic_row.State = row.dwState; - memcpy( &basic_row.LocalAddr, &row.ucLocalAddr, sizeof(row.ucLocalAddr) ); - basic_row.dwLocalScopeId = row.dwLocalScopeId; - basic_row.dwLocalPort = row.dwLocalPort; - memcpy( &basic_row.RemoteAddr, &row.ucRemoteAddr, sizeof(row.ucRemoteAddr) ); - basic_row.dwRemoteScopeId = row.dwRemoteScopeId; - basic_row.dwRemotePort = row.dwRemotePort; - if (!(table = append_table_row( heap, flags, table, &table_size, &count, &basic_row, row_size ))) - break; - continue; - } - - row.dwOwningPid = find_owning_pid( map, num_entries, inode ); - if (class >= TCP_TABLE_OWNER_MODULE_LISTENER) - { - row.liCreateTimestamp.QuadPart = 0; /* FIXME */ - memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) ); - } - if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, row_size ))) - break; - } - HeapFree( GetProcessHeap(), 0, map ); - HeapFree( GetProcessHeap(), 0, addr_scopes ); - fclose( fp ); - } - else ret = ERROR_NOT_SUPPORTED; - } -#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN) - { - static const char zero[sizeof(IN6_ADDR)] = {0}; - - MIB_TCP6ROW_OWNER_MODULE row; - size_t len = 0; - char *buf = NULL; - struct xinpgen *xig, *orig_xig; - struct pid_map *map = NULL; - unsigned num_entries; - struct ipv6_addr_scope *addr_scopes = NULL; - unsigned int addr_scopes_size = 0; - - if (sysctlbyname( "net.inet.tcp.pcblist", NULL, &len, NULL, 0 ) < 0) - { - ERR( "Failure to read net.inet.tcp.pcblist via sysctlbyname!\n" ); - ret = ERROR_NOT_SUPPORTED; - goto done; - } - - buf = HeapAlloc( GetProcessHeap(), 0, len ); - if (!buf) - { - ret = ERROR_OUTOFMEMORY; - goto done; - } - - if (sysctlbyname( "net.inet.tcp.pcblist", buf, &len, NULL, 0 ) < 0) - { - ERR( "Failure to read net.inet.tcp.pcblist via sysctlbyname!\n" ); - ret = ERROR_NOT_SUPPORTED; - goto done; - } - - addr_scopes = get_ipv6_addr_scope_table( &addr_scopes_size ); - if (!addr_scopes) - { - ret = ERROR_OUTOFMEMORY; - goto done; - } - - if (class >= TCP_TABLE_OWNER_PID_LISTENER) map = get_pid_map( &num_entries ); - - /* Might be nothing here; first entry is just a header it seems */ - if (len <= sizeof (struct xinpgen)) goto done; - - orig_xig = (struct xinpgen *)buf; - xig = orig_xig; - - for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); - xig->xig_len > sizeof (struct xinpgen); - xig = (struct xinpgen *)((char *)xig + xig->xig_len)) - { -#if __FreeBSD_version >= 1200026 - struct xtcpcb *tcp = (struct xtcpcb *)xig; - struct xinpcb *in = &tcp->xt_inp; - struct xsocket *sock = &in->xi_socket; -#else - struct tcpcb *tcp = &((struct xtcpcb *)xig)->xt_tp; - struct inpcb *in = &((struct xtcpcb *)xig)->xt_inp; - struct xsocket *sock = &((struct xtcpcb *)xig)->xt_socket; -#endif - - /* Ignore sockets for other protocols */ - if (sock->xso_protocol != IPPROTO_TCP) - continue; - - /* Ignore PCBs that were freed while generating the data */ - if (in->inp_gencnt > orig_xig->xig_gen) - continue; - - /* we're only interested in IPv6 addresses */ - if (!(in->inp_vflag & INP_IPV6) || - (in->inp_vflag & INP_IPV4)) - continue; - - /* If all 0's, skip it */ - if (!memcmp( &in->in6p_laddr, zero, sizeof(zero) ) && !in->inp_lport && - !memcmp( &in->in6p_faddr, zero, sizeof(zero) ) && !in->inp_fport) - continue; - - /* Fill in structure details */ - memcpy( &row.ucLocalAddr, &in->in6p_laddr.s6_addr, sizeof(row.ucLocalAddr) ); - row.dwLocalPort = in->inp_lport; - row.dwLocalScopeId = find_ipv6_addr_scope( (const IN6_ADDR *)&row.ucLocalAddr, addr_scopes, addr_scopes_size ); - memcpy( &row.ucRemoteAddr, &in->in6p_faddr.s6_addr, sizeof(row.ucRemoteAddr) ); - row.dwRemotePort = in->inp_fport; - row.dwRemoteScopeId = find_ipv6_addr_scope( (const IN6_ADDR *)&row.ucRemoteAddr, addr_scopes, addr_scopes_size ); - row.dwState = TCPStateToMIBState( tcp->t_state ); - if (!match_class( class, row.dwState )) continue; - - if (class <= TCP_TABLE_BASIC_ALL) - { - /* MIB_TCP6ROW has a different field order */ - MIB_TCP6ROW basic_row; - basic_row.State = row.dwState; - memcpy( &basic_row.LocalAddr, &row.ucLocalAddr, sizeof(row.ucLocalAddr) ); - basic_row.dwLocalScopeId = row.dwLocalScopeId; - basic_row.dwLocalPort = row.dwLocalPort; - memcpy( &basic_row.RemoteAddr, &row.ucRemoteAddr, sizeof(row.ucRemoteAddr) ); - basic_row.dwRemoteScopeId = row.dwRemoteScopeId; - basic_row.dwRemotePort = row.dwRemotePort; - if (!(table = append_table_row( heap, flags, table, &table_size, &count, &basic_row, row_size ))) - break; - continue; - } - - row.dwOwningPid = find_owning_pid( map, num_entries, (UINT_PTR)sock->so_pcb ); - if (class >= TCP_TABLE_OWNER_MODULE_LISTENER) - { - row.liCreateTimestamp.QuadPart = 0; /* FIXME */ - memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) ); - } - if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, row_size ))) - break; - } - - done: - HeapFree( GetProcessHeap(), 0, map ); - HeapFree( GetProcessHeap(), 0, buf ); - HeapFree( GetProcessHeap(), 0, addr_scopes ); - } -#else - FIXME( "not implemented\n" ); - ret = ERROR_NOT_SUPPORTED; -#endif - - if (!table) return ERROR_OUTOFMEMORY; - if (!ret) - { - if (order && table->dwNumEntries) - { - qsort( table->table, table->dwNumEntries, row_size, - class <= TCP_TABLE_BASIC_ALL ? compare_tcp6_basic_rows : compare_tcp6_owner_rows ); - } - *tablep = table; - } - else HeapFree( heap, flags, table ); - if (size) *size = get_tcp6_table_sizes( class, count, NULL ); - TRACE( "returning ret %u table %p\n", ret, table ); - return ret; -} - DWORD build_udp6_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE heap, DWORD flags, DWORD *size ) { diff --git a/dlls/iphlpapi/ipstats.h b/dlls/iphlpapi/ipstats.h index bb0c77758f7..60398609207 100644 --- a/dlls/iphlpapi/ipstats.h +++ b/dlls/iphlpapi/ipstats.h @@ -27,8 +27,6 @@ #include "winbase.h" #include "iprtrmib.h"
-DWORD build_tcp_table(TCP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN; -DWORD build_tcp6_table(TCP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN; DWORD build_udp_table(UDP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN; DWORD build_udp6_table(UDP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN;