VirtualBox

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

Last change on this file was 98288, checked in by vboxsync, 17 months ago

Main/src-server: rc -> hrc/vrc (partial). bugref:10223

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

© 2023 Oracle
ContactPrivacy policyTerms of Use