From: Tim Clem tclem@codeweavers.com
The handles returned by libproc (namely struct socket_info's soi_pcb) use all 64 bits, but the ones from the pcblist sysctl are truncated to 32. That makes find_owning_pid fail. The pcblist64 sysctl was added in macOS 10.6 and returns handles that match those from libproc. --- dlls/nsiproxy.sys/tcp.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/dlls/nsiproxy.sys/tcp.c b/dlls/nsiproxy.sys/tcp.c index 5734c4d9ee0..67dcfed19f3 100644 --- a/dlls/nsiproxy.sys/tcp.c +++ b/dlls/nsiproxy.sys/tcp.c @@ -29,6 +29,7 @@ #include <sys/socket.h> #include <dirent.h> #include <unistd.h> +#include <pthread.h>
#ifdef HAVE_SYS_PARAM_H #include <sys/param.h> @@ -514,6 +515,16 @@ unsigned int find_owning_pid( struct pid_map *map, unsigned int num_entries, UIN #endif }
+#ifdef __APPLE__ +static int pcblist_mib[CTL_MAXNAME]; +static size_t pcblist_mib_len = CTL_MAXNAME; + +static void init_pcblist64_mib( void ) +{ + sysctlnametomib( "net.inet.tcp.pcblist64", pcblist_mib, &pcblist_mib_len ); +} +#endif + static NTSTATUS tcp_conns_enumerate_all( UINT filter, struct nsi_tcp_conn_key *key_data, UINT key_size, void *rw, UINT rw_size, struct nsi_tcp_conn_dynamic *dynamic_data, UINT dynamic_size, @@ -625,12 +636,19 @@ static NTSTATUS tcp_conns_enumerate_all( UINT filter, struct nsi_tcp_conn_key *k } #elif defined(HAVE_SYS_SYSCTL_H) && defined(TCPCTL_PCBLIST) && defined(HAVE_STRUCT_XINPGEN) { - int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_PCBLIST }; size_t len = 0; char *buf = NULL; struct xinpgen *xig, *orig_xig;
- if (sysctl( mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0 ) < 0) +#ifdef __APPLE__ + static pthread_once_t mib_init_once = PTHREAD_ONCE_INIT; + pthread_once( &mib_init_once, init_pcblist64_mib ); +#else + int pcblist_mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_PCBLIST }; + size_t pcblist_mib_len = ARRAY_SIZE(mib); +#endif + + if (sysctl( pcblist_mib, pcblist_mib_len, NULL, &len, NULL, 0 ) < 0) { ERR( "Failure to read net.inet.tcp.pcblist via sysctl\n" ); status = STATUS_NOT_SUPPORTED; @@ -644,7 +662,7 @@ static NTSTATUS tcp_conns_enumerate_all( UINT filter, struct nsi_tcp_conn_key *k goto err; }
- if (sysctl( mib, ARRAY_SIZE(mib), buf, &len, NULL, 0 ) < 0) + if (sysctl( pcblist_mib, pcblist_mib_len, buf, &len, NULL, 0 ) < 0) { ERR( "Failure to read net.inet.tcp.pcblist via sysctl\n" ); status = STATUS_NOT_SUPPORTED; @@ -664,7 +682,11 @@ static NTSTATUS tcp_conns_enumerate_all( UINT filter, struct nsi_tcp_conn_key *k xig->xig_len > sizeof(struct xinpgen); xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { -#if __FreeBSD_version >= 1200026 +#ifdef __APPLE__ + struct xtcpcb64 *tcp = (struct xtcpcb64 *)xig; + struct xinpcb64 *in = &tcp->xt_inpcb; + struct xsocket64 *sock = &in->xi_socket; +#elif __FreeBSD_version >= 1200026 struct xtcpcb *tcp = (struct xtcpcb *)xig; struct xinpcb *in = &tcp->xt_inp; struct xsocket *sock = &in->xi_socket;