VirtualBox

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

Last change on this file since 20988 was 19239, checked in by vboxsync, 16 years ago

Main: support for using VBox from Python on Windows (still certain limitation apply, such as enum visibility)

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