VirtualBox

source: vbox/trunk/src/VBox/Main/HostNetworkInterfaceImpl.cpp@ 29788

Last change on this file since 29788 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.3 KB
Line 
1/* $Id: HostNetworkInterfaceImpl.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
2
3/** @file
4 *
5 * VirtualBox COM class implementation
6 */
7
8/*
9 * Copyright (C) 2006-2008 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#include "HostNetworkInterfaceImpl.h"
21#include "AutoCaller.h"
22#include "Logging.h"
23#include "netif.h"
24
25#ifdef RT_OS_FREEBSD
26# include <netinet/in.h> /* INADDR_NONE */
27#endif /* RT_OS_FREEBSD */
28
29// constructor / destructor
30/////////////////////////////////////////////////////////////////////////////
31
32HostNetworkInterface::HostNetworkInterface()
33 : mVBox(NULL)
34{
35}
36
37HostNetworkInterface::~HostNetworkInterface()
38{
39}
40
41HRESULT HostNetworkInterface::FinalConstruct()
42{
43 return S_OK;
44}
45
46void HostNetworkInterface::FinalRelease()
47{
48 uninit ();
49}
50
51// public initializer/uninitializer for internal purposes only
52/////////////////////////////////////////////////////////////////////////////
53
54/**
55 * Initializes the host object.
56 *
57 * @returns COM result indicator
58 * @param aInterfaceName name of the network interface
59 * @param aGuid GUID of the host network interface
60 */
61HRESULT HostNetworkInterface::init (Bstr aInterfaceName, Guid aGuid, HostNetworkInterfaceType_T ifType)
62{
63 LogFlowThisFunc(("aInterfaceName={%ls}, aGuid={%s}\n",
64 aInterfaceName.raw(), aGuid.toString().raw()));
65
66 ComAssertRet(aInterfaceName, E_INVALIDARG);
67 ComAssertRet(!aGuid.isEmpty(), E_INVALIDARG);
68
69 /* Enclose the state transition NotReady->InInit->Ready */
70 AutoInitSpan autoInitSpan(this);
71 AssertReturn(autoInitSpan.isOk(), E_FAIL);
72
73 unconst(mInterfaceName) = aInterfaceName;
74 unconst(mGuid) = aGuid;
75 mIfType = ifType;
76
77
78 /* Confirm a successful initialization */
79 autoInitSpan.setSucceeded();
80
81 return S_OK;
82}
83
84#ifdef VBOX_WITH_HOSTNETIF_API
85
86HRESULT HostNetworkInterface::updateConfig ()
87{
88 NETIFINFO info;
89 int rc = NetIfGetConfig(this, &info);
90 if (RT_SUCCESS(rc))
91 {
92 m.realIPAddress = m.IPAddress = info.IPAddress.u;
93 m.realNetworkMask = m.networkMask = info.IPNetMask.u;
94 m.dhcpEnabled = info.bDhcpEnabled;
95 m.realIPV6Address = m.IPV6Address = composeIPv6Address(&info.IPv6Address);
96 m.realIPV6PrefixLength = m.IPV6NetworkMaskPrefixLength = composeIPv6PrefixLenghFromAddress(&info.IPv6NetMask);
97 m.hardwareAddress = composeHardwareAddress(&info.MACAddress);
98#ifdef RT_OS_WINDOWS
99 m.mediumType = (HostNetworkInterfaceMediumType)info.enmMediumType;
100 m.status = (HostNetworkInterfaceStatus)info.enmStatus;
101#else /* !RT_OS_WINDOWS */
102 m.mediumType = info.enmMediumType;
103 m.status = info.enmStatus;
104
105#endif /* !RT_OS_WINDOWS */
106 return S_OK;
107 }
108 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
109}
110
111/**
112 * Initializes the host object.
113 *
114 * @returns COM result indicator
115 * @param aInterfaceName name of the network interface
116 * @param aGuid GUID of the host network interface
117 */
118HRESULT HostNetworkInterface::init (Bstr aInterfaceName, HostNetworkInterfaceType_T ifType, PNETIFINFO pIf)
119{
120// LogFlowThisFunc(("aInterfaceName={%ls}, aGuid={%s}\n",
121// aInterfaceName.raw(), aGuid.toString().raw()));
122
123// ComAssertRet(aInterfaceName, E_INVALIDARG);
124// ComAssertRet(!aGuid.isEmpty(), E_INVALIDARG);
125 ComAssertRet(pIf, E_INVALIDARG);
126
127 /* Enclose the state transition NotReady->InInit->Ready */
128 AutoInitSpan autoInitSpan(this);
129 AssertReturn(autoInitSpan.isOk(), E_FAIL);
130
131 unconst(mInterfaceName) = aInterfaceName;
132 unconst(mGuid) = pIf->Uuid;
133 mIfType = ifType;
134
135 m.realIPAddress = m.IPAddress = pIf->IPAddress.u;
136 m.realNetworkMask = m.networkMask = pIf->IPNetMask.u;
137 m.realIPV6Address = m.IPV6Address = composeIPv6Address(&pIf->IPv6Address);
138 m.realIPV6PrefixLength = m.IPV6NetworkMaskPrefixLength = composeIPv6PrefixLenghFromAddress(&pIf->IPv6NetMask);
139 m.dhcpEnabled = pIf->bDhcpEnabled;
140 m.hardwareAddress = composeHardwareAddress(&pIf->MACAddress);
141#ifdef RT_OS_WINDOWS
142 m.mediumType = (HostNetworkInterfaceMediumType)pIf->enmMediumType;
143 m.status = (HostNetworkInterfaceStatus)pIf->enmStatus;
144#else /* !RT_OS_WINDOWS */
145 m.mediumType = pIf->enmMediumType;
146 m.status = pIf->enmStatus;
147#endif /* !RT_OS_WINDOWS */
148
149 /* Confirm a successful initialization */
150 autoInitSpan.setSucceeded();
151
152 return S_OK;
153}
154#endif
155
156// IHostNetworkInterface properties
157/////////////////////////////////////////////////////////////////////////////
158
159/**
160 * Returns the name of the host network interface.
161 *
162 * @returns COM status code
163 * @param aInterfaceName address of result pointer
164 */
165STDMETHODIMP HostNetworkInterface::COMGETTER(Name) (BSTR *aInterfaceName)
166{
167 CheckComArgOutPointerValid(aInterfaceName);
168
169 AutoCaller autoCaller(this);
170 if (FAILED(autoCaller.rc())) return autoCaller.rc();
171
172 mInterfaceName.cloneTo(aInterfaceName);
173
174 return S_OK;
175}
176
177/**
178 * Returns the GUID of the host network interface.
179 *
180 * @returns COM status code
181 * @param aGuid address of result pointer
182 */
183STDMETHODIMP HostNetworkInterface::COMGETTER(Id) (BSTR *aGuid)
184{
185 CheckComArgOutPointerValid(aGuid);
186
187 AutoCaller autoCaller(this);
188 if (FAILED(autoCaller.rc())) return autoCaller.rc();
189
190 mGuid.toUtf16().cloneTo(aGuid);
191
192 return S_OK;
193}
194
195STDMETHODIMP HostNetworkInterface::COMGETTER(DhcpEnabled) (BOOL *aDhcpEnabled)
196{
197 CheckComArgOutPointerValid(aDhcpEnabled);
198
199 AutoCaller autoCaller(this);
200 if (FAILED(autoCaller.rc())) return autoCaller.rc();
201
202 *aDhcpEnabled = m.dhcpEnabled;
203
204 return S_OK;
205}
206
207
208/**
209 * Returns the IP address of the host network interface.
210 *
211 * @returns COM status code
212 * @param aIPAddress address of result pointer
213 */
214STDMETHODIMP HostNetworkInterface::COMGETTER(IPAddress) (BSTR *aIPAddress)
215{
216 CheckComArgOutPointerValid(aIPAddress);
217
218 AutoCaller autoCaller(this);
219 if (FAILED(autoCaller.rc())) return autoCaller.rc();
220
221 if (m.IPAddress == 0)
222 {
223 getDefaultIPv4Address(mInterfaceName).detachTo(aIPAddress);
224 return S_OK;
225 }
226
227 in_addr tmp;
228#if defined(RT_OS_WINDOWS)
229 tmp.S_un.S_addr = m.IPAddress;
230#else
231 tmp.s_addr = m.IPAddress;
232#endif
233 char *addr = inet_ntoa(tmp);
234 if (addr)
235 {
236 Bstr(addr).detachTo(aIPAddress);
237 return S_OK;
238 }
239
240 return E_FAIL;
241}
242
243/**
244 * Returns the netwok mask of the host network interface.
245 *
246 * @returns COM status code
247 * @param aNetworkMask address of result pointer
248 */
249STDMETHODIMP HostNetworkInterface::COMGETTER(NetworkMask) (BSTR *aNetworkMask)
250{
251 CheckComArgOutPointerValid(aNetworkMask);
252
253 AutoCaller autoCaller(this);
254 if (FAILED(autoCaller.rc())) return autoCaller.rc();
255
256 if (m.networkMask == 0)
257 {
258 Bstr(VBOXNET_IPV4MASK_DEFAULT).detachTo(aNetworkMask);
259 return S_OK;
260 }
261
262 in_addr tmp;
263#if defined(RT_OS_WINDOWS)
264 tmp.S_un.S_addr = m.networkMask;
265#else
266 tmp.s_addr = m.networkMask;
267#endif
268 char *addr = inet_ntoa(tmp);
269 if (addr)
270 {
271 Bstr(addr).detachTo(aNetworkMask);
272 return S_OK;
273 }
274
275 return E_FAIL;
276}
277
278STDMETHODIMP HostNetworkInterface::COMGETTER(IPV6Supported) (BOOL *aIPV6Supported)
279{
280 CheckComArgOutPointerValid(aIPV6Supported);
281#if defined(RT_OS_WINDOWS)
282 *aIPV6Supported = FALSE;
283#else
284 *aIPV6Supported = TRUE;
285#endif
286
287 return S_OK;
288}
289
290/**
291 * Returns the IP V6 address of the host network interface.
292 *
293 * @returns COM status code
294 * @param aIPV6Address address of result pointer
295 */
296STDMETHODIMP HostNetworkInterface::COMGETTER(IPV6Address) (BSTR *aIPV6Address)
297{
298 CheckComArgOutPointerValid(aIPV6Address);
299
300 AutoCaller autoCaller(this);
301 if (FAILED(autoCaller.rc())) return autoCaller.rc();
302
303 m.IPV6Address.cloneTo(aIPV6Address);
304
305 return S_OK;
306}
307
308/**
309 * Returns the IP V6 network mask of the host network interface.
310 *
311 * @returns COM status code
312 * @param aIPV6Mask address of result pointer
313 */
314STDMETHODIMP HostNetworkInterface::COMGETTER(IPV6NetworkMaskPrefixLength) (ULONG *aIPV6NetworkMaskPrefixLength)
315{
316 CheckComArgOutPointerValid(aIPV6NetworkMaskPrefixLength);
317
318 AutoCaller autoCaller(this);
319 if (FAILED(autoCaller.rc())) return autoCaller.rc();
320
321 *aIPV6NetworkMaskPrefixLength = m.IPV6NetworkMaskPrefixLength;
322
323 return S_OK;
324}
325
326/**
327 * Returns the hardware address of the host network interface.
328 *
329 * @returns COM status code
330 * @param aHardwareAddress address of result pointer
331 */
332STDMETHODIMP HostNetworkInterface::COMGETTER(HardwareAddress) (BSTR *aHardwareAddress)
333{
334 CheckComArgOutPointerValid(aHardwareAddress);
335
336 AutoCaller autoCaller(this);
337 if (FAILED(autoCaller.rc())) return autoCaller.rc();
338
339 m.hardwareAddress.cloneTo(aHardwareAddress);
340
341 return S_OK;
342}
343
344/**
345 * Returns the encapsulation protocol type of the host network interface.
346 *
347 * @returns COM status code
348 * @param aType address of result pointer
349 */
350STDMETHODIMP HostNetworkInterface::COMGETTER(MediumType) (HostNetworkInterfaceMediumType_T *aType)
351{
352 CheckComArgOutPointerValid(aType);
353
354 AutoCaller autoCaller(this);
355 if (FAILED(autoCaller.rc())) return autoCaller.rc();
356
357 *aType = m.mediumType;
358
359 return S_OK;
360}
361
362/**
363 * Returns the current state of the host network interface.
364 *
365 * @returns COM status code
366 * @param aStatus address of result pointer
367 */
368STDMETHODIMP HostNetworkInterface::COMGETTER(Status) (HostNetworkInterfaceStatus_T *aStatus)
369{
370 CheckComArgOutPointerValid(aStatus);
371
372 AutoCaller autoCaller(this);
373 if (FAILED(autoCaller.rc())) return autoCaller.rc();
374
375 *aStatus = m.status;
376
377 return S_OK;
378}
379
380/**
381 * Returns network interface type
382 *
383 * @returns COM status code
384 * @param aType address of result pointer
385 */
386STDMETHODIMP HostNetworkInterface::COMGETTER(InterfaceType) (HostNetworkInterfaceType_T *aType)
387{
388 CheckComArgOutPointerValid(aType);
389
390 AutoCaller autoCaller(this);
391 if (FAILED(autoCaller.rc())) return autoCaller.rc();
392
393 *aType = mIfType;
394
395 return S_OK;
396
397}
398
399STDMETHODIMP HostNetworkInterface::COMGETTER(NetworkName) (BSTR *aNetworkName)
400{
401 AutoCaller autoCaller(this);
402 if (FAILED(autoCaller.rc())) return autoCaller.rc();
403
404 Utf8Str utf8Name("HostInterfaceNetworking-");
405 utf8Name.append(Utf8Str(mInterfaceName)) ;
406 Bstr netName(utf8Name);
407 netName.detachTo(aNetworkName);
408
409 return S_OK;
410}
411
412STDMETHODIMP HostNetworkInterface::EnableStaticIpConfig (IN_BSTR aIPAddress, IN_BSTR aNetMask)
413{
414#ifndef VBOX_WITH_HOSTNETIF_API
415 return E_NOTIMPL;
416#else
417 AutoCaller autoCaller(this);
418 if (FAILED(autoCaller.rc())) return autoCaller.rc();
419
420 if (Bstr(aIPAddress).isEmpty())
421 {
422 if (m.IPAddress)
423 {
424 int rc = NetIfEnableStaticIpConfig(mVBox, this, m.IPAddress, 0, 0);
425 if (RT_SUCCESS(rc))
426 {
427 m.realIPAddress = 0;
428 if (FAILED(mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw()), NULL)))
429 return E_FAIL;
430 if (FAILED(mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPNetMask", mInterfaceName.raw()), NULL)))
431 return E_FAIL;
432 return S_OK;
433 }
434 }
435 else
436 return S_OK;
437 }
438
439 ULONG ip, mask;
440 ip = inet_addr(Utf8Str(aIPAddress).raw());
441 if (ip != INADDR_NONE)
442 {
443 if (Bstr(aNetMask).isEmpty())
444 mask = 0xFFFFFF;
445 else
446 mask = inet_addr(Utf8Str(aNetMask).raw());
447 if (mask != INADDR_NONE)
448 {
449 if (m.realIPAddress == ip && m.realNetworkMask == mask)
450 return S_OK;
451 int rc = NetIfEnableStaticIpConfig(mVBox, this, m.IPAddress, ip, mask);
452 if (RT_SUCCESS(rc))
453 {
454 m.realIPAddress = ip;
455 m.realNetworkMask = mask;
456 if (FAILED(mVBox->SetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw())), Bstr(aIPAddress))))
457 return E_FAIL;
458 if (FAILED(mVBox->SetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPNetMask", mInterfaceName.raw())), Bstr(aNetMask))))
459 return E_FAIL;
460 return S_OK;
461 }
462 else
463 {
464 LogRel(("Failed to EnableStaticIpConfig with rc=%Rrc\n", rc));
465 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
466 }
467
468 }
469 }
470 return E_FAIL;
471#endif
472}
473
474STDMETHODIMP HostNetworkInterface::EnableStaticIpConfigV6 (IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
475{
476#ifndef VBOX_WITH_HOSTNETIF_API
477 return E_NOTIMPL;
478#else
479 if (!aIPV6Address)
480 return E_INVALIDARG;
481 if (aIPV6MaskPrefixLength > 128)
482 return E_INVALIDARG;
483
484 AutoCaller autoCaller(this);
485 if (FAILED(autoCaller.rc())) return autoCaller.rc();
486
487 int rc = S_OK;
488 if (m.realIPV6Address != aIPV6Address || m.realIPV6PrefixLength != aIPV6MaskPrefixLength)
489 {
490 if (aIPV6MaskPrefixLength == 0)
491 aIPV6MaskPrefixLength = 64;
492 rc = NetIfEnableStaticIpConfigV6(mVBox, this, m.IPV6Address, aIPV6Address, aIPV6MaskPrefixLength);
493 if (RT_FAILURE(rc))
494 {
495 LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc));
496 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
497 }
498 else
499 {
500 m.realIPV6Address = aIPV6Address;
501 m.realIPV6PrefixLength = aIPV6MaskPrefixLength;
502 if (FAILED(mVBox->SetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPV6Address", mInterfaceName.raw())), Bstr(aIPV6Address))))
503 return E_FAIL;
504 if (FAILED(mVBox->SetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPV6NetMask", mInterfaceName.raw())),
505 Bstr(Utf8StrFmt("%u", aIPV6MaskPrefixLength)))))
506 return E_FAIL;
507 }
508
509 }
510 return S_OK;
511#endif
512}
513
514STDMETHODIMP HostNetworkInterface::EnableDynamicIpConfig ()
515{
516#ifndef VBOX_WITH_HOSTNETIF_API
517 return E_NOTIMPL;
518#else
519 AutoCaller autoCaller(this);
520 if (FAILED(autoCaller.rc())) return autoCaller.rc();
521
522 int rc = NetIfEnableDynamicIpConfig(mVBox, this);
523 if (RT_FAILURE(rc))
524 {
525 LogRel(("Failed to EnableDynamicIpConfig with rc=%Rrc\n", rc));
526 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
527 }
528 return S_OK;
529#endif
530}
531
532STDMETHODIMP HostNetworkInterface::DhcpRediscover ()
533{
534#ifndef VBOX_WITH_HOSTNETIF_API
535 return E_NOTIMPL;
536#else
537 AutoCaller autoCaller(this);
538 if (FAILED(autoCaller.rc())) return autoCaller.rc();
539
540 int rc = NetIfDhcpRediscover(mVBox, this);
541 if (RT_FAILURE(rc))
542 {
543 LogRel(("Failed to DhcpRediscover with rc=%Rrc\n", rc));
544 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;
545 }
546 return S_OK;
547#endif
548}
549
550HRESULT HostNetworkInterface::setVirtualBox(VirtualBox *pVBox)
551{
552 HRESULT hrc;
553 AutoCaller autoCaller(this);
554 if (FAILED(autoCaller.rc())) return autoCaller.rc();
555 unconst(mVBox) = pVBox;
556
557 /* If IPv4 address hasn't been initialized */
558 if (m.IPAddress == 0)
559 {
560 Bstr tmpAddr, tmpMask;
561 hrc = mVBox->GetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw())), tmpAddr.asOutParam());
562 hrc = mVBox->GetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPNetMask", mInterfaceName.raw())), tmpMask.asOutParam());
563 if (tmpAddr.isEmpty())
564 tmpAddr = getDefaultIPv4Address(mInterfaceName);
565 if (tmpMask.isEmpty())
566 tmpMask = Bstr(VBOXNET_IPV4MASK_DEFAULT);
567 m.IPAddress = inet_addr(Utf8Str(tmpAddr).raw());
568 m.networkMask = inet_addr(Utf8Str(tmpMask).raw());
569 }
570
571 if (m.IPV6Address.isEmpty())
572 {
573 Bstr tmpPrefixLen;
574 hrc = mVBox->GetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPV6Address", mInterfaceName.raw())), m.IPV6Address.asOutParam());
575 if (!m.IPV6Address.isEmpty())
576 {
577 hrc = mVBox->GetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPV6PrefixLen", mInterfaceName.raw())), tmpPrefixLen.asOutParam());
578 if (SUCCEEDED(hrc) && !tmpPrefixLen.isEmpty())
579 m.IPV6NetworkMaskPrefixLength = Utf8Str(tmpPrefixLen).toUInt32();
580 else
581 m.IPV6NetworkMaskPrefixLength = 64;
582 }
583 }
584
585 return S_OK;
586}
587
588/* 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