VBoxServiceVMInfo.cpp revision 2c042a102824ed308044077b31cbe508ba732721
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * VBoxService - Virtual Machine Information for the Host.
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync * Copyright (C) 2009-2010 Oracle Corporation
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * available from http://www.virtualbox.org. This file is free software;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * General Public License (GPL) as published by the Free Software
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/*******************************************************************************
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync* Header Files *
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync*******************************************************************************/
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# ifndef RT_OS_FREEBSD /* The header does not exist anymore since FreeBSD 9-current */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/*******************************************************************************
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync* Global Variables *
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync*******************************************************************************/
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** The vminfo interval (millseconds). */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** The semaphore we're blocking on. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic RTSEMEVENTMULTI g_hVMInfoEvent = NIL_RTSEMEVENTMULTI;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** The guest property service client ID. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** Number of logged in users in OS. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic uint32_t g_cVMInfoLoggedInUsers = UINT32_MAX;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** The guest property cache. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @copydoc VBOXSERVICE::pfnPreInit */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoPreInit(void)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @copydoc VBOXSERVICE::pfnOption */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoOption(const char **ppszShort, int argc, char **argv, int *pi)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /* no short options */;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync/** @copydoc VBOXSERVICE::pfnInit */
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoInit(void)
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync * If not specified, find the right interval default.
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync * Then create the event sem to block on.
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync rc = VbglR3GuestPropConnect(&g_uVMInfoGuestPropSvcClientID);
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync VBoxServiceVerbose(3, "VMInfo: Property Service Client ID: %#x\n", g_uVMInfoGuestPropSvcClientID);
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync /* If the service was not found, we disable this service without
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync causing VBoxService to fail. */
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync VBoxServiceVerbose(0, "VMInfo: Guest property service is not available, disabling the service\n");
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync VBoxServiceError("VMInfo: Failed to connect to the guest property service! Error: %Rrc\n", rc);
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync VBoxServicePropCacheCreate(&g_VMInfoPropCache, g_uVMInfoGuestPropSvcClientID);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Declare some guest properties with flags and reset values.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY, NULL /* Delete on exit */);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE, NULL /* Delete on exit */);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync * Writes the properties that won't change while the service is running.
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync * Errors are ignored.
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsyncstatic void vboxserviceVMInfoWriteFixedProperties(void)
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync * First get OS information that won't change.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync int rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szInfo, sizeof(szInfo));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Product",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Release",
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szInfo, sizeof(szInfo));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Version",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szInfo, sizeof(szInfo));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/ServicePack",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Retrieve version information about Guest Additions and installed files (components).
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VbglR3GetAdditionsVersion(&pszAddVer, &pszAddRev);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Version",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Revision",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Do windows specific properties.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VbglR3GetAdditionsInstallationPath(&pszInstDir);
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/InstallDir",
762a68c2bb3ccde807330e3d1cb05f8b244a5f72vboxsync VBoxServiceWinGetComponentVersions(g_uVMInfoGuestPropSvcClientID);
9540eeb13face31ddc1c5f15338556fe46f18a77vboxsync * Provide information about active users.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VBoxServiceVMInfoWinWriteUsers(&pszUserList, &cUsersInList);
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync /** @todo FreeBSD: Port logged on user info retrival. */
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrival. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Users: Could not set UTMP file! Error: %ld\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /* Make sure we don't add user names which are not
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync * part of type USER_PROCESS. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /** @todo Do we want to filter out user names? What if a user is logged in twice? */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync Assert(RT_FAILURE(rc) || cUsersInList == 0 || (pszUserList && *pszUserList));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", pszUserList);
762a68c2bb3ccde807330e3d1cb05f8b244a5f72vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList);
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Provide information about the guest network.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAdpInfo = (IP_ADAPTER_INFO *)RTMemAlloc(cbAdpInfo);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to allocate IP_ADAPTER_INFO\n");
7697e43970d863558b6c168a55e8948ccb18d8d1vboxsync DWORD dwRet = GetAdaptersInfo(pAdpInfo, &cbAdpInfo);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync IP_ADAPTER_INFO *pAdpInfoNew = (IP_ADAPTER_INFO*)RTMemRealloc(pAdpInfo, cbAdpInfo);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo/Network: Failed to get adapter info: Error %d\n", dwRet);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %d\n", WSAGetLastError());
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync unsigned long nBytesReturned = 0;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to WSAIoctl() on socket: Error: %d\n", WSAGetLastError());
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync int cIfacesSystem = nBytesReturned / sizeof(INTERFACE_INFO);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /** @todo Use GetAdaptersInfo() and GetAdapterAddresses (IPv4 + IPv6) for more information. */
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync for (int i = 0; i < cIfacesSystem; ++i)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (InterfaceList[i].iiFlags & IFF_LOOPBACK) /* Skip loopback device. */
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync pAddress = (sockaddr_in *)&(InterfaceList[i].iiAddress);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szIp, sizeof(szIp), "%s", inet_ntoa(pAddress->sin_addr));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szIp);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAddress = (sockaddr_in *)&(InterfaceList[i].iiNetmask);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, nFlags & IFF_UP ? "Up" : "Down");
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if (!strcmp(pAdp->IpAddressList.IpAddress.String, szIp))
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAdp->Address[0], pAdp->Address[1], pAdp->Address[2],
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAdp->Address[3], pAdp->Address[4], pAdp->Address[5]);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, NULL);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Get all available interfaces */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to get all interfaces: Error %d\n", errno);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Loop through all interfaces and set the data. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync for (struct ifaddrs *pIfCurr = pIfHead; pIfCurr; pIfCurr = pIfCurr->ifa_next)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Only AF_INET and no loopback interfaces
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * @todo: IPv6 interfaces
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync getnameinfo(pIfCurr->ifa_addr, sizeof(struct sockaddr_in),
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync getnameinfo(pIfCurr->ifa_broadaddr, sizeof(struct sockaddr_in),
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync getnameinfo(pIfCurr->ifa_netmask, sizeof(struct sockaddr_in),
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Search for the AF_LINK interface of the current AF_INET one and get the mac. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync for (struct ifaddrs *pIfLinkCurr = pIfHead; pIfLinkCurr; pIfLinkCurr = pIfLinkCurr->ifa_next)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync && !strcmp(pIfCurr->ifa_name, pIfLinkCurr->ifa_name))
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync struct sockaddr_dl *pLinkAddress = (struct sockaddr_dl *)pIfLinkCurr->ifa_addr;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3], pu8Mac[4], pu8Mac[5]);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, pIfCurr->ifa_flags & IFF_UP ? "Up" : "Down");
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync /* Free allocated resources. */
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync#else /* !RT_OS_WINDOWS && !RT_OS_FREEBSD */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %d\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFCONF) on socket: Error %d\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync for (int i = 0; i < cIfacesSystem; ++i)
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFFLAGS) on socket: Error %d\n", errno);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (ifrequest[i].ifr_flags & IFF_LOOPBACK) /* Skip the loopback device. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAddress = ((sockaddr_in *)&ifrequest[i].ifr_addr);
36fbf6dcd3e6b2e5891456b730577ff0eb355c9fvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAddress = (sockaddr_in *)&ifrequest[i].ifr_broadaddr;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAddress = (sockaddr_in *)&ifrequest[i].ifr_netmask;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
762a68c2bb3ccde807330e3d1cb05f8b244a5f72vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFHWADDR) on socket: Error %d\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync uint8_t *pu8Mac = (uint8_t*)&ifrequest[i].ifr_enaddr[0];
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync uint8_t *pu8Mac = (uint8_t*)&ifrequest[i].ifr_hwaddr.sa_data[0];
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3], pu8Mac[4], pu8Mac[5]);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, fIfUp ? "Up" : "Down");
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync#endif /* !RT_OS_WINDOWS */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * This property is a beacon which is _always_ written, even if the network configuration
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * does not change. If this property is missing, the host assumes that all other GuestInfo
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * properties are no longer valid.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d",
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /** @todo r=bird: if cIfacesReport decreased compared to the previous run, zap
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * the stale data. This can probably be encorporated into the cache. */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync/** @copydoc VBOXSERVICE::pfnWorker */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsyncDECLCALLBACK(int) VBoxServiceVMInfoWorker(bool volatile *pfShutdown)
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * Tell the control thread that it can continue
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * spawning services.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /* Required for network information (must be called per thread). */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync VBoxServiceError("VMInfo/Network: WSAStartup failed! Error: %Rrc\n", RTErrConvertFromWin32(WSAGetLastError()));
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync#endif /* RT_OS_WINDOWS */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * Write the fixed properties first.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * Now enter the loop retrieving runtime data continuously.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * Block for a while.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * The event semaphore takes care of ignoring interruptions and it
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * allows us to implement service wakeup later.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync int rc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServiceError("VMInfo: RTSemEventMultiWait failed; rc2=%Rrc\n", rc2);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @copydoc VBOXSERVICE::pfnStop */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic DECLCALLBACK(void) VBoxServiceVMInfoStop(void)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @copydoc VBOXSERVICE::pfnTerm */
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsyncstatic DECLCALLBACK(void) VBoxServiceVMInfoTerm(void)
3614117c1132a61599e6190939e775cafe549411vboxsync /** @todo temporary solution: Zap all values which are not valid
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * anymore when VM goes down (reboot/shutdown ). Needs to
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * be replaced with "temporary properties" later.
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * One idea is to introduce a (HGCM-)session guest property
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * flag meaning that a guest property is only valid as long
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * as the HGCM session isn't closed (e.g. guest application
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * terminates). [don't remove till implemented]
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /** @todo r=bird: Drop the VbglR3GuestPropDelSet call here and use the cache
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * since it remembers what we've written. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Delete the "../Net" branch. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync const char *apszPat[1] = { "/VirtualBox/GuestInfo/Net/*" };
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat));
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Destroy property cache. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Disconnect from guest properties service. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VbglR3GuestPropDisconnect(g_uVMInfoGuestPropSvcClientID);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo: Failed to disconnect from guest property service! Error: %Rrc\n", rc);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * The 'vminfo' service description.
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /* pszName. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /* pszDescription. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync "Virtual Machine Information",
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* pszUsage. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync " [--vminfo-interval <ms>]"
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /* pszOptions. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync " --vminfo-interval Specifies the interval at which to retrieve the\n"
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync " VM information. The default is 10000 ms.\n"
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /* methods */