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
57fe49f8
Commit
57fe49f8
authored
Apr 05, 2020
by
Chip Davis
Committed by
Alexandre Julliard
Apr 06, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iphlpapi: Implement GetTcp6Table() for Mac OS and FreeBSD.
Signed-off-by:
Chip Davis
<
cdavis@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
39464e86
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
165 additions
and
1 deletion
+165
-1
ipstats.c
dlls/iphlpapi/ipstats.c
+165
-1
No files found.
dlls/iphlpapi/ipstats.c
View file @
57fe49f8
...
...
@@ -139,6 +139,9 @@
#ifdef HAVE_LIBPROC_H
#include <libproc.h>
#endif
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h>
#endif
#ifndef ROUNDUP
#define ROUNDUP(a) \
...
...
@@ -2652,7 +2655,7 @@ static int compare_udp6_rows(const void *a, const void *b)
return
rowA
->
dwLocalPort
-
rowB
->
dwLocalPort
;
}
#if
def __linux__
#if
defined(__linux__) || (defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN))
struct
ipv6_addr_scope
{
IN6_ADDR
addr
;
...
...
@@ -2663,12 +2666,17 @@ static struct ipv6_addr_scope *get_ipv6_addr_scope_table(unsigned int *size)
{
struct
ipv6_addr_scope
*
table
=
NULL
;
unsigned
int
table_size
=
0
;
#ifdef __linux__
char
buf
[
512
],
*
ptr
;
FILE
*
fp
;
#elif defined(HAVE_GETIFADDRS)
struct
ifaddrs
*
addrs
,
*
cur
;
#endif
if
(
!
(
table
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
table
[
0
])
)))
return
NULL
;
#ifdef __linux__
if
(
!
(
fp
=
fopen
(
"/proc/net/if_inet6"
,
"r"
)))
goto
failed
;
...
...
@@ -2705,6 +2713,40 @@ static struct ipv6_addr_scope *get_ipv6_addr_scope_table(unsigned int *size)
}
fclose
(
fp
);
#elif defined(HAVE_GETIFADDRS)
if
(
getifaddrs
(
&
addrs
)
==
-
1
)
goto
failed
;
for
(
cur
=
addrs
;
cur
;
cur
=
cur
->
ifa_next
)
{
struct
sockaddr_in6
*
sin6
;
struct
ipv6_addr_scope
*
new_table
;
struct
ipv6_addr_scope
*
entry
;
if
(
cur
->
ifa_addr
->
sa_family
!=
AF_INET6
)
continue
;
sin6
=
(
struct
sockaddr_in6
*
)
cur
->
ifa_addr
;
table_size
++
;
if
(
!
(
new_table
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
table
,
table_size
*
sizeof
(
table
[
0
])
)))
{
freeifaddrs
(
addrs
);
goto
failed
;
}
table
=
new_table
;
entry
=
&
table
[
table_size
-
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
=
table_size
;
return
table
;
...
...
@@ -2822,6 +2864,128 @@ DWORD build_tcp6_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE
}
else
ret
=
ERROR_NOT_SUPPORTED
;
}
#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN)
{
static
const
char
zero
[
sizeof
(
IN6_ADDR
)]
=
{
0
};
MIB_TCP6ROW_OWNER_MODULE
row
;
size_t
len
=
0
;
char
*
buf
=
NULL
;
struct
xinpgen
*
xig
,
*
orig_xig
;
struct
pid_map
*
map
=
NULL
;
unsigned
num_entries
;
struct
ipv6_addr_scope
*
addr_scopes
=
NULL
;
unsigned
int
addr_scopes_size
=
0
;
if
(
sysctlbyname
(
"net.inet.tcp.pcblist"
,
NULL
,
&
len
,
NULL
,
0
)
<
0
)
{
ERR
(
"Failure to read net.inet.tcp.pcblist via sysctlbyname!
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
goto
done
;
}
buf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
if
(
!
buf
)
{
ret
=
ERROR_OUTOFMEMORY
;
goto
done
;
}
if
(
sysctlbyname
(
"net.inet.tcp.pcblist"
,
buf
,
&
len
,
NULL
,
0
)
<
0
)
{
ERR
(
"Failure to read net.inet.tcp.pcblist via sysctlbyname!
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
goto
done
;
}
addr_scopes
=
get_ipv6_addr_scope_table
(
&
addr_scopes_size
);
if
(
!
addr_scopes
)
{
ret
=
ERROR_OUTOFMEMORY
;
goto
done
;
}
if
(
class
>=
TCP_TABLE_OWNER_PID_LISTENER
)
map
=
get_pid_map
(
&
num_entries
);
/* Might be nothing here; first entry is just a header it seems */
if
(
len
<=
sizeof
(
struct
xinpgen
))
goto
done
;
orig_xig
=
(
struct
xinpgen
*
)
buf
;
xig
=
orig_xig
;
for
(
xig
=
(
struct
xinpgen
*
)((
char
*
)
xig
+
xig
->
xig_len
);
xig
->
xig_len
>
sizeof
(
struct
xinpgen
);
xig
=
(
struct
xinpgen
*
)((
char
*
)
xig
+
xig
->
xig_len
))
{
#if __FreeBSD_version >= 1200026
struct
xtcpcb
*
tcp
=
(
struct
xtcpcb
*
)
xig
;
struct
xinpcb
*
in
=
&
tcp
->
xt_inp
;
struct
xsocket
*
sock
=
&
in
->
xi_socket
;
#else
struct
tcpcb
*
tcp
=
&
((
struct
xtcpcb
*
)
xig
)
->
xt_tp
;
struct
inpcb
*
in
=
&
((
struct
xtcpcb
*
)
xig
)
->
xt_inp
;
struct
xsocket
*
sock
=
&
((
struct
xtcpcb
*
)
xig
)
->
xt_socket
;
#endif
/* Ignore sockets for other protocols */
if
(
sock
->
xso_protocol
!=
IPPROTO_TCP
)
continue
;
/* Ignore PCBs that were freed while generating the data */
if
(
in
->
inp_gencnt
>
orig_xig
->
xig_gen
)
continue
;
/* we're only interested in IPv6 addresses */
if
(
!
(
in
->
inp_vflag
&
INP_IPV6
)
||
(
in
->
inp_vflag
&
INP_IPV4
))
continue
;
/* If all 0's, skip it */
if
(
!
memcmp
(
&
in
->
in6p_laddr
,
zero
,
sizeof
(
zero
)
)
&&
!
in
->
inp_lport
&&
!
memcmp
(
&
in
->
in6p_faddr
,
zero
,
sizeof
(
zero
)
)
&&
!
in
->
inp_fport
)
continue
;
/* Fill in structure details */
memcpy
(
&
row
.
ucLocalAddr
,
&
in
->
in6p_laddr
.
s6_addr
,
sizeof
(
row
.
ucLocalAddr
)
);
row
.
dwLocalPort
=
in
->
inp_lport
;
row
.
dwLocalScopeId
=
find_ipv6_addr_scope
(
(
const
IN6_ADDR
*
)
&
row
.
ucLocalAddr
,
addr_scopes
,
addr_scopes_size
);
memcpy
(
&
row
.
ucRemoteAddr
,
&
in
->
in6p_faddr
.
s6_addr
,
sizeof
(
row
.
ucRemoteAddr
)
);
row
.
dwRemotePort
=
in
->
inp_fport
;
row
.
dwLocalScopeId
=
find_ipv6_addr_scope
(
(
const
IN6_ADDR
*
)
&
row
.
ucRemoteAddr
,
addr_scopes
,
addr_scopes_size
);
row
.
dwState
=
TCPStateToMIBState
(
tcp
->
t_state
);
if
(
!
match_class
(
class
,
row
.
dwState
))
continue
;
if
(
class
<=
TCP_TABLE_BASIC_ALL
)
{
/* MIB_TCP6ROW has a different field order */
MIB_TCP6ROW
basic_row
;
basic_row
.
State
=
row
.
dwState
;
memcpy
(
&
basic_row
.
LocalAddr
,
&
row
.
ucLocalAddr
,
sizeof
(
row
.
ucLocalAddr
)
);
basic_row
.
dwLocalScopeId
=
row
.
dwLocalScopeId
;
basic_row
.
dwLocalPort
=
row
.
dwLocalPort
;
memcpy
(
&
basic_row
.
RemoteAddr
,
&
row
.
ucRemoteAddr
,
sizeof
(
row
.
ucRemoteAddr
)
);
basic_row
.
dwRemoteScopeId
=
row
.
dwRemoteScopeId
;
basic_row
.
dwRemotePort
=
row
.
dwRemotePort
;
if
(
!
(
table
=
append_table_row
(
heap
,
flags
,
table
,
&
table_size
,
&
count
,
&
basic_row
,
row_size
)))
break
;
continue
;
}
row
.
dwOwningPid
=
find_owning_pid
(
map
,
num_entries
,
(
UINT_PTR
)
sock
->
so_pcb
);
if
(
class
>=
TCP_TABLE_OWNER_MODULE_LISTENER
)
{
row
.
liCreateTimestamp
.
QuadPart
=
0
;
/* FIXME */
memset
(
&
row
.
OwningModuleInfo
,
0
,
sizeof
(
row
.
OwningModuleInfo
)
);
}
if
(
!
(
table
=
append_table_row
(
heap
,
flags
,
table
,
&
table_size
,
&
count
,
&
row
,
row_size
)))
break
;
}
done:
HeapFree
(
GetProcessHeap
(),
0
,
map
);
HeapFree
(
GetProcessHeap
(),
0
,
buf
);
HeapFree
(
GetProcessHeap
(),
0
,
addr_scopes
);
}
#else
FIXME
(
"not implemented
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
...
...
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