VirtualBox

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

Last change on this file since 94173 was 93576, checked in by vboxsync, 3 years ago

Main/HostNetworkInterfaceImpl: Convert exit code from VBoxNetAdpCtl
using switch instead of nested ternary. Global::vboxStatusCodeToCOM
might have come in handy here, but it asserts things we cannot
guarantee. Convert exit code for the IPv6 case too. bugref:10077

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.5 KB
Line 
1/* $Id: HostNetworkInterfaceImpl.cpp 93576 2022-02-03 12:18:25Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2022 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 HRESULT hrc;
546
547 if (aIPAddress.isEmpty())
548 {
549 if (m.IPAddress)
550 {
551 int rc = NetIfEnableStaticIpConfig(mVirtualBox, this, m.IPAddress, 0, 0);
552 if (RT_SUCCESS(rc))
553 {
554 m.realIPAddress = 0;
555#if defined(RT_OS_WINDOWS)
556 eraseAdapterConfigParameter("IPAddress");
557 eraseAdapterConfigParameter("IPNetMask");
558#else /* !defined(RT_OS_WINDOWS) */
559 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPAddress",
560 mInterfaceName.c_str()).raw(), NULL)))
561 return E_FAIL;
562 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
563 mInterfaceName.c_str()).raw(), NULL)))
564 return E_FAIL;
565#endif /* !defined(RT_OS_WINDOWS) */
566 return S_OK;
567 }
568 }
569 else
570 return S_OK;
571 }
572
573 ULONG ip, mask;
574 ip = inet_addr(aIPAddress.c_str());
575 if (ip != INADDR_NONE)
576 {
577 if (aNetworkMask.isEmpty())
578 mask = 0xFFFFFF;
579 else
580 mask = inet_addr(aNetworkMask.c_str());
581 if (mask != INADDR_NONE)
582 {
583 if (m.realIPAddress == ip && m.realNetworkMask == mask)
584 return S_OK;
585 int rc = NetIfEnableStaticIpConfig(mVirtualBox, this, m.IPAddress, ip, mask);
586 if (RT_SUCCESS(rc))
587 {
588 m.realIPAddress = ip;
589 m.realNetworkMask = mask;
590#if defined(RT_OS_WINDOWS)
591 saveAdapterConfigIPv4(ip, mask);
592#else /* !defined(RT_OS_WINDOWS) */
593 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPAddress",
594 mInterfaceName.c_str()).raw(),
595 Bstr(aIPAddress).raw())))
596 return E_FAIL;
597 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
598 mInterfaceName.c_str()).raw(),
599 Bstr(aNetworkMask).raw())))
600 return E_FAIL;
601#endif /* !defined(RT_OS_WINDOWS) */
602 return S_OK;
603 }
604 else
605 {
606 LogRel(("Failed to EnableStaticIpConfig with rc=%Rrc\n", rc));
607 /* Global::vboxStatusCodeToCOM assert things we can guarantee */
608 switch (rc)
609 {
610 case VERR_NOT_IMPLEMENTED:
611 hrc = E_NOTIMPL;
612 break;
613 case VERR_ACCESS_DENIED:
614 hrc = E_ACCESSDENIED;
615 break;
616 default:
617 hrc = E_FAIL;
618 break;
619 }
620 return hrc;
621 }
622
623 }
624 }
625 return E_FAIL;
626#endif
627}
628
629HRESULT HostNetworkInterface::enableStaticIPConfigV6(const com::Utf8Str &aIPV6Address,
630 ULONG aIPV6NetworkMaskPrefixLength)
631{
632#ifndef VBOX_WITH_HOSTNETIF_API
633 return E_NOTIMPL;
634#else
635 if (aIPV6NetworkMaskPrefixLength > 128)
636 return mVirtualBox->setErrorBoth(E_INVALIDARG, VERR_INVALID_PARAMETER,
637 tr("Invalid IPv6 prefix length"));
638
639 HRESULT hrc;
640 int rc;
641
642 RTNETADDRIPV6 AddrOld, AddrNew;
643 char *pszZoneIgnored;
644 bool fAddrChanged;
645
646 rc = RTNetStrToIPv6Addr(aIPV6Address.c_str(), &AddrNew, &pszZoneIgnored);
647 if (RT_FAILURE(rc))
648 {
649 return mVirtualBox->setErrorBoth(E_INVALIDARG, rc, tr("Invalid IPv6 address"));
650 }
651
652 rc = RTNetStrToIPv6Addr(com::Utf8Str(m.realIPV6Address).c_str(), &AddrOld, &pszZoneIgnored);
653 if (RT_SUCCESS(rc))
654 {
655 fAddrChanged = (AddrNew.s.Lo != AddrOld.s.Lo || AddrNew.s.Hi != AddrOld.s.Hi);
656 }
657 else
658 {
659 fAddrChanged = true;
660 }
661
662 if ( fAddrChanged
663 || m.realIPV6PrefixLength != aIPV6NetworkMaskPrefixLength)
664 {
665 if (aIPV6NetworkMaskPrefixLength == 0)
666 aIPV6NetworkMaskPrefixLength = 64;
667 rc = NetIfEnableStaticIpConfigV6(mVirtualBox, this, m.IPV6Address.c_str(),
668 aIPV6Address.c_str(),
669 aIPV6NetworkMaskPrefixLength);
670 if (RT_FAILURE(rc))
671 {
672 LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc));
673 /* Global::vboxStatusCodeToCOM assert things we can guarantee */
674 switch (rc)
675 {
676 case VERR_NOT_IMPLEMENTED:
677 hrc = E_NOTIMPL;
678 break;
679 case VERR_ACCESS_DENIED:
680 hrc = E_ACCESSDENIED;
681 break;
682 default:
683 hrc = E_FAIL;
684 break;
685 }
686 return hrc;
687 }
688 else
689 {
690 m.realIPV6Address = aIPV6Address;
691 m.realIPV6PrefixLength = aIPV6NetworkMaskPrefixLength;
692#if defined(RT_OS_WINDOWS)
693 saveAdapterConfigIPv6(Bstr(aIPV6Address).raw(), aIPV6NetworkMaskPrefixLength);
694#else /* !defined(RT_OS_WINDOWS) */
695 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6Address",
696 mInterfaceName.c_str()).raw(),
697 Bstr(aIPV6Address).raw())))
698 return E_FAIL;
699 if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask",
700 mInterfaceName.c_str()).raw(),
701 BstrFmt("%u", aIPV6NetworkMaskPrefixLength).raw())))
702#endif /* !defined(RT_OS_WINDOWS) */
703 return E_FAIL;
704 }
705
706 }
707 return S_OK;
708#endif
709}
710
711HRESULT HostNetworkInterface::enableDynamicIPConfig()
712{
713#ifndef VBOX_WITH_HOSTNETIF_API
714 return E_NOTIMPL;
715#else
716 int rc = NetIfEnableDynamicIpConfig(mVirtualBox, this);
717 if (RT_FAILURE(rc))
718 {
719 LogRel(("Failed to EnableDynamicIpConfig with rc=%Rrc\n", rc));
720 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
721 }
722 return S_OK;
723#endif
724}
725
726HRESULT HostNetworkInterface::dHCPRediscover()
727{
728#ifndef VBOX_WITH_HOSTNETIF_API
729 return E_NOTIMPL;
730#else
731 int rc = NetIfDhcpRediscover(mVirtualBox, this);
732 if (RT_FAILURE(rc))
733 {
734 LogRel(("Failed to DhcpRediscover with rc=%Rrc\n", rc));
735 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
736 }
737 return S_OK;
738#endif
739}
740
741HRESULT HostNetworkInterface::i_setVirtualBox(VirtualBox *pVirtualBox)
742{
743 AutoCaller autoCaller(this);
744 if (FAILED(autoCaller.rc())) return autoCaller.rc();
745
746 AssertReturn(mVirtualBox != pVirtualBox, S_OK);
747
748 unconst(mVirtualBox) = pVirtualBox;
749
750#if !defined(RT_OS_WINDOWS)
751 /* If IPv4 address hasn't been initialized */
752 if (m.IPAddress == 0 && mIfType == HostNetworkInterfaceType_HostOnly)
753 {
754 Bstr tmpAddr, tmpMask;
755 HRESULT hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPAddress",
756 mInterfaceName.c_str()).raw(),
757 tmpAddr.asOutParam());
758 if (FAILED(hrc) || tmpAddr.isEmpty())
759 tmpAddr = getDefaultIPv4Address(mInterfaceName);
760
761 hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPNetMask",
762 mInterfaceName.c_str()).raw(),
763 tmpMask.asOutParam());
764 if (FAILED(hrc) || tmpMask.isEmpty())
765 tmpMask = Bstr(VBOXNET_IPV4MASK_DEFAULT);
766
767 m.IPAddress = inet_addr(Utf8Str(tmpAddr).c_str());
768 m.networkMask = inet_addr(Utf8Str(tmpMask).c_str());
769 }
770
771 if (m.IPV6Address.isEmpty())
772 {
773 Bstr bstrIPV4Addr;
774 Bstr tmpPrefixLen;
775 HRESULT hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6Address",
776 mInterfaceName.c_str()).raw(),
777 bstrIPV4Addr.asOutParam());
778 if (SUCCEEDED(hrc))
779 {
780 m.IPV6Address = bstrIPV4Addr;
781 if (!m.IPV6Address.isEmpty())
782 {
783 hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6PrefixLen",
784 mInterfaceName.c_str()).raw(),
785 tmpPrefixLen.asOutParam());
786 if (SUCCEEDED(hrc) && !tmpPrefixLen.isEmpty())
787 m.IPV6NetworkMaskPrefixLength = Utf8Str(tmpPrefixLen).toUInt32();
788 else
789 m.IPV6NetworkMaskPrefixLength = 64;
790 }
791 }
792 }
793#endif
794
795 return S_OK;
796}
797
798/* 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