VirtualBox

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

最後變更 在這個檔案從108422是 107524,由 vboxsync 提交於 2 月 前

src-server/HostNetworkInterfaceImpl.cpp: Fixed warning found by Parfait (uninitialized attributes).

Added missing HostNetworkInterfaceType_Invalid to IDL enum.

jiraref:VBP-1424

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

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