[PATCH 4/4] iphlpapi: Implement GetIpStatisticsEx() on top of nsi.
Huw Davies
huw at codeweavers.com
Wed Aug 11 05:01:31 CDT 2021
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/iphlpapi/iphlpapi_main.c | 82 +++++++++++
dlls/iphlpapi/ipstats.c | 252 ----------------------------------
dlls/nsi/tests/nsi.c | 4 -
3 files changed, 82 insertions(+), 256 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index fe2daa0f24d..78f4c582e1a 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -2436,6 +2436,88 @@ err:
return err;
}
+/******************************************************************
+ * GetIpStatistics (IPHLPAPI.@)
+ *
+ * Get the IP statistics for the local computer.
+ *
+ * PARAMS
+ * stats [Out] buffer for IP statistics
+ *
+ * RETURNS
+ * Success: NO_ERROR
+ * Failure: error code from winerror.h
+ */
+DWORD WINAPI GetIpStatistics( MIB_IPSTATS *stats )
+{
+ return GetIpStatisticsEx( stats, WS_AF_INET );
+}
+
+/******************************************************************
+ * GetIpStatisticsEx (IPHLPAPI.@)
+ *
+ * Get the IPv4 and IPv6 statistics for the local computer.
+ *
+ * PARAMS
+ * stats [Out] buffer for IP statistics
+ * family [In] specifies whether IPv4 or IPv6 statistics are returned
+ *
+ * RETURNS
+ * Success: NO_ERROR
+ * Failure: error code from winerror.h
+ */
+DWORD WINAPI GetIpStatisticsEx( MIB_IPSTATS *stats, DWORD family )
+{
+ struct nsi_ip_ipstats_dynamic dyn;
+ struct nsi_ip_ipstats_static stat;
+ struct nsi_ip_cmpt_rw cmpt_rw;
+ struct nsi_ip_cmpt_dynamic cmpt_dyn;
+ const NPI_MODULEID *mod;
+ DWORD err, cmpt = 1;
+
+ TRACE( "%p %d\n", stats, family );
+
+ if (!stats) return ERROR_INVALID_PARAMETER;
+ mod = ip_module_id( family );
+ if (!mod) return ERROR_INVALID_PARAMETER;
+
+ memset( stats, 0, sizeof(*stats) );
+
+ err = NsiGetAllParameters( 1, mod, NSI_IP_IPSTATS_TABLE, NULL, 0, NULL, 0,
+ &dyn, sizeof(dyn), &stat, sizeof(stat) );
+ if (err) return err;
+
+ err = NsiGetAllParameters( 1, mod, NSI_IP_COMPARTMENT_TABLE, &cmpt, sizeof(cmpt), &cmpt_rw, sizeof(cmpt_rw),
+ &cmpt_dyn, sizeof(cmpt_dyn), NULL, 0 );
+ if (err) return err;
+
+ stats->u.Forwarding = cmpt_rw.not_forwarding + 1;
+ stats->dwDefaultTTL = cmpt_rw.default_ttl;
+ stats->dwInReceives = dyn.in_recv;
+ stats->dwInHdrErrors = dyn.in_hdr_errs;
+ stats->dwInAddrErrors = dyn.in_addr_errs;
+ stats->dwForwDatagrams = dyn.fwd_dgrams;
+ stats->dwInUnknownProtos = dyn.in_unk_protos;
+ stats->dwInDiscards = dyn.in_discards;
+ stats->dwInDelivers = dyn.in_delivers;
+ stats->dwOutRequests = dyn.out_reqs;
+ stats->dwRoutingDiscards = dyn.routing_discards;
+ stats->dwOutDiscards = dyn.out_discards;
+ stats->dwOutNoRoutes = dyn.out_no_routes;
+ stats->dwReasmTimeout = stat.reasm_timeout;
+ stats->dwReasmReqds = dyn.reasm_reqds;
+ stats->dwReasmOks = dyn.reasm_oks;
+ stats->dwReasmFails = dyn.reasm_fails;
+ stats->dwFragOks = dyn.frag_oks;
+ stats->dwFragFails = dyn.frag_fails;
+ stats->dwFragCreates = dyn.frag_creates;
+ stats->dwNumIf = cmpt_dyn.num_ifs;
+ stats->dwNumAddr = cmpt_dyn.num_addrs;
+ stats->dwNumRoutes = cmpt_dyn.num_routes;
+
+ return err;
+}
+
/* Gets the DNS server list into the list beginning at list. Assumes that
* a single server address may be placed at list if *len is at least
* sizeof(IP_ADDR_STRING) long. Otherwise, list->Next is set to firstDynamic,
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index 115bafa6f8e..8335e4871c1 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -617,258 +617,6 @@ DWORD WINAPI GetIcmpStatisticsEx(PMIB_ICMP_EX stats, DWORD family)
return ret;
}
-/******************************************************************
- * GetIpStatisticsEx (IPHLPAPI.@)
- *
- * Get the IPv4 and IPv6 statistics for the local computer.
- *
- * PARAMS
- * stats [Out] buffer for IP statistics
- * family [In] specifies whether IPv4 or IPv6 statistics are returned
- *
- * RETURNS
- * Success: NO_ERROR
- * Failure: error code from winerror.h
- */
-DWORD WINAPI GetIpStatisticsEx(PMIB_IPSTATS stats, DWORD family)
-{
- DWORD ret = ERROR_NOT_SUPPORTED;
- MIB_IPFORWARDTABLE *fwd_table;
-
- if (!stats) return ERROR_INVALID_PARAMETER;
- if (family != WS_AF_INET && family != WS_AF_INET6) return ERROR_INVALID_PARAMETER;
- memset( stats, 0, sizeof(*stats) );
-
- stats->dwNumIf = stats->dwNumAddr = get_interface_indices( FALSE, NULL );
- if (!AllocateAndGetIpForwardTableFromStack( &fwd_table, FALSE, GetProcessHeap(), 0 ))
- {
- stats->dwNumRoutes = fwd_table->dwNumEntries;
- HeapFree( GetProcessHeap(), 0, fwd_table );
- }
-
- if (family == WS_AF_INET6)
- {
-#ifdef __linux__
- {
- FILE *fp;
-
- if ((fp = fopen("/proc/net/snmp6", "r")))
- {
- struct {
- const char *name;
- DWORD *elem;
- } ipstatlist[] = {
- { "Ip6InReceives", &stats->dwInReceives },
- { "Ip6InHdrErrors", &stats->dwInHdrErrors },
- { "Ip6InAddrErrors", &stats->dwInAddrErrors },
- { "Ip6OutForwDatagrams", &stats->dwForwDatagrams },
- { "Ip6InUnknownProtos", &stats->dwInUnknownProtos },
- { "Ip6InDiscards", &stats->dwInDiscards },
- { "Ip6InDelivers", &stats->dwInDelivers },
- { "Ip6OutRequests", &stats->dwOutRequests },
- { "Ip6OutDiscards", &stats->dwOutDiscards },
- { "Ip6OutNoRoutes", &stats->dwOutNoRoutes },
- { "Ip6ReasmTimeout", &stats->dwReasmTimeout },
- { "Ip6ReasmReqds", &stats->dwReasmReqds },
- { "Ip6ReasmOKs", &stats->dwReasmOks },
- { "Ip6ReasmFails", &stats->dwReasmFails },
- { "Ip6FragOKs", &stats->dwFragOks },
- { "Ip6FragFails", &stats->dwFragFails },
- { "Ip6FragCreates", &stats->dwFragCreates },
- /* hmm, no routingDiscards, defaultTTL and forwarding? */
- };
- char buf[512], *ptr, *value;
- DWORD res, i;
-
- while ((ptr = fgets(buf, sizeof(buf), fp)))
- {
- if (!(value = strchr(buf, ' ')))
- continue;
-
- /* terminate the valuename */
- ptr = value - 1;
- *(ptr + 1) = '\0';
-
- /* and strip leading spaces from value */
- value += 1;
- while (*value==' ') value++;
- if ((ptr = strchr(value, '\n')))
- *ptr='\0';
-
- for (i = 0; i < ARRAY_SIZE(ipstatlist); i++)
- if (!_strnicmp(buf, ipstatlist[i].name, -1) && sscanf(value, "%d", &res))
- *ipstatlist[i].elem = res;
- }
- fclose(fp);
- ret = NO_ERROR;
- }
- }
-#else
- FIXME( "unimplemented for IPv6\n" );
-#endif
- return ret;
- }
-
-#ifdef __linux__
- {
- FILE *fp;
-
- if ((fp = fopen("/proc/net/snmp", "r")))
- {
- static const char hdr[] = "Ip:";
- char buf[512], *ptr;
-
- while ((ptr = fgets(buf, sizeof(buf), fp)))
- {
- if (_strnicmp(buf, hdr, sizeof(hdr) - 1)) continue;
- /* last line was a header, get another */
- if (!(ptr = fgets(buf, sizeof(buf), fp))) break;
- if (!_strnicmp(buf, hdr, sizeof(hdr) - 1))
- {
- ptr += sizeof(hdr);
- sscanf( ptr, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u",
- &stats->u.dwForwarding,
- &stats->dwDefaultTTL,
- &stats->dwInReceives,
- &stats->dwInHdrErrors,
- &stats->dwInAddrErrors,
- &stats->dwForwDatagrams,
- &stats->dwInUnknownProtos,
- &stats->dwInDiscards,
- &stats->dwInDelivers,
- &stats->dwOutRequests,
- &stats->dwOutDiscards,
- &stats->dwOutNoRoutes,
- &stats->dwReasmTimeout,
- &stats->dwReasmReqds,
- &stats->dwReasmOks,
- &stats->dwReasmFails,
- &stats->dwFragOks,
- &stats->dwFragFails,
- &stats->dwFragCreates );
- /* hmm, no routingDiscards */
- break;
- }
- }
- fclose(fp);
- ret = NO_ERROR;
- }
- }
-#elif defined(HAVE_LIBKSTAT)
- {
- static char ip[] = "ip";
- kstat_ctl_t *kc;
- kstat_t *ksp;
-
- if ((kc = kstat_open()) &&
- (ksp = kstat_lookup( kc, ip, 0, ip )) &&
- kstat_read( kc, ksp, NULL ) != -1 &&
- ksp->ks_type == KSTAT_TYPE_NAMED)
- {
- stats->u.dwForwarding = kstat_get_ui32( ksp, "forwarding" );
- stats->dwDefaultTTL = kstat_get_ui32( ksp, "defaultTTL" );
- stats->dwInReceives = kstat_get_ui32( ksp, "inReceives" );
- stats->dwInHdrErrors = kstat_get_ui32( ksp, "inHdrErrors" );
- stats->dwInAddrErrors = kstat_get_ui32( ksp, "inAddrErrors" );
- stats->dwForwDatagrams = kstat_get_ui32( ksp, "forwDatagrams" );
- stats->dwInUnknownProtos = kstat_get_ui32( ksp, "inUnknownProtos" );
- stats->dwInDiscards = kstat_get_ui32( ksp, "inDiscards" );
- stats->dwInDelivers = kstat_get_ui32( ksp, "inDelivers" );
- stats->dwOutRequests = kstat_get_ui32( ksp, "outRequests" );
- stats->dwRoutingDiscards = kstat_get_ui32( ksp, "routingDiscards" );
- stats->dwOutDiscards = kstat_get_ui32( ksp, "outDiscards" );
- stats->dwOutNoRoutes = kstat_get_ui32( ksp, "outNoRoutes" );
- stats->dwReasmTimeout = kstat_get_ui32( ksp, "reasmTimeout" );
- stats->dwReasmReqds = kstat_get_ui32( ksp, "reasmReqds" );
- stats->dwReasmOks = kstat_get_ui32( ksp, "reasmOKs" );
- stats->dwReasmFails = kstat_get_ui32( ksp, "reasmFails" );
- stats->dwFragOks = kstat_get_ui32( ksp, "fragOKs" );
- stats->dwFragFails = kstat_get_ui32( ksp, "fragFails" );
- stats->dwFragCreates = kstat_get_ui32( ksp, "fragCreates" );
- ret = NO_ERROR;
- }
- if (kc) kstat_close( kc );
- }
-#elif defined(HAVE_SYS_SYSCTL_H) && defined(IPCTL_STATS) && (defined(HAVE_STRUCT_IPSTAT_IPS_TOTAL) || defined(HAVE_STRUCT_IP_STATS_IPS_TOTAL))
- {
- int mib[] = {CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS};
- int ip_ttl, ip_forwarding;
-#if defined(HAVE_STRUCT_IPSTAT_IPS_TOTAL)
- struct ipstat ip_stat;
-#elif defined(HAVE_STRUCT_IP_STATS_IPS_TOTAL)
- struct ip_stats ip_stat;
-#endif
- size_t needed;
-
- needed = sizeof(ip_stat);
- if(sysctl(mib, ARRAY_SIZE(mib), &ip_stat, &needed, NULL, 0) == -1)
- {
- ERR ("failed to get ipstat\n");
- return ERROR_NOT_SUPPORTED;
- }
-
- needed = sizeof(ip_ttl);
- if (sysctlbyname ("net.inet.ip.ttl", &ip_ttl, &needed, NULL, 0) == -1)
- {
- ERR ("failed to get ip Default TTL\n");
- return ERROR_NOT_SUPPORTED;
- }
-
- needed = sizeof(ip_forwarding);
- if (sysctlbyname ("net.inet.ip.forwarding", &ip_forwarding, &needed, NULL, 0) == -1)
- {
- ERR ("failed to get ip forwarding\n");
- return ERROR_NOT_SUPPORTED;
- }
-
- /* ip.forwarding is 0 or 1 on BSD */
- stats->u.dwForwarding = ip_forwarding+1;
- stats->dwDefaultTTL = ip_ttl;
- stats->dwInReceives = ip_stat.ips_total;
- stats->dwInHdrErrors = ip_stat.ips_badhlen + ip_stat.ips_badsum + ip_stat.ips_tooshort + ip_stat.ips_badlen +
- ip_stat.ips_badvers + ip_stat.ips_badoptions;
- /* ips_badaddr also includes outgoing packets with a bad address, but we can't account for that right now */
- stats->dwInAddrErrors = ip_stat.ips_cantforward + ip_stat.ips_badaddr + ip_stat.ips_notmember;
- stats->dwForwDatagrams = ip_stat.ips_forward;
- stats->dwInUnknownProtos = ip_stat.ips_noproto;
- stats->dwInDiscards = ip_stat.ips_fragdropped;
- stats->dwInDelivers = ip_stat.ips_delivered;
- stats->dwOutRequests = ip_stat.ips_localout;
- /*stats->dwRoutingDiscards = 0;*/ /* FIXME */
- stats->dwOutDiscards = ip_stat.ips_odropped;
- stats->dwOutNoRoutes = ip_stat.ips_noroute;
- stats->dwReasmTimeout = ip_stat.ips_fragtimeout;
- stats->dwReasmReqds = ip_stat.ips_fragments;
- stats->dwReasmOks = ip_stat.ips_reassembled;
- stats->dwReasmFails = ip_stat.ips_fragments - ip_stat.ips_reassembled;
- stats->dwFragOks = ip_stat.ips_fragmented;
- stats->dwFragFails = ip_stat.ips_cantfrag;
- stats->dwFragCreates = ip_stat.ips_ofragments;
- ret = NO_ERROR;
- }
-#else
- FIXME( "unimplemented for IPv4\n" );
-#endif
- return ret;
-}
-
-/******************************************************************
- * GetIpStatistics (IPHLPAPI.@)
- *
- * Get the IP statistics for the local computer.
- *
- * PARAMS
- * stats [Out] buffer for IP statistics
- *
- * RETURNS
- * Success: NO_ERROR
- * Failure: error code from winerror.h
- */
-DWORD WINAPI GetIpStatistics(PMIB_IPSTATS stats)
-{
- return GetIpStatisticsEx(stats, WS_AF_INET);
-}
-
/******************************************************************
* GetTcpStatisticsEx (IPHLPAPI.@)
*
diff --git a/dlls/nsi/tests/nsi.c b/dlls/nsi/tests/nsi.c
index 598e7124afd..7d9d8e12bac 100644
--- a/dlls/nsi/tests/nsi.c
+++ b/dlls/nsi/tests/nsi.c
@@ -436,14 +436,10 @@ static void test_ip_cmpt( int family )
ok( !err, "got %d\n", err );
if (err) goto err;
-todo_wine_if(family == AF_INET6 && table.dwForwarding - 1 != rw.not_forwarding)
ok( table.dwForwarding - 1 == rw.not_forwarding, "%x vs %x\n", table.dwForwarding, rw.not_forwarding );
-todo_wine_if(family == AF_INET6 && table.dwDefaultTTL != rw.default_ttl)
ok( table.dwDefaultTTL == rw.default_ttl, "%x vs %x\n", table.dwDefaultTTL, rw.default_ttl );
ok( table.dwNumIf == dyn.num_ifs, "%x vs %x\n", table.dwNumIf, dyn.num_ifs );
-todo_wine_if(table.dwNumAddr != dyn.num_addrs)
ok( table.dwNumAddr == dyn.num_addrs, "%x vs %x\n", table.dwNumAddr, dyn.num_addrs );
-todo_wine_if(family == AF_INET6 && table.dwNumRoutes != dyn.num_routes)
ok( table.dwNumRoutes == dyn.num_routes, "%x vs %x\n", table.dwNumRoutes, dyn.num_routes );
err:
--
2.23.0
More information about the wine-devel
mailing list