diff --git a/configure b/configure index c149359dcdd..fb051165f51 100755 --- a/configure +++ b/configure @@ -5968,6 +5968,7 @@ for ac_header in \ kstat.h \ lber.h \ ldap.h \ + libproc.h \ link.h \ linux/cdrom.h \ linux/compiler.h \ diff --git a/configure.ac b/configure.ac index b9de304277d..958fa5fa344 100644 --- a/configure.ac +++ b/configure.ac @@ -428,6 +428,7 @@ AC_CHECK_HEADERS(\ kstat.h \ lber.h \ ldap.h \ + libproc.h \ link.h \ linux/cdrom.h \ linux/compiler.h \ diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 9ca51e90fae..7b41f324b17 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -123,6 +123,9 @@ #ifdef HAVE_SYS_TIHDR_H #include #endif +#ifdef HAVE_LIBPROC_H +#include +#endif #ifndef ROUNDUP #define ROUNDUP(a) \ @@ -1950,13 +1953,13 @@ done: return map; } -static unsigned int find_owning_pid( struct pid_map *map, unsigned int num_entries, int inode ) +static unsigned int find_owning_pid( struct pid_map *map, unsigned int num_entries, UINT_PTR inode ) { #ifdef __linux__ unsigned int i, len_socket; char socket[32]; - sprintf( socket, "socket:[%d]", inode ); + sprintf( socket, "socket:[%lu]", inode ); len_socket = strlen( socket ); for (i = 0; i < num_entries; i++) { @@ -1984,6 +1987,36 @@ static unsigned int find_owning_pid( struct pid_map *map, unsigned int num_entri } } return 0; +#elif defined(HAVE_LIBPROC_H) + struct proc_fdinfo *fds; + struct socket_fdinfo sock; + unsigned int i, j, n, fd_len; + + for (i = 0; i < num_entries; i++) + { + fd_len = proc_pidinfo( map[i].unix_pid, PROC_PIDLISTFDS, 0, NULL, 0 ); + if (fd_len <= 0) continue; + + fds = HeapAlloc( GetProcessHeap(), 0, fd_len ); + if (!fds) continue; + + proc_pidinfo( map[i].unix_pid, PROC_PIDLISTFDS, 0, fds, fd_len ); + n = fd_len / sizeof(struct proc_fdinfo); + for (j = 0; j < n; j++) + { + if (fds[j].proc_fdtype != PROX_FDTYPE_SOCKET) continue; + + proc_pidfdinfo( map[i].unix_pid, fds[j].proc_fd, PROC_PIDFDSOCKETINFO, &sock, sizeof(sock) ); + if (sock.psi.soi_pcb == inode) + { + HeapFree( GetProcessHeap(), 0, fds ); + return map[i].pid; + } + } + + HeapFree( GetProcessHeap(), 0, fds ); + } + return 0; #else FIXME( "not implemented\n" ); return 0; @@ -2105,6 +2138,8 @@ DWORD build_tcp_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE size_t Len = 0; char *Buf = NULL; struct xinpgen *pXIG, *pOrigXIG; + struct pid_map *pMap; + unsigned NumEntries; if (sysctlbyname ("net.inet.tcp.pcblist", NULL, &Len, NULL, 0) < 0) { @@ -2127,6 +2162,8 @@ DWORD build_tcp_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE 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; @@ -2172,6 +2209,13 @@ DWORD build_tcp_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE 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_tcp_row( class, heap, flags, table, &count, &row, row_size ))) break; } @@ -2368,6 +2412,8 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE size_t Len = 0; char *Buf = NULL; struct xinpgen *pXIG, *pOrigXIG; + struct pid_map *pMap; + unsigned NumEntries; if (sysctlbyname ("net.inet.udp.pcblist", NULL, &Len, NULL, 0) < 0) { @@ -2390,6 +2436,9 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE goto done; } + if (class >= UDP_TABLE_OWNER_PID) + pMap = get_pid_map( &NumEntries ); + /* Might be nothing here; first entry is just a header it seems */ if (Len <= sizeof (struct xinpgen)) goto done; @@ -2427,6 +2476,14 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE /* Fill in structure details */ row.dwLocalAddr = pINData->inp_laddr.s_addr; row.dwLocalPort = pINData->inp_lport; + if (class >= UDP_TABLE_OWNER_PID) + row.dwOwningPid = find_owning_pid( pMap, NumEntries, (UINT_PTR)pSockData->so_pcb ); + if (class >= UDP_TABLE_OWNER_MODULE) + { + row.liCreateTimestamp.QuadPart = 0; /* FIXME */ + row.u.dwFlags = 0; + memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) ); + } if (!(table = append_udp_row( class, heap, flags, table, &count, &row, row_size ))) break; } diff --git a/include/config.h.in b/include/config.h.in index 014c78a658d..d377d02fc3c 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -351,6 +351,9 @@ /* Define to 1 if you have the `ossaudio' library (-lossaudio). */ #undef HAVE_LIBOSSAUDIO +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBPROC_H + /* Define to 1 if you have the header file. */ #undef HAVE_LIBV4L1_H