80
82
static Bool vmResumed;
83
* The Windows Guest Info Server runs in a separate thread,
84
* so we have to synchronize access to 'vmResumed' variable.
85
* Non-windows guest info server does not run in a separate
86
* thread, so no locking is needed.
90
typedef CRITICAL_SECTION vmResumedLockType;
91
#define GUESTINFO_DELETE_LOCK(lockPtr) DeleteCriticalSection(lockPtr)
92
#define GUESTINFO_ENTER_LOCK(lockPtr) EnterCriticalSection(lockPtr)
93
#define GUESTINFO_LEAVE_LOCK(lockPtr) LeaveCriticalSection(lockPtr)
94
#define GUESTINFO_INIT_LOCK(lockPtr) InitializeCriticalSection(lockPtr)
96
vmResumedLockType vmResumedLock;
100
typedef int vmResumedLockType;
101
#define GUESTINFO_DELETE_LOCK(lockPtr)
102
#define GUESTINFO_ENTER_LOCK(lockPtr)
103
#define GUESTINFO_LEAVE_LOCK(lockPtr)
104
#define GUESTINFO_INIT_LOCK(lockPtr)
108
84
static Bool GuestInfoGather(void * clientData);
109
85
static Bool GuestInfoUpdateVmdb(GuestInfoType infoType, void* info);
110
86
static Bool SetGuestInfo(GuestInfoType key, const char* value, char delimiter);
111
static Bool NicInfoChanged(GuestNicInfo *nicInfo);
87
static Bool NicInfoChanged(GuestNicList *nicInfo);
112
88
static Bool DiskInfoChanged(PGuestDiskInfo diskInfo);
113
89
static void GuestInfoClearCache(void);
114
static Bool GuestInfoSerializeNicInfo(GuestNicInfo *nicInfo,
115
char buffer[GUESTMSG_MAX_IN_SIZE],
117
static int PrintNicInfo(GuestNicInfo *nicInfo, int (*PrintFunc)(const char *, ...));
120
static Bool GuestInfoConvertNicInfoToNicInfoV1(GuestNicInfo *info, GuestNicInfoV1 *infoV1);
124
*-----------------------------------------------------------------------------
126
* GuestInfoServer_Main --
128
* The main event loop for the guest info server.
129
* GuestInfoServer_Init() much be called prior to calling this function.
135
* Events are processed, information gathered and updates sent.
137
*-----------------------------------------------------------------------------
141
GuestInfoServer_Main(void *data) // IN
145
HANDLE *events = (HANDLE *) data;
147
HANDLE finishedEvent;
153
quitEvent = events[0];
154
finishedEvent = events[1];
156
Debug("Starting GuestInfoServer for Windows.\n");
160
retVal = EventManager_ProcessNext(gGuestInfoEventQueue, &sleepUsecs);
162
Debug("Unexpected end of the guest info loop.\n");
167
* The number of micro seconds to sleep should not overflow a long. This
168
* corresponds to a maximum sleep time of around 4295 seconds (~ 71 minutes)
169
* which should be more than enough.
172
Debug("Sleeping for %"FMT64"u msecs...\n", sleepUsecs / 1000);
173
dwError = WaitForSingleObject(quitEvent, sleepUsecs / 1000);
174
if (dwError == WAIT_OBJECT_0) {
175
GuestApp_Log("GuestInfoServer received quit event.\n");
176
Debug("GuestInfoServer received quit event.\n");
178
} else if (dwError == WAIT_TIMEOUT) {
179
Debug("GuestInfoServer woke up.\n");
180
} else if (dwError == WAIT_FAILED) {
181
Debug("GuestInfoServer error waiting on exit event: %d %d\n",
182
dwError, GetLastError());
186
SetEvent(finishedEvent);
187
GuestApp_Log("GuestInfoServer exiting.\n");
90
static int PrintNicInfo(GuestNicList *nicInfo, int (*PrintFunc)(const char *, ...));
446
GuestInfoConvertNicInfoToNicInfoV1(GuestNicInfo *info, // IN
447
GuestNicInfoV1 *infoV1) // OUT
347
GuestInfoConvertNicInfoToNicInfoV1(GuestNicList *info, // IN
348
GuestNicInfoV1 *infoV1) // OUT
449
NicEntry *nicEntryCur;
452
DblLnkLst_Links *nicEntryLink;
454
353
if ((NULL == info) ||
455
354
(NULL == infoV1)) {
459
maxNics = info->nicInfoProto.numNicEntries > MAX_NICS ?
460
MAX_NICS : info->nicInfoProto.numNicEntries;
358
maxNics = MIN(info->nics.nics_len, MAX_NICS);
461
359
infoV1->numNicEntries = maxNics;
462
if (maxNics < info->nicInfoProto.numNicEntries) {
463
Debug("Truncating NICs.\n");
360
if (maxNics < info->nics.nics_len) {
361
Debug("GuestInfo: truncating NIC list for backwards compatibility.\n");
466
DblLnkLst_ForEach(nicEntryLink, &info->nicList) {
364
XDRUTIL_FOREACH(i, info, nics) {
469
VmIpAddressEntry *ipAddressCur;
470
DblLnkLst_Links *ipAddrLink;
472
if (nicIndex >= maxNics) {
367
GuestNic *nic = XDRUTIL_GETITEM(info, nics, i);
369
Str_Strcpy(infoV1->nicList[i].macAddress,
371
sizeof infoV1->nicList[i].macAddress);
373
maxIPs = MIN(nic->ips.ips_len, MAX_IPS);
374
infoV1->nicList[i].numIPs = 0;
376
XDRUTIL_FOREACH(j, nic, ips) {
377
VmIpAddress *ip = XDRUTIL_GETITEM(nic, ips, j);
379
if (strlen(ip->ipAddress) < sizeof infoV1->nicList[i].ipAddress[j]) {
380
Str_Strcpy(infoV1->nicList[i].ipAddress[j],
382
sizeof infoV1->nicList[i].ipAddress[j]);
383
infoV1->nicList[i].numIPs++;
384
if (infoV1->nicList[i].numIPs == maxIPs) {
388
Debug("GuestInfo: ignoring IPV6 address for compatibility.\n");
392
if (infoV1->nicList[i].numIPs != nic->ips.ips_len) {
393
Debug("GuestInfo: some IP addresses were ignored for compatibility.\n");
476
nicEntryCur = DblLnkLst_Container(nicEntryLink,
479
if (NULL == nicEntryCur) {
483
strcpy(infoV1->nicList[nicIndex].macAddress, nicEntryCur->nicEntryProto.macAddress);
485
maxIPs = nicEntryCur->nicEntryProto.numIPs > MAX_IPS ?
486
MAX_IPS : nicEntryCur->nicEntryProto.numIPs;
487
nicEntryCur -> nicEntryProto.numIPs = maxIPs;
488
if (maxIPs < nicEntryCur->nicEntryProto.numIPs) {
489
Debug("Truncating IP addresses for NIC %d.\n", nicIndex);
492
DblLnkLst_ForEach(ipAddrLink, &nicEntryCur->ipAddressList) {
494
if (ipIndex >= maxIPs) {
498
ipAddressCur = DblLnkLst_Container(ipAddrLink,
501
if (NULL == ipAddressCur) {
504
strcpy(infoV1->nicList[nicIndex].ipAddress[ipIndex],
505
ipAddressCur->ipEntryProto.ipAddress);
508
infoV1->nicList[nicIndex].numIPs = ipIndex;
576
462
case INFO_IPADDRESS:
577
if (NicInfoChanged((GuestNicInfo *)info)) {
463
if (NicInfoChanged((GuestNicList *)info)) {
578
464
static Bool isCmdV1 = FALSE;
579
char request[GUESTMSG_MAX_IN_SIZE];
580
size_t requestLength = 0;
581
465
char *reply = NULL;
585
469
if (FALSE == isCmdV1) {
586
Debug("Creating nic info message.\n");
590
GUEST_INFO_COMMAND_TWO,
593
if (GuestInfoSerializeNicInfo((GuestNicInfo *)info,
594
request + strlen(request),
596
requestLength += strlen(request);
470
/* 13 = max size of string representation of an int + 3 spaces. */
471
char request[sizeof GUEST_INFO_COMMAND + 13];
472
GuestNicProto message;
475
if (DynXdr_Create(&xdrs) == NULL) {
479
/* Add the RPC preamble: message name, and type. */
480
Str_Sprintf(request, sizeof request, "%s %d ",
481
GUEST_INFO_COMMAND, INFO_IPADDRESS_V2);
483
message.ver = NIC_INFO_V2;
484
message.GuestNicProto_u.nicsV2 = info;
486
/* Write preamble and serialized nic info to XDR stream. */
487
if (!DynXdr_AppendRaw(&xdrs, request, strlen(request)) ||
488
!xdr_GuestNicProto(&xdrs, &message)) {
489
Debug("GuestInfo: Error serializing nic info v2 data.");
490
DynXdr_Destroy(&xdrs, TRUE);
494
status = RpcOut_SendOneRaw(DynXdr_Get(&xdrs),
498
DynXdr_Destroy(&xdrs, TRUE);
500
Debug("GuestInfo: sent nic info message.\n");
601
Debug("GuestInfo: Sending nic info message.\n");
602
/* Send all the information in the message. */
603
status = RpcOut_SendOneRaw(request, requestLength, &reply, &replyLen);
605
Debug("GuestInfo: Just sent nic info message.\n");
502
Debug("GuestInfo: failed to send V2 nic info message.\n");
505
if (RpcVMX_ConfigGetBool(FALSE, "printNicInfo")) {
506
PrintNicInfo((GuestNicList *) info,
507
(int (*)(const char *fmt, ...)) RpcVMX_Log);
651
if (RpcVMX_ConfigGetBool(FALSE, "printNicInfo")) {
652
PrintNicInfo((GuestNicInfo *) info, (int (*)(const char *fmt, ...)) RpcVMX_Log);
655
554
Debug("GuestInfo: Updated new NIC information\n");
660
* Update the cache. Assign info to gInfoCache.nicInfo. First free dynamic
661
* memory allocated in gInfoCache.nicInfo. Then unlink those in nicInfo and
662
* link them back to gInfoCache.nicInfo this is sort of hacking. However, it
663
* works in this case, since nicInfo is not going to be used after this. NOTE,
664
* nicInfo CAN NOT BE USED AFTER THIS POINT.
559
* Update the cache. Release the memory previously used by the cache,
560
* and copy the new information into the cache.
666
GuestInfo_FreeDynamicMemoryInNicInfo(&gInfoCache.nicInfo);
667
/* assign the fixed memory part */
668
gInfoCache.nicInfo = *(GuestNicInfo *)info;
669
/* assign the dynamic memory part */
670
DblLnkLst_Init(&gInfoCache.nicInfo.nicList);
671
DblLnkLst_Link(&gInfoCache.nicInfo.nicList, ((GuestNicInfo *)info)->nicList.next);
672
DblLnkLst_Unlink1(&((GuestNicInfo *)info)->nicList);
562
VMX_XDR_FREE(xdr_GuestNicList, &gInfoCache.nicInfo);
563
gInfoCache.nicInfo = *(GuestNicList *)info;
674
565
Debug("GuestInfo: Nic info not changed.\n");
870
761
*-----------------------------------------------------------------------------
874
GuestInfoFindMacAddress(GuestNicInfo *nicInfo, const char *macAddress)
765
GuestInfoFindMacAddress(GuestNicList *nicInfo, // IN/OUT
766
const char *macAddress) // IN
877
DblLnkLst_Links *sCurrent;
879
if (0 == nicInfo->nicInfoProto.numNicEntries) {
883
DblLnkLst_ForEach(sCurrent, &nicInfo->nicList) {
884
nicEntry = DblLnkLst_Container(sCurrent, NicEntry, links);
885
if (Str_Strcasecmp(macAddress, nicEntry->nicEntryProto.macAddress) == 0) {
770
for (i = 0; i < nicInfo->nics.nics_len; i++) {
771
GuestNic *nic = &nicInfo->nics.nics_val[i];
772
if (strncmp(nic->macAddress, macAddress, NICINFO_MAC_LEN) == 0) {
914
NicInfoChanged(GuestNicInfo *nicInfo) // IN:
801
NicInfoChanged(GuestNicList *nicInfo) // IN
917
GuestNicInfo *cachedNicInfo;
919
DblLnkLst_Links *cachedNicLink;
921
cachedNicInfo = &gInfoCache.nicInfo;
922
cachedNic = DblLnkLst_Container(cachedNicInfo->nicList.next,
926
if (cachedNicInfo->nicInfoProto.numNicEntries !=
927
nicInfo->nicInfoProto.numNicEntries) {
804
GuestNicList *cachedNicInfo = &gInfoCache.nicInfo;
806
if (cachedNicInfo->nics.nics_len != nicInfo->nics.nics_len) {
928
807
Debug("GuestInfo: number of nics has changed\n");
932
/* Have any MAC or IP addresses been modified? */
933
DblLnkLst_ForEach(cachedNicLink, &cachedNicInfo->nicList) {
934
NicEntry *matchedNIC;
935
DblLnkLst_Links *curCachedIpLink;
937
cachedNic = DblLnkLst_Container(cachedNicLink, NicEntry, links);
938
currentMac = cachedNic->nicEntryProto.macAddress;
811
for (i = 0; i < cachedNicInfo->nics.nics_len; i++) {
813
GuestNic *cachedNic = &cachedNicInfo->nics.nics_val[i];
814
GuestNic *matchedNic;
940
816
/* Find the corresponding nic in the new nic info. */
941
matchedNIC = GuestInfoFindMacAddress(nicInfo, currentMac);
817
matchedNic = GuestInfoFindMacAddress(nicInfo, cachedNic->macAddress);
943
if (NULL == matchedNIC) {
819
if (NULL == matchedNic) {
944
820
/* This mac address has been deleted. */
948
if (matchedNIC->nicEntryProto.numIPs != cachedNic->nicEntryProto.numIPs) {
824
if (matchedNic->ips.ips_len != cachedNic->ips.ips_len) {
949
825
Debug("GuestInfo: count of ip addresses for mac %d\n",
950
matchedNIC->nicEntryProto.numIPs);
826
matchedNic->ips.ips_len);
954
830
/* Which IP addresses have been modified for this NIC? */
955
DblLnkLst_ForEach(curCachedIpLink, &cachedNic->ipAddressList) {
956
char *currentCachedIp;
957
VmIpAddressEntry *cachedIpAddress;
958
DblLnkLst_Links * matchedIpAddressLink;
831
for (j = 0; j < cachedNic->ips.ips_len; j++) {
832
VmIpAddress *cachedIp = &cachedNic->ips.ips_val[j];
959
833
Bool foundIP = FALSE;
961
cachedIpAddress = DblLnkLst_Container(curCachedIpLink,
965
if (cachedIpAddress) {
966
currentCachedIp = cachedIpAddress->ipEntryProto.ipAddress;
971
DblLnkLst_ForEach(matchedIpAddressLink, &matchedNIC->ipAddressList) {
972
VmIpAddressEntry *matchedIpAddressEntry =
973
DblLnkLst_Container(matchedIpAddressLink,
977
if (matchedIpAddressEntry) {
978
if (strncmp(matchedIpAddressEntry->ipEntryProto.ipAddress,
980
IP_ADDR_SIZE_V2) == 0) {
836
for (k = 0; k < matchedNic->ips.ips_len; k++) {
837
VmIpAddress *matchedIp = &matchedNic->ips.ips_val[k];
838
if (0 == strncmp(cachedIp->ipAddress,
839
matchedIp->ipAddress,
840
NICINFO_MAX_IP_LEN)) {
990
846
if (FALSE == foundIP) {
991
847
/* This ip address couldn't be found and has been modified. */
992
Debug("GuestInfo: mac address %s, ipaddress %s deleted\n", currentMac,
848
Debug("GuestInfo: mac address %s, ipaddress %s deleted\n",
849
cachedNic->macAddress,
850
cachedIp->ipAddress);
1006
*----------------------------------------------------------------------
1008
* GuestInfoSerializeNicInfo --
1010
* Now that GuestNicInfo is not fixed size, serialize nicInfo into a
1011
* buffer, in order to send it over wire.
1015
* TRUE if successful, FALSE otherwise.
1021
*----------------------------------------------------------------------
1025
GuestInfoSerializeNicInfo(GuestNicInfo *nicInfo, // IN
1026
char buffer[GUESTMSG_MAX_IN_SIZE], // OUT
1027
size_t *bufferLen) // OUT
1032
DblLnkLst_Links *nicEntryLink;
1034
ASSERT_ON_COMPILE(sizeof nicInfo->nicInfoProto.version == 4);
1035
ASSERT_ON_COMPILE(offsetof(NicInfoProtocol, nicEntrySizeOnWire) == 4);
1036
ASSERT_ON_COMPILE(sizeof nicInfo->nicInfoProto.nicEntrySizeOnWire == 4);
1037
ASSERT_ON_COMPILE(offsetof(NicInfoProtocol, numNicEntries) == 8);
1038
ASSERT_ON_COMPILE(sizeof nicInfo->nicInfoProto.numNicEntries == 4);
1039
ASSERT_ON_COMPILE(offsetof(NicInfoProtocol, totalInfoSizeOnWire) == 12);
1040
ASSERT_ON_COMPILE(sizeof nicInfo->nicInfoProto.totalInfoSizeOnWire == 4);
1042
if ((NULL == nicInfo) ||
1043
(NULL == buffer ) ||
1044
(NULL == bufferLen)) {
1048
if (0 == nicInfo->nicInfoProto.numNicEntries) {
1052
nicInfo->nicInfoProto.totalInfoSizeOnWire = 0;
1053
nicInfo->nicInfoProto.nicEntrySizeOnWire = sizeof(NicEntryProtocol);
1056
info = (char *)(&nicInfo->nicInfoProto);
1057
entrySize = sizeof nicInfo->nicInfoProto;
1059
memcpy(buf, info, entrySize);
1060
nicInfo->nicInfoProto.totalInfoSizeOnWire += entrySize;
1064
DblLnkLst_ForEach(nicEntryLink, &nicInfo->nicList) {
1066
DblLnkLst_Links *ipAddrLink;
1067
VmIpAddressEntry *ipAddressCur;
1068
char *nicEntryBuf = buf;
1070
nicEntry = DblLnkLst_Container(nicEntryLink, NicEntry, links);
1071
nicEntry->nicEntryProto.totalNicEntrySizeOnWire = 0;
1072
nicEntry->nicEntryProto.ipAddressSizeOnWire = sizeof(VmIpAddressEntryProtocol);
1074
info = (char *)(&nicEntry->nicEntryProto);
1076
entrySize = sizeof nicEntry->nicEntryProto;
1078
/* to prevent buffer overflow */
1079
if (buf + entrySize - buffer < GUESTMSG_MAX_IN_SIZE) {
1080
memcpy(buf, info, entrySize);
1081
nicEntry->nicEntryProto.totalNicEntrySizeOnWire += entrySize;
1082
nicInfo->nicInfoProto.totalInfoSizeOnWire += entrySize;
1089
entrySize = sizeof ipAddressCur->ipEntryProto;
1091
DblLnkLst_ForEach(ipAddrLink, &nicEntry->ipAddressList) {
1092
ipAddressCur = DblLnkLst_Container(ipAddrLink, VmIpAddressEntry, links);
1093
ipAddressCur->ipEntryProto.totalIpEntrySizeOnWire = 0;
1094
info = (char *)(&ipAddressCur->ipEntryProto);
1097
/* to prevent buffer overflow */
1098
if (buf + entrySize - buffer < GUESTMSG_MAX_IN_SIZE) {
1099
memcpy(buf, info, entrySize);
1100
ipAddressCur->ipEntryProto.totalIpEntrySizeOnWire +=
1102
nicEntry->nicEntryProto.totalNicEntrySizeOnWire +=
1104
nicInfo->nicInfoProto.totalInfoSizeOnWire +=
1112
* Update total size portion that was just calculated.
1114
memcpy(buf + offsetof(VmIpAddressEntryProtocol,
1115
totalIpEntrySizeOnWire),
1116
&ipAddressCur->ipEntryProto.totalIpEntrySizeOnWire,
1117
sizeof ipAddressCur->ipEntryProto.totalIpEntrySizeOnWire);
1121
* Update total size portion that was just calculated.
1123
memcpy(nicEntryBuf + offsetof(NicEntryProtocol ,
1124
totalNicEntrySizeOnWire),
1125
&nicEntry->nicEntryProto.totalNicEntrySizeOnWire,
1126
sizeof nicEntry->nicEntryProto.totalNicEntrySizeOnWire);
1129
*bufferLen = buf + entrySize - buffer;
1132
* Update total size portion that was just calculated.
1134
memcpy(buffer + offsetof(NicInfoProtocol, totalInfoSizeOnWire),
1135
&nicInfo->nicInfoProto.totalInfoSizeOnWire,
1136
sizeof nicInfo->nicInfoProto.totalInfoSizeOnWire);
1143
863
*----------------------------------------------------------------------------
1145
865
* PrintNicInfo --
1160
PrintNicInfo(GuestNicInfo *nicInfo, // IN
1161
int (*PrintFunc)(const char *, ...)) // IN
880
PrintNicInfo(GuestNicList *nicInfo, // IN
881
int (*PrintFunc)(const char *, ...)) // IN
1165
DblLnkLst_Links *nicEntryLink;
1168
ret += PrintFunc("GuestNicInfo: count: %d\n", nicInfo->nicInfoProto.numNicEntries);
1169
DblLnkLst_ForEach(nicEntryLink, &nicInfo->nicList) {
1171
DblLnkLst_Links *ipAddrLink;
1172
NicEntry *nicEntry = DblLnkLst_Container(nicEntryLink,
1176
ret += PrintFunc("GuestNicInfo: nic [%d/%d] mac: %s",
886
ret += PrintFunc("NicInfo: count: %ud\n", nicInfo->nics.nics_len);
887
for (i = 0; i < nicInfo->nics.nics_len; i++) {
889
GuestNic *nic = &nicInfo->nics.nics_val[i];
891
ret += PrintFunc("NicInfo: nic [%d/%d] mac: %s",
893
nicInfo->nics.nics_len,
896
for (j = 0; j < nic->ips.ips_len; j++) {
897
VmIpAddress *ipAddress = &nic->ips.ips_val[j];
899
ret += PrintFunc("NicInfo: nic [%d/%d] IP [%d/%d]: %s",
1178
nicInfo->nicInfoProto.numNicEntries,
1179
nicEntry->nicEntryProto.macAddress);
1184
DblLnkLst_ForEach(ipAddrLink, &nicEntry->ipAddressList) {
1185
VmIpAddressEntry *ipAddress = DblLnkLst_Container(
1191
ret += PrintFunc("GuestNicInfo: nic [%d/%d] IP [%d/%d]: %s",
1193
nicInfo->nicInfoProto.numNicEntries,
1195
nicEntry->nicEntryProto.numIPs,
1196
ipAddress->ipEntryProto.ipAddress);
901
nicInfo->nics.nics_len,
904
ipAddress->ipAddress);
1485
1181
* initialized with the input parameter
1488
* newly allocated NicEntry
1184
* Newly allocated GuestNic, NULL on failure.
1490
1186
* Side effects:
1491
* All linked list in the new entry is initialized. Number of Nic
1492
* entries is bumped up by 1.
1187
* Number of Nic entries is bumped up by 1.
1493
1188
*----------------------------------------------------------------------
1497
GuestInfoAddNicEntry(GuestNicInfo *nicInfo, // IN/OUT
1498
const char macAddress[MAC_ADDR_SIZE]) // IN
1192
GuestInfoAddNicEntry(GuestNicList *nicInfo, // IN/OUT
1193
const char macAddress[NICINFO_MAC_LEN]) // IN
1500
NicEntry *nicEntryCur = NULL;
1502
nicEntryCur = Util_SafeCalloc(1, sizeof(*nicEntryCur));
1503
DblLnkLst_Init(&nicEntryCur->ipAddressList);
1504
DblLnkLst_Init(&nicEntryCur->links);
1505
DblLnkLst_LinkLast(&nicInfo->nicList, &nicEntryCur->links);
1507
Str_Strcpy(nicEntryCur->nicEntryProto.macAddress, macAddress, MAC_ADDR_SIZE);
1508
nicInfo->nicInfoProto.numNicEntries++;
1197
newNic = XDRUTIL_ARRAYAPPEND(nicInfo, nics, 1);
1198
if (newNic != NULL) {
1199
Str_Strcpy(newNic->macAddress, macAddress, sizeof newNic->macAddress);
1517
1209
* GuestInfoAddIpAddress --
1519
* Add an IP address entry into NicEntry
1211
* Add an IP address entry into the GuestNic.
1522
* Newly allocated IP address Entry
1214
* Newly allocated IP address struct.
1524
1216
* Side effects:
1525
* Linked list in the new IP address entry is initialized.Number
1526
* of IP addresses on the NIC is bumped up by 1
1217
* Number of IP addresses on the NIC is bumped up by 1.
1528
1219
*----------------------------------------------------------------------
1532
GuestInfoAddIpAddress(NicEntry *nicEntry, // IN/OUT
1223
GuestInfoAddIpAddress(GuestNic *nic, // IN/OUT
1533
1224
const char *ipAddr, // IN
1534
1225
const uint32 af_type) // IN
1536
VmIpAddressEntry *ipAddressCur;
1538
ipAddressCur = Util_SafeCalloc(1, sizeof *ipAddressCur);
1539
DblLnkLst_Init(&ipAddressCur->links);
1540
DblLnkLst_LinkLast(&nicEntry->ipAddressList, &ipAddressCur->links);
1541
memcpy(ipAddressCur->ipEntryProto.ipAddress, ipAddr, IP_ADDR_SIZE_V2);
1542
ipAddressCur->ipEntryProto.addressFamily = af_type;
1544
nicEntry->nicEntryProto.numIPs++;
1546
return ipAddressCur;
1229
ip = XDRUTIL_ARRAYAPPEND(nic, ips, 1);
1231
Str_Strcpy(ip->ipAddress, ipAddr, sizeof ip->ipAddress);
1232
ip->addressFamily = af_type;