Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
e91b19bf
Commit
e91b19bf
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 GetUdpStatisticsEx() on top of nsi.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
d6278ea0
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
48 additions
and
836 deletions
+48
-836
Makefile.in
dlls/iphlpapi/Makefile.in
+1
-3
ifenum.c
dlls/iphlpapi/ifenum.c
+0
-395
ifenum.h
dlls/iphlpapi/ifenum.h
+0
-66
iphlpapi_main.c
dlls/iphlpapi/iphlpapi_main.c
+47
-1
ipstats.c
dlls/iphlpapi/ipstats.c
+0
-370
nsi.c
dlls/nsi/tests/nsi.c
+0
-1
No files found.
dlls/iphlpapi/Makefile.in
View file @
e91b19bf
...
@@ -5,8 +5,6 @@ EXTRALIBS = $(KSTAT_LIBS) $(PROCSTAT_LIBS)
...
@@ -5,8 +5,6 @@ EXTRALIBS = $(KSTAT_LIBS) $(PROCSTAT_LIBS)
C_SRCS
=
\
C_SRCS
=
\
icmp.c
\
icmp.c
\
ifenum.c
\
iphlpapi_main.c
iphlpapi_main.c
\
ipstats.c
RC_SRCS
=
version.rc
RC_SRCS
=
version.rc
dlls/iphlpapi/ifenum.c
deleted
100644 → 0
View file @
d6278ea0
/* Copyright (C) 2003,2006,2011 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
*/
#include "config.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_NET_IF_ARP_H
#include <net/if_arp.h>
#endif
#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#ifdef HAVE_NET_IF_DL_H
#include <net/if_dl.h>
#endif
#ifdef HAVE_NET_IF_TYPES_H
#include <net/if_types.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h>
#endif
#ifdef HAVE_LINUX_RTNETLINK_H
#include <linux/rtnetlink.h>
#endif
#include "ifenum.h"
#include "ws2ipdef.h"
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
#define ifreq_len(ifr) \
max(sizeof(struct ifreq), sizeof((ifr)->ifr_name)+(ifr)->ifr_addr.sa_len)
#else
#define ifreq_len(ifr) sizeof(struct ifreq)
#endif
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#ifndef IF_NAMESIZE
#define IF_NAMESIZE 16
#endif
#ifndef INADDR_NONE
#define INADDR_NONE (~0U)
#endif
#define INITIAL_INTERFACES_ASSUMED 4
/* Functions */
static
BOOL
isLoopbackInterface
(
int
fd
,
const
char
*
name
)
{
BOOL
ret
=
FALSE
;
if
(
name
)
{
struct
ifreq
ifr
;
lstrcpynA
(
ifr
.
ifr_name
,
name
,
IFNAMSIZ
);
if
(
ioctl
(
fd
,
SIOCGIFFLAGS
,
&
ifr
)
==
0
)
ret
=
ifr
.
ifr_flags
&
IFF_LOOPBACK
;
}
return
!!
ret
;
}
/* The comments say MAX_ADAPTER_NAME is required, but really only IF_NAMESIZE
* bytes are necessary.
*/
static
char
*
getInterfaceNameByIndex
(
IF_INDEX
index
,
char
*
name
)
{
return
if_indextoname
(
index
,
name
);
}
DWORD
getInterfaceIndexByName
(
const
char
*
name
,
IF_INDEX
*
index
)
{
DWORD
ret
;
unsigned
int
idx
;
if
(
!
name
)
return
ERROR_INVALID_PARAMETER
;
if
(
!
index
)
return
ERROR_INVALID_PARAMETER
;
idx
=
if_nametoindex
(
name
);
if
(
idx
)
{
*
index
=
idx
;
ret
=
NO_ERROR
;
}
else
ret
=
ERROR_INVALID_DATA
;
return
ret
;
}
static
BOOL
isIfIndexLoopback
(
ULONG
idx
)
{
BOOL
ret
=
FALSE
;
char
name
[
IFNAMSIZ
];
int
fd
;
getInterfaceNameByIndex
(
idx
,
name
);
fd
=
socket
(
PF_INET
,
SOCK_DGRAM
,
0
);
if
(
fd
!=
-
1
)
{
ret
=
isLoopbackInterface
(
fd
,
name
);
close
(
fd
);
}
return
ret
;
}
#ifdef HAVE_IF_NAMEINDEX
DWORD
get_interface_indices
(
BOOL
skip_loopback
,
InterfaceIndexTable
**
table
)
{
DWORD
count
=
0
,
i
;
struct
if_nameindex
*
p
,
*
indices
=
if_nameindex
();
InterfaceIndexTable
*
ret
;
if
(
table
)
*
table
=
NULL
;
if
(
!
indices
)
return
0
;
for
(
p
=
indices
;
p
->
if_name
;
p
++
)
{
if
(
skip_loopback
&&
isIfIndexLoopback
(
p
->
if_index
))
continue
;
count
++
;
}
if
(
table
)
{
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
FIELD_OFFSET
(
InterfaceIndexTable
,
indexes
[
count
])
);
if
(
!
ret
)
{
count
=
0
;
goto
end
;
}
for
(
p
=
indices
,
i
=
0
;
p
->
if_name
&&
i
<
count
;
p
++
)
{
if
(
skip_loopback
&&
isIfIndexLoopback
(
p
->
if_index
))
continue
;
ret
->
indexes
[
i
++
]
=
p
->
if_index
;
}
ret
->
numIndexes
=
count
=
i
;
*
table
=
ret
;
}
end:
if_freenameindex
(
indices
);
return
count
;
}
#elif defined(HAVE_LINUX_RTNETLINK_H)
static
int
open_netlink
(
int
*
pid
)
{
int
fd
=
socket
(
AF_NETLINK
,
SOCK_RAW
,
NETLINK_ROUTE
);
struct
sockaddr_nl
addr
;
socklen_t
len
;
if
(
fd
<
0
)
return
fd
;
memset
(
&
addr
,
0
,
sizeof
(
addr
)
);
addr
.
nl_family
=
AF_NETLINK
;
if
(
bind
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
)
)
<
0
)
goto
fail
;
len
=
sizeof
(
addr
);
if
(
getsockname
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
&
len
)
<
0
)
goto
fail
;
*
pid
=
addr
.
nl_pid
;
return
fd
;
fail:
close
(
fd
);
return
-
1
;
}
static
int
send_netlink_req
(
int
fd
,
int
pid
,
int
type
,
int
*
seq_no
)
{
static
LONG
seq
;
struct
request
{
struct
nlmsghdr
hdr
;
struct
rtgenmsg
gen
;
}
req
;
struct
sockaddr_nl
addr
;
req
.
hdr
.
nlmsg_len
=
sizeof
(
req
);
req
.
hdr
.
nlmsg_type
=
type
;
req
.
hdr
.
nlmsg_flags
=
NLM_F_ROOT
|
NLM_F_MATCH
|
NLM_F_REQUEST
;
req
.
hdr
.
nlmsg_pid
=
pid
;
req
.
hdr
.
nlmsg_seq
=
InterlockedIncrement
(
&
seq
);
req
.
gen
.
rtgen_family
=
AF_UNSPEC
;
memset
(
&
addr
,
0
,
sizeof
(
addr
)
);
addr
.
nl_family
=
AF_NETLINK
;
if
(
sendto
(
fd
,
&
req
,
sizeof
(
req
),
0
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
)
)
!=
sizeof
(
req
))
return
-
1
;
*
seq_no
=
req
.
hdr
.
nlmsg_seq
;
return
0
;
}
struct
netlink_reply
{
struct
netlink_reply
*
next
;
int
size
;
struct
nlmsghdr
*
hdr
;
};
static
void
free_netlink_reply
(
struct
netlink_reply
*
data
)
{
struct
netlink_reply
*
ptr
;
while
(
data
)
{
ptr
=
data
->
next
;
HeapFree
(
GetProcessHeap
(),
0
,
data
);
data
=
ptr
;
}
}
static
int
recv_netlink_reply
(
int
fd
,
int
pid
,
int
seq
,
struct
netlink_reply
**
data
)
{
int
bufsize
=
getpagesize
();
int
left
,
read
;
BOOL
done
=
FALSE
;
socklen_t
sa_len
;
struct
sockaddr_nl
addr
;
struct
netlink_reply
*
cur
,
*
last
=
NULL
;
struct
nlmsghdr
*
hdr
;
char
*
buf
;
*
data
=
NULL
;
buf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bufsize
);
if
(
!
buf
)
return
-
1
;
do
{
left
=
read
=
recvfrom
(
fd
,
buf
,
bufsize
,
0
,
(
struct
sockaddr
*
)
&
addr
,
&
sa_len
);
if
(
read
<
0
)
goto
fail
;
if
(
addr
.
nl_pid
!=
0
)
continue
;
/* not from kernel */
for
(
hdr
=
(
struct
nlmsghdr
*
)
buf
;
NLMSG_OK
(
hdr
,
left
);
hdr
=
NLMSG_NEXT
(
hdr
,
left
))
{
if
(
hdr
->
nlmsg_pid
!=
pid
||
hdr
->
nlmsg_seq
!=
seq
)
continue
;
if
(
hdr
->
nlmsg_type
==
NLMSG_DONE
)
{
done
=
TRUE
;
break
;
}
}
cur
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
cur
)
+
read
);
if
(
!
cur
)
goto
fail
;
cur
->
next
=
NULL
;
cur
->
size
=
read
;
cur
->
hdr
=
(
struct
nlmsghdr
*
)(
cur
+
1
);
memcpy
(
cur
->
hdr
,
buf
,
read
);
if
(
last
)
last
->
next
=
cur
;
else
*
data
=
cur
;
last
=
cur
;
}
while
(
!
done
);
HeapFree
(
GetProcessHeap
(),
0
,
buf
);
return
0
;
fail:
free_netlink_reply
(
*
data
);
HeapFree
(
GetProcessHeap
(),
0
,
buf
);
return
-
1
;
}
static
DWORD
get_indices_from_reply
(
struct
netlink_reply
*
reply
,
int
pid
,
int
seq
,
BOOL
skip_loopback
,
InterfaceIndexTable
*
table
)
{
struct
nlmsghdr
*
hdr
;
struct
netlink_reply
*
r
;
int
count
=
0
;
for
(
r
=
reply
;
r
;
r
=
r
->
next
)
{
int
size
=
r
->
size
;
for
(
hdr
=
r
->
hdr
;
NLMSG_OK
(
hdr
,
size
);
hdr
=
NLMSG_NEXT
(
hdr
,
size
))
{
if
(
hdr
->
nlmsg_pid
!=
pid
||
hdr
->
nlmsg_seq
!=
seq
)
continue
;
if
(
hdr
->
nlmsg_type
==
NLMSG_DONE
)
break
;
if
(
hdr
->
nlmsg_type
==
RTM_NEWLINK
)
{
struct
ifinfomsg
*
info
=
NLMSG_DATA
(
hdr
);
if
(
skip_loopback
&&
(
info
->
ifi_flags
&
IFF_LOOPBACK
))
continue
;
if
(
table
)
table
->
indexes
[
count
]
=
info
->
ifi_index
;
count
++
;
}
}
}
return
count
;
}
DWORD
get_interface_indices
(
BOOL
skip_loopback
,
InterfaceIndexTable
**
table
)
{
int
fd
,
pid
,
seq
;
struct
netlink_reply
*
reply
=
NULL
;
DWORD
count
=
0
;
if
(
table
)
*
table
=
NULL
;
fd
=
open_netlink
(
&
pid
);
if
(
fd
<
0
)
return
0
;
if
(
send_netlink_req
(
fd
,
pid
,
RTM_GETLINK
,
&
seq
)
<
0
)
goto
end
;
if
(
recv_netlink_reply
(
fd
,
pid
,
seq
,
&
reply
)
<
0
)
goto
end
;
count
=
get_indices_from_reply
(
reply
,
pid
,
seq
,
skip_loopback
,
NULL
);
if
(
table
)
{
InterfaceIndexTable
*
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
FIELD_OFFSET
(
InterfaceIndexTable
,
indexes
[
count
])
);
if
(
!
ret
)
{
count
=
0
;
goto
end
;
}
ret
->
numIndexes
=
count
;
get_indices_from_reply
(
reply
,
pid
,
seq
,
skip_loopback
,
ret
);
*
table
=
ret
;
}
end:
free_netlink_reply
(
reply
);
close
(
fd
);
return
count
;
}
#else
DWORD
get_interface_indices
(
BOOL
skip_loopback
,
InterfaceIndexTable
**
table
)
{
if
(
table
)
*
table
=
NULL
;
return
0
;
}
#endif
dlls/iphlpapi/ifenum.h
deleted
100644 → 0
View file @
d6278ea0
/* ifenum.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 network interface and address enumeration. It's
* meant to hide some problematic defines like socket(), and make iphlpapi
* more portable.
*
* Like Windows, it uses a numeric index to identify an interface uniquely.
* As implemented, an interface represents a UNIX network interface, virtual
* or real, and thus can have 0 or 1 IP addresses associated with it. (This
* only supports IPv4.)
* The indexes returned are not guaranteed to be contiguous, so don't call
* getNumInterfaces() and assume the values [0,getNumInterfaces() - 1] will be
* valid indexes; use getInterfaceIndexTable() instead.
*
* See also the companion file, ipstats.h, for functions related to getting
* statistics.
*/
#ifndef WINE_IFENUM_H_
#define WINE_IFENUM_H_
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#define USE_WS_PREFIX
#include "iprtrmib.h"
#include "winsock2.h"
#define MAX_INTERFACE_PHYSADDR 8
#define MAX_INTERFACE_DESCRIPTION 256
/* A table of interface indexes, see get_interface_indices(). */
typedef
struct
_InterfaceIndexTable
{
DWORD
numIndexes
;
IF_INDEX
indexes
[
1
];
}
InterfaceIndexTable
;
/* Returns the count of all interface indexes and optionally a ptr to an interface table.
* HeapFree() the returned table. Will optionally ignore loopback devices.
*/
DWORD
get_interface_indices
(
BOOL
skip_loopback
,
InterfaceIndexTable
**
table
)
DECLSPEC_HIDDEN
;
/* ByName/ByIndex versions of various getter functions. */
/* Fills index with the index of name, if found. Returns
* ERROR_INVALID_PARAMETER if name or index is NULL, ERROR_INVALID_DATA if name
* is not found, and NO_ERROR on success.
*/
DWORD
getInterfaceIndexByName
(
const
char
*
name
,
IF_INDEX
*
index
)
DECLSPEC_HIDDEN
;
#endif
/* ndef WINE_IFENUM_H_ */
dlls/iphlpapi/iphlpapi_main.c
View file @
e91b19bf
...
@@ -42,7 +42,6 @@
...
@@ -42,7 +42,6 @@
#include "ws2ipdef.h"
#include "ws2ipdef.h"
#include "windns.h"
#include "windns.h"
#include "iphlpapi.h"
#include "iphlpapi.h"
#include "ifenum.h"
#include "ipifcons.h"
#include "ipifcons.h"
#include "fltdefs.h"
#include "fltdefs.h"
#include "ifdef.h"
#include "ifdef.h"
...
@@ -3283,6 +3282,53 @@ DWORD WINAPI AllocateAndGetTcpExTableFromStack( void **table, BOOL sort, HANDLE
...
@@ -3283,6 +3282,53 @@ DWORD WINAPI AllocateAndGetTcpExTableFromStack( void **table, BOOL sort, HANDLE
}
}
/******************************************************************
/******************************************************************
* GetUdpStatistics (IPHLPAPI.@)
*
* Get the UDP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for UDP statistics
*/
DWORD
WINAPI
GetUdpStatistics
(
MIB_UDPSTATS
*
stats
)
{
return
GetUdpStatisticsEx
(
stats
,
WS_AF_INET
);
}
/******************************************************************
* GetUdpStatisticsEx (IPHLPAPI.@)
*
* Get the IPv4 and IPv6 UDP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for UDP statistics
* family [In] specifies whether IPv4 or IPv6 statistics are returned
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetUdpStatisticsEx
(
MIB_UDPSTATS
*
stats
,
DWORD
family
)
{
struct
nsi_udp_stats_dynamic
dyn
;
USHORT
key
=
(
USHORT
)
family
;
DWORD
err
;
if
(
!
stats
||
!
ip_module_id
(
family
))
return
ERROR_INVALID_PARAMETER
;
memset
(
stats
,
0
,
sizeof
(
*
stats
)
);
err
=
NsiGetAllParameters
(
1
,
&
NPI_MS_UDP_MODULEID
,
NSI_UDP_STATS_TABLE
,
&
key
,
sizeof
(
key
),
NULL
,
0
,
&
dyn
,
sizeof
(
dyn
),
NULL
,
0
);
if
(
err
)
return
err
;
stats
->
dwInDatagrams
=
dyn
.
in_dgrams
;
stats
->
dwNoPorts
=
dyn
.
no_ports
;
stats
->
dwInErrors
=
dyn
.
in_errs
;
stats
->
dwOutDatagrams
=
dyn
.
out_dgrams
;
stats
->
dwNumAddrs
=
dyn
.
num_addrs
;
return
err
;
}
/******************************************************************
* GetUdpTable (IPHLPAPI.@)
* GetUdpTable (IPHLPAPI.@)
*
*
* Get a table of active UDP connections.
* Get a table of active UDP connections.
...
...
dlls/iphlpapi/ipstats.c
deleted
100644 → 0
View file @
d6278ea0
/*
* Copyright (C) 2003,2006 Juan Lang
* Copyright (C) 2007 TransGaming Technologies Inc.
* Copyright (C) 2009 Alexandre Julliard
*
* 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
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_ALIAS_H
#include <alias.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SOCKETVAR_H
#include <sys/socketvar.h>
#endif
#ifdef HAVE_SYS_TIMEOUT_H
#include <sys/timeout.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_NET_IF_DL_H
#include <net/if_dl.h>
#endif
#ifdef HAVE_NET_IF_TYPES_H
#include <net/if_types.h>
#endif
#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#endif
#ifdef HAVE_NET_IF_ARP_H
#include <net/if_arp.h>
#endif
#ifdef HAVE_NETINET_IF_ETHER_H
#include <netinet/if_ether.h>
#endif
#ifdef HAVE_NETINET_IF_INARP_H
#include <netinet/if_inarp.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_NETINET_IP_VAR_H
#include <netinet/ip_var.h>
#endif
#ifdef HAVE_NETINET_TCP_FSM_H
#include <netinet/tcp_fsm.h>
#endif
#ifdef HAVE_NETINET_IN_PCB_H
#include <netinet/in_pcb.h>
#endif
#ifdef HAVE_NETINET_TCP_TIMER_H
#include <netinet/tcp_timer.h>
#endif
#ifdef HAVE_NETINET_TCP_VAR_H
#include <netinet/tcp_var.h>
#endif
#ifdef HAVE_NETINET_IP_ICMP_H
#include <netinet/ip_icmp.h>
#endif
#ifdef HAVE_NETINET_ICMP_VAR_H
#include <netinet/icmp_var.h>
#endif
#ifdef HAVE_NETINET_UDP_H
#include <netinet/udp.h>
#endif
#ifdef HAVE_NETINET_UDP_VAR_H
#include <netinet/udp_var.h>
#endif
#ifdef HAVE_SYS_PROTOSW_H
#include <sys/protosw.h>
#endif
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#ifdef HAVE_KSTAT_H
#include <kstat.h>
#endif
#ifdef HAVE_INET_MIB2_H
#include <inet/mib2.h>
#endif
#ifdef HAVE_STROPTS_H
#include <stropts.h>
#endif
#ifdef HAVE_SYS_TIHDR_H
#include <sys/tihdr.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_QUEUE_H
#include <sys/queue.h>
#endif
#ifdef HAVE_SYS_USER_H
/* Make sure the definitions of struct kinfo_proc are the same. */
#include <sys/user.h>
#endif
#ifdef HAVE_LIBPROCSTAT_H
#include <libprocstat.h>
#endif
#ifdef HAVE_LIBPROC_H
#include <libproc.h>
#endif
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h>
#endif
#ifndef ROUNDUP
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int))
#endif
#ifndef ADVANCE
#define ADVANCE(x, n) (x += ROUNDUP(((struct sockaddr *)n)->sa_len))
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
#define NONAMELESSUNION
#define USE_WS_PREFIX
#include "winsock2.h"
#include "ws2ipdef.h"
#include "ifenum.h"
#include "iphlpapi.h"
#include "wine/debug.h"
#include "wine/server.h"
#include "wine/unicode.h"
#ifndef HAVE_NETINET_TCP_FSM_H
#define TCPS_ESTABLISHED 1
#define TCPS_SYN_SENT 2
#define TCPS_SYN_RECEIVED 3
#define TCPS_FIN_WAIT_1 4
#define TCPS_FIN_WAIT_2 5
#define TCPS_TIME_WAIT 6
#define TCPS_CLOSED 7
#define TCPS_CLOSE_WAIT 8
#define TCPS_LAST_ACK 9
#define TCPS_LISTEN 10
#define TCPS_CLOSING 11
#endif
#ifndef RTF_MULTICAST
#define RTF_MULTICAST 0
/* Not available on NetBSD/OpenBSD */
#endif
#ifndef RTF_LLINFO
#define RTF_LLINFO 0
/* Not available on FreeBSD 8 and above */
#endif
WINE_DEFAULT_DEBUG_CHANNEL
(
iphlpapi
);
#ifdef HAVE_LIBKSTAT
static
DWORD
kstat_get_ui32
(
kstat_t
*
ksp
,
const
char
*
name
)
{
unsigned
int
i
;
kstat_named_t
*
data
=
ksp
->
ks_data
;
for
(
i
=
0
;
i
<
ksp
->
ks_ndata
;
i
++
)
if
(
!
strcmp
(
data
[
i
].
name
,
name
))
return
data
[
i
].
value
.
ui32
;
return
0
;
}
#endif
/******************************************************************
* GetUdpStatistics (IPHLPAPI.@)
*
* Get the IPv4 and IPv6 UDP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for UDP statistics
* family [In] specifies whether IPv4 or IPv6 statistics are returned
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetUdpStatisticsEx
(
PMIB_UDPSTATS
stats
,
DWORD
family
)
{
DWORD
ret
=
ERROR_NOT_SUPPORTED
;
if
(
!
stats
)
return
ERROR_INVALID_PARAMETER
;
if
(
family
!=
WS_AF_INET
&&
family
!=
WS_AF_INET6
)
return
ERROR_INVALID_PARAMETER
;
memset
(
stats
,
0
,
sizeof
(
*
stats
)
);
stats
->
dwNumAddrs
=
get_interface_indices
(
FALSE
,
NULL
);
if
(
family
==
WS_AF_INET6
)
{
#ifdef __linux__
{
FILE
*
fp
;
if
((
fp
=
fopen
(
"/proc/net/snmp6"
,
"r"
)))
{
struct
{
const
char
*
name
;
DWORD
*
elem
;
}
udpstatlist
[]
=
{
{
"Udp6InDatagrams"
,
&
stats
->
dwInDatagrams
},
{
"Udp6NoPorts"
,
&
stats
->
dwNoPorts
},
{
"Udp6InErrors"
,
&
stats
->
dwInErrors
},
{
"Udp6OutDatagrams"
,
&
stats
->
dwOutDatagrams
},
};
char
buf
[
512
],
*
ptr
,
*
value
;
DWORD
res
,
i
;
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
(
udpstatlist
);
i
++
)
if
(
!
_strnicmp
(
buf
,
udpstatlist
[
i
].
name
,
-
1
)
&&
sscanf
(
value
,
"%d"
,
&
res
))
*
udpstatlist
[
i
].
elem
=
res
;
}
fclose
(
fp
);
ret
=
NO_ERROR
;
}
}
#else
FIXME
(
"unimplemented for IPv6
\n
"
);
#endif
return
ret
;
}
#ifdef __linux__
{
FILE
*
fp
;
if
((
fp
=
fopen
(
"/proc/net/snmp"
,
"r"
)))
{
static
const
char
hdr
[]
=
"Udp:"
;
char
buf
[
512
],
*
ptr
;
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
))
{
ptr
+=
sizeof
(
hdr
);
sscanf
(
ptr
,
"%u %u %u %u %u"
,
&
stats
->
dwInDatagrams
,
&
stats
->
dwNoPorts
,
&
stats
->
dwInErrors
,
&
stats
->
dwOutDatagrams
,
&
stats
->
dwNumAddrs
);
break
;
}
}
fclose
(
fp
);
ret
=
NO_ERROR
;
}
}
#elif defined(HAVE_LIBKSTAT)
{
static
char
udp
[]
=
"udp"
;
kstat_ctl_t
*
kc
;
kstat_t
*
ksp
;
MIB_UDPTABLE
*
udp_table
;
if
((
kc
=
kstat_open
())
&&
(
ksp
=
kstat_lookup
(
kc
,
udp
,
0
,
udp
))
&&
kstat_read
(
kc
,
ksp
,
NULL
)
!=
-
1
&&
ksp
->
ks_type
==
KSTAT_TYPE_NAMED
)
{
stats
->
dwInDatagrams
=
kstat_get_ui32
(
ksp
,
"inDatagrams"
);
stats
->
dwNoPorts
=
0
;
/* FIXME */
stats
->
dwInErrors
=
kstat_get_ui32
(
ksp
,
"inErrors"
);
stats
->
dwOutDatagrams
=
kstat_get_ui32
(
ksp
,
"outDatagrams"
);
if
(
!
AllocateAndGetUdpTableFromStack
(
&
udp_table
,
FALSE
,
GetProcessHeap
(),
0
))
{
stats
->
dwNumAddrs
=
udp_table
->
dwNumEntries
;
HeapFree
(
GetProcessHeap
(),
0
,
udp_table
);
}
ret
=
NO_ERROR
;
}
if
(
kc
)
kstat_close
(
kc
);
}
#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
;
MIB_UDPTABLE
*
udp_table
;
size_t
needed
=
sizeof
(
udp_stat
);
if
(
sysctl
(
mib
,
ARRAY_SIZE
(
mib
),
&
udp_stat
,
&
needed
,
NULL
,
0
)
!=
-
1
)
{
stats
->
dwInDatagrams
=
udp_stat
.
udps_ipackets
;
stats
->
dwOutDatagrams
=
udp_stat
.
udps_opackets
;
stats
->
dwNoPorts
=
udp_stat
.
udps_noport
;
stats
->
dwInErrors
=
udp_stat
.
udps_hdrops
+
udp_stat
.
udps_badsum
+
udp_stat
.
udps_fullsock
+
udp_stat
.
udps_badlen
;
if
(
!
AllocateAndGetUdpTableFromStack
(
&
udp_table
,
FALSE
,
GetProcessHeap
(),
0
))
{
stats
->
dwNumAddrs
=
udp_table
->
dwNumEntries
;
HeapFree
(
GetProcessHeap
(),
0
,
udp_table
);
}
ret
=
NO_ERROR
;
}
else
ERR
(
"failed to get udpstat
\n
"
);
}
#else
FIXME
(
"unimplemented for IPv4
\n
"
);
#endif
return
ret
;
}
/******************************************************************
* GetUdpStatistics (IPHLPAPI.@)
*
* Get the UDP statistics for the local computer.
*
* PARAMS
* stats [Out] buffer for UDP statistics
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
DWORD
WINAPI
GetUdpStatistics
(
PMIB_UDPSTATS
stats
)
{
return
GetUdpStatisticsEx
(
stats
,
WS_AF_INET
);
}
dlls/nsi/tests/nsi.c
View file @
e91b19bf
...
@@ -966,7 +966,6 @@ static void test_udp_stats( int family )
...
@@ -966,7 +966,6 @@ static void test_udp_stats( int family )
table
.
dwInErrors
,
dyn
.
in_errs
,
dyn2
.
in_errs
);
table
.
dwInErrors
,
dyn
.
in_errs
,
dyn2
.
in_errs
);
ok
(
bounded
(
table
.
dwOutDatagrams
,
dyn
.
out_dgrams
,
dyn2
.
out_dgrams
),
"%d vs [%I64d %I64d]
\n
"
,
ok
(
bounded
(
table
.
dwOutDatagrams
,
dyn
.
out_dgrams
,
dyn2
.
out_dgrams
),
"%d vs [%I64d %I64d]
\n
"
,
table
.
dwOutDatagrams
,
dyn
.
out_dgrams
,
dyn2
.
out_dgrams
);
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
);
ok
(
unstable
(
table
.
dwNumAddrs
==
dyn
.
num_addrs
),
"%d %d
\n
"
,
table
.
dwNumAddrs
,
dyn
.
num_addrs
);
winetest_pop_context
();
winetest_pop_context
();
...
...
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