From 2264663c743a01c815909b9e44e71a475964b58f Mon Sep 17 00:00:00 2001 From: Chip Davis Date: Sun, 8 May 2022 16:32:21 -0500 Subject: [PATCH] nsiproxy.sys: Implement IPv6 ipstats get_all_parameters on Mac OS and BSD. Signed-off-by: Alexandre Julliard --- configure | 46 ++++++++++++++++++++++++++ configure.ac | 14 ++++++++ dlls/nsiproxy.sys/ip.c | 75 ++++++++++++++++++++++++++++++++++++++++++ include/config.h.in | 6 ++++ 4 files changed, 141 insertions(+) diff --git a/configure b/configure index 5bfc9202f33..64396a1c69b 100755 --- a/configure +++ b/configure @@ -8761,6 +8761,32 @@ if test "x$ac_cv_header_netinet_udp_h" = xyes then : printf "%s\n" "#define HAVE_NETINET_UDP_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "netinet6/ip6_var.h" "ac_cv_header_netinet6_ip6_var_h" "#include + #include + #ifdef HAVE_SYS_SOCKETVAR_H + # include + #endif + #ifdef HAVE_NET_ROUTE_H + # include + #endif + #ifdef HAVE_NETINET_IN_H + # include + #endif + #ifdef HAVE_NETINET_IN_SYSTM_H + # include + #endif + #ifdef HAVE_NET_IF_H + # include + #endif + #ifdef HAVE_NETINET_IP_H + # include + #endif +" +if test "x$ac_cv_header_netinet6_ip6_var_h" = xyes +then : + printf "%s\n" "#define HAVE_NETINET6_IP6_VAR_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "netipx/ipx.h" "ac_cv_header_netipx_ipx_h" "#include #include @@ -20651,6 +20677,26 @@ printf "%s\n" "#define HAVE_STRUCT_IP_STATS_IPS_TOTAL 1" >>confdefs.h fi +ac_fn_c_check_member "$LINENO" "struct ip6stat" "ip6s_total" "ac_cv_member_struct_ip6stat_ip6s_total" "#include +#ifdef HAVE_SYS_SOCKETVAR_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET6_IP6_VAR_H +#include +#endif +" +if test "x$ac_cv_member_struct_ip6stat_ip6s_total" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_IP6STAT_IP6S_TOTAL 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct icmpstat" "icps_error" "ac_cv_member_struct_icmpstat_icps_error" "#include #ifdef HAVE_SYS_SOCKETVAR_H #include diff --git a/configure.ac b/configure.ac index c2ea705bc63..e4abc79997b 100644 --- a/configure.ac +++ b/configure.ac @@ -532,6 +532,7 @@ AC_CHECK_HEADERS(\ netinet/ip_icmp.h \ netinet/ip_var.h \ netinet/udp.h \ + netinet6/ip6_var.h \ netipx/ipx.h \ sys/un.h \ ,,,[#include @@ -2218,6 +2219,19 @@ AC_CHECK_MEMBERS([struct ip_stats.ips_total],,, #include #endif]) +dnl Check for struct ip6stat +AC_CHECK_MEMBERS([struct ip6stat.ip6s_total],,, +[#include +#ifdef HAVE_SYS_SOCKETVAR_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET6_IP6_VAR_H +#include +#endif]) + dnl Check for struct icmpstat AC_CHECK_MEMBERS([struct icmpstat.icps_error],,, [#include diff --git a/dlls/nsiproxy.sys/ip.c b/dlls/nsiproxy.sys/ip.c index 18e88f493bb..27344756580 100644 --- a/dlls/nsiproxy.sys/ip.c +++ b/dlls/nsiproxy.sys/ip.c @@ -55,6 +55,50 @@ #include #endif +#ifdef HAVE_NETINET6_IP6_VAR_H +#include +#endif + +#ifdef __APPLE__ +/* For reasons unknown, Mac OS doesn't export to user- + * space. We'll have to define the needed struct ourselves. + */ +struct ip6stat { + u_quad_t ip6s_total; + u_quad_t ip6s_tooshort; + u_quad_t ip6s_toosmall; + u_quad_t ip6s_fragments; + u_quad_t ip6s_fragdropped; + u_quad_t ip6s_fragtimeout; + u_quad_t ip6s_fragoverflow; + u_quad_t ip6s_forward; + u_quad_t ip6s_cantforward; + u_quad_t ip6s_redirectsent; + u_quad_t ip6s_delivered; + u_quad_t ip6s_localout; + u_quad_t ip6s_odropped; + u_quad_t ip6s_reassembled; + u_quad_t ip6s_atmfrag_rcvd; + u_quad_t ip6s_fragmented; + u_quad_t ip6s_ofragments; + u_quad_t ip6s_cantfrag; + u_quad_t ip6s_badoptions; + u_quad_t ip6s_noroute; + u_quad_t ip6s_badvers; + u_quad_t ip6s_rawout; + u_quad_t ip6s_badscope; + u_quad_t ip6s_notmember; + u_quad_t ip6s_nxthist[256]; + u_quad_t ip6s_m1; + u_quad_t ip6s_m2m[32]; + u_quad_t ip6s_mext1; + u_quad_t ip6s_mext2m; + u_quad_t ip6s_exthdrtoolong; + u_quad_t ip6s_nogif; + u_quad_t ip6s_toomanyhdr; +}; +#endif + #ifdef HAVE_NETINET_ICMP_VAR_H #include #endif @@ -729,6 +773,37 @@ static NTSTATUS ipv6_ipstats_get_all_parameters( const void *key, UINT key_size, if (static_data) *(struct nsi_ip_ipstats_static *)static_data = stat; return status; } +#elif defined(HAVE_SYS_SYSCTL_H) && defined(IPV6CTL_STATS) && (defined(HAVE_STRUCT_IP6STAT_IP6S_TOTAL) || defined(__APPLE__)) + { + int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_STATS }; + struct ip6stat ip_stat; + size_t needed; + + needed = sizeof(ip_stat); + if (sysctl( mib, ARRAY_SIZE(mib), &ip_stat, &needed, NULL, 0 ) == -1) return STATUS_NOT_SUPPORTED; + + dyn.in_recv = ip_stat.ip6s_total; + dyn.in_hdr_errs = ip_stat.ip6s_tooshort + ip_stat.ip6s_toosmall + ip_stat.ip6s_badvers + + ip_stat.ip6s_badoptions + ip_stat.ip6s_exthdrtoolong + ip_stat.ip6s_toomanyhdr; + dyn.in_addr_errs = ip_stat.ip6s_cantforward + ip_stat.ip6s_badscope + ip_stat.ip6s_notmember; + dyn.fwd_dgrams = ip_stat.ip6s_forward; + dyn.in_discards = ip_stat.ip6s_fragdropped; + dyn.in_delivers = ip_stat.ip6s_delivered; + dyn.out_reqs = ip_stat.ip6s_localout; + dyn.out_discards = ip_stat.ip6s_odropped; + dyn.out_no_routes = ip_stat.ip6s_noroute; + stat.reasm_timeout = ip_stat.ip6s_fragtimeout; + dyn.reasm_reqds = ip_stat.ip6s_fragments; + dyn.reasm_oks = ip_stat.ip6s_reassembled; + dyn.reasm_fails = ip_stat.ip6s_fragments - ip_stat.ip6s_reassembled; + dyn.frag_oks = ip_stat.ip6s_fragmented; + dyn.frag_fails = ip_stat.ip6s_cantfrag; + dyn.frag_creates = ip_stat.ip6s_ofragments; + + if (dynamic_data) *(struct nsi_ip_ipstats_dynamic *)dynamic_data = dyn; + if (static_data) *(struct nsi_ip_ipstats_static *)static_data = stat; + return STATUS_SUCCESS; + } #else FIXME( "not implemented\n" ); return STATUS_NOT_IMPLEMENTED; diff --git a/include/config.h.in b/include/config.h.in index 8cbf23d417e..de1bf6c61eb 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -257,6 +257,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET6_IP6_VAR_H + /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_ICMP6_H @@ -458,6 +461,9 @@ /* Define to 1 if `ipi6_addr' is a member of `struct in6_pktinfo'. */ #undef HAVE_STRUCT_IN6_PKTINFO_IPI6_ADDR +/* Define to 1 if `ip6s_total' is a member of `struct ip6stat'. */ +#undef HAVE_STRUCT_IP6STAT_IP6S_TOTAL + /* Define to 1 if `ips_total' is a member of `struct ipstat'. */ #undef HAVE_STRUCT_IPSTAT_IPS_TOTAL