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
40a60061
Commit
40a60061
authored
Aug 17, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Aug 17, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nsiproxy: Add support for IPv6 scope ids.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
14fc7647
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
132 additions
and
6 deletions
+132
-6
nsi.c
dlls/nsi/tests/nsi.c
+0
-2
tcp.c
dlls/nsiproxy.sys/tcp.c
+132
-4
No files found.
dlls/nsi/tests/nsi.c
View file @
40a60061
...
...
@@ -916,14 +916,12 @@ todo_wine_if( !unstable(0) && row->dwOwningPid )
{
ok
(
unstable
(
!
memcmp
(
row6
->
ucLocalAddr
,
keys
[
i
].
local
.
Ipv6
.
sin6_addr
.
s6_addr
,
sizeof
(
IN6_ADDR
)
)
),
"mismatch
\n
"
);
todo_wine_if
(
!
unstable
(
0
)
&&
row6
->
dwLocalScopeId
)
ok
(
unstable
(
row6
->
dwLocalScopeId
==
keys
[
i
].
local
.
Ipv6
.
sin6_scope_id
),
"%x vs %x
\n
"
,
row6
->
dwLocalScopeId
,
keys
[
i
].
local
.
Ipv6
.
sin6_scope_id
);
ok
(
unstable
(
row6
->
dwLocalPort
==
keys
[
i
].
local
.
Ipv6
.
sin6_port
),
"%d vs %d
\n
"
,
row6
->
dwLocalPort
,
keys
[
i
].
local
.
Ipv6
.
sin6_port
);
ok
(
unstable
(
!
memcmp
(
row6
->
ucRemoteAddr
,
keys
[
i
].
remote
.
Ipv6
.
sin6_addr
.
s6_addr
,
sizeof
(
IN6_ADDR
)
)
),
"mismatch
\n
"
);
todo_wine_if
(
!
unstable
(
0
)
&&
row6
->
dwRemoteScopeId
)
ok
(
unstable
(
row6
->
dwRemoteScopeId
==
keys
[
i
].
remote
.
Ipv6
.
sin6_scope_id
),
"%x vs %x
\n
"
,
row6
->
dwRemoteScopeId
,
keys
[
i
].
remote
.
Ipv6
.
sin6_scope_id
);
ok
(
unstable
(
row6
->
dwRemotePort
==
keys
[
i
].
remote
.
Ipv6
.
sin6_port
),
"%d vs %d
\n
"
,
...
...
dlls/nsiproxy.sys/tcp.c
View file @
40a60061
...
...
@@ -54,6 +54,10 @@
#include <sys/sysctl.h>
#endif
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h>
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
...
...
@@ -209,6 +213,119 @@ static inline MIB_TCP_STATE tcp_state_to_mib_state( int state )
}
}
struct
ipv6_addr_scope
{
IN6_ADDR
addr
;
DWORD
scope
;
};
static
struct
ipv6_addr_scope
*
get_ipv6_addr_scope_table
(
unsigned
int
*
size
)
{
struct
ipv6_addr_scope
*
table
=
NULL
;
unsigned
int
table_size
=
0
,
num
=
0
;
#ifdef __linux__
{
char
buf
[
512
],
*
ptr
;
FILE
*
fp
;
if
(
!
(
fp
=
fopen
(
"/proc/net/if_inet6"
,
"r"
)))
goto
failed
;
while
((
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
)))
{
WORD
a
[
8
];
DWORD
scope
;
struct
ipv6_addr_scope
*
entry
;
unsigned
int
i
;
if
(
sscanf
(
ptr
,
"%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx %*s %*s %x"
,
a
,
a
+
1
,
a
+
2
,
a
+
3
,
a
+
4
,
a
+
5
,
a
+
6
,
a
+
7
,
&
scope
)
!=
9
)
continue
;
if
(
++
num
>
table_size
)
{
if
(
!
table_size
)
table_size
=
4
;
else
table_size
*=
2
;
if
(
!
(
table
=
heap_realloc
(
table
,
table_size
*
sizeof
(
table
[
0
])
)))
{
fclose
(
fp
);
goto
failed
;
}
}
entry
=
table
+
num
-
1
;
for
(
i
=
0
;
i
<
8
;
i
++
)
entry
->
addr
.
u
.
Word
[
i
]
=
htons
(
a
[
i
]
);
entry
->
scope
=
htons
(
scope
);
}
fclose
(
fp
);
}
#elif defined(HAVE_GETIFADDRS)
{
struct
ifaddrs
*
addrs
,
*
cur
;
if
(
getifaddrs
(
&
addrs
)
==
-
1
)
goto
failed
;
for
(
cur
=
addrs
;
cur
;
cur
=
cur
->
ifa_next
)
{
struct
sockaddr_in6
*
sin6
;
struct
ipv6_addr_scope
*
entry
;
if
(
cur
->
ifa_addr
->
sa_family
!=
AF_INET6
)
continue
;
if
(
++
num
>
table_size
)
{
if
(
!
table_size
)
table_size
=
4
;
else
table_size
*=
2
;
if
(
!
(
table
=
heap_realloc
(
table
,
table_size
*
sizeof
(
table
[
0
])
)))
{
freeifaddrs
(
addrs
);
goto
failed
;
}
}
sin6
=
(
struct
sockaddr_in6
*
)
cur
->
ifa_addr
;
entry
=
table
+
num
-
1
;
memcpy
(
&
entry
->
addr
,
&
sin6
->
sin6_addr
,
sizeof
(
entry
->
addr
)
);
entry
->
scope
=
sin6
->
sin6_scope_id
;
}
freeifaddrs
(
addrs
);
}
#else
FIXME
(
"not implemented
\n
"
);
goto
failed
;
#endif
*
size
=
num
;
return
table
;
failed:
heap_free
(
table
);
return
NULL
;
}
static
DWORD
find_ipv6_addr_scope
(
const
IN6_ADDR
*
addr
,
const
struct
ipv6_addr_scope
*
table
,
unsigned
int
size
)
{
const
BYTE
multicast_scope_mask
=
0x0F
;
const
BYTE
multicast_scope_shift
=
0
;
unsigned
int
i
;
if
(
WS_IN6_IS_ADDR_UNSPECIFIED
(
addr
))
return
0
;
if
(
WS_IN6_IS_ADDR_MULTICAST
(
addr
))
return
htons
(
(
addr
->
u
.
Byte
[
1
]
&
multicast_scope_mask
)
>>
multicast_scope_shift
);
if
(
!
table
)
return
-
1
;
for
(
i
=
0
;
i
<
size
;
i
++
)
if
(
!
memcmp
(
&
table
[
i
].
addr
,
addr
,
sizeof
(
table
[
i
].
addr
)
))
return
table
[
i
].
scope
;
return
-
1
;
}
static
NTSTATUS
tcp_conns_enumerate_all
(
DWORD
filter
,
struct
nsi_tcp_conn_key
*
key_data
,
DWORD
key_size
,
void
*
rw
,
DWORD
rw_size
,
struct
nsi_tcp_conn_dynamic
*
dynamic_data
,
DWORD
dynamic_size
,
...
...
@@ -220,6 +337,8 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key *
struct
nsi_tcp_conn_key
key
;
struct
nsi_tcp_conn_dynamic
dyn
;
struct
nsi_tcp_conn_static
stat
;
struct
ipv6_addr_scope
*
addr_scopes
=
NULL
;
unsigned
int
addr_scopes_size
=
0
;
#ifdef __linux__
{
...
...
@@ -269,6 +388,8 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key *
memset
(
&
dyn
,
0
,
sizeof
(
dyn
)
);
memset
(
&
stat
,
0
,
sizeof
(
stat
)
);
addr_scopes
=
get_ipv6_addr_scope_table
(
&
addr_scopes_size
);
/* skip header line */
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
);
while
((
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
)))
...
...
@@ -286,8 +407,10 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key *
key
.
local
.
Ipv6
.
sin6_family
=
key
.
remote
.
Ipv6
.
sin6_family
=
WS_AF_INET6
;
key
.
local
.
Ipv6
.
sin6_port
=
htons
(
key
.
local
.
Ipv6
.
sin6_port
);
key
.
remote
.
Ipv6
.
sin6_port
=
htons
(
key
.
remote
.
Ipv6
.
sin6_port
);
key
.
local
.
Ipv6
.
sin6_scope_id
=
0
;
/* FIXME */
key
.
remote
.
Ipv6
.
sin6_scope_id
=
0
;
/* FIXME */
key
.
local
.
Ipv6
.
sin6_scope_id
=
find_ipv6_addr_scope
(
&
key
.
local
.
Ipv6
.
sin6_addr
,
addr_scopes
,
addr_scopes_size
);
key
.
remote
.
Ipv6
.
sin6_scope_id
=
find_ipv6_addr_scope
(
&
key
.
remote
.
Ipv6
.
sin6_addr
,
addr_scopes
,
addr_scopes_size
);
stat
.
pid
=
0
;
/* FIXME */
stat
.
create_time
=
0
;
/* FIXME */
...
...
@@ -335,6 +458,8 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key *
/* Might be nothing here; first entry is just a header it seems */
if
(
len
<=
sizeof
(
struct
xinpgen
))
goto
err
;
addr_scopes
=
get_ipv6_addr_scope_table
(
&
addr_scopes_size
);
orig_xig
=
(
struct
xinpgen
*
)
buf
;
xig
=
orig_xig
;
...
...
@@ -384,10 +509,12 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key *
key
.
local
.
Ipv6
.
sin6_family
=
key
.
remote
.
Ipv6
.
sin6_family
=
WS_AF_INET6
;
memcpy
(
&
key
.
local
.
Ipv6
.
sin6_addr
,
&
in
->
in6p_laddr
,
sizeof
(
in
->
in6p_laddr
)
);
key
.
local
.
Ipv6
.
sin6_port
=
in
->
inp_lport
;
key
.
local
.
Ipv6
.
sin6_scope_id
=
find_ipv6_addr_scope
(
&
key
.
local
.
Ipv6
.
sin6_addr
,
addr_scopes
,
addr_scopes_size
);
memcpy
(
&
key
.
remote
.
Ipv6
.
sin6_addr
,
&
in
->
in6p_faddr
,
sizeof
(
in
->
in6p_faddr
)
);
key
.
remote
.
Ipv6
.
sin6_port
=
in
->
inp_fport
;
key
.
local
.
Ipv6
.
sin6_scope_id
=
0
;
/* FIXME */
key
.
remote
.
Ipv6
.
sin6_scope_id
=
0
;
/* FIXME */
key
.
remote
.
Ipv6
.
sin6_scope_id
=
find_ipv6_addr_scope
(
&
key
.
remote
.
Ipv6
.
sin6_addr
,
addr_scopes
,
addr_scopes_size
);
}
stat
.
pid
=
0
;
/* FIXME */
...
...
@@ -413,6 +540,7 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key *
if
(
!
want_data
||
num
<=
*
count
)
*
count
=
num
;
else
status
=
STATUS_MORE_ENTRIES
;
heap_free
(
addr_scopes
);
return
status
;
}
...
...
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