VirtualBox

Changeset 20475 in vbox for trunk/src


Ignore:
Timestamp:
Jun 11, 2009 1:30:26 PM (16 years ago)
Author:
vboxsync
Message:

#3773: Detection of primary NIC for bridging in Darwin.

File:
1 edited

Legend:

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

    r19433 r20475  
    160160#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
    161161
    162 void extractAddresses(int iAddrMask, caddr_t cp, caddr_t cplim, PNETIFINFO pInfo)
     162void extractAddresses(int iAddrMask, caddr_t cp, caddr_t cplim, struct sockaddr **pAddresses)
    163163{
    164     struct sockaddr *sa, *addresses[RTAX_MAX];
     164    struct sockaddr *sa;
    165165
    166166    for (int i = 0; i < RTAX_MAX && cp < cplim; i++) {
     
    170170        sa = (struct sockaddr *)cp;
    171171
    172         addresses[i] = sa;
     172        pAddresses[i] = sa;
    173173       
    174174        ADVANCE(cp, sa);
    175175    }
    176 
     176}
     177
     178void extractAddressesToNetInfo(int iAddrMask, caddr_t cp, caddr_t cplim, PNETIFINFO pInfo)
     179{
     180    struct sockaddr *addresses[RTAX_MAX];
     181
     182    extractAddresses(iAddrMask, cp, cplim, addresses);
    177183    switch (addresses[RTAX_IFA]->sa_family)
    178184    {
     
    196202            break;
    197203        default:
    198             Log(("NetIfList: Unsupported address family: %u\n", sa->sa_family));
     204            Log(("NetIfList: Unsupported address family: %u\n", addresses[RTAX_IFA]->sa_family));
    199205            break;
    200206    }
     207}
     208
     209static int getDefaultIfaceIndex(unsigned short *pu16Index)
     210{
     211    size_t cbNeeded;
     212    char *pBuf, *pNext;
     213    int aiMib[6];
     214    struct sockaddr *addresses[RTAX_MAX];
     215   
     216    aiMib[0] = CTL_NET;
     217    aiMib[1] = PF_ROUTE;
     218    aiMib[2] = 0;
     219    aiMib[3] = PF_INET; /* address family */
     220    aiMib[4] = NET_RT_DUMP;
     221    aiMib[5] = 0;
     222
     223    if (sysctl(aiMib, 6, NULL, &cbNeeded, NULL, 0) < 0)
     224    {
     225        Log(("getDefaultIfaceIndex: Failed to get estimate for list size (errno=%d).\n", errno));
     226        return RTErrConvertFromErrno(errno);
     227    }
     228    if ((pBuf = (char*)malloc(cbNeeded)) == NULL)
     229        return VERR_NO_MEMORY;
     230    if (sysctl(aiMib, 6, pBuf, &cbNeeded, NULL, 0) < 0)
     231    {
     232        free(pBuf);
     233        Log(("getDefaultIfaceIndex: Failed to retrieve interface table (errno=%d).\n", errno));
     234        return RTErrConvertFromErrno(errno);
     235    }
     236
     237    char *pEnd = pBuf + cbNeeded;
     238    struct rt_msghdr *pRtMsg;
     239    for (pNext = pBuf; pNext < pEnd; pNext += pRtMsg->rtm_msglen)
     240    {
     241        pRtMsg = (struct rt_msghdr *)pNext;
     242
     243        if (pRtMsg->rtm_type != RTM_GET)
     244        {
     245            Log(("getDefaultIfaceIndex: Got message %u while expecting %u.\n",
     246                 pRtMsg->rtm_type, RTM_GET));
     247            //rc = VERR_INTERNAL_ERROR;
     248            continue;
     249        }
     250        if ((char*)(pRtMsg + 1) < pEnd)
     251        {
     252            /* Extract addresses from the message. */
     253            extractAddresses(pRtMsg->rtm_addrs, (char *)(pRtMsg + 1),
     254                             pRtMsg->rtm_msglen + (char *)pRtMsg, addresses);
     255            if ((pRtMsg->rtm_addrs & RTA_DST))
     256            {
     257                if (addresses[RTAX_DST]->sa_family != AF_INET)
     258                    continue;
     259                struct sockaddr_in *addr = (struct sockaddr_in *)addresses[RTAX_DST];
     260                struct sockaddr_in *mask = (struct sockaddr_in *)addresses[RTAX_NETMASK];
     261                if ((addr->sin_addr.s_addr == INADDR_ANY) &&
     262                    mask &&
     263                    (ntohl(mask->sin_addr.s_addr) == 0L ||
     264                     mask->sin_len == 0))
     265                {
     266                    *pu16Index = pRtMsg->rtm_index;
     267                    free(pBuf);
     268                    return VINF_SUCCESS;
     269                }
     270            }
     271        }
     272    }
     273    free(pBuf);
     274    return VERR_INTERNAL_ERROR;
    201275}
    202276
     
    207281    char *pBuf, *pNext;
    208282    int aiMib[6];
    209    
     283    unsigned short u16DefaultIface;
     284
     285    /* Get the index of the interface associated with default route. */
     286    rc = getDefaultIfaceIndex(&u16DefaultIface);
     287    if (RT_FAILURE(rc))
     288        return rc;
     289
    210290    aiMib[0] = CTL_NET;
    211291    aiMib[1] = PF_ROUTE;
     
    300380            if (pIfAddrMsg->ifam_type != RTM_NEWADDR)
    301381                break;
    302             extractAddresses(pIfAddrMsg->ifam_addrs, (char *)(pIfAddrMsg + 1), pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg, pNew);
     382            extractAddressesToNetInfo(pIfAddrMsg->ifam_addrs,
     383                                      (char *)(pIfAddrMsg + 1),
     384                                      pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg,
     385                                      pNew);
    303386            pNext += pIfAddrMsg->ifam_msglen;
    304387        }
     
    325408            IfObj.createObject();
    326409            if (SUCCEEDED(IfObj->init(Bstr(pNew->szName), enmType, pNew)))
    327                 list.push_back(IfObj);
     410                /* Make sure the default interface gets to the beginning. */
     411                if (pIfMsg->ifm_index == u16DefaultIface)
     412                    list.push_front(IfObj);
     413                else
     414                    list.push_back(IfObj);
    328415        }
    329416        RTMemFree(pNew);
     
    400487                break;
    401488            if (!fSkip)
    402                 extractAddresses(pIfAddrMsg->ifam_addrs, (char *)(pIfAddrMsg + 1), pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg, pInfo);
     489                extractAddressesToNetInfo(pIfAddrMsg->ifam_addrs,
     490                                          (char *)(pIfAddrMsg + 1),
     491                                          pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg,
     492                                          pInfo);
    403493            pNext += pIfAddrMsg->ifam_msglen;
    404494        }
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