diff options
author | ZhiPeng Lu <lu.zhipeng@zte.com.cn> | 2017-09-12 16:54:26 +0800 |
---|---|---|
committer | Michael Roth <mdroth@linux.vnet.ibm.com> | 2017-10-25 19:54:11 -0500 |
commit | 53f9fcb263e40ff82b9fcbce8b8cba0f3649ac9b (patch) | |
tree | bcbb0e8989fc550b7098410a77a9ac251e677c1f /qga/commands-win32.c | |
parent | 105fad6bb226ac3404874fe3fd7013ad6f86fc86 (diff) | |
download | qemu-53f9fcb263e40ff82b9fcbce8b8cba0f3649ac9b.zip qemu-53f9fcb263e40ff82b9fcbce8b8cba0f3649ac9b.tar.gz qemu-53f9fcb263e40ff82b9fcbce8b8cba0f3649ac9b.tar.bz2 |
qga: add network stats to guest-network-get-interfaces
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us tomonitor
and analyze network traffic.
Signed-off-by: ZhiPeng Lu <lu.zhipeng@zte.com.cn>
* don't rely on sizeof(wchar[]) for wchar[] indexing
* avoid camelCase variable names
* fix up getline() usage
* condensed commit subject line
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'qga/commands-win32.c')
-rw-r--r-- | qga/commands-win32.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/qga/commands-win32.c b/qga/commands-win32.c index fbd7eb7..0322188 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1153,6 +1153,44 @@ out: } #endif +#define INTERFACE_PATH_BUF_SZ 512 + +static DWORD get_interface_index(const char *guid) +{ + ULONG index; + DWORD status; + wchar_t wbuf[INTERFACE_PATH_BUF_SZ]; + snwprintf(wbuf, INTERFACE_PATH_BUF_SZ, L"\\device\\tcpip_%s", guid); + wbuf[INTERFACE_PATH_BUF_SZ - 1] = 0; + status = GetAdapterIndex (wbuf, &index); + if (status != NO_ERROR) { + return (DWORD)~0; + } else { + return index; + } +} +static int guest_get_network_stats(const char *name, + GuestNetworkInterfaceStat *stats) +{ + DWORD if_index = 0; + MIB_IFROW a_mid_ifrow; + memset(&a_mid_ifrow, 0, sizeof(a_mid_ifrow)); + if_index = get_interface_index(name); + a_mid_ifrow.dwIndex = if_index; + if (NO_ERROR == GetIfEntry(&a_mid_ifrow)) { + stats->rx_bytes = a_mid_ifrow.dwInOctets; + stats->rx_packets = a_mid_ifrow.dwInUcastPkts; + stats->rx_errs = a_mid_ifrow.dwInErrors; + stats->rx_dropped = a_mid_ifrow.dwInDiscards; + stats->tx_bytes = a_mid_ifrow.dwOutOctets; + stats->tx_packets = a_mid_ifrow.dwOutUcastPkts; + stats->tx_errs = a_mid_ifrow.dwOutErrors; + stats->tx_dropped = a_mid_ifrow.dwOutDiscards; + return 0; + } + return -1; +} + GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) { IP_ADAPTER_ADDRESSES *adptr_addrs, *addr; @@ -1160,6 +1198,7 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) GuestNetworkInterfaceList *head = NULL, *cur_item = NULL; GuestIpAddressList *head_addr, *cur_addr; GuestNetworkInterfaceList *info; + GuestNetworkInterfaceStat *interface_stat = NULL; GuestIpAddressList *address_item = NULL; unsigned char *mac_addr; char *addr_str; @@ -1239,6 +1278,17 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) info->value->has_ip_addresses = true; info->value->ip_addresses = head_addr; } + if (!info->value->has_statistics) { + interface_stat = g_malloc0(sizeof(*interface_stat)); + if (guest_get_network_stats(addr->AdapterName, + interface_stat) == -1) { + info->value->has_statistics = false; + g_free(interface_stat); + } else { + info->value->statistics = interface_stat; + info->value->has_statistics = true; + } + } } WSACleanup(); out: |