VirtualBox

Changeset 29390 in vbox


Ignore:
Timestamp:
May 11, 2010 8:11:53 PM (15 years ago)
Author:
vboxsync
Message:

VBoxServiceVMInfo: split functions; provide MAC address for non-Windows guests

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp

    r29345 r29390  
    216216
    217217
     218/**
     219 * Provide information about active users.
     220 */
     221int VBoxServiceVMInfoWriteUsers()
     222{
     223    int rc;
     224    char szUserList[4096] = {0};
     225    uint32_t cUsersInList = 0;
     226
     227#ifdef RT_OS_WINDOWS
     228# ifndef TARGET_NT4
     229    PLUID       paSessions = NULL;
     230    ULONG       cSession = 0;
     231    NTSTATUS    r = 0;
     232
     233    /* This function can report stale or orphaned interactive logon sessions
     234       of already logged off users (especially in Windows 2000). */
     235    r = ::LsaEnumerateLogonSessions(&cSession, &paSessions);
     236    VBoxServiceVerbose(3, "Users: Found %ld users.\n", cSession);
     237    if (r != STATUS_SUCCESS)
     238    {
     239        VBoxServiceError("LsaEnumerate failed %lu\n", LsaNtStatusToWinError(r));
     240        return RTErrConvertFromWin32(LsaNtStatusToWinError(r));
     241    }
     242
     243    PVBOXSERVICEVMINFOPROC  paProcs;
     244    DWORD                   cProcs;
     245    rc = VBoxServiceVMInfoWinProcessesEnumerate(&paProcs, &cProcs);
     246    if (RT_SUCCESS(rc))
     247    {
     248        for (ULONG i = 0; i < cSession; i++)
     249        {
     250            VBOXSERVICEVMINFOUSER UserInfo;
     251            if (   VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i])
     252                && VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs))
     253            {
     254                if (cUsersInList > 0)
     255                    strcat(szUserList, ",");
     256
     257                cUsersInList++;
     258
     259                char *pszTemp;
     260                int rc2 = RTUtf16ToUtf8(UserInfo.wszUser, &pszTemp);
     261                if (RT_SUCCESS(rc2))
     262                {
     263                    strcat(szUserList, pszTemp);
     264                    RTMemFree(pszTemp);
     265                }
     266                else
     267                    strcat(szUserList, "<string-convertion-error>");
     268            }
     269        }
     270        VBoxServiceVMInfoWinProcessesFree(paProcs);
     271    }
     272
     273    ::LsaFreeReturnBuffer(paSessions);
     274# endif /* TARGET_NT4 */
     275#elif defined(RT_OS_FREEBSD)
     276        /** @todo FreeBSD: Port logged on user info retrival. */
     277#elif defined(RT_OS_OS2)
     278        /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrival. */
     279#else
     280    rc = utmpname(UTMP_FILE);
     281# ifdef RT_OS_SOLARIS
     282    if (rc != 1)
     283# else
     284    if (rc != 0)
     285# endif
     286    {
     287        VBoxServiceError("Could not set UTMP file! Error: %ld\n", errno);
     288    }
     289    setutent();
     290    utmp *ut_user;
     291    while ((ut_user = getutent()))
     292    {
     293        /* Make sure we don't add user names which are not
     294         * part of type USER_PROCESS and don't add same users twice. */
     295        if (   ut_user->ut_type == USER_PROCESS
     296            && strstr(szUserList, ut_user->ut_user) == NULL)
     297        {
     298            /** @todo Do we really want to filter out double user names? (Same user logged in twice)
     299             *  bird: If we do, then we must add checks for buffer overflows here!  */
     300            /** @todo r=bird: strstr will filtering out users with similar names. For
     301             *        example: smith, smithson, joesmith and bobsmith */
     302            if (cUsersInList > 0)
     303                strcat(szUserList, ",");
     304            strcat(szUserList, ut_user->ut_user);
     305            cUsersInList++;
     306        }
     307    }
     308    endutent();
     309#endif /* !RT_OS_WINDOWS */
     310
     311    if (cUsersInList > 0)
     312        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", szUserList);
     313    else
     314        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL);
     315    VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList);
     316    if (   g_cVMInfoLoggedInUsers != cUsersInList
     317        || g_cVMInfoLoggedInUsers == UINT32_MAX)
     318    {
     319        /*
     320         * Update this property ONLY if there is a real change from no users to
     321         * users or vice versa. The only exception is that the initialization
     322         * forces an update, but only once. This ensures consistent property
     323         * settings even if the VM aborted previously.
     324         */
     325        if (cUsersInList == 0)
     326            VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "true");
     327        else if (g_cVMInfoLoggedInUsers == 0)
     328            VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "false");
     329    }
     330    g_cVMInfoLoggedInUsers = cUsersInList;
     331
     332    return VINF_SUCCESS;
     333}
     334
     335
     336/**
     337 * Provide information about the guest network.
     338 */
     339int VBoxServiceVMInfoWriteNetwork()
     340{
     341    int cIfacesReport = 0;
     342    char szPropPath [FILENAME_MAX];
     343
     344#ifdef RT_OS_WINDOWS
     345    SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
     346    if (sd == SOCKET_ERROR) /* Socket invalid. */
     347    {
     348        VBoxServiceError("Failed to get a socket: Error %d\n", WSAGetLastError());
     349        return RTErrConvertFromWin32(WSAGetLastError());
     350    }
     351
     352    INTERFACE_INFO InterfaceList[20] = {0};
     353    unsigned long nBytesReturned = 0;
     354    if (WSAIoctl(sd,
     355                 SIO_GET_INTERFACE_LIST,
     356                 0,
     357                 0,
     358                 &InterfaceList,
     359                 sizeof(InterfaceList),
     360                 &nBytesReturned,
     361                 0,
     362                 0) ==  SOCKET_ERROR)
     363    {
     364        VBoxServiceError("Failed to WSAIoctl() on socket: Error: %d\n", WSAGetLastError());
     365        return RTErrConvertFromWin32(WSAGetLastError());
     366    }
     367    int cIfacesSystem = nBytesReturned / sizeof(INTERFACE_INFO);
     368
     369    /** @todo Use GetAdaptersInfo() and GetAdapterAddresses (IPv4 + IPv6) for more information. */
     370    for (int i = 0; i < cIfacesSystem; ++i)
     371    {
     372        sockaddr_in *pAddress;
     373        u_long nFlags = 0;
     374        if (InterfaceList[i].iiFlags & IFF_LOOPBACK) /* Skip loopback device. */
     375            continue;
     376        nFlags = InterfaceList[i].iiFlags;
     377        pAddress = (sockaddr_in *)&(InterfaceList[i].iiAddress);
     378        Assert(pAddress);
     379        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
     380        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
     381
     382        pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress);
     383        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
     384        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
     385
     386        pAddress = (sockaddr_in *)&(InterfaceList[i].iiNetmask);
     387        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
     388        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
     389
     390        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
     391        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, nFlags & IFF_UP ? "Up" : "Down");
     392        cIfacesReport++;
     393    }
     394    if (sd >= 0)
     395        closesocket(sd);
     396#else /* !RT_OS_WINDOWS */
     397    int sd = socket(AF_INET, SOCK_DGRAM, 0);
     398    if (sd < 0)
     399    {
     400        VBoxServiceError("Failed to get a socket: Error %d\n", errno);
     401        return RTErrConvertFromErrno(errno);
     402    }
     403
     404    ifconf ifcfg;
     405    char buffer[1024] = {0};
     406    ifcfg.ifc_len = sizeof(buffer);
     407    ifcfg.ifc_buf = buffer;
     408    if (ioctl(sd, SIOCGIFCONF, &ifcfg) < 0)
     409    {
     410        VBoxServiceError("Failed to ioctl(SIOCGIFCONF) on socket: Error %d\n", errno);
     411        return RTErrConvertFromErrno(errno);
     412    }
     413
     414    ifreq* ifrequest = ifcfg.ifc_req;
     415    int cIfacesSystem = ifcfg.ifc_len / sizeof(ifreq);
     416
     417    for (int i = 0; i < cIfacesSystem; ++i)
     418    {
     419        sockaddr_in *pAddress;
     420        if (ioctl(sd, SIOCGIFFLAGS, &ifrequest[i]) < 0)
     421        {
     422            VBoxServiceError("Failed to ioctl(SIOCGIFFLAGS) on socket: Error %d\n", errno);
     423            close(sd);
     424            return RTErrConvertFromErrno(errno);
     425        }
     426        if (ifrequest[i].ifr_flags & IFF_LOOPBACK) /* Skip the loopback device. */
     427            continue;
     428
     429        bool fIfUp = !!(ifrequest[i].ifr_flags & IFF_UP);
     430        pAddress = ((sockaddr_in *)&ifrequest[i].ifr_addr);
     431        Assert(pAddress);
     432        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
     433        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
     434
     435        if (ioctl(sd, SIOCGIFBRDADDR, &ifrequest[i]) < 0)
     436        {
     437            VBoxServiceError("Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
     438            close(sd);
     439            return RTErrConvertFromErrno(errno);
     440        }
     441        pAddress = (sockaddr_in *)&ifrequest[i].ifr_broadaddr;
     442        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
     443        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
     444
     445        if (ioctl(sd, SIOCGIFNETMASK, &ifrequest[i]) < 0)
     446        {
     447            VBoxServiceError("Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
     448            close(sd);
     449            return RTErrConvertFromErrno(errno);
     450        }
     451 #if defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
     452        pAddress = (sockaddr_in *)&ifrequest[i].ifr_addr;
     453 #else
     454        pAddress = (sockaddr_in *)&ifrequest[i].ifr_netmask;
     455 #endif
     456
     457        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
     458        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
     459
     460        if (ioctl(sd, SIOCGIFHWADDR, &ifrequest[i]) < 0)
     461        {
     462            VBoxServiceError("Failed to ioctl(SIOCGIFHWADDR) on socket: Error %d\n", errno);
     463            close(sd);
     464            return RTErrConvertFromErrno(errno);
     465        }
     466
     467        char szMac[32];
     468        char *pu8Mac = ifrequest[i].ifr_hwaddr.sa_data;
     469        RTStrPrintf(szMac, sizeof(szMac), "%02x:%02x:%02x:%02x:%02x:%02x",
     470                    pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3],  pu8Mac[4], pu8Mac[5]);
     471        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
     472        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
     473
     474        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
     475        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, fIfUp ? "Up" : "Down");
     476        cIfacesReport++;
     477    }
     478
     479    close(sd);
     480
     481#endif /* !RT_OS_WINDOWS */
     482
     483    /*
     484     * This property is a beacon which is _always_ written, even if the network configuration
     485     * does not change. If this property is missing, the host assumes that all other GuestInfo
     486     * properties are no longer valid.
     487     */
     488    VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d",
     489                               cIfacesReport);
     490
     491    /** @todo r=bird: if cIfacesReport decreased compared to the previous run, zap
     492     *        the stale data.  This can probably be encorporated into the cache.  */
     493
     494    return VINF_SUCCESS;
     495}
     496
     497
    218498/** @copydoc VBOXSERVICE::pfnWorker */
    219499DECLCALLBACK(int) VBoxServiceVMInfoWorker(bool volatile *pfShutdown)
    220500{
    221     int rc = VINF_SUCCESS;
     501    int rc;
    222502
    223503    /*
     
    242522     * Now enter the loop retrieving runtime data continuously.
    243523     */
    244     unsigned cErrors = 0;
    245524    for (;;)
    246525    {
    247 /** @todo r=bird: split this code up into functions!! */
    248         /* Enumerate logged in users. */
    249         uint32_t cUsersInList = 0;
    250         char szUserList[4096] = {0};
    251 
    252 #ifdef RT_OS_WINDOWS
    253 # ifndef TARGET_NT4
    254         PLUID       paSessions = NULL;
    255         ULONG       cSession = 0;
    256         NTSTATUS    r = 0;
    257 
    258         /* This function can report stale or orphaned interactive logon sessions
    259            of already logged off users (especially in Windows 2000). */
    260         r = ::LsaEnumerateLogonSessions(&cSession, &paSessions);
    261         VBoxServiceVerbose(3, "Users: Found %ld users.\n", cSession);
    262         if (r != STATUS_SUCCESS)
    263         {
    264             VBoxServiceError("LsaEnumerate failed %lu\n", LsaNtStatusToWinError(r));
    265             return 1;
    266         }
    267 
    268         PVBOXSERVICEVMINFOPROC  paProcs;
    269         DWORD                   cProcs;
    270         rc = VBoxServiceVMInfoWinProcessesEnumerate(&paProcs, &cProcs);
    271         if (RT_SUCCESS(rc))
    272         {
    273             for (ULONG i = 0; i < cSession; i++)
    274             {
    275                 VBOXSERVICEVMINFOUSER UserInfo;
    276                 if (   VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i])
    277                     && VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs))
    278                 {
    279                     if (cUsersInList > 0)
    280                         strcat(szUserList, ",");
    281 
    282                     cUsersInList++;
    283 
    284                     char *pszTemp;
    285                     int rc2 = RTUtf16ToUtf8(UserInfo.wszUser, &pszTemp);
    286                     if (RT_SUCCESS(rc2))
    287                     {
    288                         strcat(szUserList, pszTemp);
    289                         RTMemFree(pszTemp);
    290                     }
    291                     else
    292                         strcat(szUserList, "<string-convertion-error>");
    293                 }
    294             }
    295             VBoxServiceVMInfoWinProcessesFree(paProcs);
    296         }
    297 
    298         ::LsaFreeReturnBuffer(paSessions);
    299 # endif /* TARGET_NT4 */
    300 #elif defined(RT_OS_FREEBSD)
    301         /** @todo FreeBSD: Port logged on user info retrival. */
    302 #elif defined(RT_OS_OS2)
    303         /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrival. */
    304 #else
    305         rc = utmpname(UTMP_FILE);
    306 # ifdef RT_OS_SOLARIS
    307         if (rc != 1)
    308 # else
    309         if (rc != 0)
    310 # endif
    311         {
    312             VBoxServiceError("Could not set UTMP file! Error: %ld\n", errno);
    313         }
    314         setutent();
    315         utmp *ut_user;
    316         while ((ut_user = getutent()))
    317         {
    318             /* Make sure we don't add user names which are not
    319              * part of type USER_PROCESS and don't add same users twice. */
    320             if (   ut_user->ut_type == USER_PROCESS
    321                 && strstr(szUserList, ut_user->ut_user) == NULL)
    322             {
    323                 /** @todo Do we really want to filter out double user names? (Same user logged in twice)
    324                  *  bird: If we do, then we must add checks for buffer overflows here!  */
    325                 /** @todo r=bird: strstr will filtering out users with similar names. For
    326                  *        example: smith, smithson, joesmith and bobsmith */
    327                 if (cUsersInList > 0)
    328                     strcat(szUserList, ",");
    329                 strcat(szUserList, ut_user->ut_user);
    330                 cUsersInList++;
    331             }
    332         }
    333         endutent();
    334 #endif /* !RT_OS_WINDOWS */
    335 
    336         if (cUsersInList > 0)
    337             VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", szUserList);
    338         else
    339             VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL);
    340         VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList);
    341         if (   g_cVMInfoLoggedInUsers != cUsersInList
    342             || g_cVMInfoLoggedInUsers == UINT32_MAX)
    343         {
    344             /*
    345              * Update this property ONLY if there is a real change from no users to
    346              * users or vice versa. The only exception is that the initialization
    347              * forces an update, but only once. This ensures consistent property
    348              * settings even if the VM aborted previously.
    349              */
    350             if (cUsersInList == 0)
    351                 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "true");
    352             else if (g_cVMInfoLoggedInUsers == 0)
    353                 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "false");
    354         }
    355         g_cVMInfoLoggedInUsers = cUsersInList;
    356 
    357         /*
    358          * Get network configuration.
    359          */
    360         /** @todo Throw this code into a separate function/module? */
    361        int cInterfaces = 0;
    362 #ifdef RT_OS_WINDOWS
    363         SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
    364         if (sd == SOCKET_ERROR) /* Socket invalid. */
    365         {
    366             VBoxServiceError("Failed to get a socket: Error %d\n", WSAGetLastError());
    367             return -1;
    368         }
    369 
    370         INTERFACE_INFO InterfaceList[20] = {0};
    371         unsigned long nBytesReturned = 0;
    372         if (WSAIoctl(sd,
    373                      SIO_GET_INTERFACE_LIST,
    374                      0,
    375                      0,
    376                      &InterfaceList,
    377                      sizeof(InterfaceList),
    378                      &nBytesReturned,
    379                      0,
    380                      0) ==  SOCKET_ERROR)
    381         {
    382             VBoxServiceError("Failed to WSAIoctl() on socket: Error: %d\n", WSAGetLastError());
    383             return -1;
    384         }
    385         cInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
    386 #else
    387         int sd = socket(AF_INET, SOCK_DGRAM, 0);
    388         if (sd < 0) /* Socket invalid. */
    389         {
    390             VBoxServiceError("Failed to get a socket: Error %d\n", errno);
    391             return -1;
    392         }
    393 
    394         ifconf ifcfg;
    395         char buffer[1024] = {0};
    396         ifcfg.ifc_len = sizeof(buffer);
    397         ifcfg.ifc_buf = buffer;
    398         if (ioctl(sd, SIOCGIFCONF, &ifcfg) < 0)
    399         {
    400             VBoxServiceError("Failed to ioctl(SIOCGIFCONF) on socket: Error %d\n", errno);
    401             return -1;
    402         }
    403 
    404         ifreq* ifrequest = ifcfg.ifc_req;
    405         ifreq *ifreqitem = NULL;
    406         cInterfaces = ifcfg.ifc_len / sizeof(ifreq);
    407 #endif
    408         char szPropPath [FILENAME_MAX];
    409         int iCurIface = 0;
    410 
    411         /** @todo Use GetAdaptersInfo() and GetAdapterAddresses (IPv4 + IPv6) for more information. */
    412         for (int i = 0; i < cInterfaces; ++i)
    413         {
    414             sockaddr_in *pAddress;
    415             u_long nFlags = 0;
    416 #ifdef RT_OS_WINDOWS
    417             if (InterfaceList[i].iiFlags & IFF_LOOPBACK) /* Skip loopback device. */
    418                 continue;
    419             nFlags = InterfaceList[i].iiFlags;
    420             pAddress = (sockaddr_in *)&(InterfaceList[i].iiAddress);
    421 #else
    422             if (ioctl(sd, SIOCGIFFLAGS, &ifrequest[i]) < 0)
    423             {
    424                 VBoxServiceError("Failed to ioctl(SIOCGIFFLAGS) on socket: Error %d\n", errno);
    425                 return -1;
    426             }
    427             if (ifrequest[i].ifr_flags & IFF_LOOPBACK) /* Skip loopback device. */
    428                 continue;
    429             nFlags = ifrequest[i].ifr_flags;
    430             pAddress = ((sockaddr_in *)&ifrequest[i].ifr_addr);
    431 #endif
    432             Assert(pAddress);
    433             RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", iCurIface);
    434             VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
    435 
    436 #ifdef RT_OS_WINDOWS
    437             pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress);
    438 #else
    439             if (ioctl(sd, SIOCGIFBRDADDR, &ifrequest[i]) < 0)
    440             {
    441                 VBoxServiceError("Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
    442                 return -1;
    443             }
    444             pAddress = (sockaddr_in *)&ifrequest[i].ifr_broadaddr;
    445 #endif
    446             RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", iCurIface);
    447             VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
    448 
    449 #ifdef RT_OS_WINDOWS
    450             pAddress = (sockaddr_in *)&(InterfaceList[i].iiNetmask);
    451 #else
    452             if (ioctl(sd, SIOCGIFNETMASK, &ifrequest[i]) < 0)
    453             {
    454                 VBoxServiceError("Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
    455                 return -1;
    456             }
    457  #if defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
    458             pAddress = (sockaddr_in *)&ifrequest[i].ifr_addr;
    459  #else
    460             pAddress = (sockaddr_in *)&ifrequest[i].ifr_netmask;
    461  #endif
    462 
    463 #endif
    464             RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", iCurIface);
    465             VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
    466 
    467             RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", iCurIface);
    468             VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath,
    469                                        nFlags & IFF_UP ? "Up" : "Down");
    470             iCurIface++;
    471         }
    472         if (sd >= 0)
    473 #ifdef RT_OS_WINDOWS
    474             closesocket(sd);
    475 #else
    476             close(sd);
    477 #endif
    478 
    479         /*
    480          * This property is a beacon which is _always_ written, even if the network configuration
    481          * does not change. If this property is missing, the host assumes that all other GuestInfo
    482          * properties are no longer valid.
    483          *
    484          * cInterfaces also counts in local loopback, but we don't want to report that.
    485          */
    486         VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d",
    487                                    cInterfaces > 1 ? cInterfaces-1 : 0);
    488 
    489         /** @todo r=bird: if cInterfaces decreased compared to the previous run, zap
    490          *        the stale data.  This can probably be encorporated into the cache.  */
    491 
     526        rc = VBoxServiceVMInfoWriteUsers();
     527        if (RT_FAILURE(rc))
     528            break;
     529
     530        rc = VBoxServiceVMInfoWriteNetwork();
     531        if (RT_FAILURE(rc))
     532            break;
    492533
    493534        /*
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