Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
91494ae6
Commit
91494ae6
authored
Aug 11, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Aug 11, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iphlpapi: Implement GetIpStatisticsEx() on top of nsi.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
a7849502
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
82 additions
and
256 deletions
+82
-256
iphlpapi_main.c
dlls/iphlpapi/iphlpapi_main.c
+82
-0
ipstats.c
dlls/iphlpapi/ipstats.c
+0
-252
nsi.c
dlls/nsi/tests/nsi.c
+0
-4
No files found.
dlls/iphlpapi/iphlpapi_main.c
View file @
91494ae6
...
...
@@ -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,
...
...
dlls/iphlpapi/ipstats.c
View file @
91494ae6
...
...
@@ -618,258 +618,6 @@ DWORD WINAPI GetIcmpStatisticsEx(PMIB_ICMP_EX stats, DWORD family)
}
/******************************************************************
* 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.@)
*
* Get the IPv4 and IPv6 TCP statistics for the local computer.
...
...
dlls/nsi/tests/nsi.c
View file @
91494ae6
...
...
@@ -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:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment