VirtualBox

Changeset 17703 in vbox


Ignore:
Timestamp:
Mar 11, 2009 3:39:29 PM (16 years ago)
Author:
vboxsync
Message:

#3569: IPv4 static ip config for unix platforms + darwin NetIfList update

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

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

    r17443 r17703  
    2525*   Header Files                                                               *
    2626*******************************************************************************/
     27/*
     28 * Deal with conflicts first.
     29 * PVM - BSD mess, that FreeBSD has correct a long time ago.
     30 * iprt/types.h before sys/param.h - prevents UINT32_C and friends.
     31 */
     32#include <iprt/types.h>
     33#include <sys/param.h>
     34#undef PVM
     35
    2736#define LOG_GROUP LOG_GROUP_MAIN
    2837
     
    3342#include <sys/socket.h>
    3443#include <sys/ioctl.h>
     44#include <sys/sysctl.h>
    3545#include <netinet/in.h>
    3646#include <net/if.h>
     47#include <net/if_dl.h>
     48#include <net/if_types.h>
     49#include <net/route.h>
    3750#include <ifaddrs.h>
    3851#include <errno.h>
     
    4558#include "Logging.h"
    4659
     60#if 0
    4761int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
    4862{
     
    140154    return VINF_SUCCESS;
    141155}
     156#else
     157
     158#define ROUNDUP(a) \
     159        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
     160#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
     161
     162void extractAddresses(int iAddrMask, caddr_t cp, caddr_t cplim, PNETIFINFO pInfo)
     163{
     164    struct sockaddr *sa;
     165    struct sockaddr_in *pIPAddr, *pIPNetMask;
     166    struct sockaddr_in6 *pIPv6Addr, *pIPv6NetMask;
     167
     168    for (int i = 0; i < RTAX_MAX && cp < cplim; i++) {
     169        if (!(iAddrMask & (1 << i)))
     170            continue;
     171
     172        sa = (struct sockaddr *)cp;
     173
     174        switch (i)
     175        {
     176            case RTAX_IFA:
     177                switch (sa->sa_family)
     178                {
     179                    case AF_INET:
     180                        pIPAddr = (struct sockaddr_in *)sa;
     181                        Assert(sizeof(pInfo->IPAddress) == sizeof(pIPAddr->sin_addr));
     182                        if (!pInfo->IPAddress.u)
     183                            pInfo->IPAddress.u = pIPAddr->sin_addr.s_addr;
     184                        break;
     185                    case AF_INET6:
     186                        pIPv6Addr = (struct sockaddr_in6 *)sa;
     187                        Assert(sizeof(pInfo->IPv6Address) == sizeof(pIPv6Addr->sin6_addr));
     188                        if (!(pInfo->IPv6Address.s.Lo || pInfo->IPv6Address.s.Hi))
     189                            memcpy(pInfo->IPv6Address.au8,
     190                                   pIPv6Addr->sin6_addr.__u6_addr.__u6_addr8,
     191                                   sizeof(pInfo->IPv6Address));
     192                        break;
     193                    default:
     194                        Log(("NetIfList: Unsupported address family: %u\n", sa->sa_family));
     195                        break;
     196                }
     197                break;
     198            case RTAX_NETMASK:
     199                switch (sa->sa_family)
     200                {
     201                    case AF_INET:
     202                        pIPAddr = (struct sockaddr_in *)sa;
     203                        if (!pInfo->IPNetMask.u)
     204                            pInfo->IPNetMask.u = pIPAddr->sin_addr.s_addr;
     205                        break;
     206                    case AF_INET6:
     207                        pIPv6Addr = (struct sockaddr_in6 *)sa;
     208                        if (!(pInfo->IPv6NetMask.s.Lo || pInfo->IPv6NetMask.s.Hi))
     209                            memcpy(pInfo->IPv6NetMask.au8,
     210                                   pIPv6Addr->sin6_addr.__u6_addr.__u6_addr8,
     211                                   sizeof(pInfo->IPv6NetMask));
     212                        break;
     213                    default:
     214                        Log(("NetIfList: Unsupported address family: %u\n", sa->sa_family));
     215                        break;
     216                }
     217                break;
     218        }
     219        ADVANCE(cp, sa);
     220    }
     221}
     222
     223int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
     224{
     225    int rc = VINF_SUCCESS;
     226    size_t cbNeeded;
     227    char *pBuf, *pNext;
     228    int aiMib[6];
     229   
     230    aiMib[0] = CTL_NET;
     231    aiMib[1] = PF_ROUTE;
     232    aiMib[2] = 0;
     233    aiMib[3] = 0;       /* address family */
     234    aiMib[4] = NET_RT_IFLIST;
     235    aiMib[5] = 0;
     236
     237    if (sysctl(aiMib, 6, NULL, &cbNeeded, NULL, 0) < 0)
     238    {
     239        Log(("NetIfList: Failed to get estimate for list size (errno=%d).\n", errno));
     240        return RTErrConvertFromErrno(errno);
     241    }
     242    if ((pBuf = (char*)malloc(cbNeeded)) == NULL)
     243        return VERR_NO_MEMORY;
     244    if (sysctl(aiMib, 6, pBuf, &cbNeeded, NULL, 0) < 0)
     245    {
     246        free(pBuf);
     247        Log(("NetIfList: Failed to retrieve interface table (errno=%d).\n", errno));
     248        return RTErrConvertFromErrno(errno);
     249    }
     250
     251    int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
     252    if (sock < 0)
     253    {
     254        free(pBuf);
     255        Log(("NetIfList: socket() -> %d\n", errno));
     256        return RTErrConvertFromErrno(errno);
     257    }
     258
     259    char *pEnd = pBuf + cbNeeded;
     260    for (pNext = pBuf; pNext < pEnd;)
     261    {
     262        struct if_msghdr *pIfMsg = (struct if_msghdr *)pNext;
     263
     264        if (pIfMsg->ifm_type != RTM_IFINFO)
     265        {
     266            Log(("NetIfList: Got message %u while expecting %u.\n",
     267                 pIfMsg->ifm_type, RTM_IFINFO));
     268            rc = VERR_INTERNAL_ERROR;
     269            break;
     270        }
     271        struct sockaddr_dl *pSdl = (struct sockaddr_dl *)(pIfMsg + 1);
     272
     273        size_t cbNameLen = pSdl->sdl_nlen + 1;
     274        PNETIFINFO pNew = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen]));
     275        if (!pNew)
     276        {
     277            rc = VERR_NO_MEMORY;
     278            break;
     279        }
     280        memcpy(pNew->MACAddress.au8, LLADDR(pSdl), sizeof(pNew->MACAddress.au8));
     281        pNew->enmMediumType = NETIF_T_ETHERNET;
     282        // @todo: pNew->Uuid = pEtherNICs->Uuid;
     283        Assert(sizeof(pNew->szShortName) >= cbNameLen);
     284        memcpy(pNew->szShortName, pSdl->sdl_data, cbNameLen);
     285        memcpy(pNew->szName, pSdl->sdl_data, cbNameLen);
     286
     287        pNext += pIfMsg->ifm_msglen;
     288        while (pNext < pEnd)
     289        {
     290            struct ifa_msghdr *pIfAddrMsg = (struct ifa_msghdr *)pNext;
     291
     292            if (pIfAddrMsg->ifam_type != RTM_NEWADDR)
     293                break;
     294            extractAddresses(pIfAddrMsg->ifam_addrs, (char *)(pIfAddrMsg + 1), pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg, pNew);
     295            pNext += pIfAddrMsg->ifam_msglen;
     296        }
     297
     298        if (pSdl->sdl_type == IFT_ETHER)
     299        {
     300            /* Generate UUID from name and MAC address. */
     301            RTUUID uuid;
     302            RTUuidClear(&uuid);
     303            memcpy(&uuid, pNew->szShortName, RT_MIN(cbNameLen, sizeof(uuid)));
     304            uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80;
     305            uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000;
     306            memcpy(uuid.Gen.au8Node, pNew->MACAddress.au8, sizeof(uuid.Gen.au8Node));
     307            pNew->Uuid = uuid;
     308
     309            struct ifreq IfReq;
     310            strcpy(IfReq.ifr_name, pNew->szShortName);
     311            if (ioctl(sock, SIOCGIFFLAGS, &IfReq) < 0)
     312            {
     313                Log(("NetIfList: ioctl(SIOCGIFFLAGS) -> %d\n", errno));
     314                pNew->enmStatus = NETIF_S_UNKNOWN;
     315            }
     316            else
     317                pNew->enmStatus = (IfReq.ifr_flags & IFF_UP) ? NETIF_S_UP : NETIF_S_DOWN;
     318
     319            HostNetworkInterfaceType_T enmType;
     320            if (strncmp("vbox", pNew->szName, 4))
     321                enmType = HostNetworkInterfaceType_Bridged;
     322            else
     323                enmType = HostNetworkInterfaceType_HostOnly;
     324
     325            ComObjPtr<HostNetworkInterface> IfObj;
     326            IfObj.createObject();
     327            if (SUCCEEDED(IfObj->init(Bstr(pNew->szName), enmType, pNew)))
     328                list.push_back(IfObj);
     329        }
     330        RTMemFree(pNew);
     331    }
     332    close(sock);
     333    free(pBuf);
     334    return rc;
     335}
     336#endif
  • trunk/src/VBox/Main/generic/NetIf-generic.cpp

    r17679 r17703  
    2020 */
    2121
     22#include <VBox/err.h>
     23#include <VBox/log.h>
     24#include <iprt/process.h>
     25#include <iprt/env.h>
     26#include <iprt/path.h>
     27
    2228#include "HostNetworkInterfaceImpl.h"
    2329#include "netif.h"
    2430
     31#define VBOXNETADPCTL_NAME "VBoxNetAdpCtl"
     32
     33static int NetIfAdpCtl(HostNetworkInterface * pIf, char *pszAddr, char *pszMask)
     34{
     35    const char *args[] = { NULL, NULL, pszAddr, NULL, NULL, NULL };
     36    if (pszMask)
     37    {
     38        args[3] = "netmask";
     39        args[4] = pszMask;
     40    }
     41   
     42    char szAdpCtl[PATH_MAX];
     43    int rc = RTPathProgram(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME));
     44    if (RT_FAILURE(rc))
     45        return rc;
     46    strcat(szAdpCtl, "/" VBOXNETADPCTL_NAME);
     47    args[0] = szAdpCtl;
     48    Bstr interfaceName;
     49    pIf->COMGETTER(Name)(interfaceName.asOutParam());
     50    Utf8Str strName(interfaceName);
     51    args[1] = strName;
     52    if (!RTPathExists(szAdpCtl))
     53    {
     54        LogRel(("NetIf: path %s does not exist. Failed to run " VBOXNETADPCTL_NAME " helper.\n",
     55                szAdpCtl));
     56        return VERR_FILE_NOT_FOUND;
     57    }
     58   
     59    RTPROCESS pid;
     60    rc = RTProcCreate(VBOXNETADPCTL_NAME, args, RTENV_DEFAULT, 0, &pid);
     61    if (RT_SUCCESS(rc))
     62    {
     63        RTPROCSTATUS Status;
     64        rc = RTProcWait(pid, 0, &Status);
     65        if (   RT_SUCCESS(rc)
     66            && Status.iStatus == 0
     67            && Status.enmReason == RTPROCEXITREASON_NORMAL)
     68            return VINF_SUCCESS;
     69    }
     70    return rc;
     71}
     72
    2573int NetIfEnableStaticIpConfig(HostNetworkInterface * pIf, ULONG ip, ULONG mask)
    2674{
    27     return VERR_NOT_IMPLEMENTED;
     75    char szAddress[16]; /* 4*3 + 3*1 + 1 */
     76    char szNetMask[16]; /* 4*3 + 3*1 + 1 */
     77    uint8_t *pu8Addr = (uint8_t *)&ip;
     78    uint8_t *pu8Mask = (uint8_t *)&mask;
     79    RTStrPrintf(szAddress, sizeof(szAddress), "%d.%d.%d.%d",
     80                pu8Addr[0], pu8Addr[1], pu8Addr[2], pu8Addr[3]);
     81    RTStrPrintf(szNetMask, sizeof(szNetMask), "%d.%d.%d.%d",
     82                pu8Mask[0], pu8Mask[1], pu8Mask[2], pu8Mask[3]);
     83    return NetIfAdpCtl(pIf, szAddress, szNetMask);
    2884}
    2985
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