VirtualBox

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

Last change on this file since 18626 was 18594, checked in by vboxsync, 16 years ago

Fixed the problem with vboxnet0 not getting static IP on VM start.

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