summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/src-server/solaris/NetIf-solaris.cpp')
-rw-r--r--src/VBox/Main/src-server/solaris/NetIf-solaris.cpp133
1 files changed, 80 insertions, 53 deletions
diff --git a/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp b/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp
index bc700820..82e8a338 100644
--- a/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp
+++ b/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008-2011 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -24,6 +24,7 @@
#include <iprt/err.h>
#include <iprt/ctype.h>
+#include <iprt/mem.h>
#include <iprt/path.h>
#include <list>
@@ -73,10 +74,10 @@ static uint32_t getInstance(const char *pszIfaceName, char *pszDevName)
return uInstance;
}
-static uint64_t kstatGet(const char *name)
+static uint32_t kstatGet(const char *name)
{
kstat_ctl_t *kc;
- uint64_t uSpeed = 0;
+ uint32_t uSpeed = 0;
if ((kc = kstat_open()) == 0)
{
@@ -84,14 +85,14 @@ static uint64_t kstatGet(const char *name)
return 0;
}
- kstat_t *ksAdapter = kstat_lookup(kc, "link", -1, (char *)name);
+ kstat_t *ksAdapter = kstat_lookup(kc, (char *)"link", -1, (char *)name);
if (ksAdapter == 0)
{
char szModule[KSTAT_STRLEN];
uint32_t uInstance = getInstance(name, szModule);
- ksAdapter = kstat_lookup(kc, szModule, uInstance, "phys");
+ ksAdapter = kstat_lookup(kc, szModule, uInstance, (char *)"phys");
if (ksAdapter == 0)
- ksAdapter = kstat_lookup(kc, szModule, uInstance, name);
+ ksAdapter = kstat_lookup(kc, szModule, uInstance, (char*)name);
}
if (ksAdapter == 0)
LogRel(("Failed to get network statistics for %s\n", name));
@@ -103,15 +104,21 @@ static uint64_t kstatGet(const char *name)
if ((kn = (kstat_named_t *)kstat_data_lookup(ksAdapter, (char *)"ifspeed")) == 0)
LogRel(("kstat_data_lookup(ifspeed) -> %d, name=%s\n", errno, name));
else
- uSpeed = kn->value.ul;
+ uSpeed = kn->value.ul / 1000000; /* bits -> Mbits */
}
kstat_close(kc);
+ LogFlow(("kstatGet(%s) -> %u Mbit/s\n", name, uSpeed));
return uSpeed;
}
static void queryIfaceSpeed(PNETIFINFO pInfo)
{
- pInfo->uSpeedMbits = kstatGet(pInfo->szShortName) / 1000000; /* bits -> Mbits */
+ /* Don't query interface speed for inactive interfaces (see @bugref{6345}). */
+ if (pInfo->enmStatus == NETIF_S_UP)
+ pInfo->uSpeedMbits = kstatGet(pInfo->szShortName);
+ else
+ pInfo->uSpeedMbits = 0;
+ LogFlow(("queryIfaceSpeed(%s) -> %u\n", pInfo->szShortName, pInfo->uSpeedMbits));
}
static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNetworkInterfaceList)
@@ -192,12 +199,12 @@ static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNe
* Try to get IP V4 address and netmask as well as Ethernet address.
*/
NETIFINFO Info;
- memset(&Info, 0, sizeof(Info));
+ RT_ZERO(Info);
int Sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if (Sock > 0)
{
struct lifreq IfReq;
- strcpy(IfReq.lifr_name, szNICInstance);
+ RTStrCopy(IfReq.lifr_name, sizeof(IfReq.lifr_name), szNICInstance);
if (ioctl(Sock, SIOCGLIFADDR, &IfReq) >= 0)
{
memcpy(Info.IPAddress.au8, &((struct sockaddr_in *)&IfReq.lifr_addr)->sin_addr.s_addr,
@@ -236,7 +243,7 @@ static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNe
if (Sock > 0)
{
struct lifreq IfReq;
- strcpy(IfReq.lifr_name, szNICInstance);
+ RTStrCopy(IfReq.lifr_name, sizeof(IfReq.lifr_name), szNICInstance);
if (ioctl(Sock, SIOCGLIFADDR, &IfReq) >= 0)
{
memcpy(Info.IPv6Address.au8, ((struct sockaddr_in6 *)&IfReq.lifr_addr)->sin6_addr.s6_addr,
@@ -269,7 +276,7 @@ static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNe
strncpy(Info.szShortName, szNICInstance, sizeof(Info.szShortName) - 1);
HostNetworkInterfaceType_T enmType;
- if (strncmp("vboxnet", szNICInstance, 7))
+ if (strncmp(szNICInstance, RT_STR_TUPLE("vboxnet")))
enmType = HostNetworkInterfaceType_Bridged;
else
enmType = HostNetworkInterfaceType_HostOnly;
@@ -285,15 +292,15 @@ static boolean_t vboxSolarisAddLinkHostIface(const char *pszIface, void *pvHostN
/*
* Skip IPSEC interfaces. It's at IP level.
*/
- if (!strncmp(pszIface, "ip.tun", 6))
+ if (!strncmp(pszIface, RT_STR_TUPLE("ip.tun")))
return _B_FALSE;
/*
* Skip our own dynamic VNICs but don't skip VNIC templates.
* These names originate from VBoxNetFltBow-solaris.c, hardcoded here for now.
*/
- if ( strncmp(pszIface, "vboxvnic_template", 17)
- && !strncmp(pszIface, "vboxvnic", 8))
+ if ( strncmp(pszIface, RT_STR_TUPLE("vboxvnic_template"))
+ && !strncmp(pszIface, RT_STR_TUPLE("vboxvnic")))
return _B_FALSE;
/*
@@ -406,59 +413,65 @@ int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list)
if (Sock > 0)
{
struct lifnum IfNum;
- memset(&IfNum, 0, sizeof(IfNum));
+ RT_ZERO(IfNum);
IfNum.lifn_family = AF_INET;
int rc = ioctl(Sock, SIOCGLIFNUM, &IfNum);
if (!rc)
{
- struct lifreq Ifaces[24];
- struct lifconf IfConfig;
- memset(&IfConfig, 0, sizeof(IfConfig));
- IfConfig.lifc_family = AF_INET;
- IfConfig.lifc_len = sizeof(Ifaces);
- IfConfig.lifc_buf = (caddr_t)&(Ifaces[0]);
- rc = ioctl(Sock, SIOCGLIFCONF, &IfConfig);
- if (!rc)
+ int cIfaces = RT_MIN(1024, IfNum.lifn_count); /* sane limit */
+ int cbIfaces = cIfaces * sizeof(struct lifreq);
+ struct lifreq *Ifaces = (struct lifreq *)RTMemTmpAlloc(cbIfaces);
+ if (Ifaces)
{
- for (int i = 0; i < IfNum.lifn_count; i++)
+ struct lifconf IfConfig;
+ RT_ZERO(IfConfig);
+ IfConfig.lifc_family = AF_INET;
+ IfConfig.lifc_len = cbIfaces;
+ IfConfig.lifc_buf = (caddr_t)Ifaces;
+ rc = ioctl(Sock, SIOCGLIFCONF, &IfConfig);
+ if (!rc)
{
- /*
- * Skip loopback interfaces.
- */
- if (!strncmp(Ifaces[i].lifr_name, "lo", 2))
- continue;
-
-#if 0
- rc = ioctl(Sock, SIOCGLIFADDR, &(Ifaces[i]));
- if (rc >= 0)
+ for (int i = 0; i < cIfaces; i++)
{
- memcpy(Info.IPAddress.au8, ((struct sockaddr *)&Ifaces[i].lifr_addr)->sa_data,
- sizeof(Info.IPAddress.au8));
- // SIOCGLIFNETMASK
- struct arpreq ArpReq;
- memcpy(&ArpReq.arp_pa, &Ifaces[i].lifr_addr, sizeof(struct sockaddr_in));
-
/*
- * We might fail if the interface has not been assigned an IP address.
- * That doesn't matter; as long as it's plumbed we can pick it up.
- * But, if it has not acquired an IP address we cannot obtain it's MAC
- * address this way, so we just use all zeros there.
+ * Skip loopback interfaces.
*/
- rc = ioctl(Sock, SIOCGARP, &ArpReq);
+ if (!strncmp(Ifaces[i].lifr_name, RT_STR_TUPLE("lo")))
+ continue;
+
+#if 0
+ rc = ioctl(Sock, SIOCGLIFADDR, &(Ifaces[i]));
if (rc >= 0)
- memcpy(&Info.MACAddress, ArpReq.arp_ha.sa_data, sizeof(Info.MACAddress));
+ {
+ memcpy(Info.IPAddress.au8, ((struct sockaddr *)&Ifaces[i].lifr_addr)->sa_data,
+ sizeof(Info.IPAddress.au8));
+ // SIOCGLIFNETMASK
+ struct arpreq ArpReq;
+ memcpy(&ArpReq.arp_pa, &Ifaces[i].lifr_addr, sizeof(struct sockaddr_in));
+
+ /*
+ * We might fail if the interface has not been assigned an IP address.
+ * That doesn't matter; as long as it's plumbed we can pick it up.
+ * But, if it has not acquired an IP address we cannot obtain it's MAC
+ * address this way, so we just use all zeros there.
+ */
+ rc = ioctl(Sock, SIOCGARP, &ArpReq);
+ if (rc >= 0)
+ memcpy(&Info.MACAddress, ArpReq.arp_ha.sa_data, sizeof(Info.MACAddress));
+
+ char szNICDesc[LIFNAMSIZ + 256];
+ char *pszIface = Ifaces[i].lifr_name;
+ strcpy(szNICDesc, pszIface);
+
+ vboxSolarisAddLinkHostIface(pszIface, &list);
+ }
+#endif
- char szNICDesc[LIFNAMSIZ + 256];
char *pszIface = Ifaces[i].lifr_name;
- strcpy(szNICDesc, pszIface);
-
vboxSolarisAddLinkHostIface(pszIface, &list);
}
-#endif
-
- char *pszIface = Ifaces[i].lifr_name;
- vboxSolarisAddLinkHostIface(pszIface, &list);
}
+ RTMemTmpFree(Ifaces);
}
}
close(Sock);
@@ -486,3 +499,17 @@ int NetIfGetConfigByName(PNETIFINFO pInfo)
return VERR_NOT_IMPLEMENTED;
}
+/**
+ * Retrieve the physical link speed in megabits per second. If the interface is
+ * not up or otherwise unavailable the zero speed is returned.
+ *
+ * @returns VBox status code.
+ *
+ * @param pcszIfName Interface name.
+ * @param puMbits Where to store the link speed.
+ */
+int NetIfGetLinkSpeed(const char *pcszIfName, uint32_t *puMbits)
+{
+ *puMbits = kstatGet(pcszIfName);
+ return VINF_SUCCESS;
+}