/**
* Oshi (https://github.com/oshi/oshi)
*
* Copyright (c) 2010 - 2017 The Oshi Project Team
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Maintainers:
* dblock[at]dblock[dot]org
* widdis[at]gmail[dot]com
* enrico.bianchi[at]gmail[dot]com
*
* Contributors:
* https://github.com/oshi/oshi/graphs/contributors
*/
package oshi.hardware.platform.windows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinNT.OSVERSIONINFO;
import oshi.hardware.NetworkIF;
import oshi.hardware.common.AbstractNetworks;
import oshi.jna.platform.windows.IPHlpAPI;
import oshi.jna.platform.windows.IPHlpAPI.MIB_IFROW;
import oshi.jna.platform.windows.IPHlpAPI.MIB_IFROW2;
/**
* @author widdis[at]gmail[dot]com
*/
public class WindowsNetworks extends AbstractNetworks {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(WindowsNetworks.class);
// Save Windows version info for 32 bit/64 bit branch later
private static final byte majorVersion;
static {
OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO();
// GetVersionEx() isn't accurate for Win8+ but is sufficient for
// detecting versions 5.x and earlier
if (!Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)) {
majorVersion = lpVersionInfo.dwMajorVersion.byteValue();
} else {
majorVersion = 0;
}
}
/**
* Updates interface network statistics on the given interface. Statistics
* include packets and bytes sent and received, and interface speed.
*
* @param netIF
* The interface on which to update statistics
*/
public static void updateNetworkStats(NetworkIF netIF) {
// MIB_IFROW2 requires Vista (6.0) or later.
if (majorVersion >= 6) {
// Create new MIB_IFROW2 and set index to this interface index
MIB_IFROW2 ifRow = new MIB_IFROW2();
ifRow.InterfaceIndex = new ULONG(netIF.getNetworkInterface().getIndex());
if (0 != IPHlpAPI.INSTANCE.GetIfEntry2(ifRow)) {
// Error, abort
LOG.error("Failed to retrieve data for interface {}, {}", netIF.getNetworkInterface().getIndex(),
netIF.getName());
return;
}
// These are unsigned longs. netIF setter will mask sign bit.
netIF.setBytesSent(ifRow.OutOctets);
netIF.setBytesRecv(ifRow.InOctets);
netIF.setPacketsSent(ifRow.OutUcastPkts);
netIF.setPacketsRecv(ifRow.InUcastPkts);
netIF.setOutErrors(ifRow.OutErrors);
netIF.setInErrors(ifRow.InErrors);
netIF.setSpeed(ifRow.ReceiveLinkSpeed);
} else {
// Create new MIB_IFROW and set index to this interface index
MIB_IFROW ifRow = new MIB_IFROW();
ifRow.dwIndex = netIF.getNetworkInterface().getIndex();
if (0 != IPHlpAPI.INSTANCE.GetIfEntry(ifRow)) {
// Error, abort
LOG.error("Failed to retrieve data for interface {}, {}", netIF.getNetworkInterface().getIndex(),
netIF.getName());
return;
}
// These are unsigned ints. Widen them to longs.
netIF.setBytesSent(ifRow.dwOutOctets & 0xfffffffL);
netIF.setBytesRecv(ifRow.dwInOctets & 0xfffffffL);
netIF.setPacketsSent(ifRow.dwOutUcastPkts & 0xfffffffL);
netIF.setPacketsRecv(ifRow.dwInUcastPkts & 0xfffffffL);
netIF.setOutErrors(ifRow.dwOutErrors & 0xfffffffL);
netIF.setInErrors(ifRow.dwInErrors & 0xfffffffL);
netIF.setSpeed(ifRow.dwSpeed & 0xfffffffL);
}
netIF.setTimeStamp(System.currentTimeMillis());
}
}