VirtualBox

Changeset 11846 in vbox for trunk/src


Ignore:
Timestamp:
Aug 29, 2008 7:29:57 PM (16 years ago)
Author:
vboxsync
Message:

Main/vboxnetflt: Better NIC enumeration for Solaris. Got rid of libkstat.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/HostImpl.cpp

    r11829 r11846  
    4646
    4747#ifdef RT_OS_SOLARIS
    48 # include <kstat.h>
    4948# include <fcntl.h>
    5049# include <unistd.h>
     
    5352# include <limits.h>
    5453# include <stdio.h>
     54# include <sys/socket.h>
     55# include <sys/sockio.h>
     56# include <net/if_arp.h>
     57# include <net/if.h>
    5558# include <sys/types.h>
    5659# include <sys/stat.h>
     
    155158# elif defined (RT_OS_OS2)
    156159    mUSBProxyService = new USBProxyServiceOs2 (this);
    157 # elif defined (RT_OS_SOLARIS) && 0
     160# elif defined (RT_OS_SOLARIS)
    158161    mUSBProxyService = new USBProxyServiceSolaris (this);
    159162# elif defined (RT_OS_WINDOWS)
     
    553556# elif defined(RT_OS_SOLARIS)
    554557
    555     kstat_ctl_t *pStatCtl = kstat_open();
    556     if (pStatCtl)
    557     {
    558         kstat_t *pStat;
    559         for (pStat = pStatCtl->kc_chain; pStat; pStat = pStat->ks_next)
    560         {
    561             if (!strcmp(pStat->ks_class, "net"))
    562             {
    563                 if (!strcmp(pStat->ks_module, "lo"))    /** Skip loopback interfaces */
    564                     continue;
    565 
    566                 char szIface[8];
    567                 RTStrPrintf(szIface, sizeof(szIface), "%s%d", pStat->ks_module, pStat->ks_instance);
    568                 if (!strcmp(szIface, pStat->ks_name))
     558    int Sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
     559    if (Sock > 0)
     560    {
     561        struct lifnum IfNum;
     562        memset(&IfNum, 0, sizeof(IfNum));
     563        IfNum.lifn_family = AF_INET;
     564        int rc = ioctl(Sock, SIOCGLIFNUM, &IfNum);
     565        if (!rc)
     566        {
     567            struct lifreq Ifaces[24];
     568            struct lifconf IfConfig;
     569            memset(&IfConfig, 0, sizeof(IfConfig));
     570            IfConfig.lifc_family = AF_INET;
     571            IfConfig.lifc_len = sizeof(Ifaces);
     572            IfConfig.lifc_buf = (caddr_t)&(Ifaces[0]);
     573            rc = ioctl(Sock, SIOCGLIFCONF, &IfConfig);
     574            if (!rc)
     575            {
     576                /*
     577                 * Ok now we go the interfaces, get the info we need (i.e MAC address).
     578                 */
     579                for (int i = 0; i < IfNum.lifn_count; i++)
    569580                {
    570                     /*
    571                      * Figuring out the MAC address from the interface on Solaris isn't trivial.
    572                      * Requires root privileges; usage of dlpi and/or getting a MAC address from
    573                      * ARP using ioctl SIOCGARP. So we just use the BSD name for now...
    574                      */
    575                     RTUUID Uuid;
    576                     RTUuidClear(&Uuid);
    577                     memcpy(&Uuid, szIface, RT_MIN(sizeof(szIface), sizeof(Uuid)));
    578                     Uuid.Gen.u8ClockSeqHiAndReserved = (Uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80;
    579                     Uuid.Gen.u16TimeHiAndVersion = (Uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000;
    580 
    581                     ComObjPtr<HostNetworkInterface> IfObj;
    582                     IfObj.createObject();
    583                     if (SUCCEEDED(IfObj->init(Bstr(szIface), Guid(Uuid))))
    584                         list.push_back(IfObj);
     581                    rc = ioctl(Sock, SIOCGLIFADDR, &(Ifaces[i]));
     582                    if (!rc)
     583                    {
     584                        struct arpreq ArpReq;
     585                        memcpy(&ArpReq.arp_pa, &Ifaces[i].lifr_addr, sizeof(struct sockaddr_in));
     586                        rc = ioctl(Sock, SIOCGARP, &ArpReq);
     587                        if (!rc)
     588                        {
     589                            RTMAC Mac;
     590                            memcpy(&Mac, ArpReq.arp_ha.sa_data, sizeof(RTMAC));
     591
     592                            char *pszIface = Ifaces[i].lifr_name;
     593
     594                            RTUUID Uuid;
     595                            RTUuidClear(&Uuid);
     596                            memcpy(&Uuid, pszIface, RT_MIN(strlen(pszIface), sizeof(Uuid)));
     597                            Uuid.Gen.u8ClockSeqHiAndReserved = (Uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80;
     598                            Uuid.Gen.u16TimeHiAndVersion = (Uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000;
     599                            Uuid.Gen.au8Node[0] = Mac.au8[0];
     600                            Uuid.Gen.au8Node[1] = Mac.au8[1];
     601                            Uuid.Gen.au8Node[2] = Mac.au8[2];
     602                            Uuid.Gen.au8Node[3] = Mac.au8[3];
     603                            Uuid.Gen.au8Node[4] = Mac.au8[4];
     604                            Uuid.Gen.au8Node[5] = Mac.au8[5];
     605
     606                            ComObjPtr<HostNetworkInterface> IfObj;
     607                            IfObj.createObject();
     608                            if (SUCCEEDED(IfObj->init(Bstr(pszIface), Guid(Uuid))))
     609                                list.push_back(IfObj);
     610                        }
     611                    }
    585612                }
    586613            }
    587614        }
     615        close(Sock);
    588616    }
    589617
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