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
1cc49258
Commit
1cc49258
authored
Aug 12, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Aug 12, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iphlpapi: Implement GetIcmpStatisticsEx() on top of nsi.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
cf434fa3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
36 additions
and
175 deletions
+36
-175
iphlpapi_main.c
dlls/iphlpapi/iphlpapi_main.c
+36
-0
ipstats.c
dlls/iphlpapi/ipstats.c
+0
-175
No files found.
dlls/iphlpapi/iphlpapi_main.c
View file @
1cc49258
...
...
@@ -1495,6 +1495,42 @@ DWORD WINAPI GetFriendlyIfIndex(DWORD IfIndex)
return
IfIndex
;
}
/******************************************************************
* GetIcmpStatisticsEx (IPHLPAPI.@)
*
* Get the IPv4 and IPv6 ICMP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for ICMP statistics
* family [In] specifies whether IPv4 or IPv6 statistics are returned
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetIcmpStatisticsEx
(
MIB_ICMP_EX
*
stats
,
DWORD
family
)
{
const
NPI_MODULEID
*
mod
=
ip_module_id
(
family
);
struct
nsi_ip_icmpstats_dynamic
dyn
;
DWORD
err
;
if
(
!
stats
||
!
mod
)
return
ERROR_INVALID_PARAMETER
;
memset
(
stats
,
0
,
sizeof
(
*
stats
)
);
err
=
NsiGetAllParameters
(
1
,
mod
,
NSI_IP_ICMPSTATS_TABLE
,
NULL
,
0
,
NULL
,
0
,
&
dyn
,
sizeof
(
dyn
),
NULL
,
0
);
if
(
err
)
return
err
;
stats
->
icmpInStats
.
dwMsgs
=
dyn
.
in_msgs
;
stats
->
icmpInStats
.
dwErrors
=
dyn
.
in_errors
;
memcpy
(
stats
->
icmpInStats
.
rgdwTypeCount
,
dyn
.
in_type_counts
,
sizeof
(
dyn
.
in_type_counts
)
);
stats
->
icmpOutStats
.
dwMsgs
=
dyn
.
out_msgs
;
stats
->
icmpOutStats
.
dwErrors
=
dyn
.
out_errors
;
memcpy
(
stats
->
icmpOutStats
.
rgdwTypeCount
,
dyn
.
out_type_counts
,
sizeof
(
dyn
.
out_type_counts
)
);
return
ERROR_SUCCESS
;
}
static
void
if_row_fill
(
MIB_IFROW
*
row
,
struct
nsi_ndis_ifinfo_rw
*
rw
,
struct
nsi_ndis_ifinfo_dynamic
*
dyn
,
struct
nsi_ndis_ifinfo_static
*
stat
)
{
...
...
dlls/iphlpapi/ipstats.c
View file @
1cc49258
...
...
@@ -447,181 +447,6 @@ DWORD WINAPI GetIcmpStatistics(PMIB_ICMP stats)
}
/******************************************************************
* GetIcmpStatisticsEx (IPHLPAPI.@)
*
* Get the IPv4 and IPv6 ICMP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for ICMP statistics
* family [In] specifies whether IPv4 or IPv6 statistics are returned
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetIcmpStatisticsEx
(
PMIB_ICMP_EX
stats
,
DWORD
family
)
{
DWORD
ret
=
ERROR_NOT_SUPPORTED
;
MIB_ICMP
ipv4stats
;
if
(
!
stats
)
return
ERROR_INVALID_PARAMETER
;
if
(
family
!=
WS_AF_INET
&&
family
!=
WS_AF_INET6
)
return
ERROR_INVALID_PARAMETER
;
memset
(
stats
,
0
,
sizeof
(
MIB_ICMP_EX
)
);
if
(
family
==
WS_AF_INET6
)
{
#ifdef __linux__
{
FILE
*
fp
;
if
((
fp
=
fopen
(
"/proc/net/snmp6"
,
"r"
)))
{
struct
icmpstatstruct
{
const
char
*
name
;
DWORD
pos
;
};
static
const
struct
icmpstatstruct
icmpinstatlist
[]
=
{
{
"Icmp6InDestUnreachs"
,
ICMP6_DST_UNREACH
},
{
"Icmp6InPktTooBigs"
,
ICMP6_PACKET_TOO_BIG
},
{
"Icmp6InTimeExcds"
,
ICMP6_TIME_EXCEEDED
},
{
"Icmp6InParmProblems"
,
ICMP6_PARAM_PROB
},
{
"Icmp6InEchos"
,
ICMP6_ECHO_REQUEST
},
{
"Icmp6InEchoReplies"
,
ICMP6_ECHO_REPLY
},
{
"Icmp6InGroupMembQueries"
,
ICMP6_MEMBERSHIP_QUERY
},
{
"Icmp6InGroupMembResponses"
,
ICMP6_MEMBERSHIP_REPORT
},
{
"Icmp6InGroupMembReductions"
,
ICMP6_MEMBERSHIP_REDUCTION
},
{
"Icmp6InRouterSolicits"
,
ND_ROUTER_SOLICIT
},
{
"Icmp6InRouterAdvertisements"
,
ND_ROUTER_ADVERT
},
{
"Icmp6InNeighborSolicits"
,
ND_NEIGHBOR_SOLICIT
},
{
"Icmp6InNeighborAdvertisements"
,
ND_NEIGHBOR_ADVERT
},
{
"Icmp6InRedirects"
,
ND_REDIRECT
},
{
"Icmp6InMLDv2Reports"
,
ICMP6_V2_MEMBERSHIP_REPORT
},
};
static
const
struct
icmpstatstruct
icmpoutstatlist
[]
=
{
{
"Icmp6OutDestUnreachs"
,
ICMP6_DST_UNREACH
},
{
"Icmp6OutPktTooBigs"
,
ICMP6_PACKET_TOO_BIG
},
{
"Icmp6OutTimeExcds"
,
ICMP6_TIME_EXCEEDED
},
{
"Icmp6OutParmProblems"
,
ICMP6_PARAM_PROB
},
{
"Icmp6OutEchos"
,
ICMP6_ECHO_REQUEST
},
{
"Icmp6OutEchoReplies"
,
ICMP6_ECHO_REPLY
},
{
"Icmp6OutGroupMembQueries"
,
ICMP6_MEMBERSHIP_QUERY
},
{
"Icmp6OutGroupMembResponses"
,
ICMP6_MEMBERSHIP_REPORT
},
{
"Icmp6OutGroupMembReductions"
,
ICMP6_MEMBERSHIP_REDUCTION
},
{
"Icmp6OutRouterSolicits"
,
ND_ROUTER_SOLICIT
},
{
"Icmp6OutRouterAdvertisements"
,
ND_ROUTER_ADVERT
},
{
"Icmp6OutNeighborSolicits"
,
ND_NEIGHBOR_SOLICIT
},
{
"Icmp6OutNeighborAdvertisements"
,
ND_NEIGHBOR_ADVERT
},
{
"Icmp6OutRedirects"
,
ND_REDIRECT
},
{
"Icmp6OutMLDv2Reports"
,
ICMP6_V2_MEMBERSHIP_REPORT
},
};
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'
;
if
(
!
_strnicmp
(
buf
,
"Icmp6InMsgs"
,
-
1
))
{
if
(
sscanf
(
value
,
"%d"
,
&
res
))
stats
->
icmpInStats
.
dwMsgs
=
res
;
continue
;
}
if
(
!
_strnicmp
(
buf
,
"Icmp6InErrors"
,
-
1
))
{
if
(
sscanf
(
value
,
"%d"
,
&
res
))
stats
->
icmpInStats
.
dwErrors
=
res
;
continue
;
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
icmpinstatlist
);
i
++
)
{
if
(
!
_strnicmp
(
buf
,
icmpinstatlist
[
i
].
name
,
-
1
))
{
if
(
sscanf
(
value
,
"%d"
,
&
res
))
stats
->
icmpInStats
.
rgdwTypeCount
[
icmpinstatlist
[
i
].
pos
]
=
res
;
break
;
}
}
if
(
!
_strnicmp
(
buf
,
"Icmp6OutMsgs"
,
-
1
))
{
if
(
sscanf
(
value
,
"%d"
,
&
res
))
stats
->
icmpOutStats
.
dwMsgs
=
res
;
continue
;
}
if
(
!
_strnicmp
(
buf
,
"Icmp6OutErrors"
,
-
1
))
{
if
(
sscanf
(
value
,
"%d"
,
&
res
))
stats
->
icmpOutStats
.
dwErrors
=
res
;
continue
;
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
icmpoutstatlist
);
i
++
)
{
if
(
!
_strnicmp
(
buf
,
icmpoutstatlist
[
i
].
name
,
-
1
))
{
if
(
sscanf
(
value
,
"%d"
,
&
res
))
stats
->
icmpOutStats
.
rgdwTypeCount
[
icmpoutstatlist
[
i
].
pos
]
=
res
;
break
;
}
}
}
fclose
(
fp
);
ret
=
NO_ERROR
;
}
}
#else
FIXME
(
"unimplemented for IPv6
\n
"
);
#endif
return
ret
;
}
ret
=
GetIcmpStatistics
(
&
ipv4stats
);
if
(
!
ret
)
{
stats
->
icmpInStats
.
dwMsgs
=
ipv4stats
.
stats
.
icmpInStats
.
dwMsgs
;
stats
->
icmpInStats
.
dwErrors
=
ipv4stats
.
stats
.
icmpInStats
.
dwErrors
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_DST_UNREACH
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwDestUnreachs
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_SOURCE_QUENCH
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwSrcQuenchs
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_REDIRECT
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwRedirects
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_ECHO_REQUEST
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwEchos
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_ECHO_REPLY
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwEchoReps
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_TIME_EXCEEDED
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwTimeExcds
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_PARAM_PROB
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwParmProbs
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_TIMESTAMP_REQUEST
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwTimestamps
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_TIMESTAMP_REPLY
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwTimestampReps
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_MASK_REQUEST
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwAddrMasks
;
stats
->
icmpInStats
.
rgdwTypeCount
[
ICMP4_MASK_REPLY
]
=
ipv4stats
.
stats
.
icmpInStats
.
dwAddrMaskReps
;
stats
->
icmpOutStats
.
dwMsgs
=
ipv4stats
.
stats
.
icmpOutStats
.
dwMsgs
;
stats
->
icmpOutStats
.
dwErrors
=
ipv4stats
.
stats
.
icmpOutStats
.
dwErrors
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_DST_UNREACH
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwDestUnreachs
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_SOURCE_QUENCH
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwSrcQuenchs
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_REDIRECT
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwRedirects
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_ECHO_REQUEST
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwEchos
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_ECHO_REPLY
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwEchoReps
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_TIME_EXCEEDED
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwTimeExcds
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_PARAM_PROB
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwParmProbs
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_TIMESTAMP_REQUEST
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwTimestamps
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_TIMESTAMP_REPLY
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwTimestampReps
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_MASK_REQUEST
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwAddrMasks
;
stats
->
icmpOutStats
.
rgdwTypeCount
[
ICMP4_MASK_REPLY
]
=
ipv4stats
.
stats
.
icmpOutStats
.
dwAddrMaskReps
;
}
return
ret
;
}
/******************************************************************
* GetTcpStatisticsEx (IPHLPAPI.@)
*
* Get the IPv4 and IPv6 TCP statistics for the local computer.
...
...
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