VBoxServiceVMInfo.cpp revision 2caae01fb624524a93d8322500214c42d9038b74
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/* $Id$ */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/** @file
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * VBoxService - Virtual Machine Information for the Host.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2009-2010 Oracle Corporation
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync *
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * available from http://www.virtualbox.org. This file is free software;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync */
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync/*******************************************************************************
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync* Header Files *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync*******************************************************************************/
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync#ifdef RT_OS_WINDOWS
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync# include <winsock2.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <iphlpapi.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <ws2tcpip.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <windows.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <Ntsecapi.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#else
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# define __STDC_LIMIT_MACROS
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <arpa/inet.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <errno.h>
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync# include <netinet/in.h>
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync# include <sys/ioctl.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <sys/socket.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <net/if.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <unistd.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# ifndef RT_OS_FREEBSD
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <utmpx.h> /* @todo FreeBSD 9 should have this. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# ifdef RT_OS_SOLARIS
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <sys/sockio.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <net/if_arp.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# ifdef RT_OS_FREEBSD
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <ifaddrs.h> /* getifaddrs, freeifaddrs */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <net/if_dl.h> /* LLADDR */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# include <netdb.h> /* getnameinfo */
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync# endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <iprt/mem.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <iprt/thread.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <iprt/string.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <iprt/semaphore.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <iprt/system.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <iprt/time.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <iprt/assert.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <VBox/version.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include <VBox/VBoxGuestLib.h>
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include "VBoxServiceInternal.h"
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include "VBoxServiceUtils.h"
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#include "VBoxServicePropCache.h"
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/*******************************************************************************
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync* Global Variables *
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync*******************************************************************************/
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/** The vminfo interval (millseconds). */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic uint32_t g_cMsVMInfoInterval = 0;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/** The semaphore we're blocking on. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic RTSEMEVENTMULTI g_hVMInfoEvent = NIL_RTSEMEVENTMULTI;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/** The guest property service client ID. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic uint32_t g_uVMInfoGuestPropSvcClientID = 0;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/** Number of logged in users in OS. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic uint32_t g_cVMInfoLoggedInUsers = UINT32_MAX;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/** The guest property cache. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic VBOXSERVICEVEPROPCACHE g_VMInfoPropCache;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/** @copydoc VBOXSERVICE::pfnPreInit */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoPreInit(void)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync{
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync return VINF_SUCCESS;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync}
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync/** @copydoc VBOXSERVICE::pfnOption */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoOption(const char **ppszShort, int argc, char **argv, int *pi)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync{
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync int rc = -1;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (ppszShort)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /* no short options */;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync else if (!strcmp(argv[*pi], "--vminfo-interval"))
5b0a093ca572a855886faa6747ad46df859dd041vboxsync rc = VBoxServiceArgUInt32(argc, argv, "", pi,
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync &g_cMsVMInfoInterval, 1, UINT32_MAX - 1);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync return rc;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync}
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/** @copydoc VBOXSERVICE::pfnInit */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoInit(void)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync{
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /*
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * If not specified, find the right interval default.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * Then create the event sem to block on.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (!g_cMsVMInfoInterval)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync g_cMsVMInfoInterval = g_DefaultInterval * 1000;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (!g_cMsVMInfoInterval)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync g_cMsVMInfoInterval = 10 * 1000;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync int rc = RTSemEventMultiCreate(&g_hVMInfoEvent);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync AssertRCReturn(rc, rc);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = VbglR3GuestPropConnect(&g_uVMInfoGuestPropSvcClientID);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (RT_SUCCESS(rc))
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceVerbose(3, "VMInfo: Property Service Client ID: %#x\n", g_uVMInfoGuestPropSvcClientID);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync else
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /* If the service was not found, we disable this service without
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync causing VBoxService to fail. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceVerbose(0, "VMInfo: Guest property service is not available, disabling the service\n");
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = VERR_SERVICE_DISABLED;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync else
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync VBoxServiceError("VMInfo: Failed to connect to the guest property service! Error: %Rrc\n", rc);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTSemEventMultiDestroy(g_hVMInfoEvent);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync g_hVMInfoEvent = NIL_RTSEMEVENTMULTI;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (RT_SUCCESS(rc))
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheCreate(&g_VMInfoPropCache, g_uVMInfoGuestPropSvcClientID);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /*
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * Declare some guest properties with flags and reset values.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY, NULL /* Delete on exit */);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY, "0");
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY, "true");
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE, NULL /* Delete on exit */);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync return rc;
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync}
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/**
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * Writes the properties that won't change while the service is running.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync *
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * Errors are ignored.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic void vboxserviceVMInfoWriteFixedProperties(void)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync{
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /*
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync * First get OS information that won't change.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync char szInfo[256];
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync int rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szInfo, sizeof(szInfo));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Product",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync "%s", RT_FAILURE(rc) ? "" : szInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Release",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync "%s", RT_FAILURE(rc) ? "" : szInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szInfo, sizeof(szInfo));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Version",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync "%s", RT_FAILURE(rc) ? "" : szInfo);
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szInfo, sizeof(szInfo));
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/ServicePack",
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync "%s", RT_FAILURE(rc) ? "" : szInfo);
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync /*
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync * Retrieve version information about Guest Additions and installed files (components).
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync */
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync char *pszAddVer;
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync char *pszAddRev;
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync rc = VbglR3GetAdditionsVersion(&pszAddVer, &pszAddRev);
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Version",
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync "%s", RT_FAILURE(rc) ? "" : pszAddVer);
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Revision",
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync "%s", RT_FAILURE(rc) ? "" : pszAddRev);
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync if (RT_SUCCESS(rc))
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync {
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync RTStrFree(pszAddVer);
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync RTStrFree(pszAddRev);
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync }
3ae788d4138a852743619b65c7404deb5cbae3e7vboxsync
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync#ifdef RT_OS_WINDOWS
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /*
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * Do windows specific properties.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync char *pszInstDir;
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync rc = VbglR3GetAdditionsInstallationPath(&pszInstDir);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/InstallDir",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync "%s", RT_FAILURE(rc) ? "" : pszInstDir);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (RT_SUCCESS(rc))
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrFree(pszInstDir);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceWinGetComponentVersions(g_uVMInfoGuestPropSvcClientID);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync}
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/**
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * Provide information about active users.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic int vboxserviceVMInfoWriteUsers(void)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync{
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync int rc = VINF_SUCCESS;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync char *pszUserList = NULL;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync uint32_t cUsersInList = 0;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#ifdef RT_OS_WINDOWS
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# ifndef TARGET_NT4
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = VBoxServiceVMInfoWinWriteUsers(&pszUserList, &cUsersInList);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# else
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = VERR_NOT_IMPLEMENTED;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#elif defined(RT_OS_FREEBSD)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /** @todo FreeBSD: Port logged on user info retrival.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * However, FreeBSD 9 supports utmpx, so we could use the code
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * block below (?). */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = VERR_NOT_IMPLEMENTED;
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#elif defined(RT_OS_OS2)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrival. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = VERR_NOT_IMPLEMENTED;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#else
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync setutxent();
5b0a093ca572a855886faa6747ad46df859dd041vboxsync utmpx *ut_user;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync uint32_t cListSize = 32;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /* Allocate a first array to hold 32 users max. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync char **papszUsers = (char **)RTMemAllocZ(cListSize * sizeof(char *));
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync if (papszUsers == NULL)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = VERR_NO_MEMORY;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /* Process all entries in the utmp file. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync while ( (ut_user = getutxent())
5b0a093ca572a855886faa6747ad46df859dd041vboxsync && RT_SUCCESS(rc))
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceVerbose(4, "VMInfo: Found logged in user \"%s\"\n", ut_user->ut_user);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (cUsersInList > cListSize)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync cListSize += 32;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync void *pvNew = RTMemRealloc(papszUsers, cListSize * sizeof(char*));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync AssertPtrBreakStmt(pvNew, cListSize -= 32);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync papszUsers = (char **)pvNew;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /* Make sure we don't add user names which are not
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * part of type USER_PROCESS. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (ut_user->ut_type == USER_PROCESS)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync bool fFound = false;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync for (uint32_t i = 0; i < cUsersInList && !fFound; i++)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync fFound = strcmp(papszUsers[i], ut_user->ut_user) == 0;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (!fFound)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = RTStrDupEx(&papszUsers[cUsersInList], (const char *)ut_user->ut_user);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (RT_FAILURE(rc))
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync break;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync cUsersInList++;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /* Calc the string length. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync size_t cchUserList = 0;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync for (uint32_t i = 0; i < cUsersInList; i++)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync cchUserList += (i != 0) + strlen(papszUsers[i]);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /* Build the user list. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync rc = RTStrAllocEx(&pszUserList, cchUserList + 1);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (RT_SUCCESS(rc))
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync char *psz = pszUserList;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync for (uint32_t i = 0; i < cUsersInList; i++)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (i != 0)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync *psz++ = ',';
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync size_t cch = strlen(papszUsers[i]);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync memcpy(psz, papszUsers[i], cch);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync psz += cch;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync *psz = '\0';
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /* Cleanup. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync for (uint32_t i = 0; i < cUsersInList; i++)
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync RTStrFree(papszUsers[i]);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTMemFree(papszUsers);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync endutxent(); /* Close utmpx file. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync Assert(RT_FAILURE(rc) || cUsersInList == 0 || (pszUserList && *pszUserList));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (RT_FAILURE(rc))
5b0a093ca572a855886faa6747ad46df859dd041vboxsync cUsersInList = 0;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync if (pszUserList && cUsersInList > 0)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", pszUserList);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync else
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (g_cVMInfoLoggedInUsers != cUsersInList)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync cUsersInList == 0 ? "true" : "false");
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync g_cVMInfoLoggedInUsers = cUsersInList;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (RT_SUCCESS(rc) && pszUserList)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrFree(pszUserList);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync return VINF_SUCCESS;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync}
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync/**
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * Provide information about the guest network.
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsyncstatic int vboxserviceVMInfoWriteNetwork(void)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync{
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync int cIfacesReport = 0;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync char szPropPath[256];
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#ifdef RT_OS_WINDOWS
5b0a093ca572a855886faa6747ad46df859dd041vboxsync IP_ADAPTER_INFO *pAdpInfo = NULL;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# ifndef TARGET_NT4
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync ULONG cbAdpInfo = sizeof(*pAdpInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAdpInfo = (IP_ADAPTER_INFO *)RTMemAlloc(cbAdpInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (!pAdpInfo)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceError("VMInfo/Network: Failed to allocate IP_ADAPTER_INFO\n");
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync return VERR_NO_MEMORY;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync DWORD dwRet = GetAdaptersInfo(pAdpInfo, &cbAdpInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (dwRet == ERROR_BUFFER_OVERFLOW)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync IP_ADAPTER_INFO *pAdpInfoNew = (IP_ADAPTER_INFO*)RTMemRealloc(pAdpInfo, cbAdpInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (pAdpInfoNew)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAdpInfo = pAdpInfoNew;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync dwRet = GetAdaptersInfo(pAdpInfo, &cbAdpInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (dwRet != ERROR_SUCCESS)
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (pAdpInfo)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTMemFree(pAdpInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceError("VMInfo/Network: Failed to get adapter info: Error %d\n", dwRet);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync return RTErrConvertFromWin32(dwRet);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync# endif
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (sd == SOCKET_ERROR) /* Socket invalid. */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %d\n", WSAGetLastError());
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (pAdpInfo)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync RTMemFree(pAdpInfo);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return RTErrConvertFromWin32(WSAGetLastError());
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync INTERFACE_INFO InterfaceList[20] = {0};
5b0a093ca572a855886faa6747ad46df859dd041vboxsync unsigned long nBytesReturned = 0;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (WSAIoctl(sd,
5b0a093ca572a855886faa6747ad46df859dd041vboxsync SIO_GET_INTERFACE_LIST,
5b0a093ca572a855886faa6747ad46df859dd041vboxsync 0,
5b0a093ca572a855886faa6747ad46df859dd041vboxsync 0,
5b0a093ca572a855886faa6747ad46df859dd041vboxsync &InterfaceList,
5b0a093ca572a855886faa6747ad46df859dd041vboxsync sizeof(InterfaceList),
5b0a093ca572a855886faa6747ad46df859dd041vboxsync &nBytesReturned,
5b0a093ca572a855886faa6747ad46df859dd041vboxsync 0,
5b0a093ca572a855886faa6747ad46df859dd041vboxsync 0) == SOCKET_ERROR)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync VBoxServiceError("VMInfo/Network: Failed to WSAIoctl() on socket: Error: %d\n", WSAGetLastError());
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (pAdpInfo)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTMemFree(pAdpInfo);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync return RTErrConvertFromWin32(WSAGetLastError());
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync int cIfacesSystem = nBytesReturned / sizeof(INTERFACE_INFO);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /** @todo Use GetAdaptersInfo() and GetAdapterAddresses (IPv4 + IPv6) for more information. */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync for (int i = 0; i < cIfacesSystem; ++i)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync sockaddr_in *pAddress;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync u_long nFlags = 0;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (InterfaceList[i].iiFlags & IFF_LOOPBACK) /* Skip loopback device. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync continue;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync nFlags = InterfaceList[i].iiFlags;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAddress = (sockaddr_in *)&(InterfaceList[i].iiAddress);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync Assert(pAddress);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync char szIp[32];
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szIp, sizeof(szIp), "%s", inet_ntoa(pAddress->sin_addr));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szIp);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAddress = (sockaddr_in *)&(InterfaceList[i].iiNetmask);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, nFlags & IFF_UP ? "Up" : "Down");
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# ifndef TARGET_NT4
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync IP_ADAPTER_INFO *pAdp;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync for (pAdp = pAdpInfo; pAdp; pAdp = pAdp->Next)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (!strcmp(pAdp->IpAddressList.IpAddress.String, szIp))
993a55bd118e0b54549b3f0b380a8fbd6246a040vboxsync break;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (pAdp)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync char szMac[32];
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAdp->Address[0], pAdp->Address[1], pAdp->Address[2],
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAdp->Address[3], pAdp->Address[4], pAdp->Address[5]);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync else
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, NULL);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync cIfacesReport++;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (pAdpInfo)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTMemFree(pAdpInfo);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (sd >= 0)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync closesocket(sd);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync#elif defined(RT_OS_FREEBSD)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync int rc = 0;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync struct ifaddrs *pIfHead = NULL;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /* Get all available interfaces */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync rc = getifaddrs(&pIfHead);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (rc < 0)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync VBoxServiceError("VMInfo/Network: Failed to get all interfaces: Error %d\n", errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return RTErrConvertFromErrno(errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /* Loop through all interfaces and set the data. */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync for (struct ifaddrs *pIfCurr = pIfHead; pIfCurr; pIfCurr = pIfCurr->ifa_next)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /*
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * Only AF_INET and no loopback interfaces
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * @todo: IPv6 interfaces
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if ( pIfCurr->ifa_addr->sa_family == AF_INET
5b0a093ca572a855886faa6747ad46df859dd041vboxsync && !(pIfCurr->ifa_flags & IFF_LOOPBACK))
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync char szInetAddr[NI_MAXHOST];
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync memset(szInetAddr, 0, NI_MAXHOST);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync getnameinfo(pIfCurr->ifa_addr, sizeof(struct sockaddr_in),
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync memset(szInetAddr, 0, NI_MAXHOST);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync getnameinfo(pIfCurr->ifa_broadaddr, sizeof(struct sockaddr_in),
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync memset(szInetAddr, 0, NI_MAXHOST);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync getnameinfo(pIfCurr->ifa_netmask, sizeof(struct sockaddr_in),
993a55bd118e0b54549b3f0b380a8fbd6246a040vboxsync szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /* Search for the AF_LINK interface of the current AF_INET one and get the mac. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync for (struct ifaddrs *pIfLinkCurr = pIfHead; pIfLinkCurr; pIfLinkCurr = pIfLinkCurr->ifa_next)
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if ( pIfLinkCurr->ifa_addr->sa_family == AF_LINK
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync && !strcmp(pIfCurr->ifa_name, pIfLinkCurr->ifa_name))
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync char szMac[32];
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync uint8_t *pu8Mac = NULL;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync struct sockaddr_dl *pLinkAddress = (struct sockaddr_dl *)pIfLinkCurr->ifa_addr;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync AssertPtr(pLinkAddress);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pu8Mac = (uint8_t *)LLADDR(pLinkAddress);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3], pu8Mac[4], pu8Mac[5]);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync break;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, pIfCurr->ifa_flags & IFF_UP ? "Up" : "Down");
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync cIfacesReport++;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /* Free allocated resources. */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync freeifaddrs(pIfHead);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync#else /* !RT_OS_WINDOWS && !RT_OS_FREEBSD */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync int sd = socket(AF_INET, SOCK_DGRAM, 0);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (sd < 0)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %d\n", errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return RTErrConvertFromErrno(errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync ifconf ifcfg;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync char buffer[1024] = {0};
5b0a093ca572a855886faa6747ad46df859dd041vboxsync ifcfg.ifc_len = sizeof(buffer);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync ifcfg.ifc_buf = buffer;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (ioctl(sd, SIOCGIFCONF, &ifcfg) < 0)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFCONF) on socket: Error %d\n", errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return RTErrConvertFromErrno(errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync ifreq* ifrequest = ifcfg.ifc_req;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync int cIfacesSystem = ifcfg.ifc_len / sizeof(ifreq);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync for (int i = 0; i < cIfacesSystem; ++i)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync sockaddr_in *pAddress;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (ioctl(sd, SIOCGIFFLAGS, &ifrequest[i]) < 0)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFFLAGS) on socket: Error %d\n", errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync close(sd);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return RTErrConvertFromErrno(errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (ifrequest[i].ifr_flags & IFF_LOOPBACK) /* Skip the loopback device. */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync continue;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync bool fIfUp = !!(ifrequest[i].ifr_flags & IFF_UP);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync pAddress = ((sockaddr_in *)&ifrequest[i].ifr_addr);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync Assert(pAddress);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (ioctl(sd, SIOCGIFBRDADDR, &ifrequest[i]) < 0)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync close(sd);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return RTErrConvertFromErrno(errno);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAddress = (sockaddr_in *)&ifrequest[i].ifr_broadaddr;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
192a1d418422c3b5905dd2577527c07a8ed8b61evboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync if (ioctl(sd, SIOCGIFNETMASK, &ifrequest[i]) < 0)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync {
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync close(sd);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync return RTErrConvertFromErrno(errno);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync }
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# if defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAddress = (sockaddr_in *)&ifrequest[i].ifr_addr;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# else
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync pAddress = (sockaddr_in *)&ifrequest[i].ifr_netmask;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# endif
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync# if defined(RT_OS_SOLARIS)
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /*
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * "ifreq" is obsolete on Solaris. We use the recommended "lifreq".
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * We might fail if the interface has not been assigned an IP address.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * That doesn't matter; as long as it's plumbed we can pick it up.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * But, if it has not acquired an IP address we cannot obtain it's MAC
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync * address this way, so we just use all zeros there.
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync */
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RTMAC IfMac;
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync RT_ZERO(IfMac);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync struct lifreq IfReq;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync RT_ZERO(IfReq);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync AssertCompile(sizeof(IfReq.lifr_name) >= sizeof(ifrequest[i].ifr_name));
5b0a093ca572a855886faa6747ad46df859dd041vboxsync strncpy(IfReq.lifr_name, ifrequest[i].ifr_name, sizeof(ifrequest[i].ifr_name));
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (ioctl(sd, SIOCGLIFADDR, &IfReq) >= 0)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync struct arpreq ArpReq;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync RT_ZERO(ArpReq);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync memcpy(&ArpReq.arp_pa, &IfReq.lifr_addr, sizeof(struct sockaddr_in));
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync if (ioctl(sd, SIOCGARP, &ArpReq) >= 0)
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync memcpy(&IfMac, ArpReq.arp_ha.sa_data, sizeof(IfMac));
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync else
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync VBoxServiceError("VMInfo/Network: failed to ioctl(SIOCGARP) on socket: Error %d\n", errno);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync }
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync else
5b0a093ca572a855886faa6747ad46df859dd041vboxsync VBoxServiceError("VMInfo/Network: failed to ioctl(SIOCGLIFADDR) on socket: Error %d\n", errno);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync# else
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync if (ioctl(sd, SIOCGIFHWADDR, &ifrequest[i]) < 0)
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync {
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync /* @todo don't fail here, handle failure with zero MAC address */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFHWADDR) on socket: Error %d\n", errno);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync close(sd);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync return RTErrConvertFromErrno(errno);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync }
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync# endif
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync char szMac[32];
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync# if defined(RT_OS_SOLARIS)
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync uint8_t *pu8Mac = IfMac.au8;
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync# else
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync uint8_t *pu8Mac = (uint8_t*)&ifrequest[i].ifr_hwaddr.sa_data[0]; /* @todo see above */
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync# endif
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3], pu8Mac[4], pu8Mac[5]);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, fIfUp ? "Up" : "Down");
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync cIfacesReport++;
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync }
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync close(sd);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync#endif /* !RT_OS_WINDOWS */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /*
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * This property is a beacon which is _always_ written, even if the network configuration
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * does not change. If this property is missing, the host assumes that all other GuestInfo
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * properties are no longer valid.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d",
5b0a093ca572a855886faa6747ad46df859dd041vboxsync cIfacesReport);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /** @todo r=bird: if cIfacesReport decreased compared to the previous run, zap
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * the stale data. This can probably be encorporated into the cache. */
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync return VINF_SUCCESS;
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync}
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync/** @copydoc VBOXSERVICE::pfnWorker */
5b0a093ca572a855886faa6747ad46df859dd041vboxsyncDECLCALLBACK(int) VBoxServiceVMInfoWorker(bool volatile *pfShutdown)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync{
5b0a093ca572a855886faa6747ad46df859dd041vboxsync int rc;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /*
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * Tell the control thread that it can continue
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * spawning services.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync RTThreadUserSignal(RTThreadSelf());
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync#ifdef RT_OS_WINDOWS
809e0c4b84167932d92a1df4edcbab2edf0ddf25vboxsync /* Required for network information (must be called per thread). */
d3dea25ec07f6546715fe3af943ea863294b392evboxsync WSADATA wsaData;
d3dea25ec07f6546715fe3af943ea863294b392evboxsync if (WSAStartup(MAKEWORD(2, 2), &wsaData))
d3dea25ec07f6546715fe3af943ea863294b392evboxsync VBoxServiceError("VMInfo/Network: WSAStartup failed! Error: %Rrc\n", RTErrConvertFromWin32(WSAGetLastError()));
d3dea25ec07f6546715fe3af943ea863294b392evboxsync#endif /* RT_OS_WINDOWS */
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync /*
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync * Write the fixed properties first.
d3dea25ec07f6546715fe3af943ea863294b392evboxsync */
d3dea25ec07f6546715fe3af943ea863294b392evboxsync vboxserviceVMInfoWriteFixedProperties();
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync /*
d3dea25ec07f6546715fe3af943ea863294b392evboxsync * Now enter the loop retrieving runtime data continuously.
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync */
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync for (;;)
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync {
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync rc = vboxserviceVMInfoWriteUsers();
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync if (RT_FAILURE(rc))
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync break;
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync rc = vboxserviceVMInfoWriteNetwork();
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync if (RT_FAILURE(rc))
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync break;
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync /*
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync * Block for a while.
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync *
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync * The event semaphore takes care of ignoring interruptions and it
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync * allows us to implement service wakeup later.
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync */
d3dea25ec07f6546715fe3af943ea863294b392evboxsync if (*pfShutdown)
d3dea25ec07f6546715fe3af943ea863294b392evboxsync break;
d3dea25ec07f6546715fe3af943ea863294b392evboxsync int rc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval);
d3dea25ec07f6546715fe3af943ea863294b392evboxsync if (*pfShutdown)
d3dea25ec07f6546715fe3af943ea863294b392evboxsync break;
d3dea25ec07f6546715fe3af943ea863294b392evboxsync if (rc2 != VERR_TIMEOUT && RT_FAILURE(rc2))
d3dea25ec07f6546715fe3af943ea863294b392evboxsync {
d3dea25ec07f6546715fe3af943ea863294b392evboxsync VBoxServiceError("VMInfo: RTSemEventMultiWait failed; rc2=%Rrc\n", rc2);
d3dea25ec07f6546715fe3af943ea863294b392evboxsync rc = rc2;
d3dea25ec07f6546715fe3af943ea863294b392evboxsync break;
d3dea25ec07f6546715fe3af943ea863294b392evboxsync }
d3dea25ec07f6546715fe3af943ea863294b392evboxsync }
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync#ifdef RT_OS_WINDOWS
d3dea25ec07f6546715fe3af943ea863294b392evboxsync WSACleanup();
d3dea25ec07f6546715fe3af943ea863294b392evboxsync#endif
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync return rc;
d3dea25ec07f6546715fe3af943ea863294b392evboxsync}
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync/** @copydoc VBOXSERVICE::pfnStop */
d3dea25ec07f6546715fe3af943ea863294b392evboxsyncstatic DECLCALLBACK(void) VBoxServiceVMInfoStop(void)
d3dea25ec07f6546715fe3af943ea863294b392evboxsync{
d3dea25ec07f6546715fe3af943ea863294b392evboxsync RTSemEventMultiSignal(g_hVMInfoEvent);
d3dea25ec07f6546715fe3af943ea863294b392evboxsync}
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync/** @copydoc VBOXSERVICE::pfnTerm */
d3dea25ec07f6546715fe3af943ea863294b392evboxsyncstatic DECLCALLBACK(void) VBoxServiceVMInfoTerm(void)
d3dea25ec07f6546715fe3af943ea863294b392evboxsync{
d3dea25ec07f6546715fe3af943ea863294b392evboxsync int rc;
d3dea25ec07f6546715fe3af943ea863294b392evboxsync
d3dea25ec07f6546715fe3af943ea863294b392evboxsync if (g_hVMInfoEvent != NIL_RTSEMEVENTMULTI)
d3dea25ec07f6546715fe3af943ea863294b392evboxsync {
d3dea25ec07f6546715fe3af943ea863294b392evboxsync /** @todo temporary solution: Zap all values which are not valid
d3dea25ec07f6546715fe3af943ea863294b392evboxsync * anymore when VM goes down (reboot/shutdown ). Needs to
d3dea25ec07f6546715fe3af943ea863294b392evboxsync * be replaced with "temporary properties" later.
d3dea25ec07f6546715fe3af943ea863294b392evboxsync *
d3dea25ec07f6546715fe3af943ea863294b392evboxsync * One idea is to introduce a (HGCM-)session guest property
d3dea25ec07f6546715fe3af943ea863294b392evboxsync * flag meaning that a guest property is only valid as long
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * as the HGCM session isn't closed (e.g. guest application
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * terminates). [don't remove till implemented]
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /** @todo r=bird: Drop the VbglR3GuestPropDelSet call here and use the cache
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * since it remembers what we've written. */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* Delete the "../Net" branch. */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync const char *apszPat[1] = { "/VirtualBox/GuestInfo/Net/*" };
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat));
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* Destroy property cache. */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync VBoxServicePropCacheDestroy(&g_VMInfoPropCache);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* Disconnect from guest properties service. */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync rc = VbglR3GuestPropDisconnect(g_uVMInfoGuestPropSvcClientID);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (RT_FAILURE(rc))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync VBoxServiceError("VMInfo: Failed to disconnect from guest property service! Error: %Rrc\n", rc);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync g_uVMInfoGuestPropSvcClientID = 0;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync RTSemEventMultiDestroy(g_hVMInfoEvent);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync g_hVMInfoEvent = NIL_RTSEMEVENTMULTI;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync }
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync}
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync/**
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * The 'vminfo' service description.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsyncVBOXSERVICE g_VMInfo =
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync{
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* pszName. */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync "vminfo",
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* pszDescription. */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync "Virtual Machine Information",
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* pszUsage. */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync " [--vminfo-interval <ms>]"
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync ,
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* pszOptions. */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync " --vminfo-interval Specifies the interval at which to retrieve the\n"
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync " VM information. The default is 10000 ms.\n"
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync ,
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* methods */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync VBoxServiceVMInfoPreInit,
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync VBoxServiceVMInfoOption,
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync VBoxServiceVMInfoInit,
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync VBoxServiceVMInfoWorker,
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync VBoxServiceVMInfoStop,
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync VBoxServiceVMInfoTerm
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync};
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync