VirtualBox

Changeset 15510 in vbox for trunk


Ignore:
Timestamp:
Dec 15, 2008 3:32:45 PM (16 years ago)
Author:
vboxsync
Message:

#3282 HostNetIf API: Windows implementation is working and is enabled by default.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Config.kmk

    r15483 r15510  
    396396VBOX_WITH_SCSI = 1
    397397# Enable host network interface API.
    398 if1of ($(KBUILD_TARGET), darwin solaris linux)
     398if1of ($(KBUILD_TARGET), darwin solaris linux win)
    399399 VBOX_WITH_HOSTNETIF_API = 1
    400400endif
  • trunk/src/VBox/Main/HostNetworkInterfaceImpl.cpp

    r15442 r15510  
    130130    m.IPV6NetworkMask = composeIPv6Address(&pIf->IPv6NetMask);
    131131    m.hardwareAddress = composeHardwareAddress(&pIf->MACAddress);
    132     m.type = pIf->enmType;
    133     m.status = pIf->enmStatus;
     132    m.type = (HostNetworkInterfaceType)pIf->enmType;
     133    m.status = (HostNetworkInterfaceStatus)pIf->enmStatus;
    134134
    135135    /* Confirm a successful initialization */
  • trunk/src/VBox/Main/solaris/NetIfList-solaris.cpp

    r15456 r15510  
    166166    {
    167167        struct lifreq IfReq;
    168         strcpy(IfReq.lifr_name, szNICInstance);        if (ioctl(Sock, SIOCGLIFADDR, &IfReq) >= 0)
     168        strcpy(IfReq.lifr_name, szNICInstance);
     169        if (ioctl(Sock, SIOCGLIFADDR, &IfReq) >= 0)
    169170        {
    170171            memcpy(Info.IPv6Address.au8, ((struct sockaddr_in6 *)&IfReq.lifr_addr)->sin6_addr.s6_addr,
  • trunk/src/VBox/Main/win/NetIfList-win.cpp

    r15442 r15510  
    3636#define LOG_GROUP LOG_GROUP_MAIN
    3737
     38#include <iprt/asm.h>
    3839#include <iprt/err.h>
    3940#include <list>
    4041
     42#define _WIN32_DCOM
     43#include <winsock2.h>
     44#include <ws2tcpip.h>
     45#include <windows.h>
     46
     47#ifdef VBOX_WITH_NETFLT
     48#include "VBox/WinNetConfig.h"
     49#endif
     50
     51#include <iphlpapi.h>
     52
     53#include "Logging.h"
    4154#include "HostNetworkInterfaceImpl.h"
    4255#include "netif.h"
    4356
     57
     58static int collectNetIfInfo(Bstr &strName, PNETIFINFO pInfo)
     59{
     60    DWORD dwRc;
     61    /*
     62     * Most of the hosts probably have less than 10 adapters,
     63     * so we'll mostly succeed from the first attempt.
     64     */
     65    ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
     66    PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
     67    if (!pAddresses)
     68        return VERR_NO_MEMORY;
     69    dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
     70    if (dwRc == ERROR_BUFFER_OVERFLOW)
     71    {
     72        /* Impressive! More than 10 adapters! Get more memory and try again. */
     73        RTMemFree(pAddresses);
     74        pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
     75        if (!pAddresses)
     76            return VERR_NO_MEMORY;
     77        dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
     78    }
     79    if (dwRc == NO_ERROR)
     80    {
     81        PIP_ADAPTER_ADDRESSES pAdapter;
     82        for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
     83        {
     84            char *pszUuid = RTStrDup(pAdapter->AdapterName);
     85            size_t len = strlen(pszUuid) - 1;
     86            if (pszUuid[0] == '{' && pszUuid[len] == '}')
     87            {
     88                pszUuid[len] = 0;
     89                if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
     90                {
     91                    bool fIPFound, fIPv6Found;
     92                    PIP_ADAPTER_UNICAST_ADDRESS pAddr;
     93                    fIPFound = fIPv6Found = false;
     94                    for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
     95                    {
     96                        switch (pAddr->Address.lpSockaddr->sa_family)
     97                        {
     98                            case AF_INET:
     99                                if (!fIPFound)
     100                                {
     101                                    fIPFound = true;
     102                                    memcpy(&pInfo->IPAddress,
     103                                        &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
     104                                        sizeof(pInfo->IPAddress));
     105                                }
     106                                break;
     107                            case AF_INET6:
     108                                if (!fIPv6Found)
     109                                {
     110                                    fIPv6Found = true;
     111                                    memcpy(&pInfo->IPv6Address,
     112                                        ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
     113                                        sizeof(pInfo->IPv6Address));
     114                                }
     115                                break;
     116                        }
     117                    }
     118                    PIP_ADAPTER_PREFIX pPrefix;
     119                    fIPFound = fIPv6Found = false;
     120                    for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
     121                    {
     122                        switch (pPrefix->Address.lpSockaddr->sa_family)
     123                        {
     124                            case AF_INET:
     125                                if (!fIPFound)
     126                                {
     127                                    fIPFound = true;
     128                                    ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
     129                                }
     130                                break;
     131                            case AF_INET6:
     132                                if (!fIPv6Found)
     133                                {
     134                                    fIPv6Found = true;
     135                                    ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
     136                                }
     137                                break;
     138                        }
     139                    }
     140                    if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
     141                        Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
     142                    else
     143                        memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
     144                    pInfo->enmType = NETIF_T_ETHERNET;
     145                    pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
     146                    RTStrFree(pszUuid);
     147                    break;
     148                }
     149            }
     150            RTStrFree(pszUuid);
     151        }
     152    }
     153    RTMemFree(pAddresses);
     154
     155    return VINF_SUCCESS;
     156}
     157
     158#ifdef VBOX_WITH_NETFLT
     159# define VBOX_APP_NAME L"VirtualBox"
     160
     161static int vboxNetWinAddComponent(std::list <ComObjPtr <HostNetworkInterface> > * pPist, INetCfgComponent * pncc)
     162{
     163    LPWSTR              lpszName;
     164    GUID                IfGuid;
     165    HRESULT hr;
     166    int rc = VERR_GENERAL_FAILURE;
     167
     168    hr = pncc->GetDisplayName( &lpszName );
     169    Assert(hr == S_OK);
     170    if(hr == S_OK)
     171    {
     172        size_t cUnicodeName = wcslen(lpszName) + 1;
     173        size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
     174        Bstr name (uniLen + 1 /* extra zero */);
     175        wcscpy((wchar_t *) name.mutableRaw(), lpszName);
     176
     177        hr = pncc->GetInstanceGuid(&IfGuid);
     178        Assert(hr == S_OK);
     179        if (hr == S_OK)
     180        {
     181            NETIFINFO Info;
     182            memset(&Info, 0, sizeof(Info));
     183            Info.Uuid = *(Guid(IfGuid).raw());
     184            rc = collectNetIfInfo(name, &Info);
     185            if (RT_FAILURE(rc))
     186            {
     187                Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
     188            }
     189            /* create a new object and add it to the list */
     190            ComObjPtr <HostNetworkInterface> iface;
     191            iface.createObject();
     192            /* remove the curly bracket at the end */
     193            if (SUCCEEDED (iface->init (name, &Info)))
     194            {
     195                pPist->push_back (iface);
     196                rc = VINF_SUCCESS;
     197            }
     198            else
     199            {
     200                Assert(0);
     201            }
     202        }
     203        CoTaskMemFree(lpszName);
     204    }
     205
     206    return rc;
     207}
     208
     209#else /* #ifndef VBOX_WITH_NETFLT */
     210/**
     211 * Windows helper function for NetIfList().
     212 *
     213 * @returns true / false.
     214 *
     215 * @param   guid        The GUID.
     216 */
     217static bool IsTAPDevice(const char *guid)
     218{
     219    HKEY hNetcard;
     220    LONG status;
     221    DWORD len;
     222    int i = 0;
     223    bool ret = false;
     224
     225    status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ, &hNetcard);
     226    if (status != ERROR_SUCCESS)
     227        return false;
     228
     229    for (;;)
     230    {
     231        char szEnumName[256];
     232        char szNetCfgInstanceId[256];
     233        DWORD dwKeyType;
     234        HKEY  hNetCardGUID;
     235
     236        len = sizeof(szEnumName);
     237        status = RegEnumKeyExA(hNetcard, i, szEnumName, &len, NULL, NULL, NULL, NULL);
     238        if (status != ERROR_SUCCESS)
     239            break;
     240
     241        status = RegOpenKeyExA(hNetcard, szEnumName, 0, KEY_READ, &hNetCardGUID);
     242        if (status == ERROR_SUCCESS)
     243        {
     244            len = sizeof(szNetCfgInstanceId);
     245            status = RegQueryValueExA(hNetCardGUID, "NetCfgInstanceId", NULL, &dwKeyType, (LPBYTE)szNetCfgInstanceId, &len);
     246            if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
     247            {
     248                char szNetProductName[256];
     249                char szNetProviderName[256];
     250
     251                szNetProductName[0] = 0;
     252                len = sizeof(szNetProductName);
     253                status = RegQueryValueExA(hNetCardGUID, "ProductName", NULL, &dwKeyType, (LPBYTE)szNetProductName, &len);
     254
     255                szNetProviderName[0] = 0;
     256                len = sizeof(szNetProviderName);
     257                status = RegQueryValueExA(hNetCardGUID, "ProviderName", NULL, &dwKeyType, (LPBYTE)szNetProviderName, &len);
     258
     259                if (   !strcmp(szNetCfgInstanceId, guid)
     260                    && !strcmp(szNetProductName, "VirtualBox TAP Adapter")
     261                    && (   (!strcmp(szNetProviderName, "innotek GmbH"))
     262                        || (!strcmp(szNetProviderName, "Sun Microsystems, Inc."))))
     263                {
     264                    ret = true;
     265                    RegCloseKey(hNetCardGUID);
     266                    break;
     267                }
     268            }
     269            RegCloseKey(hNetCardGUID);
     270        }
     271        ++i;
     272    }
     273
     274    RegCloseKey(hNetcard);
     275    return ret;
     276}
     277#endif /* #ifndef VBOX_WITH_NETFLT */
     278
    44279int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
    45280{
    46     return VERR_NOT_IMPLEMENTED;
     281#ifndef VBOX_WITH_NETFLT
     282    static const char *NetworkKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\"
     283                                    "{4D36E972-E325-11CE-BFC1-08002BE10318}";
     284    HKEY hCtrlNet;
     285    LONG status;
     286    DWORD len;
     287    status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, NetworkKey, 0, KEY_READ, &hCtrlNet);
     288    if (status != ERROR_SUCCESS)
     289    {
     290        Log(("NetIfList: Could not open registry key \"%s\"", NetworkKey));
     291        return E_FAIL;
     292    }
     293
     294    for (int i = 0;; ++ i)
     295    {
     296        char szNetworkGUID [256];
     297        HKEY hConnection;
     298        char szNetworkConnection [256];
     299
     300        len = sizeof (szNetworkGUID);
     301        status = RegEnumKeyExA (hCtrlNet, i, szNetworkGUID, &len, NULL, NULL, NULL, NULL);
     302        if (status != ERROR_SUCCESS)
     303            break;
     304
     305        if (!IsTAPDevice(szNetworkGUID))
     306            continue;
     307
     308        RTStrPrintf (szNetworkConnection, sizeof (szNetworkConnection),
     309                     "%s\\Connection", szNetworkGUID);
     310        status = RegOpenKeyExA (hCtrlNet, szNetworkConnection, 0, KEY_READ,  &hConnection);
     311        if (status == ERROR_SUCCESS)
     312        {
     313            DWORD dwKeyType;
     314            status = RegQueryValueExW (hConnection, TEXT("Name"), NULL,
     315                                       &dwKeyType, NULL, &len);
     316            if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
     317            {
     318                size_t uniLen = (len + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
     319                Bstr name (uniLen + 1 /* extra zero */);
     320                status = RegQueryValueExW (hConnection, TEXT("Name"), NULL,
     321                                           &dwKeyType, (LPBYTE) name.mutableRaw(), &len);
     322                if (status == ERROR_SUCCESS)
     323                {
     324                    LogFunc(("Connection name %ls\n", name.mutableRaw()));
     325                    /* put a trailing zero, just in case (see MSDN) */
     326                    name.mutableRaw() [uniLen] = 0;
     327                    /* create a new object and add it to the list */
     328                    ComObjPtr <HostNetworkInterface> iface;
     329                    iface.createObject();
     330                    /* remove the curly bracket at the end */
     331                    szNetworkGUID [strlen(szNetworkGUID) - 1] = '\0';
     332
     333                    NETIFINFO Info;
     334                    memset(&Info, 0, sizeof(Info));
     335                    Info.Uuid = *(Guid(szNetworkGUID + 1).raw());
     336                    int rc = collectNetIfInfo(name, &Info);
     337                    if (RT_FAILURE(rc))
     338                    {
     339                        Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
     340                    }
     341
     342                    if (SUCCEEDED (iface->init (name, &Info)))
     343                        list.push_back (iface);
     344                }
     345            }
     346            RegCloseKey (hConnection);
     347        }
     348    }
     349    RegCloseKey (hCtrlNet);
     350#else /* #  if defined VBOX_WITH_NETFLT */
     351    INetCfg              *pNc;
     352    INetCfgComponent     *pMpNcc;
     353    INetCfgComponent     *pTcpIpNcc;
     354    LPWSTR               lpszApp;
     355    HRESULT              hr;
     356    IEnumNetCfgBindingPath      *pEnumBp;
     357    INetCfgBindingPath          *pBp;
     358    IEnumNetCfgBindingInterface *pEnumBi;
     359    INetCfgBindingInterface *pBi;
     360
     361    /* we are using the INetCfg API for getting the list of miniports */
     362    hr = VBoxNetCfgWinQueryINetCfg( FALSE,
     363                       VBOX_APP_NAME,
     364                       &pNc,
     365                       &lpszApp );
     366    Assert(hr == S_OK);
     367    if(hr == S_OK)
     368    {
     369# ifdef VBOX_NETFLT_ONDEMAND_BIND
     370        /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
     371        hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
     372# else
     373        /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
     374        hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
     375#  ifndef VBOX_WITH_HARDENING
     376        if(hr != S_OK)
     377        {
     378            /* TODO: try to install the netflt from here */
     379        }
     380#  endif
     381
     382# endif
     383
     384        if(hr == S_OK)
     385        {
     386            hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
     387            Assert(hr == S_OK);
     388            if ( hr == S_OK )
     389            {
     390                hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
     391                Assert(hr == S_OK || hr == S_FALSE);
     392                while( hr == S_OK )
     393                {
     394                    /* S_OK == enabled, S_FALSE == disabled */
     395                    if(pBp->IsEnabled() == S_OK)
     396                    {
     397                        hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
     398                        Assert(hr == S_OK);
     399                        if ( hr == S_OK )
     400                        {
     401                            hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
     402                            Assert(hr == S_OK);
     403                            while(hr == S_OK)
     404                            {
     405                                hr = pBi->GetLowerComponent( &pMpNcc );
     406                                Assert(hr == S_OK);
     407                                if(hr == S_OK)
     408                                {
     409                                    vboxNetWinAddComponent(&list, pMpNcc);
     410                                    VBoxNetCfgWinReleaseRef( pMpNcc );
     411                                }
     412                                VBoxNetCfgWinReleaseRef(pBi);
     413
     414                                hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
     415                            }
     416                            VBoxNetCfgWinReleaseRef(pEnumBi);
     417                        }
     418                    }
     419                    VBoxNetCfgWinReleaseRef(pBp);
     420
     421                    hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
     422                }
     423                VBoxNetCfgWinReleaseRef(pEnumBp);
     424            }
     425            VBoxNetCfgWinReleaseRef(pTcpIpNcc);
     426        }
     427        else
     428        {
     429            LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
     430        }
     431
     432        VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
     433    }
     434#endif /* #  if defined VBOX_WITH_NETFLT */
     435    return VINF_SUCCESS;
    47436}
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