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
88e44332
Commit
88e44332
authored
Aug 27, 2018
by
Guillaume Charifi
Committed by
Alexandre Julliard
Aug 29, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iphlpapi: Implement GetUdp6Table().
Signed-off-by:
Guillaume Charifi
<
guillaume.charifi@sfr.fr
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ad8f4509
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
349 additions
and
16 deletions
+349
-16
iphlpapi.spec
dlls/iphlpapi/iphlpapi.spec
+1
-1
iphlpapi_main.c
dlls/iphlpapi/iphlpapi_main.c
+24
-6
ipstats.c
dlls/iphlpapi/ipstats.c
+244
-0
ipstats.h
dlls/iphlpapi/ipstats.h
+1
-0
iphlpapi.h
include/iphlpapi.h
+2
-0
udpmib.h
include/udpmib.h
+51
-0
ws2ipdef.h
include/ws2ipdef.h
+26
-9
No files found.
dlls/iphlpapi/iphlpapi.spec
View file @
88e44332
...
...
@@ -141,7 +141,7 @@
@ stdcall GetTcpTable2( ptr ptr long )
@ stub GetTcpTableFromStack
#@ stub GetTeredoPort
#@ stub GetUdp6Table
@ stdcall GetUdp6Table( ptr ptr long )
@ stdcall GetUdpStatisticsEx( ptr long )
@ stdcall GetUdpStatistics( ptr )
@ stub GetUdpStatsFromStack
...
...
dlls/iphlpapi/iphlpapi_main.c
View file @
88e44332
...
...
@@ -2443,6 +2443,14 @@ DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder)
}
/******************************************************************
* GetUdp6Table (IPHLPAPI.@)
*/
DWORD
WINAPI
GetUdp6Table
(
PMIB_UDP6TABLE
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
)
{
return
GetExtendedUdpTable
(
pUdpTable
,
pdwSize
,
bOrder
,
WS_AF_INET6
,
UDP_TABLE_BASIC
,
0
);
}
/******************************************************************
* GetExtendedUdpTable (IPHLPAPI.@)
*/
DWORD
WINAPI
GetExtendedUdpTable
(
PVOID
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
,
...
...
@@ -2456,15 +2464,25 @@ DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder,
if
(
!
pdwSize
)
return
ERROR_INVALID_PARAMETER
;
if
(
ulAf
!=
WS_AF_INET
)
{
FIXME
(
"ulAf = %u not supported
\n
"
,
ulAf
);
return
ERROR_NOT_SUPPORTED
;
}
if
(
TableClass
==
UDP_TABLE_OWNER_MODULE
)
FIXME
(
"UDP_TABLE_OWNER_MODULE not fully supported
\n
"
);
if
((
ret
=
build_udp_table
(
TableClass
,
&
table
,
bOrder
,
GetProcessHeap
(),
0
,
&
size
)))
switch
(
ulAf
)
{
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
;
default:
FIXME
(
"ulAf = %u not supported
\n
"
,
ulAf
);
ret
=
ERROR_NOT_SUPPORTED
;
}
if
(
ret
)
return
ret
;
if
(
!
pUdpTable
||
*
pdwSize
<
size
)
...
...
dlls/iphlpapi/ipstats.c
View file @
88e44332
...
...
@@ -151,6 +151,9 @@
#include "ntstatus.h"
#define WIN32_NO_STATUS
#define NONAMELESSUNION
#define USE_WS_PREFIX
#include "winsock2.h"
#include "ws2ipdef.h"
#include "ifenum.h"
#include "ipstats.h"
#include "iphlpapi.h"
...
...
@@ -2565,6 +2568,247 @@ 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
MIB_UDP6TABLE
*
append_udp6_row
(
UDP_TABLE_CLASS
class
,
HANDLE
heap
,
DWORD
flags
,
MIB_UDP6TABLE
*
table
,
DWORD
*
count
,
const
MIB_UDP6ROW_OWNER_MODULE
*
row
,
DWORD
row_size
)
{
if
(
table
->
dwNumEntries
>=
*
count
)
{
MIB_UDP6TABLE
*
new_table
;
DWORD
new_count
=
table
->
dwNumEntries
*
2
,
new_table_size
;
new_table_size
=
get_udp6_table_sizes
(
class
,
new_count
,
NULL
);
if
(
!
(
new_table
=
HeapReAlloc
(
heap
,
flags
,
table
,
new_table_size
)))
{
HeapFree
(
heap
,
0
,
table
);
return
NULL
;
}
*
count
=
new_count
;
table
=
new_table
;
}
memcpy
(
(
char
*
)
table
->
table
+
(
table
->
dwNumEntries
*
row_size
),
row
,
row_size
);
table
->
dwNumEntries
++
;
return
table
;
}
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
;
}
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
;
if
(
!
(
table
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
table
[
0
])
)))
return
NULL
;
#ifdef __linux__
{
FILE
*
fp
;
char
buf
[
512
],
*
ptr
;
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
);
}
}
#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
;
}
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
;
unsigned
int
dummy
;
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
in6_addr32
[
4
];
if
(
sscanf
(
ptr
,
"%u: %8x%8x%8x%8x:%x %*s %*s %*s %*s %*s %*s %*s %d"
,
&
dummy
,
&
in6_addr32
[
0
],
&
in6_addr32
[
1
],
&
in6_addr32
[
2
],
&
in6_addr32
[
3
],
&
row
.
dwLocalPort
,
&
inode
)
!=
7
)
continue
;
memcpy
(
&
row
.
ucLocalAddr
,
in6_addr32
,
sizeof
(
row
.
ucLocalAddr
));
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
.
u
.
dwFlags
=
0
;
memset
(
&
row
.
OwningModuleInfo
,
0
,
sizeof
(
row
.
OwningModuleInfo
)
);
}
if
(
!
(
table
=
append_udp6_row
(
class
,
heap
,
flags
,
table
,
&
count
,
&
row
,
row_size
)))
break
;
}
HeapFree
(
GetProcessHeap
(),
0
,
map
);
if
(
addr_scopes
)
HeapFree
(
GetProcessHeap
(),
0
,
addr_scopes
);
fclose
(
fp
);
}
else
ret
=
ERROR_NOT_SUPPORTED
;
}
#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
View file @
88e44332
...
...
@@ -34,5 +34,6 @@ DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry) DECLSPEC_HIDDE
DWORD
build_tcp_table
(
TCP_TABLE_CLASS
,
void
**
,
BOOL
,
HANDLE
,
DWORD
,
DWORD
*
)
DECLSPEC_HIDDEN
;
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_ */
include/iphlpapi.h
View file @
88e44332
...
...
@@ -51,6 +51,8 @@ DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder);
DWORD
WINAPI
GetUdpTable
(
PMIB_UDPTABLE
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
);
DWORD
WINAPI
GetUdp6Table
(
PMIB_UDP6TABLE
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
);
DWORD
WINAPI
GetIpStatistics
(
PMIB_IPSTATS
pStats
);
DWORD
WINAPI
GetIpStatisticsEx
(
PMIB_IPSTATS
pStats
,
DWORD
dwFamily
);
...
...
include/udpmib.h
View file @
88e44332
...
...
@@ -71,6 +71,57 @@ typedef struct _MIB_UDPTABLE_OWNER_MODULE
MIB_UDPROW_OWNER_MODULE
table
[
1
];
}
MIB_UDPTABLE_OWNER_MODULE
,
*
PMIB_UDPTABLE_OWNER_MODULE
;
typedef
struct
_MIB_UDP6ROW
{
IN6_ADDR
dwLocalAddr
;
DWORD
dwLocalScopeId
;
DWORD
dwLocalPort
;
}
MIB_UDP6ROW
,
*
PMIB_UDP6ROW
;
typedef
struct
_MIB_UDP6TABLE
{
DWORD
dwNumEntries
;
MIB_UDP6ROW
table
[
1
];
}
MIB_UDP6TABLE
,
*
PMIB_UDP6TABLE
;
typedef
struct
_MIB_UDP6ROW_OWNER_PID
{
UCHAR
ucLocalAddr
[
16
];
DWORD
dwLocalScopeId
;
DWORD
dwLocalPort
;
DWORD
dwOwningPid
;
}
MIB_UDP6ROW_OWNER_PID
,
*
PMIB_UDP6ROW_OWNER_PID
;
typedef
struct
_MIB_UDP6TABLE_OWNER_PID
{
DWORD
dwNumEntries
;
MIB_UDP6ROW_OWNER_PID
table
[
1
];
}
MIB_UDP6TABLE_OWNER_PID
,
*
PMIB_UDP6TABLE_OWNER_PID
;
typedef
struct
_MIB_UDP6ROW_OWNER_MODULE
{
UCHAR
ucLocalAddr
[
16
];
DWORD
dwLocalScopeId
;
DWORD
dwLocalPort
;
DWORD
dwOwningPid
;
LARGE_INTEGER
liCreateTimestamp
;
__C89_NAMELESS
union
{
__C89_NAMELESS
struct
{
int
SpecificPortBind
:
1
;
}
__C89_NAMELESSSTRUCTNAME
;
int
dwFlags
;
}
__C89_NAMELESSUNIONNAME
;
ULONGLONG
OwningModuleInfo
[
TCPIP_OWNING_MODULE_SIZE
];
}
MIB_UDP6ROW_OWNER_MODULE
,
*
PMIB_UDP6ROW_OWNER_MODULE
;
typedef
struct
_MIB_UDP6TABLE_OWNER_MODULE
{
DWORD
dwNumEntries
;
MIB_UDP6ROW_OWNER_MODULE
table
[
1
];
}
MIB_UDP6TABLE_OWNER_MODULE
,
*
PMIB_UDP6TABLE_OWNER_MODULE
;
/* UDP statistics */
typedef
struct
_MIB_UDPSTATS
...
...
include/ws2ipdef.h
View file @
88e44332
...
...
@@ -284,16 +284,33 @@ typedef struct WS(in_pktinfo) {
extern
"C"
{
#endif
static
inline
BOOL
WS
(
IN6_IS_ADDR_LOOPBACK
)
(
const
IN6_ADDR
*
a
)
static
inline
BOOL
EAN
WS
(
IN6_IS_ADDR_LOOPBACK
)
(
const
IN6_ADDR
*
a
)
{
return
(
BOOL
)((
a
->
s6_words
[
0
]
==
0
)
&&
(
a
->
s6_words
[
1
]
==
0
)
&&
(
a
->
s6_words
[
2
]
==
0
)
&&
(
a
->
s6_words
[
3
]
==
0
)
&&
(
a
->
s6_words
[
4
]
==
0
)
&&
(
a
->
s6_words
[
5
]
==
0
)
&&
(
a
->
s6_words
[
6
]
==
0
)
&&
(
a
->
s6_words
[
7
]
==
0x0100
));
return
((
a
->
s6_words
[
0
]
==
0
)
&&
(
a
->
s6_words
[
1
]
==
0
)
&&
(
a
->
s6_words
[
2
]
==
0
)
&&
(
a
->
s6_words
[
3
]
==
0
)
&&
(
a
->
s6_words
[
4
]
==
0
)
&&
(
a
->
s6_words
[
5
]
==
0
)
&&
(
a
->
s6_words
[
6
]
==
0
)
&&
(
a
->
s6_words
[
7
]
==
0x0100
));
}
static
inline
BOOLEAN
WS
(
IN6_IS_ADDR_MULTICAST
)
(
const
IN6_ADDR
*
a
)
{
return
(
a
->
s6_bytes
[
0
]
==
0xff
);
}
static
inline
BOOLEAN
WS
(
IN6_IS_ADDR_UNSPECIFIED
)
(
const
IN6_ADDR
*
a
)
{
return
((
a
->
s6_words
[
0
]
==
0
)
&&
(
a
->
s6_words
[
1
]
==
0
)
&&
(
a
->
s6_words
[
2
]
==
0
)
&&
(
a
->
s6_words
[
3
]
==
0
)
&&
(
a
->
s6_words
[
4
]
==
0
)
&&
(
a
->
s6_words
[
5
]
==
0
)
&&
(
a
->
s6_words
[
6
]
==
0
)
&&
(
a
->
s6_words
[
7
]
==
0
));
}
#ifdef __cplusplus
...
...
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