aboutsummaryrefslogtreecommitdiff
path: root/qga/commands-win32.c
diff options
context:
space:
mode:
authorZhiPeng Lu <lu.zhipeng@zte.com.cn>2017-09-12 16:54:26 +0800
committerMichael Roth <mdroth@linux.vnet.ibm.com>2017-10-25 19:54:11 -0500
commit53f9fcb263e40ff82b9fcbce8b8cba0f3649ac9b (patch)
treebcbb0e8989fc550b7098410a77a9ac251e677c1f /qga/commands-win32.c
parent105fad6bb226ac3404874fe3fd7013ad6f86fc86 (diff)
downloadqemu-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.c50
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: