Skip to content

Add GetTcpStatistics and GetUdpStatistics #1178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ Next Release (5.6.0)
Features
--------
* [#1160](https://github.com/java-native-access/jna/issues/1160): Make FileUtils#moveToTrash a varargs method - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#1167](https://github.com/java-native-access/jna/pull/1167): Add `c.s.j.p.win32.Kernel32.GetProcessAffinityMask` - [@dbwiddis](https://github.com/dbwiddis).
* [#1168](https://github.com/java-native-access/jna/pull/1168): Add `c.s.j.p.win32.Kernel32.SetProcessAffinityMask` - [@dbwiddis](https://github.com/dbwiddis).
* [#1167](https://github.com/java-native-access/jna/pull/1167): Add `c.s.j.p.win32.Kernel32#GetProcessAffinityMask` - [@dbwiddis](https://github.com/dbwiddis).
* [#1168](https://github.com/java-native-access/jna/pull/1168): Add `c.s.j.p.win32.Kernel32#SetProcessAffinityMask` - [@dbwiddis](https://github.com/dbwiddis).
* [#1169](https://github.com/java-native-access/jna/issues/1169): Wait for process in getLinuxLdPaths - [@rdesgroppes](https://github.com/rdesgroppes).
* [#1178](https://github.com/java-native-access/jna/pull/1178): Add `c.s.j.p.win32.IPHlpAPI#GetTcpStatistics`, `c.s.j.p.win32.IPHlpAPI#GetUdpStatistics`, `c.s.j.p.win32.IPHlpAPI#GetTcpStatisticsEx` and `c.s.j.p.win32.IPHlpAPI#GetUdpStatisticsEx` - [@dbwiddis](https://github.com/dbwiddis).

Bug Fixes
---------
Expand Down
187 changes: 147 additions & 40 deletions contrib/platform/src/com/sun/jna/platform/win32/IPHlpAPI.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018 Daniel Widdis, All Rights Reserved
/* Copyright (c) 2018,2020 Daniel Widdis, All Rights Reserved
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
Expand Down Expand Up @@ -51,6 +51,10 @@ public interface IPHlpAPI extends Library {
int MAX_DOMAIN_NAME_LEN = 128;
int MAX_SCOPE_ID_LEN = 256;

// Source: Winsock2.h
int AF_INET = 2; // The Internet Protocol version 4 (IPv4) address family.
int AF_INET6 = 23; // The Internet Protocol version 6 (IPv6) address family.

/**
* The MIB_IFROW structure stores information about a particular interface.
*
Expand Down Expand Up @@ -89,8 +93,7 @@ class MIB_IFROW extends Structure {
}

/**
* The MIB_IF_ROW2 structure stores information about a particular
* interface.
* The MIB_IF_ROW2 structure stores information about a particular interface.
*
* @see <A HREF=
* "https://msdn.microsoft.com/library/windows/hardware/ff559214">MIB_IF_ROW2</A>
Expand Down Expand Up @@ -184,8 +187,8 @@ public static class ByReference extends IP_ADDR_STRING implements Structure.ByRe
}

/**
* The FIXED_INFO structure contains information that is the same across all
* the interfaces on a computer.
* The FIXED_INFO structure contains information that is the same across all the
* interfaces on a computer.
*
* @see <A HREF=
* "https://docs.microsoft.com/en-us/windows/desktop/api/iptypes/ns-iptypes-fixed_info_w2ksp1">FIXED_INFO</A>
Expand Down Expand Up @@ -214,45 +217,90 @@ public FIXED_INFO() {
}

/**
* The GetIfEntry function retrieves information for the specified interface
* The MIB_TCPSTATS structure contains statistics for the TCP protocol running
* on the local computer.
*
* The dwIndex member in the MIB_IFROW structure pointed to by the pIfRow
* parameter must be initialized to a valid network interface index
* retrieved by a previous call to the GetIfTable, GetIfTable2, or
* GetIfTable2Ex function. The GetIfEntry function will fail if the dwIndex
* member of the MIB_IFROW pointed to by the pIfRow parameter does not match
* an existing interface index on the local computer.
* <p>
* In the Windows SDK, the version of the structure for use on Windows Vista and
* later is defined as {@code MIB_TCPSTATS_LH}. In the Windows SDK, the version
* of this structure to be used on earlier systems including Windows 2000 and
* later is defined as {@code MIB_TCPSTATS_W2K}.
*/
@FieldOrder({ "dwRtoAlgorithm", "dwRtoMin", "dwRtoMax", "dwMaxConn", "dwActiveOpens", "dwPassiveOpens",
"dwAttemptFails", "dwEstabResets", "dwCurrEstab", "dwInSegs", "dwOutSegs", "dwRetransSegs", "dwInErrs",
"dwOutRsts", "dwNumConns" })
class MIB_TCPSTATS extends Structure {
public int dwRtoAlgorithm; // Union for _W2K version, doesn't change mapping
public int dwRtoMin;
public int dwRtoMax;
public int dwMaxConn;
public int dwActiveOpens;
public int dwPassiveOpens;
public int dwAttemptFails;
public int dwEstabResets;
public int dwCurrEstab;
public int dwInSegs;
public int dwOutSegs;
public int dwRetransSegs;
public int dwInErrs;
public int dwOutRsts;
public int dwNumConns;
}

/**
* The MIB_UDPSTATS structure contains statistics for the User Datagram Protocol
* (UDP) running on the local computer.
*/
@FieldOrder({ "dwInDatagrams", "dwNoPorts", "dwInErrors", "dwOutDatagrams", "dwNumAddrs" })
class MIB_UDPSTATS extends Structure {
public int dwInDatagrams;
public int dwNoPorts;
public int dwInErrors;
public int dwOutDatagrams;
public int dwNumAddrs;
}

/**
* The GetIfEntry function retrieves information for the specified interface on
* the local computer.
* <p>
* The {@code dwIndex} member in the {@link MIB_IFROW} structure pointed to by
* the pIfRow parameter must be initialized to a valid network interface index
* retrieved by a previous call to the GetIfTable, GetIfTable2, or GetIfTable2Ex
* function. The GetIfEntry function will fail if the dwIndex member of the
* {@link MIB_IFROW} pointed to by the pIfRow parameter does not match an
* existing interface index on the local computer.
*
* @param pIfRow
* A pointer to a MIB_IFROW structure that, on successful return,
* receives information for an interface on the local computer.
* On input, set the dwIndex member of MIB_IFROW to the index of
* receives information for an interface on the local computer. On
* input, set the dwIndex member of {@link MIB_IFROW} to the index of
* the interface for which to retrieve information.
* @return If the function succeeds, the return value is NO_ERROR.
* @return If the function succeeds, the return value is
* {@link WinError#NO_ERROR}.
*/
int GetIfEntry(MIB_IFROW pIfRow);

/**
* The GetIfEntry2 function retrieves information for the specified
* interface on the local computer.
*
* On input, at least one of the following members in the MIB_IF_ROW2
* structure passed in the Row parameter must be initialized: InterfaceLuid
* or InterfaceIndex. The fields are used in the order listed above. So if
* the InterfaceLuid is specified, then this member is used to determine the
* The GetIfEntry2 function retrieves information for the specified interface on
* the local computer.
* <p>
* On input, at least one of the following members in the {@link MIB_IF_ROW2}
* structure passed in the Row parameter must be initialized: InterfaceLuid or
* InterfaceIndex. The fields are used in the order listed above. So if the
* InterfaceLuid is specified, then this member is used to determine the
* interface. If no value was set for the InterfaceLuid member (the value of
* this member was set to zero), then the InterfaceIndex member is next used
* to determine the interface. On output, the remaining fields of the
* MIB_IF_ROW2 structure pointed to by the Row parameter are filled in.
* this member was set to zero), then the InterfaceIndex member is next used to
* determine the interface. On output, the remaining fields of the
* {@link MIB_IF_ROW2} structure pointed to by the Row parameter are filled in.
*
* @param pIfRow2
* A pointer to a MIB_IF_ROW2 structure that, on successful
* A pointer to a {@link MIB_IF_ROW2} structure that, on successful
* return, receives information for an interface on the local
* computer. On input, the InterfaceLuid or the InterfaceIndex
* member of the MIB_IF_ROW2 must be set to the interface for
* which to retrieve information.
* @return If the function succeeds, the return value is NO_ERROR.
* computer. On input, the InterfaceLuid or the InterfaceIndex member
* of the {@link MIB_IF_ROW2} must be set to the interface for which
* to retrieve information.
* @return If the function succeeds, the return value is
* {@link WinError#NO_ERROR}.
*/
int GetIfEntry2(MIB_IF_ROW2 pIfRow2);

Expand All @@ -261,18 +309,77 @@ public FIXED_INFO() {
* computer.
*
* @param pFixedInfo
* A pointer to a buffer that contains a FIXED_INFO structure
* that receives the network parameters for the local computer,
* if the function was successful. This buffer must be allocated
* by the caller prior to calling the GetNetworkParams function.
* A pointer to a buffer that contains a {@link FIXED_INFO} structure
* that receives the network parameters for the local computer, if
* the function was successful. This buffer must be allocated by the
* caller prior to calling the GetNetworkParams function.
* @param pOutBufLen
* A pointer to a ULONG variable that specifies the size of the
* FIXED_INFO structure. If this size is insufficient to hold the
* information, GetNetworkParams fills in this variable with the
* {@link FIXED_INFO} structure. If this size is insufficient to hold
* the information, GetNetworkParams fills in this variable with the
* required size, and returns an error code of
* ERROR_BUFFER_OVERFLOW.
* @return If the function succeeds, the return value is ERROR_SUCCESS.
* {@link WinError#ERROR_BUFFER_OVERFLOW}.
* @return If the function succeeds, the return value is
* {@link WinError#ERROR_SUCCESS}.
*/
int GetNetworkParams(Pointer pFixedInfo, IntByReference pOutBufLen);
}

/**
* The GetTcpStatistics function retrieves the TCP statistics for the local
* computer.
*
* @param Statistics
* A {@link MIB_TCPSTATS} structure that receives the TCP statistics
* for the local computer.
* @return If the function succeeds, the return value is
* {@link WinError#NO_ERROR}.
*/
int GetTcpStatistics(MIB_TCPSTATS Statistics);

/**
* The GetTcpStatisticsEx function retrieves the Transmission Control Protocol
* (TCP) statistics for the current computer. The GetTcpStatisticsEx function
* differs from the {@link #GetTcpStatistics} function in that
* GetTcpStatisticsEx also supports the Internet Protocol version 6 (IPv6)
* protocol family.
*
* @param Statistics
* A {@link MIB_TCPSTATS} structure that receives the TCP statistics
* for the local computer.
* @param Family
* The protocol family for which to retrieve statistics. This
* parameter must be {@link #AF_INET} or {@link #AF_INET6}.
* @return If the function succeeds, the return value is
* {@link WinError#NO_ERROR}.
*/
int GetTcpStatisticsEx(MIB_TCPSTATS Statistics, int Family);

/**
* The GetUdpStatistics function retrieves the User Datagram Protocol (UDP)
* statistics for the local computer.
*
* @param Statistics
* A {@link MIB_UDPSTATS} structure that receives the UDP statistics
* for the local computer.
* @return If the function succeeds, the return value is
* {@link WinError#NO_ERROR}.
*/
int GetUdpStatistics(MIB_UDPSTATS Statistics);

/**
* The GetUdpStatisticsEx function retrieves the User Datagram Protocol (UDP)
* statistics for the current computer. The GetUdpStatisticsEx function differs
* from the {@link #GetUdpStatistics} function in that GetUdpStatisticsEx also
* supports the Internet Protocol version 6 (IPv6) protocol family.
*
* @param Statistics
* A {@link MIB_UDPSTATS} structure that receives the UDP statistics
* for the local computer.
* @param Family
* The protocol family for which to retrieve statistics. This
* parameter must be {@link #AF_INET} or {@link #AF_INET6}.
* @return If the function succeeds, the return value is
* {@link WinError#NO_ERROR}.
*/
int GetUdpStatisticsEx(MIB_UDPSTATS Statistics, int Family);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018 Daniel Widdis, All Rights Reserved
/* Copyright (c) 2018,2020 Daniel Widdis, All Rights Reserved
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
Expand Down Expand Up @@ -39,6 +39,8 @@
import com.sun.jna.platform.win32.IPHlpAPI.FIXED_INFO;
import com.sun.jna.platform.win32.IPHlpAPI.MIB_IFROW;
import com.sun.jna.platform.win32.IPHlpAPI.MIB_IF_ROW2;
import com.sun.jna.platform.win32.IPHlpAPI.MIB_TCPSTATS;
import com.sun.jna.platform.win32.IPHlpAPI.MIB_UDPSTATS;
import com.sun.jna.ptr.IntByReference;

public class IPHlpAPITest {
Expand Down Expand Up @@ -135,4 +137,36 @@ public void testGetNetworkParams() {
dns = dns.Next;
}
}

@Test
public void testGetTcpStatistics() {
MIB_TCPSTATS stats = new MIB_TCPSTATS();
assertEquals(WinError.NO_ERROR, IPHlpAPI.INSTANCE.GetTcpStatistics(stats));
assertTrue(stats.dwRtoAlgorithm >= 1);
assertTrue(stats.dwRtoAlgorithm <= 4);
assertTrue(stats.dwEstabResets <= stats.dwCurrEstab);

// Above should roughly match IPv4 stats with Ex version
MIB_TCPSTATS stats4 = new MIB_TCPSTATS();
assertEquals(WinError.NO_ERROR, IPHlpAPI.INSTANCE.GetTcpStatisticsEx(stats4, IPHlpAPI.AF_INET));
assertEquals(stats.dwRtoAlgorithm, stats4.dwRtoAlgorithm);
assertTrue(stats4.dwEstabResets <= stats4.dwCurrEstab);
assertTrue(stats.dwActiveOpens <= stats4.dwActiveOpens);
assertTrue(stats.dwPassiveOpens <= stats4.dwPassiveOpens);
}

@Test
public void testGetUdpStatistics() {
MIB_UDPSTATS stats = new MIB_UDPSTATS();
assertEquals(WinError.NO_ERROR, IPHlpAPI.INSTANCE.GetUdpStatistics(stats));
assertTrue(stats.dwNoPorts + stats.dwInErrors <= stats.dwInDatagrams);

// Above should roughly match IPv4 stats with Ex version
MIB_UDPSTATS stats4 = new MIB_UDPSTATS();
assertEquals(WinError.NO_ERROR, IPHlpAPI.INSTANCE.GetUdpStatisticsEx(stats4, IPHlpAPI.AF_INET));
assertTrue(stats.dwNoPorts <= stats4.dwNoPorts);
assertTrue(stats.dwInErrors <= stats4.dwInErrors);
assertTrue(stats.dwInDatagrams <= stats4.dwInDatagrams);
assertTrue(stats4.dwNoPorts + stats4.dwInErrors <= stats4.dwInDatagrams);
}
}