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
d6278ea0
Commit
d6278ea0
authored
Aug 18, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Aug 18, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nsiproxy: Implement UDP stats get_all_parameters.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ec0cf434
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
175 additions
and
0 deletions
+175
-0
nsi.c
dlls/nsi/tests/nsi.c
+36
-0
udp.c
dlls/nsiproxy.sys/udp.c
+128
-0
nsi.h
include/wine/nsi.h
+11
-0
No files found.
dlls/nsi/tests/nsi.c
View file @
d6278ea0
...
...
@@ -938,6 +938,40 @@ static void test_tcp_tables( int family, int table_type )
winetest_pop_context
();
}
static
void
test_udp_stats
(
int
family
)
{
DWORD
err
;
USHORT
key
=
family
;
struct
nsi_udp_stats_dynamic
dyn
,
dyn2
;
MIB_UDPSTATS
table
;
winetest_push_context
(
family
==
AF_INET
?
"AF_INET"
:
"AF_INET6"
);
err
=
NsiGetAllParameters
(
1
,
&
NPI_MS_UDP_MODULEID
,
NSI_UDP_STATS_TABLE
,
&
key
,
sizeof
(
key
),
NULL
,
0
,
&
dyn
,
sizeof
(
dyn
),
NULL
,
0
);
ok
(
!
err
,
"got %x
\n
"
,
err
);
err
=
GetUdpStatisticsEx
(
&
table
,
family
);
ok
(
!
err
,
"got %d
\n
"
,
err
);
err
=
NsiGetAllParameters
(
1
,
&
NPI_MS_UDP_MODULEID
,
NSI_UDP_STATS_TABLE
,
&
key
,
sizeof
(
key
),
NULL
,
0
,
&
dyn2
,
sizeof
(
dyn2
),
NULL
,
0
);
ok
(
!
err
,
"got %x
\n
"
,
err
);
ok
(
bounded
(
table
.
dwInDatagrams
,
dyn
.
in_dgrams
,
dyn2
.
in_dgrams
),
"%d vs [%I64d %I64d]
\n
"
,
table
.
dwInDatagrams
,
dyn
.
in_dgrams
,
dyn2
.
in_dgrams
);
ok
(
bounded
(
table
.
dwNoPorts
,
dyn
.
no_ports
,
dyn2
.
no_ports
),
"%d vs [%d %d]
\n
"
,
table
.
dwNoPorts
,
dyn
.
no_ports
,
dyn2
.
no_ports
);
ok
(
bounded
(
table
.
dwInErrors
,
dyn
.
in_errs
,
dyn2
.
in_errs
),
"%d vs [%d %d]
\n
"
,
table
.
dwInErrors
,
dyn
.
in_errs
,
dyn2
.
in_errs
);
ok
(
bounded
(
table
.
dwOutDatagrams
,
dyn
.
out_dgrams
,
dyn2
.
out_dgrams
),
"%d vs [%I64d %I64d]
\n
"
,
table
.
dwOutDatagrams
,
dyn
.
out_dgrams
,
dyn2
.
out_dgrams
);
todo_wine_if
(
!
unstable
(
0
)
&&
table
.
dwNumAddrs
!=
dyn
.
num_addrs
)
ok
(
unstable
(
table
.
dwNumAddrs
==
dyn
.
num_addrs
),
"%d %d
\n
"
,
table
.
dwNumAddrs
,
dyn
.
num_addrs
);
winetest_pop_context
();
}
static
void
test_udp_tables
(
int
family
)
{
DWORD
i
,
err
,
count
,
size
;
...
...
@@ -1030,6 +1064,8 @@ START_TEST( nsi )
test_tcp_tables
(
AF_INET6
,
TCP_TABLE_OWNER_MODULE_CONNECTIONS
);
test_tcp_tables
(
AF_INET6
,
TCP_TABLE_OWNER_MODULE_LISTENER
);
test_udp_stats
(
AF_INET
);
test_udp_stats
(
AF_INET6
);
test_udp_tables
(
AF_INET
);
test_udp_tables
(
AF_INET6
);
}
dlls/nsiproxy.sys/udp.c
View file @
d6278ea0
...
...
@@ -73,6 +73,125 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
nsi
);
static
DWORD
udp_num_addrs
(
USHORT
family
)
{
DWORD
endpoint_count
=
0
;
nsi_enumerate_all
(
1
,
0
,
&
NPI_MS_UDP_MODULEID
,
NSI_UDP_ENDPOINT_TABLE
,
NULL
,
0
,
NULL
,
0
,
NULL
,
0
,
NULL
,
0
,
&
endpoint_count
);
/* FIXME: actually retrieve the keys and only count endpoints which match family */
return
endpoint_count
;
}
static
NTSTATUS
udp_stats_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_udp_stats_dynamic
dyn
;
const
USHORT
*
family
=
key
;
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
);
if
(
*
family
!=
WS_AF_INET
&&
*
family
!=
WS_AF_INET6
)
return
STATUS_NOT_SUPPORTED
;
memset
(
&
dyn
,
0
,
sizeof
(
dyn
)
);
dyn
.
num_addrs
=
udp_num_addrs
(
*
family
);
#ifdef __linux__
if
(
*
family
==
WS_AF_INET
)
{
NTSTATUS
status
=
STATUS_NOT_SUPPORTED
;
static
const
char
hdr
[]
=
"Udp:"
;
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
))
{
unsigned
int
in_dgrams
,
out_dgrams
;
ptr
+=
sizeof
(
hdr
);
sscanf
(
ptr
,
"%u %u %u %u %u"
,
&
in_dgrams
,
&
dyn
.
no_ports
,
&
dyn
.
in_errs
,
&
out_dgrams
,
&
dyn
.
num_addrs
);
dyn
.
in_dgrams
=
in_dgrams
;
dyn
.
out_dgrams
=
out_dgrams
;
if
(
dynamic_data
)
*
(
struct
nsi_udp_stats_dynamic
*
)
dynamic_data
=
dyn
;
status
=
STATUS_SUCCESS
;
break
;
}
}
fclose
(
fp
);
return
status
;
}
else
{
unsigned
int
in_dgrams
=
0
,
out_dgrams
=
0
;
struct
{
const
char
*
name
;
DWORD
*
elem
;
}
udp_stat_list
[]
=
{
{
"Udp6InDatagrams"
,
&
in_dgrams
},
{
"Udp6NoPorts"
,
&
dyn
.
no_ports
},
{
"Udp6InErrors"
,
&
dyn
.
in_errs
},
{
"Udp6OutDatagrams"
,
&
out_dgrams
},
};
char
buf
[
512
],
*
ptr
,
*
value
;
DWORD
res
,
i
;
FILE
*
fp
;
if
(
!
(
fp
=
fopen
(
"/proc/net/snmp6"
,
"r"
)))
return
STATUS_NOT_SUPPORTED
;
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
(
udp_stat_list
);
i
++
)
if
(
!
_strnicmp
(
buf
,
udp_stat_list
[
i
].
name
,
-
1
)
&&
sscanf
(
value
,
"%d"
,
&
res
))
*
udp_stat_list
[
i
].
elem
=
res
;
}
dyn
.
in_dgrams
=
in_dgrams
;
dyn
.
out_dgrams
=
out_dgrams
;
if
(
dynamic_data
)
*
(
struct
nsi_udp_stats_dynamic
*
)
dynamic_data
=
dyn
;
fclose
(
fp
);
return
STATUS_SUCCESS
;
}
#elif defined(HAVE_SYS_SYSCTL_H) && defined(UDPCTL_STATS) && defined(HAVE_STRUCT_UDPSTAT_UDPS_IPACKETS)
{
int
mib
[]
=
{
CTL_NET
,
PF_INET
,
IPPROTO_UDP
,
UDPCTL_STATS
};
struct
udpstat
udp_stat
;
size_t
needed
=
sizeof
(
udp_stat
);
if
(
sysctl
(
mib
,
ARRAY_SIZE
(
mib
),
&
udp_stat
,
&
needed
,
NULL
,
0
)
==
-
1
)
return
STATUS_NOT_SUPPORTED
;
dyn
.
in_dgrams
=
udp_stat
.
udps_ipackets
;
dyn
.
out_dgrams
=
udp_stat
.
udps_opackets
;
dyn
.
no_ports
=
udp_stat
.
udps_noport
;
dyn
.
in_errs
=
udp_stat
.
udps_hdrops
+
udp_stat
.
udps_badsum
+
udp_stat
.
udps_fullsock
+
udp_stat
.
udps_badlen
;
if
(
dynamic_data
)
*
(
struct
nsi_udp_stats_dynamic
*
)
dynamic_data
=
dyn
;
return
STATUS_SUCCESS
;
}
#endif
FIXME
(
"Not implemented
\n
"
);
return
STATUS_NOT_SUPPORTED
;
}
static
NTSTATUS
udp_endpoint_enumerate_all
(
void
*
key_data
,
DWORD
key_size
,
void
*
rw_data
,
DWORD
rw_size
,
void
*
dynamic_data
,
DWORD
dynamic_size
,
void
*
static_data
,
DWORD
static_size
,
DWORD_PTR
*
count
)
...
...
@@ -272,6 +391,15 @@ static NTSTATUS udp_endpoint_enumerate_all( void *key_data, DWORD key_size, void
static
struct
module_table
udp_tables
[]
=
{
{
NSI_UDP_STATS_TABLE
,
{
sizeof
(
USHORT
),
0
,
sizeof
(
struct
nsi_udp_stats_dynamic
),
0
},
NULL
,
udp_stats_get_all_parameters
,
},
{
NSI_UDP_ENDPOINT_TABLE
,
{
sizeof
(
struct
nsi_udp_endpoint_key
),
0
,
...
...
include/wine/nsi.h
View file @
d6278ea0
...
...
@@ -347,8 +347,19 @@ struct nsi_tcp_conn_static
};
/* Undocumented NSI UDP tables */
#define NSI_UDP_STATS_TABLE 0
#define NSI_UDP_ENDPOINT_TABLE 1
struct
nsi_udp_stats_dynamic
{
ULONGLONG
in_dgrams
;
DWORD
no_ports
;
DWORD
in_errs
;
ULONGLONG
out_dgrams
;
DWORD
num_addrs
;
DWORD
unk
[
5
];
};
struct
nsi_udp_endpoint_key
{
SOCKADDR_INET
local
;
...
...
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