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
4716138d
Commit
4716138d
authored
Aug 13, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Aug 13, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iphlpapi: Implement GetTcpStatisticsEx() on top of nsi.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
c9680e89
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
64 additions
and
166 deletions
+64
-166
iphlpapi_main.c
dlls/iphlpapi/iphlpapi_main.c
+62
-0
ipstats.c
dlls/iphlpapi/ipstats.c
+0
-161
iphlpapi.c
dlls/iphlpapi/tests/iphlpapi.c
+2
-2
nsi.c
dlls/nsi/tests/nsi.c
+0
-3
No files found.
dlls/iphlpapi/iphlpapi_main.c
View file @
4716138d
...
...
@@ -2807,6 +2807,68 @@ BOOL WINAPI GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount, ULONG MaxHo
return
FALSE
;
}
/******************************************************************
* GetTcpStatistics (IPHLPAPI.@)
*
* Get the TCP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for TCP statistics
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetTcpStatistics
(
MIB_TCPSTATS
*
stats
)
{
return
GetTcpStatisticsEx
(
stats
,
WS_AF_INET
);
}
/******************************************************************
* GetTcpStatisticsEx (IPHLPAPI.@)
*
* Get the IPv4 and IPv6 TCP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for TCP statistics
* family [In] specifies whether IPv4 or IPv6 statistics are returned
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetTcpStatisticsEx
(
MIB_TCPSTATS
*
stats
,
DWORD
family
)
{
struct
nsi_tcp_stats_dynamic
dyn
;
struct
nsi_tcp_stats_static
stat
;
USHORT
key
=
(
USHORT
)
family
;
DWORD
err
;
if
(
!
stats
||
!
ip_module_id
(
family
))
return
ERROR_INVALID_PARAMETER
;
memset
(
stats
,
0
,
sizeof
(
*
stats
)
);
err
=
NsiGetAllParameters
(
1
,
&
NPI_MS_TCP_MODULEID
,
NSI_TCP_STATS_TABLE
,
&
key
,
sizeof
(
key
),
NULL
,
0
,
&
dyn
,
sizeof
(
dyn
),
&
stat
,
sizeof
(
stat
)
);
if
(
err
)
return
err
;
stats
->
u
.
RtoAlgorithm
=
stat
.
rto_algo
;
stats
->
dwRtoMin
=
stat
.
rto_min
;
stats
->
dwRtoMax
=
stat
.
rto_max
;
stats
->
dwMaxConn
=
stat
.
max_conns
;
stats
->
dwActiveOpens
=
dyn
.
active_opens
;
stats
->
dwPassiveOpens
=
dyn
.
passive_opens
;
stats
->
dwAttemptFails
=
dyn
.
attempt_fails
;
stats
->
dwEstabResets
=
dyn
.
est_rsts
;
stats
->
dwCurrEstab
=
dyn
.
cur_est
;
stats
->
dwInSegs
=
(
DWORD
)
dyn
.
in_segs
;
stats
->
dwOutSegs
=
(
DWORD
)
dyn
.
out_segs
;
stats
->
dwRetransSegs
=
dyn
.
retrans_segs
;
stats
->
dwInErrs
=
dyn
.
in_errs
;
stats
->
dwOutRsts
=
dyn
.
out_rsts
;
stats
->
dwNumConns
=
dyn
.
num_conns
;
return
err
;
}
/******************************************************************
* GetTcpTable (IPHLPAPI.@)
...
...
dlls/iphlpapi/ipstats.c
View file @
4716138d
...
...
@@ -277,167 +277,6 @@ static void *read_mib_entry( int fd, int level, int name, int *len )
#endif
/* HAVE_SYS_TIHDR_H && T_OPTMGMT_ACK */
/******************************************************************
* GetTcpStatisticsEx (IPHLPAPI.@)
*
* Get the IPv4 and IPv6 TCP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for TCP statistics
* family [In] specifies whether IPv4 or IPv6 statistics are returned
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetTcpStatisticsEx
(
PMIB_TCPSTATS
stats
,
DWORD
family
)
{
DWORD
ret
=
ERROR_NOT_SUPPORTED
;
if
(
!
stats
)
return
ERROR_INVALID_PARAMETER
;
if
(
family
!=
WS_AF_INET
&&
family
!=
WS_AF_INET6
)
return
ERROR_INVALID_PARAMETER
;
memset
(
stats
,
0
,
sizeof
(
*
stats
)
);
if
(
family
==
WS_AF_INET6
)
{
FIXME
(
"unimplemented for IPv6
\n
"
);
return
ret
;
}
#ifdef __linux__
{
FILE
*
fp
;
if
((
fp
=
fopen
(
"/proc/net/snmp"
,
"r"
)))
{
static
const
char
hdr
[]
=
"Tcp:"
;
MIB_TCPTABLE
*
tcp_table
;
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"
,
&
stats
->
u
.
dwRtoAlgorithm
,
&
stats
->
dwRtoMin
,
&
stats
->
dwRtoMax
,
&
stats
->
dwMaxConn
,
&
stats
->
dwActiveOpens
,
&
stats
->
dwPassiveOpens
,
&
stats
->
dwAttemptFails
,
&
stats
->
dwEstabResets
,
&
stats
->
dwCurrEstab
,
&
stats
->
dwInSegs
,
&
stats
->
dwOutSegs
,
&
stats
->
dwRetransSegs
,
&
stats
->
dwInErrs
,
&
stats
->
dwOutRsts
);
break
;
}
}
if
(
!
AllocateAndGetTcpTableFromStack
(
&
tcp_table
,
FALSE
,
GetProcessHeap
(),
0
))
{
stats
->
dwNumConns
=
tcp_table
->
dwNumEntries
;
HeapFree
(
GetProcessHeap
(),
0
,
tcp_table
);
}
fclose
(
fp
);
ret
=
NO_ERROR
;
}
}
#elif defined(HAVE_LIBKSTAT)
{
static
char
tcp
[]
=
"tcp"
;
kstat_ctl_t
*
kc
;
kstat_t
*
ksp
;
if
((
kc
=
kstat_open
())
&&
(
ksp
=
kstat_lookup
(
kc
,
tcp
,
0
,
tcp
))
&&
kstat_read
(
kc
,
ksp
,
NULL
)
!=
-
1
&&
ksp
->
ks_type
==
KSTAT_TYPE_NAMED
)
{
stats
->
u
.
dwRtoAlgorithm
=
kstat_get_ui32
(
ksp
,
"rtoAlgorithm"
);
stats
->
dwRtoMin
=
kstat_get_ui32
(
ksp
,
"rtoMin"
);
stats
->
dwRtoMax
=
kstat_get_ui32
(
ksp
,
"rtoMax"
);
stats
->
dwMaxConn
=
kstat_get_ui32
(
ksp
,
"maxConn"
);
stats
->
dwActiveOpens
=
kstat_get_ui32
(
ksp
,
"activeOpens"
);
stats
->
dwPassiveOpens
=
kstat_get_ui32
(
ksp
,
"passiveOpens"
);
stats
->
dwAttemptFails
=
kstat_get_ui32
(
ksp
,
"attemptFails"
);
stats
->
dwEstabResets
=
kstat_get_ui32
(
ksp
,
"estabResets"
);
stats
->
dwCurrEstab
=
kstat_get_ui32
(
ksp
,
"currEstab"
);
stats
->
dwInSegs
=
kstat_get_ui32
(
ksp
,
"inSegs"
);
stats
->
dwOutSegs
=
kstat_get_ui32
(
ksp
,
"outSegs"
);
stats
->
dwRetransSegs
=
kstat_get_ui32
(
ksp
,
"retransSegs"
);
stats
->
dwInErrs
=
kstat_get_ui32
(
ksp
,
"inErrs"
);
stats
->
dwOutRsts
=
kstat_get_ui32
(
ksp
,
"outRsts"
);
stats
->
dwNumConns
=
kstat_get_ui32
(
ksp
,
"connTableSize"
);
ret
=
NO_ERROR
;
}
if
(
kc
)
kstat_close
(
kc
);
}
#elif defined(HAVE_SYS_SYSCTL_H) && defined(TCPCTL_STATS) && (defined(HAVE_STRUCT_TCPSTAT_TCPS_CONNATTEMPT) || defined(HAVE_STRUCT_TCP_STATS_TCPS_CONNATTEMPT))
{
#ifndef TCPTV_MIN
/* got removed in Mac OS X for some reason */
#define TCPTV_MIN 2
#define TCPTV_REXMTMAX 128
#endif
int
mib
[]
=
{
CTL_NET
,
PF_INET
,
IPPROTO_TCP
,
TCPCTL_STATS
};
#define hz 1000
#if defined(HAVE_STRUCT_TCPSTAT_TCPS_CONNATTEMPT)
struct
tcpstat
tcp_stat
;
#elif defined(HAVE_STRUCT_TCP_STATS_TCPS_CONNATTEMPT)
struct
tcp_stats
tcp_stat
;
#endif
size_t
needed
=
sizeof
(
tcp_stat
);
if
(
sysctl
(
mib
,
ARRAY_SIZE
(
mib
),
&
tcp_stat
,
&
needed
,
NULL
,
0
)
!=
-
1
)
{
stats
->
u
.
RtoAlgorithm
=
MIB_TCP_RTO_VANJ
;
stats
->
dwRtoMin
=
TCPTV_MIN
;
stats
->
dwRtoMax
=
TCPTV_REXMTMAX
;
stats
->
dwMaxConn
=
-
1
;
stats
->
dwActiveOpens
=
tcp_stat
.
tcps_connattempt
;
stats
->
dwPassiveOpens
=
tcp_stat
.
tcps_accepts
;
stats
->
dwAttemptFails
=
tcp_stat
.
tcps_conndrops
;
stats
->
dwEstabResets
=
tcp_stat
.
tcps_drops
;
stats
->
dwCurrEstab
=
0
;
stats
->
dwInSegs
=
tcp_stat
.
tcps_rcvtotal
;
stats
->
dwOutSegs
=
tcp_stat
.
tcps_sndtotal
-
tcp_stat
.
tcps_sndrexmitpack
;
stats
->
dwRetransSegs
=
tcp_stat
.
tcps_sndrexmitpack
;
stats
->
dwInErrs
=
tcp_stat
.
tcps_rcvbadsum
+
tcp_stat
.
tcps_rcvbadoff
+
tcp_stat
.
tcps_rcvmemdrop
+
tcp_stat
.
tcps_rcvshort
;
stats
->
dwOutRsts
=
tcp_stat
.
tcps_sndctrl
-
tcp_stat
.
tcps_closed
;
stats
->
dwNumConns
=
tcp_stat
.
tcps_connects
;
ret
=
NO_ERROR
;
}
else
ERR
(
"failed to get tcpstat
\n
"
);
}
#else
FIXME
(
"unimplemented
\n
"
);
#endif
return
ret
;
}
/******************************************************************
* GetTcpStatistics (IPHLPAPI.@)
*
* Get the TCP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for TCP statistics
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetTcpStatistics
(
PMIB_TCPSTATS
stats
)
{
return
GetTcpStatisticsEx
(
stats
,
WS_AF_INET
);
}
/******************************************************************
* GetUdpStatistics (IPHLPAPI.@)
*
* Get the IPv4 and IPv6 UDP statistics for the local computer.
...
...
dlls/iphlpapi/tests/iphlpapi.c
View file @
4716138d
...
...
@@ -715,8 +715,8 @@ static void testGetTcpStatisticsEx(void)
}
apiReturn
=
GetTcpStatisticsEx
(
&
stats
,
AF_INET6
);
todo_wine
ok
(
apiReturn
==
NO_ERROR
||
broken
(
apiReturn
==
ERROR_NOT_SUPPORTED
),
"GetTcpStatisticsEx returned %d, expected NO_ERROR
\n
"
,
apiReturn
);
ok
(
apiReturn
==
NO_ERROR
||
broken
(
apiReturn
==
ERROR_NOT_SUPPORTED
),
"GetTcpStatisticsEx returned %d, expected NO_ERROR
\n
"
,
apiReturn
);
if
(
apiReturn
==
NO_ERROR
&&
winetest_debug
>
1
)
{
trace
(
"TCP IPv6 Ex stats:
\n
"
);
...
...
dlls/nsi/tests/nsi.c
View file @
4716138d
...
...
@@ -815,9 +815,7 @@ static void test_tcp_stats( int family )
ok
(
!
err
,
"got %x
\n
"
,
err
);
err
=
GetTcpStatisticsEx
(
&
table
,
family
);
todo_wine_if
(
family
==
AF_INET6
)
ok
(
!
err
,
"got %d
\n
"
,
err
);
if
(
err
)
goto
err
;
err
=
NsiGetAllParameters
(
1
,
&
NPI_MS_TCP_MODULEID
,
NSI_TCP_STATS_TABLE
,
&
key
,
sizeof
(
key
),
NULL
,
0
,
&
dyn2
,
sizeof
(
dyn
),
NULL
,
0
);
...
...
@@ -847,7 +845,6 @@ todo_wine_if(family == AF_INET6)
table
.
dwOutRsts
,
dyn
.
out_rsts
,
dyn2
.
out_rsts
);
ok
(
unstable
(
table
.
dwNumConns
==
dyn
.
num_conns
),
"%d vs %d
\n
"
,
table
.
dwNumConns
,
dyn
.
num_conns
);
err:
winetest_pop_context
();
}
...
...
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