1
/*********************************************************
2
* Copyright (C) 2008 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License as published
6
* by the Free Software Foundation version 2.1 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
11
* License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*********************************************************/
22
* Library backing parts of the vm.GuestInfo VIM APIs.
29
# include <ws2tcpip.h>
32
#include "vm_assert.h"
34
#include "getlibInt.h"
43
* Helper to initialize an opaque struct member.
45
* @todo Move to xdrutil.h? Sticking point is dependency on Util_SafeMalloc.
47
#define XDRUTIL_SAFESETOPAQUE(ptr, type, src, size) \
49
(ptr)->type##_len = (size); \
50
(ptr)->type##_val = Util_SafeMalloc((size)); \
51
memcpy((ptr)->type##_val, (src), (size)); \
61
******************************************************************************
62
* GuestInfo_GetFqdn -- */ /**
64
* @brief Returns the guest's hostname (aka fully qualified domain name, FQDN).
66
* @param[in] outBufLen Size of outBuf.
67
* @param[out] outBuf Output buffer.
69
* @retval TRUE Success. Hostname written to @a outBuf.
70
* @retval FALSE Failure.
72
******************************************************************************
76
GuestInfo_GetFqdn(int outBufLen,
79
return GuestInfoGetFqdn(outBufLen, fqdn);
84
******************************************************************************
85
* GuestInfo_GetNicInfo -- */ /**
87
* @brief Returns guest networking configuration (and some runtime state).
89
* @param[out] nicInfo Will point to a newly allocated NicInfo.
92
* Caller is responsible for freeing @a nicInfo with GuestInfo_FreeNicInfo.
94
* @retval TRUE Success. @a nicInfo now points to a populated NicInfoV3.
95
* @retval FALSE Failure.
97
******************************************************************************
101
GuestInfo_GetNicInfo(NicInfoV3 **nicInfo)
105
*nicInfo = Util_SafeCalloc(1, sizeof (struct NicInfoV3));
107
retval = GuestInfoGetNicInfo(*nicInfo);
118
******************************************************************************
119
* GuestInfo_FreeNicInfo -- */ /**
121
* @brief Frees a NicInfoV3 structure and all memory it points to.
123
* @param[in] nicInfo Pointer to NicInfoV3 container.
125
* @sa GuestInfo_GetNicInfo
127
******************************************************************************
131
GuestInfo_FreeNicInfo(NicInfoV3 *nicInfo)
133
if (nicInfo != NULL) {
134
VMX_XDR_FREE(xdr_NicInfoV3, nicInfo);
141
******************************************************************************
142
* GuestInfo_FreeDiskInfo -- */ /**
144
* @brief Frees memory allocated by GuestInfoGetDiskInfo.
146
* @param[in] di DiskInfo container.
148
******************************************************************************
152
GuestInfo_FreeDiskInfo(GuestDiskInfo *di)
155
free(di->partitionList);
162
* Private library functions.
167
******************************************************************************
168
* GuestInfoGetDiskInfoWiper -- */ /**
170
* Uses wiper library to enumerate fixed volumes and lookup utilization data.
172
* @return Pointer to a GuestDiskInfo structure on success or NULL on failure.
173
* Caller should free returned pointer with GuestInfoFreeDiskInfo.
175
******************************************************************************
179
GuestInfoGetDiskInfoWiper(void)
181
WiperPartition_List pl;
182
DblLnkLst_Links *curr;
183
unsigned int partCount = 0;
184
uint64 freeBytes = 0;
185
uint64 totalBytes = 0;
186
unsigned int partNameSize = 0;
187
Bool success = FALSE;
190
/* Get partition list. */
191
if (!WiperPartition_Open(&pl)) {
192
g_debug("GetDiskInfo: ERROR: could not get partition list\n");
196
di = Util_SafeCalloc(1, sizeof *di);
197
partNameSize = sizeof (di->partitionList)[0].name;
199
DblLnkLst_ForEach(curr, &pl.link) {
200
WiperPartition *part = DblLnkLst_Container(curr, WiperPartition, link);
202
if (part->type != PARTITION_UNSUPPORTED) {
203
PPartitionEntry newPartitionList;
204
PPartitionEntry partEntry;
205
unsigned char *error;
207
error = WiperSinglePartition_GetSpace(part, &freeBytes, &totalBytes);
209
g_debug("GetDiskInfo: ERROR: could not get space for partition %s: %s\n",
210
part->mountPoint, error);
214
if (strlen(part->mountPoint) + 1 > partNameSize) {
215
g_debug("GetDiskInfo: ERROR: Partition name buffer too small\n");
219
newPartitionList = Util_SafeRealloc(di->partitionList,
221
sizeof *di->partitionList);
223
partEntry = &newPartitionList[partCount++];
224
Str_Strcpy(partEntry->name, part->mountPoint, partNameSize);
225
partEntry->freeBytes = freeBytes;
226
partEntry->totalBytes = totalBytes;
228
di->partitionList = newPartitionList;
232
di->numEntries = partCount;
237
GuestInfo_FreeDiskInfo(di);
240
WiperPartition_Close(&pl);
246
******************************************************************************
247
* GuestInfoAddNicEntry -- */ /**
249
* @brief GuestNicV3 constructor.
251
* @param[in,out] nicInfo List of NICs.
252
* @param[in] macAddress MAC address of new NIC.
253
* @param[in] dnsInfo Per-NIC DNS config state.
254
* @param[in] winsInfo Per-NIC WINS config state.
256
* @note The returned GuestNic will take ownership of @a dnsInfo and
257
* @a winsInfo The caller must not free it directly.
259
* @return Pointer to the new NIC, or NULL if NIC limit was reached.
261
******************************************************************************
265
GuestInfoAddNicEntry(NicInfoV3 *nicInfo,
266
const char macAddress[NICINFO_MAC_LEN],
267
DnsConfigInfo *dnsInfo,
268
WinsConfigInfo *winsInfo)
272
/* Check to see if we're going above our limit. See bug 605821. */
273
if (nicInfo->nics.nics_len == NICINFO_MAX_NICS) {
274
g_message("%s: NIC limit (%d) reached, skipping overflow.",
275
__FUNCTION__, NICINFO_MAX_NICS);
279
newNic = XDRUTIL_ARRAYAPPEND(nicInfo, nics, 1);
280
ASSERT_MEM_ALLOC(newNic);
282
newNic->macAddress = Util_SafeStrdup(macAddress);
283
newNic->dnsConfigInfo = dnsInfo;
284
newNic->winsConfigInfo = winsInfo;
291
******************************************************************************
292
* GuestInfoAddIpAddress -- */ /**
294
* @brief Add an IP address entry into the GuestNic.
296
* @param[in,out] nic The NIC information.
297
* @param[in] sockAddr The new IP address.
298
* @param[in] pfxLen Prefix length (use 0 if unknown).
299
* @param[in] origin Address's origin. (Optional.)
300
* @param[in] status Address's status. (Optional.)
302
* @return Newly allocated IP address struct, NULL on failure.
304
******************************************************************************
308
GuestInfoAddIpAddress(GuestNicV3 *nic,
309
const struct sockaddr *sockAddr,
310
InetAddressPrefixLength pfxLen,
311
const IpAddressOrigin *origin,
312
const IpAddressStatus *status)
318
/* Check to see if we're going above our limit. See bug 605821. */
319
if (nic->ips.ips_len == NICINFO_MAX_IPS) {
320
g_message("%s: IP address limit (%d) reached, skipping overflow.",
321
__FUNCTION__, NICINFO_MAX_IPS);
325
ip = XDRUTIL_ARRAYAPPEND(nic, ips, 1);
326
ASSERT_MEM_ALLOC(ip);
328
ASSERT_ON_COMPILE(sizeof *origin == sizeof *ip->ipAddressOrigin);
329
ASSERT_ON_COMPILE(sizeof *status == sizeof *ip->ipAddressStatus);
331
switch (sockAddr->sa_family) {
334
static const IpAddressStatus defaultStatus = IAS_PREFERRED;
336
GuestInfoSockaddrToTypedIpAddress(sockAddr, &ip->ipAddressAddr);
338
ip->ipAddressPrefixLength = pfxLen;
339
ip->ipAddressOrigin = origin ? Util_DupeThis(origin, sizeof *origin) : NULL;
340
ip->ipAddressStatus = status ? Util_DupeThis(status, sizeof *status) :
341
Util_DupeThis(&defaultStatus, sizeof defaultStatus);
346
static const IpAddressStatus defaultStatus = IAS_UNKNOWN;
348
GuestInfoSockaddrToTypedIpAddress(sockAddr, &ip->ipAddressAddr);
350
ip->ipAddressPrefixLength = pfxLen;
351
ip->ipAddressOrigin = origin ? Util_DupeThis(origin, sizeof *origin) : NULL;
352
ip->ipAddressStatus = status ? Util_DupeThis(status, sizeof *status) :
353
Util_DupeThis(&defaultStatus, sizeof defaultStatus);
365
******************************************************************************
366
* GuestInfoSockaddrToTypedIpAddress -- */ /**
368
* @brief Converts a <tt>struct sockaddr</tt> to a @c TypedIpAddress.
370
* @param[in] sa Source @c sockaddr.
371
* @param[out] typedIp Destination @c TypedIpAddress.
373
* @warning Caller is responsible for making sure source is AF_INET or
376
******************************************************************************
380
GuestInfoSockaddrToTypedIpAddress(const struct sockaddr *sa,
381
TypedIpAddress *typedIp)
383
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
384
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
386
switch (sa->sa_family) {
388
typedIp->ipAddressAddrType = IAT_IPV4;
389
XDRUTIL_SAFESETOPAQUE(&typedIp->ipAddressAddr, InetAddress,
390
&sin->sin_addr.s_addr,
391
sizeof sin->sin_addr.s_addr);
394
typedIp->ipAddressAddrType = IAT_IPV6;
395
XDRUTIL_SAFESETOPAQUE(&typedIp->ipAddressAddr, InetAddress,
396
&sin6->sin6_addr.s6_addr,
397
sizeof sin6->sin6_addr.s6_addr);
405
#if defined linux || defined _WIN32
407
******************************************************************************
408
* GuestInfoGetNicInfoIfIndex -- */ /**
410
* @brief Given a local interface's index, find its corresponding location in the
411
* NicInfoV3 @c nics vector.
413
* @param[in] nicInfo NIC container.
414
* @param[in] ifIndex Device to search for.
415
* @param[out] nicifIndex Array offset, if found.
417
* @retval TRUE Device found.
418
* @retval FALSE Device not found.
420
******************************************************************************
424
GuestInfoGetNicInfoIfIndex(NicInfoV3 *nicInfo,
428
char hwAddrString[NICINFO_MAC_LEN];
429
unsigned char hwAddr[16];
437
if (NetUtil_GetHardwareAddress(ifIndex, hwAddr, sizeof hwAddr,
439
ifType != IANA_IFTYPE_ETHERNETCSMACD) {
443
Str_Sprintf(hwAddrString, sizeof hwAddrString,
444
"%02x:%02x:%02x:%02x:%02x:%02x",
445
hwAddr[0], hwAddr[1], hwAddr[2],
446
hwAddr[3], hwAddr[4], hwAddr[5]);
448
XDRUTIL_FOREACH(i, nicInfo, nics) {
449
GuestNicV3 *nic = XDRUTIL_GETITEM(nicInfo, nics, i);
450
if (!strcasecmp(nic->macAddress, hwAddrString)) {
459
#endif // if defined linux || defined _WIN32
468
* Return a copy of arbitrary memory.
470
* @param[in] source Source address.
471
* @param[in] sourceSize Number of bytes to allocate, copy.
473
* @return Pointer to newly allocated memory.
475
* @todo Determine if I'm duplicating functionality.
476
* @todo Move this to bora/lib/util or whatever.
480
Util_DupeThis(const void *source,
487
dest = Util_SafeMalloc(sourceSize);
488
memcpy(dest, source, sourceSize);