VirtualBox

Changeset 57554 in vbox for trunk/src/VBox/Main/src-server


Ignore:
Timestamp:
Aug 27, 2015 9:13:49 AM (9 years ago)
Author:
vboxsync
Message:

Main/Network: alternative implementation of NetIfList using GetAdaptersAddresses instead of INetCfg (#7993)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/win/NetIf-win.cpp

    r57536 r57554  
    2222*********************************************************************************************************************************/
    2323#define LOG_GROUP LOG_GROUP_MAIN
     24
     25#define NETIF_WITHOUT_NETCFG
    2426
    2527#include <iprt/asm.h>
     
    14511453}
    14521454
     1455#ifndef NETIF_WITHOUT_NETCFG
    14531456int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
    14541457{
     
    16391642#endif /* #  if defined VBOX_WITH_NETFLT */
    16401643}
     1644
     1645#else /* !NETIF_WITHOUT_NETCFG */
     1646int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
     1647{
     1648    DWORD dwRc;
     1649    int rc = VINF_SUCCESS;
     1650    int iDefault = getDefaultInterfaceIndex();
     1651    /*
     1652     * Most of the hosts probably have less than 10 adapters,
     1653     * so we'll mostly succeed from the first attempt.
     1654     */
     1655    ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
     1656    PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
     1657    if (!pAddresses)
     1658        return VERR_NO_MEMORY;
     1659    dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
     1660    if (dwRc == ERROR_BUFFER_OVERFLOW)
     1661    {
     1662        /* Impressive! More than 10 adapters! Get more memory and try again. */
     1663        RTMemFree(pAddresses);
     1664        pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
     1665        if (!pAddresses)
     1666            return VERR_NO_MEMORY;
     1667        dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
     1668    }
     1669    if (dwRc == NO_ERROR)
     1670    {
     1671        PIP_ADAPTER_ADDRESSES pAdapter;
     1672        for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
     1673        {
     1674            LogRel(("Enumerating %s\n", pAdapter->AdapterName));
     1675            if (pAdapter->IfType != IF_TYPE_ETHERNET_CSMACD)
     1676            {
     1677                LogRel(("Skipped non-Ethernet '%ls'\n", pAdapter->FriendlyName));
     1678                continue;
     1679            }
     1680
     1681            NETIFINFO Info;
     1682            RT_ZERO(Info);
     1683
     1684            if (pAdapter->AdapterName[0] == '{')
     1685            {
     1686                char *pszUuid = pAdapter->AdapterName + 1;
     1687                size_t len = strlen(pszUuid) - 1;
     1688                if (pszUuid[len] != '}')
     1689                {
     1690                    LogRel(("%s is not a valid UUID!\n", pAdapter->AdapterName));
     1691                    continue;
     1692                }
     1693                pszUuid[len] = 0;
     1694                rc = RTUuidFromStr(&Info.Uuid, pszUuid);
     1695                if (RT_FAILURE(rc))
     1696                {
     1697                    LogRel(("NetIfList: Failed to convert %s to UUID (%Rrc)\n", pszUuid, rc));
     1698                    continue;
     1699                }
     1700                bool fIPv4Found, fIPv6Found;
     1701                PIP_ADAPTER_UNICAST_ADDRESS pAddr;
     1702                fIPv4Found = fIPv6Found = false;
     1703                for (pAddr = pAdapter->FirstUnicastAddress;
     1704                     pAddr && !(fIPv4Found && fIPv6Found);
     1705                     pAddr = pAddr->Next)
     1706                {
     1707                    switch (pAddr->Address.lpSockaddr->sa_family)
     1708                    {
     1709                        case AF_INET:
     1710                            if (!fIPv4Found)
     1711                            {
     1712                                fIPv4Found = true;
     1713                                memcpy(&Info.IPAddress,
     1714                                       &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
     1715                                       sizeof(Info.IPAddress));
     1716                            }
     1717                            break;
     1718                        case AF_INET6:
     1719                            if (!fIPv6Found)
     1720                            {
     1721                                fIPv6Found = true;
     1722                                memcpy(&Info.IPv6Address,
     1723                                       ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
     1724                                       sizeof(Info.IPv6Address));
     1725                            }
     1726                            break;
     1727                    }
     1728                }
     1729                PIP_ADAPTER_PREFIX pPrefix;
     1730                fIPv4Found = fIPv6Found = false;
     1731                for (pPrefix = pAdapter->FirstPrefix;
     1732                     pPrefix && !(fIPv4Found && fIPv6Found);
     1733                     pPrefix = pPrefix->Next)
     1734                {
     1735                    switch (pPrefix->Address.lpSockaddr->sa_family)
     1736                    {
     1737                        case AF_INET:
     1738                            if (!fIPv4Found)
     1739                            {
     1740                                if (pPrefix->PrefixLength <= sizeof(Info.IPNetMask) * 8)
     1741                                {
     1742                                    fIPv4Found = true;
     1743                                    ASMBitSetRange(&Info.IPNetMask, 0, pPrefix->PrefixLength);
     1744                                }
     1745                                else
     1746                                    LogRel(("NetIfList: Unexpected IPv4 prefix length of %d\n",
     1747                                            pPrefix->PrefixLength));
     1748                            }
     1749                            break;
     1750                        case AF_INET6:
     1751                            if (!fIPv6Found)
     1752                            {
     1753                                if (pPrefix->PrefixLength <= sizeof(Info.IPv6NetMask) * 8)
     1754                                {
     1755                                    fIPv6Found = true;
     1756                                    ASMBitSetRange(&Info.IPv6NetMask, 0, pPrefix->PrefixLength);
     1757                                }
     1758                                else
     1759                                    LogRel(("NetIfList: Unexpected IPv6 prefix length of %d\n",
     1760                                            pPrefix->PrefixLength));
     1761                            }
     1762                            break;
     1763                    }
     1764                }
     1765                if (sizeof(Info.MACAddress) != pAdapter->PhysicalAddressLength)
     1766                    LogRel(("NetIfList: Unexpected physical address length: %u\n",
     1767                            pAdapter->PhysicalAddressLength));
     1768                else
     1769                    memcpy(Info.MACAddress.au8, pAdapter->PhysicalAddress, sizeof(Info.MACAddress));
     1770                Info.enmMediumType = NETIF_T_ETHERNET;
     1771                Info.enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
     1772                Info.bDhcpEnabled = !!(pAdapter->Flags & IP_ADAPTER_DHCP_ENABLED);
     1773                Info.bIsDefault = (pAdapter->IfIndex == iDefault);
     1774                HostNetworkInterfaceType enmType;
     1775                /*
     1776                 * For some reason, I would not even want to speculate what it is, the users see
     1777                 * adapter's description as its name in its property dialog box.
     1778                 */
     1779                enmType = wcsncmp(pAdapter->Description, L"VirtualBox", 10) == 0
     1780                    ? HostNetworkInterfaceType_HostOnly
     1781                    : HostNetworkInterfaceType_Bridged;
     1782                LogRel(("Adding %ls as %s\n", pAdapter->Description,
     1783                        enmType == HostNetworkInterfaceType_Bridged ? "bridged" : "host-only"));
     1784                /* create a new object and add it to the list */
     1785                ComObjPtr<HostNetworkInterface> iface;
     1786                iface.createObject();
     1787                /* remove the curly bracket at the end */
     1788                rc = iface->init(pAdapter->Description, enmType, &Info);
     1789                if (SUCCEEDED(rc))
     1790                {
     1791                    if (Info.bIsDefault)
     1792                        list.push_front(iface);
     1793                    else
     1794                        list.push_back(iface);
     1795                }
     1796                else
     1797                {
     1798                    LogRel(("vboxNetWinAddComponent: HostNetworkInterface::init() -> %Rrc\n", rc));
     1799                    Assert(0);
     1800                }
     1801            }
     1802        }
     1803    }
     1804
     1805    RTMemFree(pAddresses);
     1806
     1807    return VINF_SUCCESS;
     1808}
     1809#endif /* !NETIF_WITHOUT_NETCFG */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette