From 84e9696078aae9fef0dc34d99eebedfacc0b58e5 Mon Sep 17 00:00:00 2001 From: Chip Davis Date: Tue, 19 Apr 2022 19:19:45 -0500 Subject: [PATCH] nsiproxy.sys: Implement IPv6 icmpstats get_all_parameters on Mac OS and BSD. Signed-off-by: Alexandre Julliard --- configure | 52 +++++++++++++++++++++++++++++ configure.ac | 15 ++++++++- dlls/nsiproxy.sys/ip.c | 75 ++++++++++++++++++++++++++++++++++++++++++ include/config.h.in | 6 ++++ 4 files changed, 147 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 5eff6d59592..5bfc9202f33 100755 --- a/configure +++ b/configure @@ -8879,6 +8879,38 @@ if test "x$ac_cv_header_netinet_icmp_var_h" = xyes then : printf "%s\n" "#define HAVE_NETINET_ICMP_VAR_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "netinet/icmp6.h" "ac_cv_header_netinet_icmp6_h" "#include + #include + #ifdef HAVE_SYS_SOCKETVAR_H + # include + #endif + #ifdef HAVE_NETINET_IN_H + # include + #endif + #ifdef HAVE_NETINET_IN_SYSTM_H + # include + #endif + #ifdef HAVE_NETINET_IP_H + # include + #endif + #ifdef HAVE_NETINET_IP_VAR_H + # include + #endif + #ifdef HAVE_NETINET_IP_ICMP_H + # include + #endif + #ifdef HAVE_NETINET_UDP_H + # include + #endif + #ifdef HAVE_NETINET_TCP_H + # include + #endif +" +if test "x$ac_cv_header_netinet_icmp6_h" = xyes +then : + printf "%s\n" "#define HAVE_NETINET_ICMP6_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "netinet/tcp_var.h" "ac_cv_header_netinet_tcp_var_h" "#include #include @@ -20645,6 +20677,26 @@ printf "%s\n" "#define HAVE_STRUCT_ICMPSTAT_ICPS_ERROR 1" >>confdefs.h fi +ac_fn_c_check_member "$LINENO" "struct icmp6stat" "icp6s_error" "ac_cv_member_struct_icmp6stat_icp6s_error" "#include +#ifdef HAVE_SYS_SOCKETVAR_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET_ICMP6_H +#include +#endif +" +if test "x$ac_cv_member_struct_icmp6stat_icp6s_error" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_ICMP6STAT_ICP6S_ERROR 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct tcpstat" "tcps_connattempt" "ac_cv_member_struct_tcpstat_tcps_connattempt" "#include #ifdef HAVE_SYS_SOCKETVAR_H #include diff --git a/configure.ac b/configure.ac index 5036857db71..c2ea705bc63 100644 --- a/configure.ac +++ b/configure.ac @@ -555,7 +555,7 @@ AC_CHECK_HEADERS(\ # include #endif]) -AC_CHECK_HEADERS([netinet/udp_var.h netinet/icmp_var.h netinet/tcp_var.h ],,, +AC_CHECK_HEADERS([netinet/udp_var.h netinet/icmp_var.h netinet/icmp6.h netinet/tcp_var.h ],,, [#include #include #ifdef HAVE_SYS_SOCKETVAR_H @@ -2237,6 +2237,19 @@ AC_CHECK_MEMBERS([struct icmpstat.icps_error],,, #include #endif]) +dnl Check for struct icmp6stat +AC_CHECK_MEMBERS([struct icmp6stat.icp6s_error],,, +[#include +#ifdef HAVE_SYS_SOCKETVAR_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET_ICMP6_H +#include +#endif]) + dnl Check for struct tcpstat AC_CHECK_MEMBERS([struct tcpstat.tcps_connattempt],,, [#include diff --git a/dlls/nsiproxy.sys/ip.c b/dlls/nsiproxy.sys/ip.c index 69f286a41a0..18e88f493bb 100644 --- a/dlls/nsiproxy.sys/ip.c +++ b/dlls/nsiproxy.sys/ip.c @@ -59,6 +59,24 @@ #include #endif +#ifdef HAVE_NETINET_ICMP6_H +#include +#undef ICMP6_DST_UNREACH +#undef ICMP6_PACKET_TOO_BIG +#undef ICMP6_TIME_EXCEEDED +#undef ICMP6_PARAM_PROB +#undef ICMP6_ECHO_REQUEST +#undef ICMP6_ECHO_REPLY +#undef ICMP6_MEMBERSHIP_QUERY +#undef ICMP6_MEMBERSHIP_REPORT +#undef ICMP6_MEMBERSHIP_REDUCTION +#undef ND_ROUTER_SOLICIT +#undef ND_ROUTER_ADVERT +#undef ND_NEIGHBOR_SOLICIT +#undef ND_NEIGHBOR_ADVERT +#undef ND_REDIRECT +#endif + #ifdef HAVE_NETINET_IF_ETHER_H #include #endif @@ -472,6 +490,63 @@ static NTSTATUS ipv6_icmpstats_get_all_parameters( const void *key, UINT key_siz if (dynamic_data) *(struct nsi_ip_icmpstats_dynamic *)dynamic_data = dyn; return STATUS_SUCCESS; } +#elif defined(HAVE_SYS_SYSCTL_H) && defined(ICMPV6CTL_STATS) && defined(HAVE_STRUCT_ICMP6STAT_ICP6S_ERROR) + { + int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_STATS }; + struct icmp6stat icmp_stat; + size_t needed = sizeof(icmp_stat); + int i; + + if (sysctl( mib, ARRAY_SIZE(mib), &icmp_stat, &needed, NULL, 0 ) == -1) return STATUS_NOT_SUPPORTED; + + dyn.in_msgs = icmp_stat.icp6s_badcode + icmp_stat.icp6s_checksum + icmp_stat.icp6s_tooshort + + icmp_stat.icp6s_badlen + icmp_stat.icp6s_nd_toomanyopt; + for (i = 0; i <= ICMP6_MAXTYPE; i++) + dyn.in_msgs += icmp_stat.icp6s_inhist[i]; + + dyn.in_errors = icmp_stat.icp6s_badcode + icmp_stat.icp6s_checksum + icmp_stat.icp6s_tooshort + + icmp_stat.icp6s_badlen + icmp_stat.icp6s_nd_toomanyopt; + + dyn.in_type_counts[ICMP6_DST_UNREACH] = icmp_stat.icp6s_inhist[ICMP6_DST_UNREACH]; + dyn.in_type_counts[ICMP6_PACKET_TOO_BIG] = icmp_stat.icp6s_inhist[ICMP6_PACKET_TOO_BIG]; + dyn.in_type_counts[ICMP6_TIME_EXCEEDED] = icmp_stat.icp6s_inhist[ICMP6_TIME_EXCEEDED]; + dyn.in_type_counts[ICMP6_PARAM_PROB] = icmp_stat.icp6s_inhist[ICMP6_PARAM_PROB]; + dyn.in_type_counts[ICMP6_ECHO_REQUEST] = icmp_stat.icp6s_inhist[ICMP6_ECHO_REQUEST]; + dyn.in_type_counts[ICMP6_ECHO_REPLY] = icmp_stat.icp6s_inhist[ICMP6_ECHO_REPLY]; + dyn.in_type_counts[ICMP6_MEMBERSHIP_QUERY] = icmp_stat.icp6s_inhist[ICMP6_MEMBERSHIP_QUERY]; + dyn.in_type_counts[ICMP6_MEMBERSHIP_REPORT] = icmp_stat.icp6s_inhist[ICMP6_MEMBERSHIP_REPORT]; + dyn.in_type_counts[ICMP6_MEMBERSHIP_REDUCTION] = icmp_stat.icp6s_inhist[ICMP6_MEMBERSHIP_REDUCTION]; + dyn.in_type_counts[ND_ROUTER_SOLICIT] = icmp_stat.icp6s_inhist[ND_ROUTER_SOLICIT]; + dyn.in_type_counts[ND_ROUTER_ADVERT] = icmp_stat.icp6s_inhist[ND_ROUTER_ADVERT]; + dyn.in_type_counts[ND_NEIGHBOR_SOLICIT] = icmp_stat.icp6s_inhist[ND_NEIGHBOR_SOLICIT]; + dyn.in_type_counts[ND_NEIGHBOR_ADVERT] = icmp_stat.icp6s_inhist[ND_NEIGHBOR_ADVERT]; + dyn.in_type_counts[ND_REDIRECT] = icmp_stat.icp6s_inhist[ND_REDIRECT]; + dyn.in_type_counts[ICMP6_V2_MEMBERSHIP_REPORT] = icmp_stat.icp6s_inhist[MLDV2_LISTENER_REPORT]; + + dyn.out_msgs = icmp_stat.icp6s_canterror + icmp_stat.icp6s_toofreq; + for (i = 0; i <= ICMP6_MAXTYPE; i++) + dyn.out_msgs += icmp_stat.icp6s_outhist[i]; + + dyn.out_errors = icmp_stat.icp6s_canterror + icmp_stat.icp6s_toofreq; + + dyn.out_type_counts[ICMP6_DST_UNREACH] = icmp_stat.icp6s_outhist[ICMP6_DST_UNREACH]; + dyn.out_type_counts[ICMP6_PACKET_TOO_BIG] = icmp_stat.icp6s_outhist[ICMP6_PACKET_TOO_BIG]; + dyn.out_type_counts[ICMP6_TIME_EXCEEDED] = icmp_stat.icp6s_outhist[ICMP6_TIME_EXCEEDED]; + dyn.out_type_counts[ICMP6_PARAM_PROB] = icmp_stat.icp6s_outhist[ICMP6_PARAM_PROB]; + dyn.out_type_counts[ICMP6_ECHO_REQUEST] = icmp_stat.icp6s_outhist[ICMP6_ECHO_REQUEST]; + dyn.out_type_counts[ICMP6_ECHO_REPLY] = icmp_stat.icp6s_outhist[ICMP6_ECHO_REPLY]; + dyn.out_type_counts[ICMP6_MEMBERSHIP_QUERY] = icmp_stat.icp6s_outhist[ICMP6_MEMBERSHIP_QUERY]; + dyn.out_type_counts[ICMP6_MEMBERSHIP_REPORT] = icmp_stat.icp6s_outhist[ICMP6_MEMBERSHIP_REPORT]; + dyn.out_type_counts[ICMP6_MEMBERSHIP_REDUCTION] = icmp_stat.icp6s_outhist[ICMP6_MEMBERSHIP_REDUCTION]; + dyn.out_type_counts[ND_ROUTER_SOLICIT] = icmp_stat.icp6s_outhist[ND_ROUTER_SOLICIT]; + dyn.out_type_counts[ND_ROUTER_ADVERT] = icmp_stat.icp6s_outhist[ND_ROUTER_ADVERT]; + dyn.out_type_counts[ND_NEIGHBOR_SOLICIT] = icmp_stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]; + dyn.out_type_counts[ND_NEIGHBOR_ADVERT] = icmp_stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]; + dyn.out_type_counts[ND_REDIRECT] = icmp_stat.icp6s_outhist[ND_REDIRECT]; + dyn.out_type_counts[ICMP6_V2_MEMBERSHIP_REPORT] = icmp_stat.icp6s_outhist[MLDV2_LISTENER_REPORT]; + if (dynamic_data) *(struct nsi_ip_icmpstats_dynamic *)dynamic_data = dyn; + 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 bc5ecdebc91..8cbf23d417e 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_NETINET_ICMP6_H + /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_ICMP_VAR_H @@ -443,6 +446,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H +/* Define to 1 if `icp6s_error' is a member of `struct icmp6stat'. */ +#undef HAVE_STRUCT_ICMP6STAT_ICP6S_ERROR + /* Define to 1 if `icps_error' is a member of `struct icmpstat'. */ #undef HAVE_STRUCT_ICMPSTAT_ICPS_ERROR