VirtualBox

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

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

Main: Bstr makeover (third attempt) -- make Bstr(NULL) and Bstr() behave the same; resulting cleanup; make some more internal methods use Utf8Str instead of Bstr; fix a lot of CheckComArgNotNull??() usage

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