diff options
Diffstat (limited to 'src/VBox/Main/src-server/solaris/NetIf-solaris.cpp')
-rw-r--r-- | src/VBox/Main/src-server/solaris/NetIf-solaris.cpp | 133 |
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; +} |