Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
2f3fc13c
Commit
2f3fc13c
authored
Aug 11, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Aug 11, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nsiproxy: Implement IPv4 ipstats get_all_parameters.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
1e0f7d64
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
200 additions
and
0 deletions
+200
-0
nsi.c
dlls/nsi/tests/nsi.c
+50
-0
ip.c
dlls/nsiproxy.sys/ip.c
+115
-0
nsi.h
include/wine/nsi.h
+35
-0
No files found.
dlls/nsi/tests/nsi.c
View file @
2f3fc13c
...
...
@@ -411,6 +411,54 @@ static void test_ndis_index_luid( void )
ok
(
err
==
ERROR_FILE_NOT_FOUND
,
"got %d
\n
"
,
err
);
}
static
void
test_ip_ipstats
(
int
family
)
{
const
NPI_MODULEID
*
mod
=
(
family
==
AF_INET
)
?
&
NPI_MS_IPV4_MODULEID
:
&
NPI_MS_IPV6_MODULEID
;
struct
nsi_ip_ipstats_dynamic
dyn
,
dyn2
;
struct
nsi_ip_ipstats_static
stat
;
MIB_IPSTATS
table
;
DWORD
err
;
winetest_push_context
(
family
==
AF_INET
?
"AF_INET"
:
"AF_INET6"
);
/* The table appears to consist of a single object without a key. The rw data does exist but
isn't part of GetIpStatisticsEx() and isn't yet tested */
err
=
NsiGetAllParameters
(
1
,
mod
,
NSI_IP_IPSTATS_TABLE
,
NULL
,
0
,
NULL
,
0
,
&
dyn
,
sizeof
(
dyn
),
&
stat
,
sizeof
(
stat
)
);
todo_wine_if
(
family
==
AF_INET6
)
ok
(
!
err
,
"got %x
\n
"
,
err
);
if
(
err
)
goto
err
;
err
=
GetIpStatisticsEx
(
&
table
,
family
);
ok
(
!
err
,
"got %d
\n
"
,
err
);
err
=
NsiGetAllParameters
(
1
,
mod
,
NSI_IP_IPSTATS_TABLE
,
NULL
,
0
,
NULL
,
0
,
&
dyn2
,
sizeof
(
dyn2
),
NULL
,
0
);
ok
(
!
err
,
"got %x
\n
"
,
err
);
/* dwForwarding and dwDefaultTTL come from the compartment table */
ok
(
bounded
(
table
.
dwInReceives
,
dyn
.
in_recv
,
dyn2
.
in_recv
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwInHdrErrors
,
dyn
.
in_hdr_errs
,
dyn2
.
in_hdr_errs
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwInAddrErrors
,
dyn
.
in_addr_errs
,
dyn2
.
in_addr_errs
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwForwDatagrams
,
dyn
.
fwd_dgrams
,
dyn2
.
fwd_dgrams
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwInUnknownProtos
,
dyn
.
in_unk_protos
,
dyn2
.
in_unk_protos
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwInDiscards
,
dyn
.
in_discards
,
dyn2
.
in_discards
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwInDelivers
,
dyn
.
in_delivers
,
dyn2
.
in_delivers
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwOutRequests
,
dyn
.
out_reqs
,
dyn2
.
out_reqs
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwRoutingDiscards
,
dyn
.
routing_discards
,
dyn2
.
routing_discards
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwOutDiscards
,
dyn
.
out_discards
,
dyn2
.
out_discards
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwOutNoRoutes
,
dyn
.
out_no_routes
,
dyn2
.
out_no_routes
),
"mismatch
\n
"
);
ok
(
table
.
dwReasmTimeout
==
stat
.
reasm_timeout
,
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwReasmReqds
,
dyn
.
reasm_reqds
,
dyn2
.
reasm_reqds
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwReasmOks
,
dyn
.
reasm_oks
,
dyn2
.
reasm_oks
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwReasmFails
,
dyn
.
reasm_fails
,
dyn2
.
reasm_fails
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwFragOks
,
dyn
.
frag_oks
,
dyn2
.
frag_oks
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwFragFails
,
dyn
.
frag_fails
,
dyn2
.
frag_fails
),
"mismatch
\n
"
);
ok
(
bounded
(
table
.
dwFragCreates
,
dyn
.
frag_creates
,
dyn2
.
frag_creates
),
"mismatch
\n
"
);
/* dwNumIf, dwNumAddr and dwNumRoutes come from the compartment table */
err:
winetest_pop_context
();
}
static
void
test_ip_unicast
(
int
family
)
{
DWORD
rw_sizes
[]
=
{
FIELD_OFFSET
(
struct
nsi_ip_unicast_rw
,
unk
[
0
]),
FIELD_OFFSET
(
struct
nsi_ip_unicast_rw
,
unk
[
1
]),
...
...
@@ -678,6 +726,8 @@ START_TEST( nsi )
test_ndis_ifinfo
();
test_ndis_index_luid
();
test_ip_ipstats
(
AF_INET
);
test_ip_ipstats
(
AF_INET6
);
test_ip_unicast
(
AF_INET
);
test_ip_unicast
(
AF_INET6
);
test_ip_neighbour
(
AF_INET
);
...
...
dlls/nsiproxy.sys/ip.c
View file @
2f3fc13c
...
...
@@ -120,6 +120,112 @@ static ULONG64 get_boot_time( void )
return
ti
.
BootTime
.
QuadPart
;
}
static
NTSTATUS
ipv4_ipstats_get_all_parameters
(
const
void
*
key
,
DWORD
key_size
,
void
*
rw_data
,
DWORD
rw_size
,
void
*
dynamic_data
,
DWORD
dynamic_size
,
void
*
static_data
,
DWORD
static_size
)
{
struct
nsi_ip_ipstats_dynamic
dyn
;
struct
nsi_ip_ipstats_static
stat
;
TRACE
(
"%p %d %p %d %p %d %p %d
\n
"
,
key
,
key_size
,
rw_data
,
rw_size
,
dynamic_data
,
dynamic_size
,
static_data
,
static_size
);
memset
(
&
dyn
,
0
,
sizeof
(
dyn
)
);
memset
(
&
stat
,
0
,
sizeof
(
stat
)
);
#ifdef __linux__
{
NTSTATUS
status
=
STATUS_NOT_SUPPORTED
;
static
const
char
hdr
[]
=
"Ip:"
;
char
buf
[
512
],
*
ptr
;
FILE
*
fp
;
if
(
!
(
fp
=
fopen
(
"/proc/net/snmp"
,
"r"
)))
return
STATUS_NOT_SUPPORTED
;
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
))
{
DWORD
in_recv
,
in_hdr_errs
,
fwd_dgrams
,
in_delivers
,
out_reqs
;
ptr
+=
sizeof
(
hdr
);
sscanf
(
ptr
,
"%*u %*u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u"
,
&
in_recv
,
&
in_hdr_errs
,
&
dyn
.
in_addr_errs
,
&
fwd_dgrams
,
&
dyn
.
in_unk_protos
,
&
dyn
.
in_discards
,
&
in_delivers
,
&
out_reqs
,
&
dyn
.
out_discards
,
&
dyn
.
out_no_routes
,
&
stat
.
reasm_timeout
,
&
dyn
.
reasm_reqds
,
&
dyn
.
reasm_oks
,
&
dyn
.
reasm_fails
,
&
dyn
.
frag_oks
,
&
dyn
.
frag_fails
,
&
dyn
.
frag_creates
);
/* no routingDiscards */
dyn
.
in_recv
=
in_recv
;
dyn
.
in_hdr_errs
=
in_hdr_errs
;
dyn
.
fwd_dgrams
=
fwd_dgrams
;
dyn
.
in_delivers
=
in_delivers
;
dyn
.
out_reqs
=
out_reqs
;
if
(
dynamic_data
)
*
(
struct
nsi_ip_ipstats_dynamic
*
)
dynamic_data
=
dyn
;
if
(
static_data
)
*
(
struct
nsi_ip_ipstats_static
*
)
static_data
=
stat
;
status
=
STATUS_SUCCESS
;
break
;
}
}
fclose
(
fp
);
return
status
;
}
#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
};
#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
)
return
STATUS_NOT_SUPPORTED
;
dyn
.
in_recv
=
ip_stat
.
ips_total
;
dyn
.
in_hdr_errs
=
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 */
dyn
.
in_addr_errs
=
ip_stat
.
ips_cantforward
+
ip_stat
.
ips_badaddr
+
ip_stat
.
ips_notmember
;
dyn
.
fwd_dgrams
=
ip_stat
.
ips_forward
;
dyn
.
in_unk_protos
=
ip_stat
.
ips_noproto
;
dyn
.
in_discards
=
ip_stat
.
ips_fragdropped
;
dyn
.
in_delivers
=
ip_stat
.
ips_delivered
;
dyn
.
out_reqs
=
ip_stat
.
ips_localout
;
dyn
.
out_discards
=
ip_stat
.
ips_odropped
;
dyn
.
out_no_routes
=
ip_stat
.
ips_noroute
;
stat
.
reasm_timeout
=
ip_stat
.
ips_fragtimeout
;
dyn
.
reasm_reqds
=
ip_stat
.
ips_fragments
;
dyn
.
reasm_oks
=
ip_stat
.
ips_reassembled
;
dyn
.
reasm_fails
=
ip_stat
.
ips_fragments
-
ip_stat
.
ips_reassembled
;
dyn
.
frag_oks
=
ip_stat
.
ips_fragmented
;
dyn
.
frag_fails
=
ip_stat
.
ips_cantfrag
;
dyn
.
frag_creates
=
ip_stat
.
ips_ofragments
;
if
(
dynamic_data
)
*
(
struct
nsi_ip_ipstats_dynamic
*
)
dynamic_data
=
dyn
;
if
(
static_data
)
*
(
struct
nsi_ip_ipstats_static
*
)
static_data
=
stat
;
return
STATUS_SUCCESS
;
}
#else
FIXME
(
"not implemented
\n
"
);
return
STATUS_NOT_IMPLEMENTED
;
#endif
}
static
void
unicast_fill_entry
(
struct
ifaddrs
*
entry
,
void
*
key
,
struct
nsi_ip_unicast_rw
*
rw
,
struct
nsi_ip_unicast_dynamic
*
dyn
,
struct
nsi_ip_unicast_static
*
stat
)
{
...
...
@@ -688,6 +794,15 @@ static NTSTATUS ipv6_forward_enumerate_all( void *key_data, DWORD key_size, void
static
struct
module_table
ipv4_tables
[]
=
{
{
NSI_IP_IPSTATS_TABLE
,
{
0
,
0
,
sizeof
(
struct
nsi_ip_ipstats_dynamic
),
sizeof
(
struct
nsi_ip_ipstats_static
)
},
NULL
,
ipv4_ipstats_get_all_parameters
,
},
{
NSI_IP_UNICAST_TABLE
,
{
sizeof
(
struct
nsi_ipv4_unicast_key
),
sizeof
(
struct
nsi_ip_unicast_rw
),
...
...
include/wine/nsi.h
View file @
2f3fc13c
...
...
@@ -97,10 +97,45 @@ struct nsi_ndis_ifinfo_static
};
/* Undocumented NSI IP tables */
#define NSI_IP_IPSTATS_TABLE 6
#define NSI_IP_UNICAST_TABLE 10
#define NSI_IP_NEIGHBOUR_TABLE 11
#define NSI_IP_FORWARD_TABLE 16
struct
nsi_ip_ipstats_dynamic
{
DWORD
unk
[
4
];
ULONGLONG
in_recv
;
ULONGLONG
in_octets
;
ULONGLONG
fwd_dgrams
;
ULONGLONG
in_delivers
;
ULONGLONG
out_reqs
;
ULONGLONG
unk2
;
ULONGLONG
unk3
;
ULONGLONG
out_octets
;
ULONGLONG
unk4
[
6
];
ULONGLONG
in_hdr_errs
;
DWORD
in_addr_errs
;
DWORD
in_unk_protos
;
DWORD
unk5
;
DWORD
reasm_reqds
;
DWORD
reasm_oks
;
DWORD
reasm_fails
;
DWORD
in_discards
;
DWORD
out_no_routes
;
DWORD
out_discards
;
DWORD
routing_discards
;
DWORD
frag_oks
;
DWORD
frag_fails
;
DWORD
frag_creates
;
DWORD
unk6
[
7
];
};
struct
nsi_ip_ipstats_static
{
DWORD
reasm_timeout
;
};
struct
nsi_ipv4_unicast_key
{
NET_LUID
luid
;
...
...
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