VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp@ 79862

Last change on this file since 79862 was 77804, checked in by vboxsync, 6 years ago

NetAdp/Win: (bugref:9409) Store host-only adapter configuration in extra data. Create missing adapters when listing/creating/removing adapters.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.6 KB
Line 
1/* $Id: HostNetworkInterfaceImpl.cpp 77804 2019-03-20 08:05:37Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#define LOG_GROUP LOG_GROUP_MAIN_HOSTNETWORKINTERFACE
19#include "HostNetworkInterfaceImpl.h"
20#include "AutoCaller.h"
21#include "netif.h"
22#ifdef VBOX_WITH_RESOURCE_USAGE_API
23# include "Performance.h"
24# include "PerformanceImpl.h"
25#endif
26#include "LoggingNew.h"
27
28#include <iprt/cpp/utils.h>
29
30#ifdef RT_OS_FREEBSD
31# include <netinet/in.h> /* INADDR_NONE */
32#endif /* RT_OS_FREEBSD */
33
34#include "VirtualBoxImpl.h"
35
36// constructor / destructor
37/////////////////////////////////////////////////////////////////////////////
38
39HostNetworkInterface::HostNetworkInterface()
40 : mVirtualBox(NULL)
41{
42}
43
44HostNetworkInterface::~HostNetworkInterface()
45{
46}
47
48HRESULT HostNetworkInterface::FinalConstruct()
49{
50 return BaseFinalConstruct();
51}
52
53void HostNetworkInterface::FinalRelease()
54{
55 uninit();
56 BaseFinalRelease();
57}
58
59// public initializer/uninitializer for internal purposes only
60/////////////////////////////////////////////////////////////////////////////
61
62/**
63 * Initializes the host object.
64 *
65 * @returns COM result indicator
66 * @param aInterfaceName name of the network interface
67 * @param aShortName short name of the network interface
68 * @param aGuid GUID of the host network interface
69 * @param ifType interface type
70 */
71HRESULT HostNetworkInterface::init(Utf8Str aInterfaceName, Utf8Str aShortName, Guid aGuid, HostNetworkInterfaceType_T ifType)
72{
73 LogFlowThisFunc(("aInterfaceName={%s}, aGuid={%s}\n",
74 aInterfaceName.c_str(), aGuid.toString().c_str()));
75
76 ComAssertRet(!aInterfaceName.isEmpty(), E_INVALIDARG);
77 ComAssertRet(aGuid.isValid(), E_INVALIDARG);
78
79 /* Enclose the state transition NotReady->InInit->Ready */
80 AutoInitSpan autoInitSpan(this);
81 AssertReturn(autoInitSpan.isOk(), E_FAIL);
82
83 unconst(mInterfaceName) = aInterfaceName;
84 unconst(mNetworkName) = i_composeNetworkName(aShortName);
85 unconst(mShortName) = aShortName;
86 unconst(mGuid) = aGuid;
87 mIfType = ifType;
88
89 /* Confirm a successful initialization */
90 autoInitSpan.setSucceeded();
91
92 return S_OK;
93}
94
95#ifdef VBOX_WITH_RESOURCE_USAGE_API
96
97void HostNetworkInterface::i_registerMetrics(PerformanceCollector *aCollector, ComPtr<IUnknown> objptr)
98{
99 LogFlowThisFunc(("mShortName={%s}, mInterfaceName={%s}, mGuid={%s}, mSpeedMbits=%u\n",
100 mShortName.c_str(), mInterfaceName.c_str(), mGuid.toString().c_str(), m.speedMbits));
101 pm::CollectorHAL *hal = aCollector->getHAL();
102 /* Create sub metrics */
103 Utf8StrFmt strName("Net/%s", mShortName.c_str());
104 pm::SubMetric *networkLoadRx = new pm::SubMetric(strName + "/Load/Rx",
105 "Percentage of network interface receive bandwidth used.");
106 pm::SubMetric *networkLoadTx = new pm::SubMetric(strName + "/Load/Tx",
107 "Percentage of network interface transmit bandwidth used.");
108 pm::SubMetric *networkLinkSpeed = new pm::SubMetric(strName + "/LinkSpeed",
109 "Physical link speed.");
110
111 /* Create and register base metrics */
112 pm::BaseMetric *networkSpeed = new pm::HostNetworkSpeed(hal, objptr, strName + "/LinkSpeed",
113 Utf8Str(mShortName), Utf8Str(mInterfaceName),
114 m.speedMbits, networkLinkSpeed);
115 aCollector->registerBaseMetric(networkSpeed);
116 pm::BaseMetric *networkLoad = new pm::HostNetworkLoadRaw(hal, objptr, strName + "/Load",
117 Utf8Str(mShortName), Utf8Str(mInterfaceName),
118 m.speedMbits, networkLoadRx, networkLoadTx);
119 aCollector->registerBaseMetric(networkLoad);
120
121 aCollector->registerMetric(new pm::Metric(networkSpeed, networkLinkSpeed, 0));
122 aCollector->registerMetric(new pm::Metric(networkSpeed, networkLinkSpeed,
123 new pm::AggregateAvg()));
124 aCollector->registerMetric(new pm::Metric(networkSpeed, networkLinkSpeed,
125 new pm::AggregateMin()));
126 aCollector->registerMetric(new pm::Metric(networkSpeed, networkLinkSpeed,
127 new pm::AggregateMax()));
128
129 aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadRx, 0));
130 aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadRx,
131 new pm::AggregateAvg()));
132 aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadRx,
133 new pm::AggregateMin()));
134 aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadRx,
135 new pm::AggregateMax()));
136
137 aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadTx, 0));
138 aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadTx,
139 new pm::AggregateAvg()));
140 aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadTx,
141 new pm::AggregateMin()));
142 aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadTx,
143 new pm::AggregateMax()));
144}
145
146void HostNetworkInterface::i_unregisterMetrics(PerformanceCollector *aCollector, ComPtr<IUnknown> objptr)
147{
148 LogFlowThisFunc(("mShortName={%s}, mInterfaceName={%s}, mGuid={%s}\n",
149 mShortName.c_str(), mInterfaceName.c_str(), mGuid.toString().c_str()));
150 Utf8StrFmt name("Net/%s", mShortName.c_str());
151 aCollector->unregisterMetricsFor(objptr, name + "/*");
152 aCollector->unregisterBaseMetricsFor(objptr, name);
153}
154
155#endif /* VBOX_WITH_RESOURCE_USAGE_API */
156
157#ifdef VBOX_WITH_HOSTNETIF_API
158
159#if defined(RT_OS_WINDOWS)
160HRESULT HostNetworkInterface::saveAdapterConfigParameter(const char *szParamName, const Utf8Str &strValue)
161{
162 AssertReturn(mVirtualBox != NULL, E_POINTER);
163 return mVirtualBox->SetExtraData(Bstr(Utf8StrFmt("HostOnly/{%RTuuid}/%s", mGuid, szParamName)).raw(), Bstr(strValue).raw());
164}
165
166HRESULT HostNetworkInterface::eraseAdapterConfigParameter(const char *szParamName)
167{
168 AssertReturn(mVirtualBox != NULL, E_POINTER);
169 return mVirtualBox->SetExtraData(Bstr(Utf8StrFmt("HostOnly/{%RTuuid}/%s", mGuid, szParamName)).raw(), NULL);
170}
171
172HRESULT HostNetworkInterface::saveAdapterConfigIPv4Dhcp()
173{
174 HRESULT hrc = saveAdapterConfigParameter("IPAddress", "DHCP");
175 if (hrc == S_OK)
176 hrc = eraseAdapterConfigParameter("IPNetMask");
177 return hrc;
178}
179
180HRESULT HostNetworkInterface::saveAdapterConfigIPv4(ULONG addr, ULONG mask)
181{
182 HRESULT hrc = saveAdapterConfigParameter("IPAddress", Utf8StrFmt("%RTnaipv4", addr));
183 if (hrc == S_OK)
184 hrc = saveAdapterConfigParameter("IPNetMask", Utf8StrFmt("%RTnaipv4", mask));
185 return hrc;
186}
187
188HRESULT HostNetworkInterface::saveAdapterConfigIPv6(const Utf8Str& addr, ULONG prefix)
189{
190 HRESULT hrc = saveAdapterConfigParameter("IPV6Address", addr);
191 if (hrc == S_OK)
192 hrc = saveAdapterConfigParameter("IPV6PrefixLen", Utf8StrFmt("%u", prefix));
193 return hrc;
194}
195
196bool HostNetworkInterface::isInConfigFile(void)
197{
198 /* We care about host-only adapters only */
199 if (mIfType != HostNetworkInterfaceType_HostOnly)
200 return true;
201
202 Assert(mVirtualBox != NULL);
203 if (mVirtualBox == NULL)
204 return false; /* Trigger config update, which will fail with proper return code */
205 Bstr tmpName;
206 mVirtualBox->GetExtraData(Bstr(Utf8StrFmt("HostOnly/{%RTuuid}/Name", mGuid)).raw(), tmpName.asOutParam());
207 return (tmpName.isNotEmpty() && tmpName == mInterfaceName);
208
209}
210
211HRESULT HostNetworkInterface::saveAdapterConfig(void)
212{
213 /* We care about host-only adapters only */
214 if (mIfType != HostNetworkInterfaceType_HostOnly)
215 return true;
216
217 HRESULT hrc = saveAdapterConfigParameter("Name", mInterfaceName.c_str());
218 if (FAILED(hrc))
219 return hrc;
220 if (m.dhcpEnabled)
221 hrc = saveAdapterConfigIPv4Dhcp();
222 else
223 hrc = saveAdapterConfigIPv4(m.IPAddress, m.networkMask);
224 if (SUCCEEDED(hrc))
225 hrc = saveAdapterConfigIPv6(m.IPV6Address.c_str(), m.IPV6NetworkMaskPrefixLength);
226 return hrc;
227}
228
229HRESULT HostNetworkInterface::i_updatePersistentConfig(void)
230{
231 if (mVirtualBox == NULL)
232 return E_POINTER;
233
234 HRESULT hrc = S_OK;
235 if (!isInConfigFile())
236 {
237 hrc = saveAdapterConfig();
238 }
239 return hrc;
240}
241#endif /* defined(RT_OS_WINDOWS) */
242
243HRESULT HostNetworkInterface::updateConfig()
244{
245 NETIFINFO info;
246 int rc = NetIfGetConfig(this, &info);
247 if (RT_SUCCESS(rc))
248 {
249 int iPrefixIPv6;
250
251 m.realIPAddress = m.IPAddress = info.IPAddress.u;
252 m.realNetworkMask = m.networkMask = info.IPNetMask.u;
253 m.dhcpEnabled = info.fDhcpEnabled;
254 if (info.IPv6Address.s.Lo || info.IPv6Address.s.Hi)
255 m.realIPV6Address = m.IPV6Address = Utf8StrFmt("%RTnaipv6", &info.IPv6Address);
256 else
257 m.realIPV6Address = m.IPV6Address = Utf8Str::Empty;
258 RTNetMaskToPrefixIPv6(&info.IPv6NetMask, &iPrefixIPv6);
259 m.realIPV6PrefixLength = m.IPV6NetworkMaskPrefixLength = iPrefixIPv6;
260 m.hardwareAddress = Utf8StrFmt("%RTmac", &info.MACAddress);
261 AssertCompile((unsigned)NETIF_T_UNKNOWN == (unsigned)HostNetworkInterfaceMediumType_Unknown);
262 m.mediumType = (HostNetworkInterfaceMediumType_T)info.enmMediumType;
263 AssertCompile((unsigned)NETIF_S_UNKNOWN == (unsigned)HostNetworkInterfaceStatus_Unknown);
264 m.status = (HostNetworkInterfaceStatus_T)info.enmStatus;
265 m.speedMbits = info.uSpeedMbits;
266 m.wireless = info.fWireless;
267 return S_OK;
268 }
269 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
270}
271
272Utf8Str HostNetworkInterface::i_composeNetworkName(const Utf8Str aShortName)
273{
274 return Utf8Str("HostInterfaceNetworking-").append(aShortName);
275}
276/**
277 * Initializes the host object.
278 *
279 * @returns COM result indicator
280 * @param aInterfaceName name of the network interface
281 * @param aGuid GUID of the host network interface
282 */
283HRESULT HostNetworkInterface::init(Utf8Str aInterfaceName, HostNetworkInterfaceType_T ifType, PNETIFINFO pIf)
284{
285// LogFlowThisFunc(("aInterfaceName={%s}, aGuid={%s}\n",
286// aInterfaceName.c_str(), aGuid.toString().c_str()));
287
288// ComAssertRet(aInterfaceName, E_INVALIDARG);
289// ComAssertRet(aGuid.isValid(), E_INVALIDARG);
290 ComAssertRet(pIf, E_INVALIDARG);
291
292 /* Enclose the state transition NotReady->InInit->Ready */
293 AutoInitSpan autoInitSpan(this);
294 AssertReturn(autoInitSpan.isOk(), E_FAIL);
295
296 unconst(mInterfaceName) = aInterfaceName;
297 unconst(mGuid) = pIf->Uuid;
298 if (pIf->szShortName[0])
299 {
300 unconst(mNetworkName) = i_composeNetworkName(pIf->szShortName);
301 unconst(mShortName) = pIf->szShortName;
302 }
303 else
304 {
305 unconst(mNetworkName) = i_composeNetworkName(aInterfaceName);
306 unconst(mShortName) = aInterfaceName;
307 }
308 mIfType = ifType;
309
310 int iPrefixIPv6;
311
312 m.realIPAddress = m.IPAddress = pIf->IPAddress.u;
313 m.realNetworkMask = m.networkMask = pIf->IPNetMask.u;
314 if (pIf->IPv6Address.s.Lo || pIf->IPv6Address.s.Hi)
315 m.realIPV6Address = m.IPV6Address = Utf8StrFmt("%RTnaipv6", &pIf->IPv6Address);
316 else
317 m.realIPV6Address = m.IPV6Address = Utf8Str::Empty;
318 RTNetMaskToPrefixIPv6(&pIf->IPv6NetMask, &iPrefixIPv6);
319 m.realIPV6PrefixLength = m.IPV6NetworkMaskPrefixLength = iPrefixIPv6;
320 m.dhcpEnabled = pIf->fDhcpEnabled;
321 m.hardwareAddress = Utf8StrFmt("%RTmac", &pIf->MACAddress);
322 AssertCompile((unsigned)NETIF_T_UNKNOWN == (unsigned)HostNetworkInterfaceMediumType_Unknown);
323 m.mediumType = (HostNetworkInterfaceMediumType_T)pIf->enmMediumType;
324 AssertCompile((unsigned)NETIF_S_UNKNOWN == (unsigned)HostNetworkInterfaceStatus_Unknown);
325 m.status = (HostNetworkInterfaceStatus_T)pIf->enmStatus;
326 m.speedMbits = pIf->uSpeedMbits;
327 m.wireless = pIf->fWireless;
328
329 /* Confirm a successful initialization */
330 autoInitSpan.setSucceeded();
331
332 return S_OK;
333}
334#endif
335
336// wrapped IHostNetworkInterface properties
337/////////////////////////////////////////////////////////////////////////////
338/**
339 * Returns the name of the host network interface.
340 *
341 * @returns COM status code
342 * @param aInterfaceName - Interface Name
343 */
344
345HRESULT HostNetworkInterface::getName(com::Utf8Str &aInterfaceName)
346{
347 aInterfaceName = mInterfaceName;
348 return S_OK;
349}
350
351/**
352 * Returns the short name of the host network interface.
353 *
354 * @returns COM status code
355 * @param aShortName Short Name
356 */
357
358HRESULT HostNetworkInterface::getShortName(com::Utf8Str &aShortName)
359{
360 aShortName = mShortName;
361
362 return S_OK;
363}
364
365/**
366 * Returns the GUID of the host network interface.
367 *
368 * @returns COM status code
369 * @param aGuid GUID
370 */
371HRESULT HostNetworkInterface::getId(com::Guid &aGuid)
372{
373 aGuid = mGuid;
374
375 return S_OK;
376}
377
378HRESULT HostNetworkInterface::getDHCPEnabled(BOOL *aDHCPEnabled)
379{
380 *aDHCPEnabled = m.dhcpEnabled;
381
382 return S_OK;
383}
384
385
386/**
387 * Returns the IP address of the host network interface.
388 *
389 * @returns COM status code
390 * @param aIPAddress Address name
391 */
392HRESULT HostNetworkInterface::getIPAddress(com::Utf8Str &aIPAddress)
393{
394 in_addr tmp;
395#if defined(RT_OS_WINDOWS)
396 tmp.S_un.S_addr = m.IPAddress;
397#else
398 tmp.s_addr = m.IPAddress;
399#endif
400 char *addr = inet_ntoa(tmp);
401 if (addr)
402 {
403 aIPAddress = addr;
404 return S_OK;
405 }
406
407 return E_FAIL;
408}
409
410/**
411 * Returns the netwok mask of the host network interface.
412 *
413 * @returns COM status code
414 * @param aNetworkMask name.
415 */
416HRESULT HostNetworkInterface::getNetworkMask(com::Utf8Str &aNetworkMask)
417{
418
419 in_addr tmp;
420#if defined(RT_OS_WINDOWS)
421 tmp.S_un.S_addr = m.networkMask;
422#else
423 tmp.s_addr = m.networkMask;
424#endif
425 char *addr = inet_ntoa(tmp);
426 if (addr)
427 {
428 aNetworkMask = Utf8Str(addr);
429 return S_OK;
430 }
431
432 return E_FAIL;
433}
434
435HRESULT HostNetworkInterface::getIPV6Supported(BOOL *aIPV6Supported)
436{
437#if defined(RT_OS_WINDOWS)
438 *aIPV6Supported = FALSE;
439#else
440 *aIPV6Supported = TRUE;
441#endif
442
443 return S_OK;
444}
445
446/**
447 * Returns the IP V6 address of the host network interface.
448 *
449 * @returns COM status code
450 * @param aIPV6Address
451 */
452HRESULT HostNetworkInterface::getIPV6Address(com::Utf8Str &aIPV6Address)
453{
454 aIPV6Address = m.IPV6Address;
455 return S_OK;
456}
457
458/**
459 * Returns the IP V6 network mask prefix length of the host network interface.
460 *
461 * @returns COM status code
462 * @param aIPV6NetworkMaskPrefixLength address of result pointer
463 */
464HRESULT HostNetworkInterface::getIPV6NetworkMaskPrefixLength(ULONG *aIPV6NetworkMaskPrefixLength)
465{
466 *aIPV6NetworkMaskPrefixLength = m.IPV6NetworkMaskPrefixLength;
467
468 return S_OK;
469}
470
471/**
472 * Returns the hardware address of the host network interface.
473 *
474 * @returns COM status code
475 * @param aHardwareAddress hardware address
476 */
477HRESULT HostNetworkInterface::getHardwareAddress(com::Utf8Str &aHardwareAddress)
478{
479 aHardwareAddress = m.hardwareAddress;
480 return S_OK;
481}
482
483/**
484 * Returns the encapsulation protocol type of the host network interface.
485 *
486 * @returns COM status code
487 * @param aType address of result pointer
488 */
489HRESULT HostNetworkInterface::getMediumType(HostNetworkInterfaceMediumType_T *aType)
490{
491 *aType = m.mediumType;
492
493 return S_OK;
494}
495
496/**
497 * Returns the current state of the host network interface.
498 *
499 * @returns COM status code
500 * @param aStatus address of result pointer
501 */
502HRESULT HostNetworkInterface::getStatus(HostNetworkInterfaceStatus_T *aStatus)
503{
504 *aStatus = m.status;
505
506 return S_OK;
507}
508
509/**
510 * Returns network interface type
511 *
512 * @returns COM status code
513 * @param aType address of result pointer
514 */
515HRESULT HostNetworkInterface::getInterfaceType(HostNetworkInterfaceType_T *aType)
516{
517 *aType = mIfType;
518
519 return S_OK;
520
521}
522
523HRESULT HostNetworkInterface::getNetworkName(com::Utf8Str &aNetworkName)
524{
525 aNetworkName = mNetworkName;
526
527 return S_OK;
528}
529
530HRESULT HostNetworkInterface::getWireless(BOOL *aWireless)
531{
532 *aWireless = m.wireless;
533
534 return S_OK;
535}
536
537HRESULT HostNetworkInterface::enableStaticIPConfig(const com::Utf8Str &aIPAddress,
538 const com::Utf8Str &aNetworkMask)
539{
540#ifndef VBOX_WITH_HOSTNETIF_API
541 return E_NOTIMPL;
542#else
543 if (aIPAddress.isEmpty())
544 {
545 if (m.IPAddress)
546 {
547 int rc = NetIfEnableStaticIpConfig(mVirtualBox, this, m.IPAddress, 0, 0);
548 if (RT_SUCCESS(rc))
549 {
550 m.realIPAddress = 0;
551#if defined(RT_OS_WINDOWS)
552 eraseAdapterConfigParameter("IPAddress");
553 eraseAdapterConfigParameter("IPNetMask");
554#else /* !defined(RT_OS_WINDOWS) */
555 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPAddress",
556 mInterfaceName.c_str()).raw(), NULL)))
557 return E_FAIL;
558 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
559 mInterfaceName.c_str()).raw(), NULL)))
560 return E_FAIL;
561#endif /* !defined(RT_OS_WINDOWS) */
562 return S_OK;
563 }
564 }
565 else
566 return S_OK;
567 }
568
569 ULONG ip, mask;
570 ip = inet_addr(aIPAddress.c_str());
571 if (ip != INADDR_NONE)
572 {
573 if (aNetworkMask.isEmpty())
574 mask = 0xFFFFFF;
575 else
576 mask = inet_addr(aNetworkMask.c_str());
577 if (mask != INADDR_NONE)
578 {
579 if (m.realIPAddress == ip && m.realNetworkMask == mask)
580 return S_OK;
581 int rc = NetIfEnableStaticIpConfig(mVirtualBox, this, m.IPAddress, ip, mask);
582 if (RT_SUCCESS(rc))
583 {
584 m.realIPAddress = ip;
585 m.realNetworkMask = mask;
586#if defined(RT_OS_WINDOWS)
587 saveAdapterConfigIPv4(ip, mask);
588#else /* !defined(RT_OS_WINDOWS) */
589 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPAddress",
590 mInterfaceName.c_str()).raw(),
591 Bstr(aIPAddress).raw())))
592 return E_FAIL;
593 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
594 mInterfaceName.c_str()).raw(),
595 Bstr(aNetworkMask).raw())))
596 return E_FAIL;
597#endif /* !defined(RT_OS_WINDOWS) */
598 return S_OK;
599 }
600 else
601 {
602 LogRel(("Failed to EnableStaticIpConfig with rc=%Rrc\n", rc));
603 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
604 }
605
606 }
607 }
608 return E_FAIL;
609#endif
610}
611
612HRESULT HostNetworkInterface::enableStaticIPConfigV6(const com::Utf8Str &aIPV6Address,
613 ULONG aIPV6NetworkMaskPrefixLength)
614{
615#ifndef VBOX_WITH_HOSTNETIF_API
616 return E_NOTIMPL;
617#else
618 if (aIPV6NetworkMaskPrefixLength > 128)
619 return mVirtualBox->setErrorBoth(E_INVALIDARG, VERR_INVALID_PARAMETER,
620 "Invalid IPv6 prefix length");
621
622 int rc;
623
624 RTNETADDRIPV6 AddrOld, AddrNew;
625 char *pszZoneIgnored;
626 bool fAddrChanged;
627
628 rc = RTNetStrToIPv6Addr(aIPV6Address.c_str(), &AddrNew, &pszZoneIgnored);
629 if (RT_FAILURE(rc))
630 {
631 return mVirtualBox->setErrorBoth(E_INVALIDARG, rc, "Invalid IPv6 address");
632 }
633
634 rc = RTNetStrToIPv6Addr(com::Utf8Str(m.realIPV6Address).c_str(), &AddrOld, &pszZoneIgnored);
635 if (RT_SUCCESS(rc))
636 {
637 fAddrChanged = (AddrNew.s.Lo != AddrOld.s.Lo || AddrNew.s.Hi != AddrOld.s.Hi);
638 }
639 else
640 {
641 fAddrChanged = true;
642 }
643
644 if ( fAddrChanged
645 || m.realIPV6PrefixLength != aIPV6NetworkMaskPrefixLength)
646 {
647 if (aIPV6NetworkMaskPrefixLength == 0)
648 aIPV6NetworkMaskPrefixLength = 64;
649 rc = NetIfEnableStaticIpConfigV6(mVirtualBox, this, m.IPV6Address.c_str(),
650 aIPV6Address.c_str(),
651 aIPV6NetworkMaskPrefixLength);
652 if (RT_FAILURE(rc))
653 {
654 LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc));
655 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
656 }
657 else
658 {
659 m.realIPV6Address = aIPV6Address;
660 m.realIPV6PrefixLength = aIPV6NetworkMaskPrefixLength;
661#if defined(RT_OS_WINDOWS)
662 saveAdapterConfigIPv6(Bstr(aIPV6Address).raw(), aIPV6NetworkMaskPrefixLength);
663#else /* !defined(RT_OS_WINDOWS) */
664 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6Address",
665 mInterfaceName.c_str()).raw(),
666 Bstr(aIPV6Address).raw())))
667 return E_FAIL;
668 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask",
669 mInterfaceName.c_str()).raw(),
670 BstrFmt("%u", aIPV6NetworkMaskPrefixLength).raw())))
671#endif /* !defined(RT_OS_WINDOWS) */
672 return E_FAIL;
673 }
674
675 }
676 return S_OK;
677#endif
678}
679
680HRESULT HostNetworkInterface::enableDynamicIPConfig()
681{
682#ifndef VBOX_WITH_HOSTNETIF_API
683 return E_NOTIMPL;
684#else
685 int rc = NetIfEnableDynamicIpConfig(mVirtualBox, this);
686 if (RT_FAILURE(rc))
687 {
688 LogRel(("Failed to EnableDynamicIpConfig with rc=%Rrc\n", rc));
689 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
690 }
691 return S_OK;
692#endif
693}
694
695HRESULT HostNetworkInterface::dHCPRediscover()
696{
697#ifndef VBOX_WITH_HOSTNETIF_API
698 return E_NOTIMPL;
699#else
700 int rc = NetIfDhcpRediscover(mVirtualBox, this);
701 if (RT_FAILURE(rc))
702 {
703 LogRel(("Failed to DhcpRediscover with rc=%Rrc\n", rc));
704 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
705 }
706 return S_OK;
707#endif
708}
709
710HRESULT HostNetworkInterface::i_setVirtualBox(VirtualBox *pVirtualBox)
711{
712 AutoCaller autoCaller(this);
713 if (FAILED(autoCaller.rc())) return autoCaller.rc();
714
715 AssertReturn(mVirtualBox != pVirtualBox, S_OK);
716
717 unconst(mVirtualBox) = pVirtualBox;
718
719#if !defined(RT_OS_WINDOWS)
720 /* If IPv4 address hasn't been initialized */
721 if (m.IPAddress == 0 && mIfType == HostNetworkInterfaceType_HostOnly)
722 {
723 Bstr tmpAddr, tmpMask;
724 HRESULT hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPAddress",
725 mInterfaceName.c_str()).raw(),
726 tmpAddr.asOutParam());
727 if (FAILED(hrc) || tmpAddr.isEmpty())
728 tmpAddr = getDefaultIPv4Address(mInterfaceName);
729
730 hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
731 mInterfaceName.c_str()).raw(),
732 tmpMask.asOutParam());
733 if (FAILED(hrc) || tmpMask.isEmpty())
734 tmpMask = Bstr(VBOXNET_IPV4MASK_DEFAULT);
735
736 m.IPAddress = inet_addr(Utf8Str(tmpAddr).c_str());
737 m.networkMask = inet_addr(Utf8Str(tmpMask).c_str());
738 }
739
740 if (m.IPV6Address.isEmpty())
741 {
742 Bstr bstrIPV4Addr;
743 Bstr tmpPrefixLen;
744 HRESULT hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6Address",
745 mInterfaceName.c_str()).raw(),
746 bstrIPV4Addr.asOutParam());
747 if (SUCCEEDED(hrc))
748 {
749 m.IPV6Address = bstrIPV4Addr;
750 if (!m.IPV6Address.isEmpty())
751 {
752 hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6PrefixLen",
753 mInterfaceName.c_str()).raw(),
754 tmpPrefixLen.asOutParam());
755 if (SUCCEEDED(hrc) && !tmpPrefixLen.isEmpty())
756 m.IPV6NetworkMaskPrefixLength = Utf8Str(tmpPrefixLen).toUInt32();
757 else
758 m.IPV6NetworkMaskPrefixLength = 64;
759 }
760 }
761 }
762#endif
763
764 return S_OK;
765}
766
767/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette