qga: replace GetIfEntry with GetIfEntry2 for interface stats

The data obtained by GetIfEntry is 32 bits, and it may overflow. Thus
using GetIfEntry2 instead of GetIfEntry.

Signed-off-by: ZhiPeng Lu <lu.zhipeng@zte.com.cn>
*avoid CamelCase variable names
*update field names for MIB_IFROW -> MIB_IF_ROW2
*dynamically probe for GetIfIndex2 to deal with older OSs
*check return value from get_interface_index
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
This commit is contained in:
ZhiPeng Lu 2017-11-03 22:54:20 +08:00 committed by Michael Roth
parent b2996bb405
commit df83eabd52
1 changed files with 38 additions and 16 deletions

View File

@ -1169,25 +1169,47 @@ static DWORD get_interface_index(const char *guid)
return index; return index;
} }
} }
typedef NETIOAPI_API (WINAPI *GetIfEntry2Func)(PMIB_IF_ROW2 Row);
static int guest_get_network_stats(const char *name, static int guest_get_network_stats(const char *name,
GuestNetworkInterfaceStat *stats) GuestNetworkInterfaceStat *stats)
{ {
OSVERSIONINFO os_ver;
os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&os_ver);
if (os_ver.dwMajorVersion >= 6) {
MIB_IF_ROW2 a_mid_ifrow;
GetIfEntry2Func getifentry2_ex;
DWORD if_index = 0; DWORD if_index = 0;
MIB_IFROW a_mid_ifrow; HMODULE module = GetModuleHandle("iphlpapi");
memset(&a_mid_ifrow, 0, sizeof(a_mid_ifrow)); PVOID func = GetProcAddress(module, "GetIfEntry2");
if (func == NULL) {
return -1;
}
getifentry2_ex = (GetIfEntry2Func)func;
if_index = get_interface_index(name); if_index = get_interface_index(name);
a_mid_ifrow.dwIndex = if_index; if (if_index == (DWORD)~0) {
if (NO_ERROR == GetIfEntry(&a_mid_ifrow)) { return -1;
stats->rx_bytes = a_mid_ifrow.dwInOctets; }
stats->rx_packets = a_mid_ifrow.dwInUcastPkts;
stats->rx_errs = a_mid_ifrow.dwInErrors; memset(&a_mid_ifrow, 0, sizeof(a_mid_ifrow));
stats->rx_dropped = a_mid_ifrow.dwInDiscards; a_mid_ifrow.InterfaceIndex = if_index;
stats->tx_bytes = a_mid_ifrow.dwOutOctets; if (NO_ERROR == getifentry2_ex(&a_mid_ifrow)) {
stats->tx_packets = a_mid_ifrow.dwOutUcastPkts; stats->rx_bytes = a_mid_ifrow.InOctets;
stats->tx_errs = a_mid_ifrow.dwOutErrors; stats->rx_packets = a_mid_ifrow.InUcastPkts;
stats->tx_dropped = a_mid_ifrow.dwOutDiscards; stats->rx_errs = a_mid_ifrow.InErrors;
stats->rx_dropped = a_mid_ifrow.InDiscards;
stats->tx_bytes = a_mid_ifrow.OutOctets;
stats->tx_packets = a_mid_ifrow.OutUcastPkts;
stats->tx_errs = a_mid_ifrow.OutErrors;
stats->tx_dropped = a_mid_ifrow.OutDiscards;
return 0; return 0;
} }
}
return -1; return -1;
} }