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.
--
There does not seem to be a MIB constant for the pcblist64 sysctls, so I'm caching the result of sysctlnametomib.
-- v5: nsiproxy.sys: Use the pcblist64 sysctl to enumerate UDP connections on macOS. nsiproxy.sys: Use the pcblist64 sysctl to enumerate TCP connections on macOS.
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..1bf9cc49217 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; + +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;
From: Tim Clem tclem@codeweavers.com
--- dlls/nsiproxy.sys/udp.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-)
diff --git a/dlls/nsiproxy.sys/udp.c b/dlls/nsiproxy.sys/udp.c index 2248d74234b..03bbb3d0511 100644 --- a/dlls/nsiproxy.sys/udp.c +++ b/dlls/nsiproxy.sys/udp.c @@ -27,6 +27,7 @@ #include <stddef.h> #include <sys/types.h> #include <sys/socket.h> +#include <pthread.h>
#ifdef HAVE_SYS_PARAM_H #include <sys/param.h> @@ -202,6 +203,16 @@ static NTSTATUS udp_stats_get_all_parameters( const void *key, UINT key_size, vo return STATUS_NOT_SUPPORTED; }
+#ifdef __APPLE__ +static int pcblist_mib[CTL_MAXNAME]; +static size_t pcblist_mib_len; + +static void init_pcblist64_mib( void ) +{ + sysctlnametomib( "net.inet.udp.pcblist64", pcblist_mib, &pcblist_mib_len ); +} +#endif + static NTSTATUS udp_endpoint_enumerate_all( void *key_data, UINT key_size, void *rw_data, UINT rw_size, void *dynamic_data, UINT dynamic_size, void *static_data, UINT static_size, UINT_PTR *count ) @@ -296,14 +307,21 @@ static NTSTATUS udp_endpoint_enumerate_all( void *key_data, UINT key_size, void } #elif defined(HAVE_SYS_SYSCTL_H) && defined(UDPCTL_PCBLIST) && defined(HAVE_STRUCT_XINPGEN) { - int mib[] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_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_UDP, UDPCTL_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.udp.pcblist via sysctlbyname!\n" ); + ERR( "Failure to read net.inet.udp.pcblist via sysctl!\n" ); status = STATUS_NOT_SUPPORTED; goto err; } @@ -315,9 +333,9 @@ static NTSTATUS udp_endpoint_enumerate_all( void *key_data, UINT key_size, void 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.udp.pcblist via sysctlbyname!\n" ); + ERR( "Failure to read net.inet.udp.pcblist via sysctl!\n" ); status = STATUS_NOT_SUPPORTED; goto err; } @@ -335,7 +353,10 @@ static NTSTATUS udp_endpoint_enumerate_all( void *key_data, UINT key_size, void xig->xig_len > sizeof (struct xinpgen); xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { -#if __FreeBSD_version >= 1200026 +#ifdef __APPLE__ + struct xinpcb64 *in = (struct xinpcb64 *)xig; + struct xsocket64 *sock = &in->xi_socket; +#elif __FreeBSD_version >= 1200026 struct xinpcb *in = (struct xinpcb *)xig; struct xsocket *sock = &in->xi_socket; #else
On Thu Jul 11 16:16:06 2024 +0000, Tim Clem wrote:
changed this line in [version 5 of the diff](/wine/wine/-/merge_requests/6021/diffs?diff_id=121821&start_sha=7f3f4aaaaf11df27c4c9bd57de9e43aa911f61eb#f0fe6bc1fc67e81a852d4e47efddd6b0f50404f1_308_315)
`pthread_once` version up now.