|
@@ -41,20 +41,12 @@
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-#ifdef __FreeBSD__
|
|
|
|
-/*
|
|
|
|
- * The code under HAVE_GETIFADDRS condition can't be compiled in FreeBSD.
|
|
|
|
- * Fix it in one of the following patches.
|
|
|
|
- */
|
|
|
|
-#undef HAVE_GETIFADDRS
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
#ifdef HAVE_GETIFADDRS
|
|
#ifdef HAVE_GETIFADDRS
|
|
#include <arpa/inet.h>
|
|
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/socket.h>
|
|
#include <net/if.h>
|
|
#include <net/if.h>
|
|
|
|
+#include <net/ethernet.h>
|
|
#include <sys/types.h>
|
|
#include <sys/types.h>
|
|
-#include <ifaddrs.h>
|
|
|
|
#ifdef CONFIG_SOLARIS
|
|
#ifdef CONFIG_SOLARIS
|
|
#include <sys/sockio.h>
|
|
#include <sys/sockio.h>
|
|
#endif
|
|
#endif
|
|
@@ -2889,6 +2881,57 @@ static int guest_get_network_stats(const char *name,
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifndef __FreeBSD__
|
|
|
|
+/*
|
|
|
|
+ * Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a
|
|
|
|
+ * buffer with ETHER_ADDR_LEN length at least.
|
|
|
|
+ *
|
|
|
|
+ * Returns false in case of an error, otherwise true. "obtained" argument
|
|
|
|
+ * is true if a MAC address was obtained successful, otherwise false.
|
|
|
|
+ */
|
|
|
|
+bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf,
|
|
|
|
+ bool *obtained, Error **errp)
|
|
|
|
+{
|
|
|
|
+ struct ifreq ifr;
|
|
|
|
+ int sock;
|
|
|
|
+
|
|
|
|
+ *obtained = false;
|
|
|
|
+
|
|
|
|
+ /* we haven't obtained HW address yet */
|
|
|
|
+ sock = socket(PF_INET, SOCK_STREAM, 0);
|
|
|
|
+ if (sock == -1) {
|
|
|
|
+ error_setg_errno(errp, errno, "failed to create socket");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ memset(&ifr, 0, sizeof(ifr));
|
|
|
|
+ pstrcpy(ifr.ifr_name, IF_NAMESIZE, ifa->ifa_name);
|
|
|
|
+ if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
|
|
|
|
+ /*
|
|
|
|
+ * We can't get the hw addr of this interface, but that's not a
|
|
|
|
+ * fatal error.
|
|
|
|
+ */
|
|
|
|
+ if (errno == EADDRNOTAVAIL) {
|
|
|
|
+ /* The interface doesn't have a hw addr (e.g. loopback). */
|
|
|
|
+ g_debug("failed to get MAC address of %s: %s",
|
|
|
|
+ ifa->ifa_name, strerror(errno));
|
|
|
|
+ } else{
|
|
|
|
+ g_warning("failed to get MAC address of %s: %s",
|
|
|
|
+ ifa->ifa_name, strerror(errno));
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+#ifdef CONFIG_SOLARIS
|
|
|
|
+ memcpy(buf, &ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
|
|
|
|
+#else
|
|
|
|
+ memcpy(buf, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
|
|
|
|
+#endif
|
|
|
|
+ *obtained = true;
|
|
|
|
+ }
|
|
|
|
+ close(sock);
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+#endif /* __FreeBSD__ */
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Build information about guest interfaces
|
|
* Build information about guest interfaces
|
|
*/
|
|
*/
|
|
@@ -2909,9 +2952,8 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
|
|
GuestNetworkInterfaceStat *interface_stat = NULL;
|
|
GuestNetworkInterfaceStat *interface_stat = NULL;
|
|
char addr4[INET_ADDRSTRLEN];
|
|
char addr4[INET_ADDRSTRLEN];
|
|
char addr6[INET6_ADDRSTRLEN];
|
|
char addr6[INET6_ADDRSTRLEN];
|
|
- int sock;
|
|
|
|
- struct ifreq ifr;
|
|
|
|
- unsigned char *mac_addr;
|
|
|
|
|
|
+ unsigned char mac_addr[ETHER_ADDR_LEN];
|
|
|
|
+ bool obtained;
|
|
void *p;
|
|
void *p;
|
|
|
|
|
|
g_debug("Processing %s interface", ifa->ifa_name);
|
|
g_debug("Processing %s interface", ifa->ifa_name);
|
|
@@ -2926,45 +2968,17 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
|
|
}
|
|
}
|
|
|
|
|
|
if (!info->has_hardware_address) {
|
|
if (!info->has_hardware_address) {
|
|
- /* we haven't obtained HW address yet */
|
|
|
|
- sock = socket(PF_INET, SOCK_STREAM, 0);
|
|
|
|
- if (sock == -1) {
|
|
|
|
- error_setg_errno(errp, errno, "failed to create socket");
|
|
|
|
|
|
+ if (!guest_get_hw_addr(ifa, mac_addr, &obtained, errp)) {
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
-
|
|
|
|
- memset(&ifr, 0, sizeof(ifr));
|
|
|
|
- pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->name);
|
|
|
|
- if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
|
|
|
|
- /*
|
|
|
|
- * We can't get the hw addr of this interface, but that's not a
|
|
|
|
- * fatal error. Don't set info->hardware_address, but keep
|
|
|
|
- * going.
|
|
|
|
- */
|
|
|
|
- if (errno == EADDRNOTAVAIL) {
|
|
|
|
- /* The interface doesn't have a hw addr (e.g. loopback). */
|
|
|
|
- g_debug("failed to get MAC address of %s: %s",
|
|
|
|
- ifa->ifa_name, strerror(errno));
|
|
|
|
- } else{
|
|
|
|
- g_warning("failed to get MAC address of %s: %s",
|
|
|
|
- ifa->ifa_name, strerror(errno));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-#ifdef CONFIG_SOLARIS
|
|
|
|
- mac_addr = (unsigned char *) &ifr.ifr_addr.sa_data;
|
|
|
|
-#else
|
|
|
|
- mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
|
|
|
|
-#endif
|
|
|
|
|
|
+ if (obtained) {
|
|
info->hardware_address =
|
|
info->hardware_address =
|
|
g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
|
|
g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
|
|
(int) mac_addr[0], (int) mac_addr[1],
|
|
(int) mac_addr[0], (int) mac_addr[1],
|
|
(int) mac_addr[2], (int) mac_addr[3],
|
|
(int) mac_addr[2], (int) mac_addr[3],
|
|
(int) mac_addr[4], (int) mac_addr[5]);
|
|
(int) mac_addr[4], (int) mac_addr[5]);
|
|
-
|
|
|
|
info->has_hardware_address = true;
|
|
info->has_hardware_address = true;
|
|
}
|
|
}
|
|
- close(sock);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if (ifa->ifa_addr &&
|
|
if (ifa->ifa_addr &&
|