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
566079d4
Commit
566079d4
authored
Aug 18, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Aug 18, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iphlpapi: Implement GetExtendedUdpTable() on top of nsi.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7841c8af
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
175 additions
and
433 deletions
+175
-433
iphlpapi_main.c
dlls/iphlpapi/iphlpapi_main.c
+175
-50
ipstats.c
dlls/iphlpapi/ipstats.c
+0
-350
ipstats.h
dlls/iphlpapi/ipstats.h
+0
-33
No files found.
dlls/iphlpapi/iphlpapi_main.c
View file @
566079d4
...
...
@@ -43,7 +43,6 @@
#include "windns.h"
#include "iphlpapi.h"
#include "ifenum.h"
#include "ipstats.h"
#include "ipifcons.h"
#include "fltdefs.h"
#include "ifdef.h"
...
...
@@ -3289,81 +3288,207 @@ DWORD WINAPI AllocateAndGetTcpExTableFromStack( void **table, BOOL sort, HANDLE
* Get a table of active UDP connections.
*
* PARAMS
* pUdpTable [Out] buffer for UDP connections table
* pdwSize [In/Out] length of output buffer
* bOrder [In] whether to order the table
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
* table [Out] buffer for UDP connections table
* size [In/Out] length of output buffer
* sort [In] whether to order the table
*
* NOTES
* If pdwSize is less than required, the function will return
* ERROR_INSUFFICIENT_BUFFER, and *pdwSize will be set to the
* required byte size.
* If bOrder is true, the returned table will be sorted, first by
* local address, then by local port number.
*/
DWORD
WINAPI
GetUdpTable
(
PMIB_UDPTABLE
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
)
DWORD
WINAPI
GetUdpTable
(
MIB_UDPTABLE
*
table
,
DWORD
*
size
,
BOOL
sort
)
{
return
GetExtendedUdpTable
(
pUdpTable
,
pdwSize
,
bOrder
,
WS_AF_INET
,
UDP_TABLE_BASIC
,
0
);
return
GetExtendedUdpTable
(
table
,
size
,
sort
,
WS_AF_INET
,
UDP_TABLE_BASIC
,
0
);
}
/******************************************************************
* GetUdp6Table (IPHLPAPI.@)
*/
DWORD
WINAPI
GetUdp6Table
(
PMIB_UDP6TABLE
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
)
DWORD
WINAPI
GetUdp6Table
(
MIB_UDP6TABLE
*
table
,
DWORD
*
size
,
BOOL
sort
)
{
return
GetExtendedUdpTable
(
pUdpTable
,
pdwSize
,
bOrder
,
WS_AF_INET6
,
UDP_TABLE_BASIC
,
0
);
return
GetExtendedUdpTable
(
table
,
size
,
sort
,
WS_AF_INET6
,
UDP_TABLE_BASIC
,
0
);
}
/******************************************************************
* GetExtendedUdpTable (IPHLPAPI.@)
*/
DWORD
WINAPI
GetExtendedUdpTable
(
PVOID
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
,
ULONG
ulAf
,
UDP_TABLE_CLASS
TableClass
,
ULONG
Reserved
)
static
DWORD
udp_table_size
(
ULONG
family
,
ULONG
table_class
,
DWORD
row_count
,
DWORD
*
row_size
)
{
DWORD
ret
,
size
;
void
*
table
;
switch
(
table_class
)
{
case
UDP_TABLE_BASIC
:
*
row_size
=
(
family
==
WS_AF_INET
)
?
sizeof
(
MIB_UDPROW
)
:
sizeof
(
MIB_UDP6ROW
);
return
(
family
==
WS_AF_INET
)
?
FIELD_OFFSET
(
MIB_UDPTABLE
,
table
[
row_count
])
:
FIELD_OFFSET
(
MIB_UDP6TABLE
,
table
[
row_count
]);
TRACE
(
"pUdpTable %p, pdwSize %p, bOrder %d, ulAf %u, TableClass %u, Reserved %u
\n
"
,
pUdpTable
,
pdwSize
,
bOrder
,
ulAf
,
TableClass
,
Reserved
);
case
UDP_TABLE_OWNER_PID
:
*
row_size
=
(
family
==
WS_AF_INET
)
?
sizeof
(
MIB_UDPROW_OWNER_PID
)
:
sizeof
(
MIB_UDP6ROW_OWNER_PID
);
return
(
family
==
WS_AF_INET
)
?
FIELD_OFFSET
(
MIB_UDPTABLE_OWNER_PID
,
table
[
row_count
])
:
FIELD_OFFSET
(
MIB_UDP6TABLE_OWNER_PID
,
table
[
row_count
]);
if
(
!
pdwSize
)
return
ERROR_INVALID_PARAMETER
;
case
UDP_TABLE_OWNER_MODULE
:
*
row_size
=
(
family
==
WS_AF_INET
)
?
sizeof
(
MIB_UDPROW_OWNER_MODULE
)
:
sizeof
(
MIB_UDP6ROW_OWNER_MODULE
);
return
(
family
==
WS_AF_INET
)
?
FIELD_OFFSET
(
MIB_UDPTABLE_OWNER_MODULE
,
table
[
row_count
])
:
FIELD_OFFSET
(
MIB_UDP6TABLE_OWNER_MODULE
,
table
[
row_count
]);
if
(
TableClass
==
UDP_TABLE_OWNER_MODULE
)
FIXME
(
"UDP_TABLE_OWNER_MODULE not fully supported
\n
"
);
default:
ERR
(
"unhandled class %u
\n
"
,
table_class
);
return
0
;
}
}
switch
(
ulAf
)
static
void
udp_row_fill
(
void
*
table
,
DWORD
num
,
ULONG
family
,
ULONG
table_class
,
struct
nsi_udp_endpoint_key
*
key
,
struct
nsi_udp_endpoint_static
*
stat
)
{
if
(
family
==
WS_AF_INET
)
{
case
WS_AF_INET
:
ret
=
build_udp_table
(
TableClass
,
&
table
,
bOrder
,
GetProcessHeap
(),
0
,
&
size
);
break
;
case
WS_AF_INET6
:
ret
=
build_udp6_table
(
TableClass
,
&
table
,
bOrder
,
GetProcessHeap
(),
0
,
&
size
);
break
;
switch
(
table_class
)
{
case
UDP_TABLE_BASIC
:
{
MIB_UDPROW
*
row
=
((
MIB_UDPTABLE
*
)
table
)
->
table
+
num
;
row
->
dwLocalAddr
=
key
->
local
.
Ipv4
.
sin_addr
.
WS_s_addr
;
row
->
dwLocalPort
=
key
->
local
.
Ipv4
.
sin_port
;
return
;
}
case
UDP_TABLE_OWNER_PID
:
{
MIB_UDPROW_OWNER_PID
*
row
=
((
MIB_UDPTABLE_OWNER_PID
*
)
table
)
->
table
+
num
;
row
->
dwLocalAddr
=
key
->
local
.
Ipv4
.
sin_addr
.
WS_s_addr
;
row
->
dwLocalPort
=
key
->
local
.
Ipv4
.
sin_port
;
row
->
dwOwningPid
=
stat
->
pid
;
return
;
}
case
UDP_TABLE_OWNER_MODULE
:
{
MIB_UDPROW_OWNER_MODULE
*
row
=
((
MIB_UDPTABLE_OWNER_MODULE
*
)
table
)
->
table
+
num
;
row
->
dwLocalAddr
=
key
->
local
.
Ipv4
.
sin_addr
.
WS_s_addr
;
row
->
dwLocalPort
=
key
->
local
.
Ipv4
.
sin_port
;
row
->
dwOwningPid
=
stat
->
pid
;
row
->
liCreateTimestamp
.
QuadPart
=
stat
->
create_time
;
row
->
dwFlags
=
stat
->
flags
;
row
->
OwningModuleInfo
[
0
]
=
stat
->
mod_info
;
memset
(
row
->
OwningModuleInfo
+
1
,
0
,
sizeof
(
row
->
OwningModuleInfo
)
-
sizeof
(
row
->
OwningModuleInfo
[
0
])
);
return
;
}
default:
FIXME
(
"ulAf = %u not supported
\n
"
,
ulAf
);
ret
=
ERROR_NOT_SUPPORTED
;
ERR
(
"Unknown class %d
\n
"
,
table_class
);
return
;
}
}
else
{
switch
(
table_class
)
{
case
UDP_TABLE_BASIC
:
{
MIB_UDP6ROW
*
row
=
((
MIB_UDP6TABLE
*
)
table
)
->
table
+
num
;
memcpy
(
&
row
->
dwLocalAddr
,
&
key
->
local
.
Ipv6
.
sin6_addr
,
sizeof
(
row
->
dwLocalAddr
)
);
row
->
dwLocalScopeId
=
key
->
local
.
Ipv6
.
sin6_scope_id
;
row
->
dwLocalPort
=
key
->
local
.
Ipv6
.
sin6_port
;
return
;
}
case
UDP_TABLE_OWNER_PID
:
{
MIB_UDP6ROW_OWNER_PID
*
row
=
((
MIB_UDP6TABLE_OWNER_PID
*
)
table
)
->
table
+
num
;
memcpy
(
&
row
->
ucLocalAddr
,
&
key
->
local
.
Ipv6
.
sin6_addr
,
sizeof
(
row
->
ucLocalAddr
)
);
row
->
dwLocalScopeId
=
key
->
local
.
Ipv6
.
sin6_scope_id
;
row
->
dwLocalPort
=
key
->
local
.
Ipv6
.
sin6_port
;
row
->
dwOwningPid
=
stat
->
pid
;
return
;
}
case
UDP_TABLE_OWNER_MODULE
:
{
MIB_UDP6ROW_OWNER_MODULE
*
row
=
((
MIB_UDP6TABLE_OWNER_MODULE
*
)
table
)
->
table
+
num
;
memcpy
(
&
row
->
ucLocalAddr
,
&
key
->
local
.
Ipv6
.
sin6_addr
,
sizeof
(
row
->
ucLocalAddr
)
);
row
->
dwLocalScopeId
=
key
->
local
.
Ipv6
.
sin6_scope_id
;
row
->
dwLocalPort
=
key
->
local
.
Ipv6
.
sin6_port
;
row
->
dwOwningPid
=
stat
->
pid
;
row
->
liCreateTimestamp
.
QuadPart
=
stat
->
create_time
;
row
->
dwFlags
=
stat
->
flags
;
row
->
OwningModuleInfo
[
0
]
=
stat
->
mod_info
;
memset
(
row
->
OwningModuleInfo
+
1
,
0
,
sizeof
(
row
->
OwningModuleInfo
)
-
sizeof
(
row
->
OwningModuleInfo
[
0
])
);
return
;
}
default:
ERR
(
"Unknown class %d
\n
"
,
table_class
);
return
;
}
}
ERR
(
"Unknown family %d
\n
"
,
family
);
return
;
}
if
(
ret
)
return
ret
;
static
int
udp_row_cmp
(
const
void
*
a
,
const
void
*
b
)
{
const
MIB_UDPROW
*
rowA
=
a
;
const
MIB_UDPROW
*
rowB
=
b
;
int
ret
;
if
((
ret
=
RtlUlongByteSwap
(
rowA
->
dwLocalAddr
)
-
RtlUlongByteSwap
(
rowB
->
dwLocalAddr
))
!=
0
)
return
ret
;
return
RtlUshortByteSwap
(
rowA
->
dwLocalPort
)
-
RtlUshortByteSwap
(
rowB
->
dwLocalPort
);
}
static
int
udp6_row_cmp
(
const
void
*
a
,
const
void
*
b
)
{
const
MIB_UDP6ROW
*
rowA
=
a
;
const
MIB_UDP6ROW
*
rowB
=
b
;
int
ret
;
if
((
ret
=
memcmp
(
&
rowA
->
dwLocalAddr
,
&
rowB
->
dwLocalAddr
,
sizeof
(
rowA
->
dwLocalAddr
)
))
!=
0
)
return
ret
;
if
((
ret
=
rowA
->
dwLocalScopeId
-
rowB
->
dwLocalScopeId
)
!=
0
)
return
ret
;
return
RtlUshortByteSwap
(
rowA
->
dwLocalPort
)
-
RtlUshortByteSwap
(
rowB
->
dwLocalPort
);
}
/******************************************************************
* GetExtendedUdpTable (IPHLPAPI.@)
*/
DWORD
WINAPI
GetExtendedUdpTable
(
void
*
table
,
DWORD
*
size
,
BOOL
sort
,
ULONG
family
,
UDP_TABLE_CLASS
table_class
,
ULONG
reserved
)
{
DWORD
err
,
count
,
needed
,
i
,
num
=
0
,
row_size
=
0
;
struct
nsi_udp_endpoint_key
*
key
;
struct
nsi_udp_endpoint_static
*
stat
;
TRACE
(
"table %p, size %p, sort %d, family %u, table_class %u, reserved %u
\n
"
,
table
,
size
,
sort
,
family
,
table_class
,
reserved
);
if
(
!
size
||
!
ip_module_id
(
family
))
return
ERROR_INVALID_PARAMETER
;
err
=
NsiAllocateAndGetTable
(
1
,
&
NPI_MS_UDP_MODULEID
,
NSI_UDP_ENDPOINT_TABLE
,
(
void
**
)
&
key
,
sizeof
(
*
key
),
NULL
,
0
,
NULL
,
0
,
(
void
**
)
&
stat
,
sizeof
(
*
stat
),
&
count
,
0
);
if
(
err
)
return
err
;
for
(
i
=
0
;
i
<
count
;
i
++
)
if
(
key
[
i
].
local
.
si_family
==
family
)
num
++
;
if
(
!
pUdpTable
||
*
pdwSize
<
size
)
needed
=
udp_table_size
(
family
,
table_class
,
num
,
&
row_size
);
if
(
!
table
||
*
size
<
needed
)
{
*
pdwSize
=
size
;
ret
=
ERROR_INSUFFICIENT_BUFFER
;
*
size
=
needed
;
err
=
ERROR_INSUFFICIENT_BUFFER
;
}
else
{
*
pdwSize
=
size
;
memcpy
(
pUdpTable
,
table
,
size
);
*
size
=
needed
;
*
(
DWORD
*
)
table
=
num
;
num
=
0
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
key
[
i
].
local
.
si_family
!=
family
)
continue
;
udp_row_fill
(
table
,
num
++
,
family
,
table_class
,
key
+
i
,
stat
+
i
);
}
}
if
(
!
err
&&
sort
)
{
int
(
*
fn
)(
const
void
*
,
const
void
*
);
DWORD
offset
=
udp_table_size
(
family
,
table_class
,
0
,
&
row_size
);
if
(
family
==
WS_AF_INET
)
fn
=
udp_row_cmp
;
else
fn
=
udp6_row_cmp
;
qsort
(
(
BYTE
*
)
table
+
offset
,
num
,
row_size
,
fn
);
}
HeapFree
(
GetProcessHeap
(),
0
,
table
);
return
ret
;
NsiFreeTable
(
key
,
NULL
,
NULL
,
stat
);
return
err
;
}
static
void
unicast_row_fill
(
MIB_UNICASTIPADDRESS_ROW
*
row
,
USHORT
fam
,
void
*
key
,
struct
nsi_ip_unicast_rw
*
rw
,
...
...
dlls/iphlpapi/ipstats.c
View file @
566079d4
...
...
@@ -158,7 +158,6 @@
#include "winsock2.h"
#include "ws2ipdef.h"
#include "ifenum.h"
#include "ipstats.h"
#include "iphlpapi.h"
#include "wine/debug.h"
...
...
@@ -868,355 +867,6 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE
return
ret
;
}
static
DWORD
get_udp6_table_sizes
(
UDP_TABLE_CLASS
class
,
DWORD
row_count
,
DWORD
*
row_size
)
{
DWORD
table_size
;
switch
(
class
)
{
case
UDP_TABLE_BASIC
:
{
table_size
=
FIELD_OFFSET
(
MIB_UDP6TABLE
,
table
[
row_count
]);
if
(
row_size
)
*
row_size
=
sizeof
(
MIB_UDP6ROW
);
break
;
}
case
UDP_TABLE_OWNER_PID
:
{
table_size
=
FIELD_OFFSET
(
MIB_UDP6TABLE_OWNER_PID
,
table
[
row_count
]);
if
(
row_size
)
*
row_size
=
sizeof
(
MIB_UDP6ROW_OWNER_PID
);
break
;
}
case
UDP_TABLE_OWNER_MODULE
:
{
table_size
=
FIELD_OFFSET
(
MIB_UDP6TABLE_OWNER_MODULE
,
table
[
row_count
]);
if
(
row_size
)
*
row_size
=
sizeof
(
MIB_UDP6ROW_OWNER_MODULE
);
break
;
}
default:
ERR
(
"unhandled class %u
\n
"
,
class
);
return
0
;
}
return
table_size
;
}
static
int
compare_udp6_rows
(
const
void
*
a
,
const
void
*
b
)
{
const
MIB_UDP6ROW
*
rowA
=
a
;
const
MIB_UDP6ROW
*
rowB
=
b
;
int
ret
;
if
((
ret
=
memcmp
(
&
rowA
->
dwLocalAddr
,
&
rowB
->
dwLocalAddr
,
sizeof
(
rowA
->
dwLocalAddr
)))
!=
0
)
return
ret
;
if
((
ret
=
rowA
->
dwLocalScopeId
-
rowB
->
dwLocalScopeId
)
!=
0
)
return
ret
;
return
rowA
->
dwLocalPort
-
rowB
->
dwLocalPort
;
}
#if defined(__linux__) || (defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN))
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
;
#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
;
while
((
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
)))
{
WORD
a
[
8
];
DWORD
scope
;
struct
ipv6_addr_scope
*
new_table
;
struct
ipv6_addr_scope
*
entry
;
unsigned
int
i
;
if
(
sscanf
(
ptr
,
"%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx %*s %*s %x"
,
&
a
[
0
],
&
a
[
1
],
&
a
[
2
],
&
a
[
3
],
&
a
[
4
],
&
a
[
5
],
&
a
[
6
],
&
a
[
7
],
&
scope
)
!=
9
)
continue
;
table_size
++
;
if
(
!
(
new_table
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
table
,
table_size
*
sizeof
(
table
[
0
])
)))
{
fclose
(
fp
);
goto
failed
;
}
table
=
new_table
;
entry
=
&
table
[
table_size
-
1
];
i
=
0
;
while
(
i
<
8
)
{
entry
->
addr
.
u
.
Word
[
i
]
=
htons
(
a
[
i
]);
i
++
;
}
entry
->
scope
=
htons
(
scope
);
}
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
;
failed:
HeapFree
(
GetProcessHeap
(),
0
,
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
=
0
;
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
;
while
(
i
<
size
)
{
if
(
memcmp
(
&
table
[
i
].
addr
,
addr
,
sizeof
(
table
[
i
].
addr
))
==
0
)
return
table
[
i
].
scope
;
i
++
;
}
return
-
1
;
}
#endif
DWORD
build_udp6_table
(
UDP_TABLE_CLASS
class
,
void
**
tablep
,
BOOL
order
,
HANDLE
heap
,
DWORD
flags
,
DWORD
*
size
)
{
MIB_UDP6TABLE
*
table
;
MIB_UDP6ROW_OWNER_MODULE
row
;
DWORD
ret
=
NO_ERROR
,
count
=
16
,
table_size
,
row_size
;
if
(
!
(
table_size
=
get_udp6_table_sizes
(
class
,
count
,
&
row_size
)))
return
ERROR_INVALID_PARAMETER
;
if
(
!
(
table
=
HeapAlloc
(
heap
,
flags
,
table_size
)))
return
ERROR_OUTOFMEMORY
;
table
->
dwNumEntries
=
0
;
memset
(
&
row
,
0
,
sizeof
(
row
)
);
#ifdef __linux__
{
FILE
*
fp
;
if
((
fp
=
fopen
(
"/proc/net/udp6"
,
"r"
)))
{
char
buf
[
512
],
*
ptr
;
struct
pid_map
*
map
=
NULL
;
unsigned
int
num_entries
=
0
;
struct
ipv6_addr_scope
*
addr_scopes
;
unsigned
int
addr_scopes_size
=
0
;
int
inode
;
addr_scopes
=
get_ipv6_addr_scope_table
(
&
addr_scopes_size
);
if
(
class
>=
UDP_TABLE_OWNER_PID
)
map
=
get_pid_map
(
&
num_entries
);
/* skip header line */
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
);
while
((
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
)))
{
DWORD
*
local_addr
=
(
DWORD
*
)
&
row
.
ucLocalAddr
;
if
(
sscanf
(
ptr
,
"%*u: %8x%8x%8x%8x:%x %*s %*s %*s %*s %*s %*s %*s %d"
,
&
local_addr
[
0
],
&
local_addr
[
1
],
&
local_addr
[
2
],
&
local_addr
[
3
],
&
row
.
dwLocalPort
,
&
inode
)
!=
6
)
continue
;
row
.
dwLocalScopeId
=
find_ipv6_addr_scope
((
const
IN6_ADDR
*
)
&
row
.
ucLocalAddr
,
addr_scopes
,
addr_scopes_size
);
row
.
dwLocalPort
=
htons
(
row
.
dwLocalPort
);
if
(
class
>=
UDP_TABLE_OWNER_PID
)
row
.
dwOwningPid
=
find_owning_pid
(
map
,
num_entries
,
inode
);
if
(
class
>=
UDP_TABLE_OWNER_MODULE
)
{
row
.
liCreateTimestamp
.
QuadPart
=
0
;
/* FIXME */
row
.
dwFlags
=
0
;
memset
(
&
row
.
OwningModuleInfo
,
0
,
sizeof
(
row
.
OwningModuleInfo
)
);
}
if
(
!
(
table
=
append_table_row
(
heap
,
flags
,
table
,
&
table_size
,
&
count
,
&
row
,
row_size
)))
break
;
}
HeapFree
(
GetProcessHeap
(),
0
,
map
);
HeapFree
(
GetProcessHeap
(),
0
,
addr_scopes
);
fclose
(
fp
);
}
else
ret
=
ERROR_NOT_SUPPORTED
;
}
#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN)
{
static
const
char
zero
[
sizeof
(
IN6_ADDR
)]
=
{
0
};
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.udp.pcblist"
,
NULL
,
&
len
,
NULL
,
0
)
<
0
)
{
ERR
(
"Failure to read net.inet.udp.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.udp.pcblist"
,
buf
,
&
len
,
NULL
,
0
)
<
0
)
{
ERR
(
"Failure to read net.inet.udp.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
>=
UDP_TABLE_OWNER_PID
)
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
xinpcb
*
in
=
(
struct
xinpcb
*
)
xig
;
struct
xsocket
*
sock
=
&
in
->
xi_socket
;
#else
struct
inpcb
*
in
=
&
((
struct
xinpcb
*
)
xig
)
->
xi_inp
;
struct
xsocket
*
sock
=
&
((
struct
xinpcb
*
)
xig
)
->
xi_socket
;
#endif
/* Ignore sockets for other protocols */
if
(
sock
->
xso_protocol
!=
IPPROTO_UDP
)
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
.
s6_addr
,
zero
,
sizeof
(
zero
)
)
&&
!
in
->
inp_lport
)
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
);
if
(
class
>=
UDP_TABLE_OWNER_PID
)
row
.
dwOwningPid
=
find_owning_pid
(
map
,
num_entries
,
(
UINT_PTR
)
sock
->
so_pcb
);
if
(
class
>=
UDP_TABLE_OWNER_MODULE
)
{
row
.
liCreateTimestamp
.
QuadPart
=
0
;
/* FIXME */
row
.
dwFlags
=
0
;
row
.
SpecificPortBind
=
!
(
in
->
inp_flags
&
INP_ANONPORT
);
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
;
#endif
if
(
!
table
)
return
ERROR_OUTOFMEMORY
;
if
(
!
ret
)
{
if
(
order
&&
table
->
dwNumEntries
)
qsort
(
table
->
table
,
table
->
dwNumEntries
,
row_size
,
compare_udp6_rows
);
*
tablep
=
table
;
}
else
HeapFree
(
heap
,
flags
,
table
);
if
(
size
)
*
size
=
get_udp6_table_sizes
(
class
,
count
,
NULL
);
TRACE
(
"returning ret %u table %p
\n
"
,
ret
,
table
);
return
ret
;
}
/******************************************************************
* AllocateAndGetUdpTableFromStack (IPHLPAPI.@)
*
...
...
dlls/iphlpapi/ipstats.h
deleted
100644 → 0
View file @
7841c8af
/* ipstats.h
* Copyright (C) 2003,2006 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* This module implements functions that get network-related statistics.
* It's meant to hide some platform-specificisms.
*/
#ifndef WINE_IPSTATS_H_
#define WINE_IPSTATS_H_
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "iprtrmib.h"
DWORD
build_udp_table
(
UDP_TABLE_CLASS
,
void
**
,
BOOL
,
HANDLE
,
DWORD
,
DWORD
*
)
DECLSPEC_HIDDEN
;
DWORD
build_udp6_table
(
UDP_TABLE_CLASS
,
void
**
,
BOOL
,
HANDLE
,
DWORD
,
DWORD
*
)
DECLSPEC_HIDDEN
;
#endif
/* ndef WINE_IPSTATS_H_ */
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