VirtualBox

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

Last change on this file since 92154 was 91769, checked in by vboxsync, 3 years ago

VBoxNetAdp: (bugref:10077) More administrative control over network ranges

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 KB
Line 
1/* $Id: HostNetworkInterfaceImpl.cpp 91769 2021-10-15 19:24:43Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2020 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#if defined(RT_OS_WINDOWS)
159
160HRESULT HostNetworkInterface::saveAdapterConfigParameter(const char *szParamName, const Utf8Str &strValue)
161{
162 AssertReturn(mVirtualBox != NULL, E_POINTER);
163 return mVirtualBox->SetExtraData(BstrFmt("HostOnly/{%RTuuid}/%s", mGuid.raw(), szParamName).raw(), Bstr(strValue).raw());
164}
165
166HRESULT HostNetworkInterface::eraseAdapterConfigParameter(const char *szParamName)
167{
168 AssertReturn(mVirtualBox != NULL, E_POINTER);
169 return mVirtualBox->SetExtraData(BstrFmt("HostOnly/{%RTuuid}/%s", mGuid.raw(), 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(BstrFmt("HostOnly/{%RTuuid}/Name", mGuid.raw()).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
242#endif /* defined(RT_OS_WINDOWS) */
243
244HRESULT HostNetworkInterface::updateConfig()
245{
246 NETIFINFO info;
247 int rc = NetIfGetConfig(this, &info);
248 if (RT_SUCCESS(rc))
249 {
250 int iPrefixIPv6;
251
252 m.realIPAddress = m.IPAddress = info.IPAddress.u;
253 m.realNetworkMask = m.networkMask = info.IPNetMask.u;
254 m.dhcpEnabled = info.fDhcpEnabled;
255 if (info.IPv6Address.s.Lo || info.IPv6Address.s.Hi)
256 m.realIPV6Address = m.IPV6Address = Utf8StrFmt("%RTnaipv6", &info.IPv6Address);
257 else
258 m.realIPV6Address = m.IPV6Address = Utf8Str::Empty;
259 RTNetMaskToPrefixIPv6(&info.IPv6NetMask, &iPrefixIPv6);
260 m.realIPV6PrefixLength = m.IPV6NetworkMaskPrefixLength = (ULONG)iPrefixIPv6;
261 m.hardwareAddress = Utf8StrFmt("%RTmac", &info.MACAddress);
262 AssertCompile((unsigned)NETIF_T_UNKNOWN == (unsigned)HostNetworkInterfaceMediumType_Unknown);
263 m.mediumType = (HostNetworkInterfaceMediumType_T)info.enmMediumType;
264 AssertCompile((unsigned)NETIF_S_UNKNOWN == (unsigned)HostNetworkInterfaceStatus_Unknown);
265 m.status = (HostNetworkInterfaceStatus_T)info.enmStatus;
266 m.speedMbits = info.uSpeedMbits;
267 m.wireless = info.fWireless;
268 return S_OK;
269 }
270 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
271}
272
273Utf8Str HostNetworkInterface::i_composeNetworkName(const Utf8Str aShortName)
274{
275 return Utf8Str("HostInterfaceNetworking-").append(aShortName);
276}
277/**
278 * Initializes the host object.
279 *
280 * @returns COM result indicator
281 * @param aInterfaceName name of the network interface
282 * @param aGuid GUID of the host network interface
283 */
284HRESULT HostNetworkInterface::init(Utf8Str aInterfaceName, HostNetworkInterfaceType_T ifType, PNETIFINFO pIf)
285{
286// LogFlowThisFunc(("aInterfaceName={%s}, aGuid={%s}\n",
287// aInterfaceName.c_str(), aGuid.toString().c_str()));
288
289// ComAssertRet(aInterfaceName, E_INVALIDARG);
290// ComAssertRet(aGuid.isValid(), E_INVALIDARG);
291 ComAssertRet(pIf, E_INVALIDARG);
292
293 /* Enclose the state transition NotReady->InInit->Ready */
294 AutoInitSpan autoInitSpan(this);
295 AssertReturn(autoInitSpan.isOk(), E_FAIL);
296
297 unconst(mInterfaceName) = aInterfaceName;
298 unconst(mGuid) = pIf->Uuid;
299 if (pIf->szShortName[0])
300 {
301 unconst(mNetworkName) = i_composeNetworkName(pIf->szShortName);
302 unconst(mShortName) = pIf->szShortName;
303 }
304 else
305 {
306 unconst(mNetworkName) = i_composeNetworkName(aInterfaceName);
307 unconst(mShortName) = aInterfaceName;
308 }
309 mIfType = ifType;
310
311 int iPrefixIPv6;
312
313 m.realIPAddress = m.IPAddress = pIf->IPAddress.u;
314 m.realNetworkMask = m.networkMask = pIf->IPNetMask.u;
315 if (pIf->IPv6Address.s.Lo || pIf->IPv6Address.s.Hi)
316 m.realIPV6Address = m.IPV6Address = Utf8StrFmt("%RTnaipv6", &pIf->IPv6Address);
317 else
318 m.realIPV6Address = m.IPV6Address = Utf8Str::Empty;
319 RTNetMaskToPrefixIPv6(&pIf->IPv6NetMask, &iPrefixIPv6);
320 m.realIPV6PrefixLength = m.IPV6NetworkMaskPrefixLength = (ULONG)iPrefixIPv6;
321 m.dhcpEnabled = pIf->fDhcpEnabled;
322 m.hardwareAddress = Utf8StrFmt("%RTmac", &pIf->MACAddress);
323 AssertCompile((unsigned)NETIF_T_UNKNOWN == (unsigned)HostNetworkInterfaceMediumType_Unknown);
324 m.mediumType = (HostNetworkInterfaceMediumType_T)pIf->enmMediumType;
325 AssertCompile((unsigned)NETIF_S_UNKNOWN == (unsigned)HostNetworkInterfaceStatus_Unknown);
326 m.status = (HostNetworkInterfaceStatus_T)pIf->enmStatus;
327 m.speedMbits = pIf->uSpeedMbits;
328 m.wireless = pIf->fWireless;
329
330 /* Confirm a successful initialization */
331 autoInitSpan.setSucceeded();
332
333 return S_OK;
334}
335
336#endif /* VBOX_WITH_HOSTNETIF_API */
337
338// wrapped IHostNetworkInterface properties
339/////////////////////////////////////////////////////////////////////////////
340/**
341 * Returns the name of the host network interface.
342 *
343 * @returns COM status code
344 * @param aInterfaceName - Interface Name
345 */
346
347HRESULT HostNetworkInterface::getName(com::Utf8Str &aInterfaceName)
348{
349 aInterfaceName = mInterfaceName;
350 return S_OK;
351}
352
353/**
354 * Returns the short name of the host network interface.
355 *
356 * @returns COM status code
357 * @param aShortName Short Name
358 */
359
360HRESULT HostNetworkInterface::getShortName(com::Utf8Str &aShortName)
361{
362 aShortName = mShortName;
363
364 return S_OK;
365}
366
367/**
368 * Returns the GUID of the host network interface.
369 *
370 * @returns COM status code
371 * @param aGuid GUID
372 */
373HRESULT HostNetworkInterface::getId(com::Guid &aGuid)
374{
375 aGuid = mGuid;
376
377 return S_OK;
378}
379
380HRESULT HostNetworkInterface::getDHCPEnabled(BOOL *aDHCPEnabled)
381{
382 *aDHCPEnabled = m.dhcpEnabled;
383
384 return S_OK;
385}
386
387
388/**
389 * Returns the IP address of the host network interface.
390 *
391 * @returns COM status code
392 * @param aIPAddress Address name
393 */
394HRESULT HostNetworkInterface::getIPAddress(com::Utf8Str &aIPAddress)
395{
396 in_addr tmp;
397#if defined(RT_OS_WINDOWS)
398 tmp.S_un.S_addr = m.IPAddress;
399#else
400 tmp.s_addr = m.IPAddress;
401#endif
402 char *addr = inet_ntoa(tmp);
403 if (addr)
404 {
405 aIPAddress = addr;
406 return S_OK;
407 }
408
409 return E_FAIL;
410}
411
412/**
413 * Returns the netwok mask of the host network interface.
414 *
415 * @returns COM status code
416 * @param aNetworkMask name.
417 */
418HRESULT HostNetworkInterface::getNetworkMask(com::Utf8Str &aNetworkMask)
419{
420
421 in_addr tmp;
422#if defined(RT_OS_WINDOWS)
423 tmp.S_un.S_addr = m.networkMask;
424#else
425 tmp.s_addr = m.networkMask;
426#endif
427 char *addr = inet_ntoa(tmp);
428 if (addr)
429 {
430 aNetworkMask = Utf8Str(addr);
431 return S_OK;
432 }
433
434 return E_FAIL;
435}
436
437HRESULT HostNetworkInterface::getIPV6Supported(BOOL *aIPV6Supported)
438{
439#if defined(RT_OS_WINDOWS)
440 *aIPV6Supported = FALSE;
441#else
442 *aIPV6Supported = TRUE;
443#endif
444
445 return S_OK;
446}
447
448/**
449 * Returns the IP V6 address of the host network interface.
450 *
451 * @returns COM status code
452 * @param aIPV6Address
453 */
454HRESULT HostNetworkInterface::getIPV6Address(com::Utf8Str &aIPV6Address)
455{
456 aIPV6Address = m.IPV6Address;
457 return S_OK;
458}
459
460/**
461 * Returns the IP V6 network mask prefix length of the host network interface.
462 *
463 * @returns COM status code
464 * @param aIPV6NetworkMaskPrefixLength address of result pointer
465 */
466HRESULT HostNetworkInterface::getIPV6NetworkMaskPrefixLength(ULONG *aIPV6NetworkMaskPrefixLength)
467{
468 *aIPV6NetworkMaskPrefixLength = m.IPV6NetworkMaskPrefixLength;
469
470 return S_OK;
471}
472
473/**
474 * Returns the hardware address of the host network interface.
475 *
476 * @returns COM status code
477 * @param aHardwareAddress hardware address
478 */
479HRESULT HostNetworkInterface::getHardwareAddress(com::Utf8Str &aHardwareAddress)
480{
481 aHardwareAddress = m.hardwareAddress;
482 return S_OK;
483}
484
485/**
486 * Returns the encapsulation protocol type of the host network interface.
487 *
488 * @returns COM status code
489 * @param aType address of result pointer
490 */
491HRESULT HostNetworkInterface::getMediumType(HostNetworkInterfaceMediumType_T *aType)
492{
493 *aType = m.mediumType;
494
495 return S_OK;
496}
497
498/**
499 * Returns the current state of the host network interface.
500 *
501 * @returns COM status code
502 * @param aStatus address of result pointer
503 */
504HRESULT HostNetworkInterface::getStatus(HostNetworkInterfaceStatus_T *aStatus)
505{
506 *aStatus = m.status;
507
508 return S_OK;
509}
510
511/**
512 * Returns network interface type
513 *
514 * @returns COM status code
515 * @param aType address of result pointer
516 */
517HRESULT HostNetworkInterface::getInterfaceType(HostNetworkInterfaceType_T *aType)
518{
519 *aType = mIfType;
520
521 return S_OK;
522
523}
524
525HRESULT HostNetworkInterface::getNetworkName(com::Utf8Str &aNetworkName)
526{
527 aNetworkName = mNetworkName;
528
529 return S_OK;
530}
531
532HRESULT HostNetworkInterface::getWireless(BOOL *aWireless)
533{
534 *aWireless = m.wireless;
535
536 return S_OK;
537}
538
539HRESULT HostNetworkInterface::enableStaticIPConfig(const com::Utf8Str &aIPAddress,
540 const com::Utf8Str &aNetworkMask)
541{
542#ifndef VBOX_WITH_HOSTNETIF_API
543 return E_NOTIMPL;
544#else
545 if (aIPAddress.isEmpty())
546 {
547 if (m.IPAddress)
548 {
549 int rc = NetIfEnableStaticIpConfig(mVirtualBox, this, m.IPAddress, 0, 0);
550 if (RT_SUCCESS(rc))
551 {
552 m.realIPAddress = 0;
553#if defined(RT_OS_WINDOWS)
554 eraseAdapterConfigParameter("IPAddress");
555 eraseAdapterConfigParameter("IPNetMask");
556#else /* !defined(RT_OS_WINDOWS) */
557 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPAddress",
558 mInterfaceName.c_str()).raw(), NULL)))
559 return E_FAIL;
560 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
561 mInterfaceName.c_str()).raw(), NULL)))
562 return E_FAIL;
563#endif /* !defined(RT_OS_WINDOWS) */
564 return S_OK;
565 }
566 }
567 else
568 return S_OK;
569 }
570
571 ULONG ip, mask;
572 ip = inet_addr(aIPAddress.c_str());
573 if (ip != INADDR_NONE)
574 {
575 if (aNetworkMask.isEmpty())
576 mask = 0xFFFFFF;
577 else
578 mask = inet_addr(aNetworkMask.c_str());
579 if (mask != INADDR_NONE)
580 {
581 if (m.realIPAddress == ip && m.realNetworkMask == mask)
582 return S_OK;
583 int rc = NetIfEnableStaticIpConfig(mVirtualBox, this, m.IPAddress, ip, mask);
584 if (RT_SUCCESS(rc))
585 {
586 m.realIPAddress = ip;
587 m.realNetworkMask = mask;
588#if defined(RT_OS_WINDOWS)
589 saveAdapterConfigIPv4(ip, mask);
590#else /* !defined(RT_OS_WINDOWS) */
591 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPAddress",
592 mInterfaceName.c_str()).raw(),
593 Bstr(aIPAddress).raw())))
594 return E_FAIL;
595 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
596 mInterfaceName.c_str()).raw(),
597 Bstr(aNetworkMask).raw())))
598 return E_FAIL;
599#endif /* !defined(RT_OS_WINDOWS) */
600 return S_OK;
601 }
602 else
603 {
604 LogRel(("Failed to EnableStaticIpConfig with rc=%Rrc\n", rc));
605 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : (rc == VERR_ACCESS_DENIED ? E_ACCESSDENIED : E_FAIL);
606 }
607
608 }
609 }
610 return E_FAIL;
611#endif
612}
613
614HRESULT HostNetworkInterface::enableStaticIPConfigV6(const com::Utf8Str &aIPV6Address,
615 ULONG aIPV6NetworkMaskPrefixLength)
616{
617#ifndef VBOX_WITH_HOSTNETIF_API
618 return E_NOTIMPL;
619#else
620 if (aIPV6NetworkMaskPrefixLength > 128)
621 return mVirtualBox->setErrorBoth(E_INVALIDARG, VERR_INVALID_PARAMETER,
622 tr("Invalid IPv6 prefix length"));
623
624 int rc;
625
626 RTNETADDRIPV6 AddrOld, AddrNew;
627 char *pszZoneIgnored;
628 bool fAddrChanged;
629
630 rc = RTNetStrToIPv6Addr(aIPV6Address.c_str(), &AddrNew, &pszZoneIgnored);
631 if (RT_FAILURE(rc))
632 {
633 return mVirtualBox->setErrorBoth(E_INVALIDARG, rc, tr("Invalid IPv6 address"));
634 }
635
636 rc = RTNetStrToIPv6Addr(com::Utf8Str(m.realIPV6Address).c_str(), &AddrOld, &pszZoneIgnored);
637 if (RT_SUCCESS(rc))
638 {
639 fAddrChanged = (AddrNew.s.Lo != AddrOld.s.Lo || AddrNew.s.Hi != AddrOld.s.Hi);
640 }
641 else
642 {
643 fAddrChanged = true;
644 }
645
646 if ( fAddrChanged
647 || m.realIPV6PrefixLength != aIPV6NetworkMaskPrefixLength)
648 {
649 if (aIPV6NetworkMaskPrefixLength == 0)
650 aIPV6NetworkMaskPrefixLength = 64;
651 rc = NetIfEnableStaticIpConfigV6(mVirtualBox, this, m.IPV6Address.c_str(),
652 aIPV6Address.c_str(),
653 aIPV6NetworkMaskPrefixLength);
654 if (RT_FAILURE(rc))
655 {
656 LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc));
657 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
658 }
659 else
660 {
661 m.realIPV6Address = aIPV6Address;
662 m.realIPV6PrefixLength = aIPV6NetworkMaskPrefixLength;
663#if defined(RT_OS_WINDOWS)
664 saveAdapterConfigIPv6(Bstr(aIPV6Address).raw(), aIPV6NetworkMaskPrefixLength);
665#else /* !defined(RT_OS_WINDOWS) */
666 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6Address",
667 mInterfaceName.c_str()).raw(),
668 Bstr(aIPV6Address).raw())))
669 return E_FAIL;
670 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask",
671 mInterfaceName.c_str()).raw(),
672 BstrFmt("%u", aIPV6NetworkMaskPrefixLength).raw())))
673#endif /* !defined(RT_OS_WINDOWS) */
674 return E_FAIL;
675 }
676
677 }
678 return S_OK;
679#endif
680}
681
682HRESULT HostNetworkInterface::enableDynamicIPConfig()
683{
684#ifndef VBOX_WITH_HOSTNETIF_API
685 return E_NOTIMPL;
686#else
687 int rc = NetIfEnableDynamicIpConfig(mVirtualBox, this);
688 if (RT_FAILURE(rc))
689 {
690 LogRel(("Failed to EnableDynamicIpConfig with rc=%Rrc\n", rc));
691 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
692 }
693 return S_OK;
694#endif
695}
696
697HRESULT HostNetworkInterface::dHCPRediscover()
698{
699#ifndef VBOX_WITH_HOSTNETIF_API
700 return E_NOTIMPL;
701#else
702 int rc = NetIfDhcpRediscover(mVirtualBox, this);
703 if (RT_FAILURE(rc))
704 {
705 LogRel(("Failed to DhcpRediscover with rc=%Rrc\n", rc));
706 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
707 }
708 return S_OK;
709#endif
710}
711
712HRESULT HostNetworkInterface::i_setVirtualBox(VirtualBox *pVirtualBox)
713{
714 AutoCaller autoCaller(this);
715 if (FAILED(autoCaller.rc())) return autoCaller.rc();
716
717 AssertReturn(mVirtualBox != pVirtualBox, S_OK);
718
719 unconst(mVirtualBox) = pVirtualBox;
720
721#if !defined(RT_OS_WINDOWS)
722 /* If IPv4 address hasn't been initialized */
723 if (m.IPAddress == 0 && mIfType == HostNetworkInterfaceType_HostOnly)
724 {
725 Bstr tmpAddr, tmpMask;
726 HRESULT hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPAddress",
727 mInterfaceName.c_str()).raw(),
728 tmpAddr.asOutParam());
729 if (FAILED(hrc) || tmpAddr.isEmpty())
730 tmpAddr = getDefaultIPv4Address(mInterfaceName);
731
732 hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
733 mInterfaceName.c_str()).raw(),
734 tmpMask.asOutParam());
735 if (FAILED(hrc) || tmpMask.isEmpty())
736 tmpMask = Bstr(VBOXNET_IPV4MASK_DEFAULT);
737
738 m.IPAddress = inet_addr(Utf8Str(tmpAddr).c_str());
739 m.networkMask = inet_addr(Utf8Str(tmpMask).c_str());
740 }
741
742 if (m.IPV6Address.isEmpty())
743 {
744 Bstr bstrIPV4Addr;
745 Bstr tmpPrefixLen;
746 HRESULT hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6Address",
747 mInterfaceName.c_str()).raw(),
748 bstrIPV4Addr.asOutParam());
749 if (SUCCEEDED(hrc))
750 {
751 m.IPV6Address = bstrIPV4Addr;
752 if (!m.IPV6Address.isEmpty())
753 {
754 hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6PrefixLen",
755 mInterfaceName.c_str()).raw(),
756 tmpPrefixLen.asOutParam());
757 if (SUCCEEDED(hrc) && !tmpPrefixLen.isEmpty())
758 m.IPV6NetworkMaskPrefixLength = Utf8Str(tmpPrefixLen).toUInt32();
759 else
760 m.IPV6NetworkMaskPrefixLength = 64;
761 }
762 }
763 }
764#endif
765
766 return S_OK;
767}
768
769/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use