[PATCH] iphlpapi: Implement find_owning_pid() for Mac OS.

Charles Davis cdavis5x at gmail.com
Mon Aug 19 13:07:25 CDT 2013


---
 configure.ac            |    1 +
 dlls/iphlpapi/ipstats.c |   61 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index b9de304..958fa5f 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 9ca51e9..cbeea61 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -123,6 +123,9 @@
 #ifdef HAVE_SYS_TIHDR_H
 #include <sys/tihdr.h>
 #endif
+#ifdef HAVE_LIBPROC_H
+#include <libproc.h>
+#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:[%u]", (UINT)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;
         }
 
-- 
1.7.5.4




More information about the wine-patches mailing list