- Timestamp:
- Jun 12, 2009 3:28:26 PM (16 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Makefile.kmk
r20501 r20521 286 286 Serial/DevSerial.cpp \ 287 287 Parallel/DevParallel.cpp 288 289 ifdef VBOX_DYNAMIC_NET_ATTACH 290 DevicesR3_DEFS += VBOX_DYNAMIC_NET_ATTACH 291 endif 288 292 289 293 ifdef VBOX_WITH_E1000 … … 466 470 Parallel/DevParallel.cpp 467 471 472 ifdef VBOX_DYNAMIC_NET_ATTACH 473 VBoxDDGC_DEFS += VBOX_DYNAMIC_NET_ATTACH 474 endif 475 468 476 ifdef VBOX_WITH_E1000 469 477 VBoxDDGC_DEFS += VBOX_WITH_E1000 … … 548 556 Serial/DevSerial.cpp \ 549 557 Parallel/DevParallel.cpp 558 559 ifdef VBOX_DYNAMIC_NET_ATTACH 560 VBoxDDR0_DEFS += VBOX_DYNAMIC_NET_ATTACH 561 endif 550 562 551 563 ifdef VBOX_WITH_E1000 -
trunk/src/VBox/Devices/Network/DevPCNet.cpp
r20374 r20521 4651 4651 4652 4652 4653 #ifdef VBOX_DYNAMIC_NET_ATTACH 4654 /** 4655 * Detach notification. 4656 * 4657 * One network card at one port has been unplugged. 4658 * The VM is suspended at this point. 4659 * 4660 * @param pDevIns The device instance. 4661 * @param iLUN The logical unit which is being detached. 4662 */ 4663 static DECLCALLBACK(void) pcnetDetach(PPDMDEVINS pDevIns, unsigned iLUN) 4664 { 4665 PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *); 4666 4667 Log(("%s:\n", __FUNCTION__)); 4668 4669 int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY); 4670 AssertReleaseRC(rc); 4671 4672 /* @todo: r=pritesh still need to check if i missed 4673 * to clean something in this function 4674 */ 4675 4676 /* 4677 * Zero some important members. 4678 */ 4679 pThis->pDrvBase = NULL; 4680 pThis->pDrv = NULL; 4681 4682 PDMCritSectLeave(&pThis->CritSect); 4683 } 4684 4685 4686 /** 4687 * Attach the Network attachment. 4688 * 4689 * @returns VBox status code. 4690 * @param pDevIns The device instance. 4691 * @param iLUN The logical unit which is being detached. 4692 */ 4693 static DECLCALLBACK(int) pcnetAttach(PPDMDEVINS pDevIns, unsigned iLUN) 4694 { 4695 PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *); 4696 int rc = VINF_SUCCESS; 4697 4698 Log(("%s:\n", __FUNCTION__)); 4699 4700 rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY); 4701 AssertReleaseRC(rc); 4702 4703 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Network Port"); 4704 if (RT_SUCCESS(rc)) 4705 { 4706 if (rc == VINF_NAT_DNS) 4707 { 4708 #ifdef RT_OS_LINUX 4709 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT", 4710 N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so")); 4711 #else 4712 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT", 4713 N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so")); 4714 #endif 4715 } 4716 pThis->pDrv = (PPDMINETWORKCONNECTOR) 4717 pThis->pDrvBase->pfnQueryInterface(pThis->pDrvBase, PDMINTERFACE_NETWORK_CONNECTOR); 4718 if (!pThis->pDrv) 4719 { 4720 AssertMsgFailed(("Failed to obtain the PDMINTERFACE_NETWORK_CONNECTOR interface!\n")); 4721 return VERR_PDM_MISSING_INTERFACE_BELOW; 4722 } 4723 } 4724 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 4725 Log(("No attached driver!\n")); 4726 else 4727 return rc; 4728 4729 /* 4730 * Temporary set the link down if it was up so that the guest 4731 * will know that we have change the configuration of the 4732 * network card 4733 */ 4734 if (pThis->fLinkUp) 4735 { 4736 pThis->fLinkTempDown = true; 4737 pThis->cLinkDownReported = 0; 4738 pThis->aCSR[0] |= RT_BIT(15) | RT_BIT(13); /* ERR | CERR (this is probably wrong) */ 4739 pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1; 4740 TMTimerSetMillies(pThis->pTimerRestore, 20000); 4741 } 4742 PDMCritSectLeave(&pThis->CritSect); 4743 4744 return rc; 4745 4746 } 4747 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 4748 4749 4653 4750 /** 4654 4751 * @copydoc FNPDMDEVSUSPEND … … 5163 5260 /* pfnResume */ 5164 5261 NULL, 5262 #ifdef VBOX_DYNAMIC_NET_ATTACH 5263 /* pfnAttach */ 5264 pcnetAttach, 5265 /* pfnDetach */ 5266 pcnetDetach, 5267 #else /* !VBOX_DYNAMIC_NET_ATTACH */ 5165 5268 /* pfnAttach */ 5166 5269 NULL, 5167 5270 /* pfnDetach */ 5168 5271 NULL, 5272 #endif /* !VBOX_DYNAMIC_NET_ATTACH */ 5169 5273 /* pfnQueryInterface. */ 5170 5274 NULL, -
trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk
r20501 r20521 47 47 $(if $(VBOX_WITH_HOSTNETIF_API), VBOX_WITH_HOSTNETIF_API) 48 48 VBoxManage_DEFS.win = _WIN32_WINNT=0x0500 49 ifdef VBOX_DYNAMIC_NET_ATTACH 50 VBoxManage_DEFS += VBOX_DYNAMIC_NET_ATTACH 51 endif 49 52 ifdef VBOX_WITH_NETFLT 50 53 VBoxManage_DEFS += VBOX_WITH_NETFLT -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r20313 r20521 751 751 } 752 752 } 753 #ifdef VBOX_DYNAMIC_NET_ATTACH 754 else if (!strncmp(a->argv[1], "nic", 3)) 755 { 756 /* Get the number of network adapters */ 757 ULONG NetworkAdapterCount = 0; 758 ComPtr <ISystemProperties> info; 759 CHECK_ERROR_BREAK (a->virtualBox, COMGETTER(SystemProperties) (info.asOutParam())); 760 CHECK_ERROR_BREAK (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount)); 761 762 unsigned n = parseNum(&a->argv[1][3], NetworkAdapterCount, "NIC"); 763 if (!n) 764 { 765 rc = E_FAIL; 766 break; 767 } 768 if (a->argc <= 1 + 1) 769 { 770 errorArgument("Missing argument to '%s'", a->argv[1]); 771 rc = E_FAIL; 772 break; 773 } 774 775 /* get the corresponding network adapter */ 776 ComPtr<INetworkAdapter> adapter; 777 CHECK_ERROR_BREAK (sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam())); 778 if (adapter) 779 { 780 if (!strcmp(a->argv[2], "none")) 781 { 782 CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (FALSE), 1); 783 } 784 else if (!strcmp(a->argv[2], "null")) 785 { 786 CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1); 787 CHECK_ERROR_RET(adapter, Detach(), 1); 788 } 789 else if (!strcmp(a->argv[2], "nat")) 790 { 791 if (a->argc == 3) 792 CHECK_ERROR_RET(adapter, COMSETTER(NATNetwork)(Bstr(a->argv[3])), 1); 793 CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1); 794 CHECK_ERROR_RET(adapter, AttachToNAT(), 1); 795 } 796 else if ( !strcmp(a->argv[2], "bridged") 797 || !strcmp(a->argv[2], "hostif")) /* backward compatibility */ 798 { 799 if (a->argc <= 1 + 2) 800 { 801 errorArgument("Missing argument to '%s'", a->argv[2]); 802 rc = E_FAIL; 803 break; 804 } 805 CHECK_ERROR_RET(adapter, COMSETTER(HostInterface)(Bstr(a->argv[3])), 1); 806 CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1); 807 CHECK_ERROR_RET(adapter, AttachToBridgedInterface(), 1); 808 } 809 else if (!strcmp(a->argv[2], "intnet")) 810 { 811 if (a->argc <= 1 + 2) 812 { 813 errorArgument("Missing argument to '%s'", a->argv[2]); 814 rc = E_FAIL; 815 break; 816 } 817 CHECK_ERROR_RET(adapter, COMSETTER(InternalNetwork)(Bstr(a->argv[3])), 1); 818 CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1); 819 CHECK_ERROR_RET(adapter, AttachToInternalNetwork(), 1); 820 } 821 #if defined(VBOX_WITH_NETFLT) 822 else if (!strcmp(a->argv[2], "hostonly")) 823 { 824 if (a->argc <= 1 + 2) 825 { 826 errorArgument("Missing argument to '%s'", a->argv[2]); 827 rc = E_FAIL; 828 break; 829 } 830 CHECK_ERROR_RET(adapter, COMSETTER(HostInterface)(Bstr(a->argv[3])), 1); 831 CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1); 832 CHECK_ERROR_RET(adapter, AttachToHostOnlyInterface(), 1); 833 } 834 #endif 835 else 836 { 837 errorArgument("Invalid type '%s' specfied for NIC %lu", Utf8Str(a->argv[2]).raw(), n + 1); 838 rc = E_FAIL; 839 break; 840 } 841 } 842 } 843 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 753 844 #ifdef VBOX_WITH_VRDP 754 845 else if (!strcmp(a->argv[1], "vrdp")) -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
r20501 r20521 278 278 " injectnmi|\n" 279 279 " setlinkstate<1-N> on|off |\n" 280 #ifdef VBOX_DYNAMIC_NET_ATTACH 281 #if defined(VBOX_WITH_NETFLT) 282 " nic<1-N> none|null|nat|bridged|intnet|hostonly\n" 283 " [<devicename>] |\n" 284 #else /* !RT_OS_LINUX && !RT_OS_DARWIN */ 285 " nic<1-N> none|null|nat|bridged|intnet\n" 286 " [<devicename>] |\n" 287 #endif /* !RT_OS_LINUX && !RT_OS_DARWIN */ 288 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 280 289 " usbattach <uuid>|<address> |\n" 281 290 " usbdetach <uuid>|<address> |\n" -
trunk/src/VBox/Main/ConsoleImpl.cpp
r20384 r20521 30 30 # include <sys/types.h> 31 31 # include <sys/wait.h> 32 #ifndef VBOX_DYNAMIC_NET_ATTACH 32 33 # include <net/if.h> 34 #endif /* !VBOX_DYNAMIC_NET_ATTACH */ 33 35 # include <linux/if_tun.h> 34 36 # include <stdio.h> … … 89 91 # include <VBox/com/array.h> 90 92 #endif 93 94 #ifdef VBOX_DYNAMIC_NET_ATTACH 95 #include <VBox/intnet.h> 96 97 #if defined(RT_OS_LINUX) && defined(VBOX_WITH_NETFLT) 98 # include <unistd.h> 99 # include <sys/ioctl.h> 100 # include <sys/socket.h> 101 # include <linux/types.h> 102 # include <linux/if.h> 103 # include <linux/wireless.h> 104 #endif 105 106 #if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT) 107 # include <VBox/WinNetConfig.h> 108 # include <Ntddndis.h> 109 # include <devguid.h> 110 #endif 111 112 #if !defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT) 113 # include <HostNetworkInterfaceImpl.h> 114 # include <netif.h> 115 #endif 116 117 #include "DHCPServerRunner.h" 118 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 91 119 92 120 #include <set> … … 249 277 memset(&mapUSBLed, 0, sizeof(mapUSBLed)); 250 278 memset(&mapSharedFolderLed, 0, sizeof(mapSharedFolderLed)); 279 #ifdef VBOX_DYNAMIC_NET_ATTACH 280 memset(&meAttachmentType, 0, sizeof(meAttachmentType)); 281 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 251 282 252 283 return S_OK; … … 3181 3212 CheckComRCReturnRC (autoVMCaller.rc()); 3182 3213 3214 #ifdef VBOX_DYNAMIC_NET_ATTACH 3215 /* Get the current network attachment type */ 3216 HRESULT rc; 3217 NetworkAttachmentType_T eAttachmentType; 3218 3219 rc = aNetworkAdapter->COMGETTER (AttachmentType) (&eAttachmentType); 3220 ComAssertComRCRetRC (rc); 3221 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 3222 3183 3223 /* Get the properties we need from the adapter */ 3184 3224 BOOL fCableConnected; 3225 #ifdef VBOX_DYNAMIC_NET_ATTACH 3226 rc = aNetworkAdapter->COMGETTER(CableConnected) (&fCableConnected); 3227 #else /* !VBOX_DYNAMIC_NET_ATTACH */ 3185 3228 HRESULT rc = aNetworkAdapter->COMGETTER(CableConnected) (&fCableConnected); 3229 #endif /* !VBOX_DYNAMIC_NET_ATTACH */ 3186 3230 AssertComRC(rc); 3187 3231 if (SUCCEEDED(rc)) … … 3230 3274 } 3231 3275 3276 #ifdef VBOX_DYNAMIC_NET_ATTACH 3277 if (VBOX_SUCCESS (vrc) && 3278 !((eAttachmentType == meAttachmentType[ulInstance]) || 3279 (eAttachmentType == NetworkAttachmentType_Null && 3280 meAttachmentType[ulInstance] == NetworkAttachmentType_Null))) 3281 { 3282 rc = doNetworkAdapterChange(cszAdapterName, 3283 ulInstance, 0, 3284 eAttachmentType, 3285 &meAttachmentType[ulInstance], 3286 aNetworkAdapter); 3287 } 3288 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 3289 3232 3290 if (VBOX_FAILURE (vrc)) 3233 3291 rc = E_FAIL; … … 3246 3304 return rc; 3247 3305 } 3306 3307 3308 #ifdef VBOX_DYNAMIC_NET_ATTACH 3309 /** 3310 * Process a network adaptor change. 3311 * 3312 * @returns COM status code. 3313 * 3314 * @param pszDevice The PDM device name. 3315 * @param uInstance The PDM device instance. 3316 * @param uLun The PDM LUN number of the drive. 3317 * @param aAttachmentType The attachment type. 3318 * 3319 * @note Locks this object for writing. 3320 */ 3321 HRESULT Console::doNetworkAdapterChange (const char *pszDevice, unsigned uInstance, 3322 unsigned uLun, NetworkAttachmentType_T eAttachmentType, 3323 NetworkAttachmentType_T *meAttachmentType, 3324 INetworkAdapter *aNetworkAdapter) 3325 { 3326 LogFlowThisFunc (("pszDevice=%p:{%s} uInstance=%u uLun=%u eAttachmentType=%d " 3327 "meAttachmentType=%p:{%d} aNetworkAdapter=%p\n", 3328 pszDevice, pszDevice, uInstance, uLun, eAttachmentType, 3329 meAttachmentType, *meAttachmentType, aNetworkAdapter)); 3330 3331 AutoCaller autoCaller (this); 3332 AssertComRCReturnRC (autoCaller.rc()); 3333 3334 /* We will need to release the write lock before calling EMT */ 3335 AutoWriteLock alock (this); 3336 3337 /* protect mpVM */ 3338 AutoVMCaller autoVMCaller (this); 3339 CheckComRCReturnRC (autoVMCaller.rc()); 3340 3341 /* 3342 * Call worker in EMT, that's faster and safer than doing everything 3343 * using VM3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait 3344 * here to make requests from under the lock in order to serialize them. 3345 */ 3346 PVMREQ pReq; 3347 int vrc = VMR3ReqCall (mpVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, 3348 (PFNRT) Console::changeNetworkAttachment, 7, 3349 this, pszDevice, uInstance, uLun, eAttachmentType, 3350 meAttachmentType, aNetworkAdapter); 3351 /// @todo (r=dmik) bird, it would be nice to have a special VMR3Req method 3352 // for that purpose, that doesn't return useless VERR_TIMEOUT 3353 if (vrc == VERR_TIMEOUT) 3354 vrc = VINF_SUCCESS; 3355 3356 /* leave the lock before waiting for a result (EMT will call us back!) */ 3357 alock.leave(); 3358 3359 if (VBOX_SUCCESS (vrc)) 3360 { 3361 vrc = VMR3ReqWait (pReq, RT_INDEFINITE_WAIT); 3362 AssertRC (vrc); 3363 if (VBOX_SUCCESS (vrc)) 3364 vrc = pReq->iStatus; 3365 } 3366 VMR3ReqFree (pReq); 3367 3368 if (VBOX_SUCCESS (vrc)) 3369 { 3370 LogFlowThisFunc (("Returns S_OK\n")); 3371 return S_OK; 3372 } 3373 3374 return setError (E_FAIL, 3375 tr ("Could not change the network adaptor attachement type (%Rrc)"), vrc); 3376 } 3377 3378 3379 /** 3380 * Performs the Network Adaptor change in EMT. 3381 * 3382 * @returns VBox status code. 3383 * 3384 * @param pThis Pointer to the Console object. 3385 * @param pszDevice The PDM device name. 3386 * @param uInstance The PDM device instance. 3387 * @param uLun The PDM LUN number of the drive. 3388 * @param aAttachmentType The attachment type. 3389 * 3390 * @thread EMT 3391 * @note Locks the Console object for writing. 3392 */ 3393 DECLCALLBACK(int) Console::changeNetworkAttachment (Console *pThis, const char *pszDevice, 3394 unsigned uInstance, unsigned uLun, 3395 NetworkAttachmentType_T eAttachmentType, 3396 NetworkAttachmentType_T *meAttachmentType, 3397 INetworkAdapter *aNetworkAdapter) 3398 { 3399 LogFlowFunc (("pThis=%p pszDevice=%p:{%s} uInstance=%u uLun=%u eAttachmentType=%d " 3400 "meAttachmentType=%p{%d} aNetworkAdapter=%p\n", 3401 pThis, pszDevice, pszDevice, uInstance, uLun, eAttachmentType, 3402 meAttachmentType, *meAttachmentType, aNetworkAdapter)); 3403 3404 AssertReturn (pThis, VERR_INVALID_PARAMETER); 3405 3406 AssertMsg ( (!strcmp (pszDevice, "pcnet") && uLun == 0 && uInstance < 8) 3407 || (!strcmp (pszDevice, "e1000") && uLun == 0 && uInstance < 8), 3408 ("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance)); 3409 Log(("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance)); 3410 3411 AutoCaller autoCaller (pThis); 3412 AssertComRCReturn (autoCaller.rc(), VERR_ACCESS_DENIED); 3413 3414 /* 3415 * Locking the object before doing VMR3* calls is quite safe here, since 3416 * we're on EMT. Write lock is necessary because we indirectly modify the 3417 * meAttachmentType member. 3418 */ 3419 AutoWriteLock alock (pThis); 3420 3421 /* protect mpVM */ 3422 AutoVMCaller autoVMCaller (pThis); 3423 CheckComRCReturnRC (autoVMCaller.rc()); 3424 3425 PVM pVM = pThis->mpVM; 3426 3427 /* 3428 * Suspend the VM first. 3429 * 3430 * The VM must not be running since it might have pending I/O to 3431 * the drive which is being changed. 3432 */ 3433 bool fResume; 3434 VMSTATE enmVMState = VMR3GetState (pVM); 3435 switch (enmVMState) 3436 { 3437 case VMSTATE_RESETTING: 3438 case VMSTATE_RUNNING: 3439 { 3440 LogFlowFunc (("Suspending the VM...\n")); 3441 /* disable the callback to prevent Console-level state change */ 3442 pThis->mVMStateChangeCallbackDisabled = true; 3443 int rc = VMR3Suspend (pVM); 3444 pThis->mVMStateChangeCallbackDisabled = false; 3445 AssertRCReturn (rc, rc); 3446 fResume = true; 3447 break; 3448 } 3449 3450 case VMSTATE_SUSPENDED: 3451 case VMSTATE_CREATED: 3452 case VMSTATE_OFF: 3453 fResume = false; 3454 break; 3455 3456 default: 3457 AssertMsgFailedReturn (("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED); 3458 } 3459 3460 int rc = VINF_SUCCESS; 3461 int rcRet = VINF_SUCCESS; 3462 3463 #define STR_CONV() do { rc = RTUtf16ToUtf8(str, &psz); RC_CHECK(); } while (0) 3464 #define STR_FREE() do { if (str) { SysFreeString(str); str = NULL; } if (psz) { RTStrFree(psz); psz = NULL; } } while (0) 3465 #define RC_CHECK() do { if (RT_FAILURE(rc)) { AssertMsgFailed(("rc=%Rrc\n", rc)); rcRet = rc; goto rcfailed; } } while (0) 3466 #define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%#x\n", hrc)); rcRet = VERR_GENERAL_FAILURE; goto rcfailed; } } while (0) 3467 do 3468 { 3469 HRESULT hrc; 3470 ComPtr <IMachine> pMachine = pThis->machine(); 3471 3472 ComPtr<IVirtualBox> virtualBox; 3473 hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam()); 3474 H(); 3475 3476 ComPtr<IHost> host; 3477 hrc = virtualBox->COMGETTER(Host)(host.asOutParam()); 3478 H(); 3479 3480 BSTR str = NULL; 3481 char *psz = NULL; 3482 3483 /* 3484 * Detach the device train for the current network attachment. 3485 */ 3486 rc = PDMR3DeviceDetach (pVM, pszDevice, uInstance, uLun); 3487 if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN) 3488 rc = VINF_SUCCESS; 3489 AssertRC (rc); 3490 3491 PCFGMNODE pCfg = NULL; /* /Devices/Dev/.../Config/ */ 3492 PCFGMNODE pLunL0 = NULL; /* /Devices/Dev/0/LUN#0/ */ 3493 PCFGMNODE pInst = CFGMR3GetChildF (CFGMR3GetRoot (pVM), "Devices/%s/%d/", pszDevice, uInstance); 3494 AssertRelease (pInst); 3495 3496 /* nuke anything which might have been left behind. */ 3497 CFGMR3RemoveNode (CFGMR3GetChildF (pInst, "LUN#%d", uLun)); 3498 3499 /* 3500 * Enable the packet sniffer if requested. 3501 */ 3502 BOOL fSniffer; 3503 hrc = aNetworkAdapter->COMGETTER(TraceEnabled)(&fSniffer); 3504 H(); 3505 if (fSniffer) 3506 { 3507 /* insert the sniffer filter driver. */ 3508 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); 3509 RC_CHECK(); 3510 rc = CFGMR3InsertString(pLunL0, "Driver", "NetSniffer"); 3511 RC_CHECK(); 3512 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); 3513 RC_CHECK(); 3514 hrc = aNetworkAdapter->COMGETTER(TraceFile)(&str); 3515 H(); 3516 if (str) /* check convention for indicating default file. */ 3517 { 3518 STR_CONV(); 3519 rc = CFGMR3InsertString(pCfg, "File", psz); 3520 RC_CHECK(); 3521 STR_FREE(); 3522 } 3523 } 3524 3525 Bstr networkName, trunkName, trunkType; 3526 switch (eAttachmentType) 3527 { 3528 case NetworkAttachmentType_Null: 3529 break; 3530 3531 case NetworkAttachmentType_NAT: 3532 { 3533 if (fSniffer) 3534 { 3535 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); 3536 RC_CHECK(); 3537 } 3538 else 3539 { 3540 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); 3541 RC_CHECK(); 3542 } 3543 3544 rc = CFGMR3InsertString(pLunL0, "Driver", "NAT"); 3545 RC_CHECK(); 3546 3547 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); 3548 RC_CHECK(); 3549 3550 /* Configure TFTP prefix and boot filename. */ 3551 hrc = virtualBox->COMGETTER(HomeFolder)(&str); 3552 H(); 3553 STR_CONV(); 3554 if (psz && *psz) 3555 { 3556 char *pszTFTPPrefix = NULL; 3557 RTStrAPrintf(&pszTFTPPrefix, "%s%c%s", psz, RTPATH_DELIMITER, "TFTP"); 3558 rc = CFGMR3InsertString(pCfg, "TFTPPrefix", pszTFTPPrefix); 3559 RC_CHECK(); 3560 RTStrFree(pszTFTPPrefix); 3561 } 3562 STR_FREE(); 3563 hrc = pMachine->COMGETTER(Name)(&str); 3564 H(); 3565 STR_CONV(); 3566 char *pszBootFile = NULL; 3567 RTStrAPrintf(&pszBootFile, "%s.pxe", psz); 3568 STR_FREE(); 3569 rc = CFGMR3InsertString(pCfg, "BootFile", pszBootFile); 3570 RC_CHECK(); 3571 RTStrFree(pszBootFile); 3572 3573 hrc = aNetworkAdapter->COMGETTER(NATNetwork)(&str); 3574 H(); 3575 if (str) 3576 { 3577 STR_CONV(); 3578 if (psz && *psz) 3579 { 3580 rc = CFGMR3InsertString(pCfg, "Network", psz); 3581 RC_CHECK(); 3582 /* NAT uses its own DHCP implementation */ 3583 //networkName = Bstr(psz); 3584 } 3585 3586 STR_FREE(); 3587 } 3588 break; 3589 } 3590 3591 case NetworkAttachmentType_Bridged: 3592 { 3593 #if !defined(VBOX_WITH_NETFLT) && defined(RT_OS_LINUX) 3594 Assert ((int)pConsole->maTapFD[ulInstance] >= 0); 3595 if ((int)pConsole->maTapFD[ulInstance] >= 0) 3596 { 3597 if (fSniffer) 3598 { 3599 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); 3600 RC_CHECK(); 3601 } 3602 else 3603 { 3604 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); 3605 RC_CHECK(); 3606 } 3607 rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface"); 3608 RC_CHECK(); 3609 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); 3610 RC_CHECK(); 3611 rc = CFGMR3InsertInteger(pCfg, "FileHandle", pConsole->maTapFD[ulInstance]); 3612 RC_CHECK(); 3613 } 3614 #elif defined(VBOX_WITH_NETFLT) 3615 /* 3616 * This is the new VBoxNetFlt+IntNet stuff. 3617 */ 3618 if (fSniffer) 3619 { 3620 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); 3621 RC_CHECK(); 3622 } 3623 else 3624 { 3625 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); 3626 RC_CHECK(); 3627 } 3628 3629 Bstr HifName; 3630 hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam()); 3631 if(FAILED(hrc)) 3632 { 3633 LogRel(("NetworkAttachmentType_Bridged: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc)); 3634 H(); 3635 } 3636 3637 Utf8Str HifNameUtf8(HifName); 3638 const char *pszHifName = HifNameUtf8.raw(); 3639 3640 # if defined(RT_OS_DARWIN) 3641 /* The name is on the form 'ifX: long name', chop it off at the colon. */ 3642 char szTrunk[8]; 3643 strncpy(szTrunk, pszHifName, sizeof(szTrunk)); 3644 char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk)); 3645 if (!pszColon) 3646 { 3647 hrc = networkAdapter->Detach(); 3648 H(); 3649 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS, 3650 N_("Malformed host interface networking name '%ls'"), 3651 HifName.raw()); 3652 } 3653 *pszColon = '\0'; 3654 const char *pszTrunk = szTrunk; 3655 3656 # elif defined(RT_OS_SOLARIS) 3657 /* The name is on the form format 'ifX[:1] - long name, chop it off at space. */ 3658 char szTrunk[256]; 3659 strlcpy(szTrunk, pszHifName, sizeof(szTrunk)); 3660 char *pszSpace = (char *)memchr(szTrunk, ' ', sizeof(szTrunk)); 3661 3662 /* 3663 * Currently don't bother about malformed names here for the sake of people using 3664 * VBoxManage and setting only the NIC name from there. If there is a space we 3665 * chop it off and proceed, otherwise just use whatever we've got. 3666 */ 3667 if (pszSpace) 3668 *pszSpace = '\0'; 3669 3670 /* Chop it off at the colon (zone naming eg: e1000g:1 we need only the e1000g) */ 3671 char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk)); 3672 if (pszColon) 3673 *pszColon = '\0'; 3674 3675 const char *pszTrunk = szTrunk; 3676 3677 # elif defined(RT_OS_WINDOWS) 3678 ComPtr<IHostNetworkInterface> hostInterface; 3679 rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam()); 3680 if (!SUCCEEDED(rc)) 3681 { 3682 AssertBreakpoint(); 3683 LogRel(("NetworkAttachmentType_Bridged: FindByName failed, rc (0x%x)", rc)); 3684 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS, 3685 N_("Inexistent host networking interface, name '%ls'"), 3686 HifName.raw()); 3687 } 3688 3689 HostNetworkInterfaceType_T ifType; 3690 hrc = hostInterface->COMGETTER(InterfaceType)(&ifType); 3691 if(FAILED(hrc)) 3692 { 3693 LogRel(("NetworkAttachmentType_Bridged: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc)); 3694 H(); 3695 } 3696 3697 if(ifType != HostNetworkInterfaceType_Bridged) 3698 { 3699 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS, 3700 N_("Interface ('%ls') is not a Bridged Adapter interface"), 3701 HifName.raw()); 3702 } 3703 3704 Bstr hostIFGuid_; 3705 hrc = hostInterface->COMGETTER(Id)(hostIFGuid_.asOutParam()); 3706 if(FAILED(hrc)) 3707 { 3708 LogRel(("NetworkAttachmentType_Bridged: COMGETTER(Id) failed, hrc (0x%x)", hrc)); 3709 H(); 3710 } 3711 Guid hostIFGuid(hostIFGuid_); 3712 3713 INetCfg *pNc; 3714 ComPtr<INetCfgComponent> pAdaptorComponent; 3715 LPWSTR lpszApp; 3716 int rc = VERR_INTNET_FLT_IF_NOT_FOUND; 3717 3718 hrc = VBoxNetCfgWinQueryINetCfg( FALSE, 3719 L"VirtualBox", 3720 &pNc, 3721 &lpszApp ); 3722 Assert(hrc == S_OK); 3723 if(hrc == S_OK) 3724 { 3725 /* get the adapter's INetCfgComponent*/ 3726 hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam()); 3727 if(hrc != S_OK) 3728 { 3729 VBoxNetCfgWinReleaseINetCfg( pNc, FALSE ); 3730 LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc)); 3731 H(); 3732 } 3733 } 3734 #define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\" 3735 char szTrunkName[INTNET_MAX_TRUNK_NAME]; 3736 char *pszTrunkName = szTrunkName; 3737 wchar_t * pswzBindName; 3738 hrc = pAdaptorComponent->GetBindName(&pswzBindName); 3739 Assert(hrc == S_OK); 3740 if (hrc == S_OK) 3741 { 3742 int cwBindName = (int)wcslen(pswzBindName) + 1; 3743 int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX); 3744 if(sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName) 3745 { 3746 strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX); 3747 pszTrunkName += cbFullBindNamePrefix-1; 3748 if(!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName, 3749 sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL)) 3750 { 3751 Assert(0); 3752 DWORD err = GetLastError(); 3753 hrc = HRESULT_FROM_WIN32(err); 3754 AssertMsgFailed(("%hrc=%Rhrc %#x\n", hrc, hrc)); 3755 LogRel(("NetworkAttachmentType_Bridged: WideCharToMultiByte failed, hr=%Rhrc (0x%x)\n", hrc, hrc)); 3756 } 3757 } 3758 else 3759 { 3760 Assert(0); 3761 LogRel(("NetworkAttachmentType_Bridged: insufficient szTrunkName buffer space\n")); 3762 /** @todo set appropriate error code */ 3763 hrc = E_FAIL; 3764 } 3765 3766 if(hrc != S_OK) 3767 { 3768 Assert(0); 3769 CoTaskMemFree(pswzBindName); 3770 VBoxNetCfgWinReleaseINetCfg( pNc, FALSE ); 3771 H(); 3772 } 3773 3774 /* we're not freeing the bind name since we'll use it later for detecting wireless*/ 3775 } 3776 else 3777 { 3778 Assert(0); 3779 VBoxNetCfgWinReleaseINetCfg( pNc, FALSE ); 3780 LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc)); 3781 H(); 3782 } 3783 const char *pszTrunk = szTrunkName; 3784 /* we're not releasing the INetCfg stuff here since we use it later to figure out whether it is wireless */ 3785 3786 # elif defined(RT_OS_LINUX) 3787 /* @todo Check for malformed names. */ 3788 const char *pszTrunk = pszHifName; 3789 3790 # else 3791 # error "PORTME (VBOX_WITH_NETFLT)" 3792 # endif 3793 3794 rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet"); 3795 RC_CHECK(); 3796 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); 3797 RC_CHECK(); 3798 rc = CFGMR3InsertString(pCfg, "Trunk", pszTrunk); 3799 RC_CHECK(); 3800 rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt); 3801 RC_CHECK(); 3802 char szNetwork[80]; 3803 RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName); 3804 rc = CFGMR3InsertString(pCfg, "Network", szNetwork); 3805 RC_CHECK(); 3806 networkName = Bstr(szNetwork); 3807 trunkName = Bstr(pszTrunk); 3808 trunkType = Bstr(TRUNKTYPE_NETFLT); 3809 3810 # if defined(RT_OS_DARWIN) 3811 /** @todo Come up with a better deal here. Problem is that IHostNetworkInterface is completely useless here. */ 3812 if ( strstr(pszHifName, "Wireless") 3813 || strstr(pszHifName, "AirPort" )) 3814 { 3815 rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true); 3816 RC_CHECK(); 3817 } 3818 # elif defined(RT_OS_LINUX) 3819 int iSock = socket(AF_INET, SOCK_DGRAM, 0); 3820 if (iSock >= 0) 3821 { 3822 struct iwreq WRq; 3823 3824 memset(&WRq, 0, sizeof(WRq)); 3825 strncpy(WRq.ifr_name, pszHifName, IFNAMSIZ); 3826 if (ioctl(iSock, SIOCGIWNAME, &WRq) >= 0) 3827 { 3828 rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true); 3829 RC_CHECK(); 3830 Log(("Set SharedMacOnWire\n")); 3831 } 3832 else 3833 { 3834 Log(("Failed to get wireless name\n")); 3835 } 3836 close(iSock); 3837 } 3838 else 3839 { 3840 Log(("Failed to open wireless socket\n")); 3841 } 3842 # elif defined(RT_OS_WINDOWS) 3843 # define DEVNAME_PREFIX L"\\\\.\\" 3844 /* we are getting the medium type via IOCTL_NDIS_QUERY_GLOBAL_STATS Io Control 3845 * there is a pretty long way till there though since we need to obtain the symbolic link name 3846 * for the adapter device we are going to query given the device Guid */ 3847 3848 3849 /* prepend the "\\\\.\\" to the bind name to obtain the link name */ 3850 3851 wchar_t FileName[MAX_PATH]; 3852 wcscpy(FileName, DEVNAME_PREFIX); 3853 wcscpy((wchar_t*)(((char*)FileName) + sizeof(DEVNAME_PREFIX) - sizeof(FileName[0])), pswzBindName); 3854 3855 /* open the device */ 3856 HANDLE hDevice = CreateFile(FileName, 3857 GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 3858 NULL, 3859 OPEN_EXISTING, 3860 FILE_ATTRIBUTE_NORMAL, 3861 NULL); 3862 3863 if (hDevice != INVALID_HANDLE_VALUE) 3864 { 3865 /* now issue the OID_GEN_PHYSICAL_MEDIUM query */ 3866 DWORD Oid = OID_GEN_PHYSICAL_MEDIUM; 3867 NDIS_PHYSICAL_MEDIUM PhMedium; 3868 DWORD cbResult; 3869 if (DeviceIoControl(hDevice, 3870 IOCTL_NDIS_QUERY_GLOBAL_STATS, 3871 &Oid, 3872 sizeof(Oid), 3873 &PhMedium, 3874 sizeof(PhMedium), 3875 &cbResult, 3876 NULL)) 3877 { 3878 /* that was simple, now examine PhMedium */ 3879 if ( PhMedium == NdisPhysicalMediumWirelessWan 3880 || PhMedium == NdisPhysicalMediumWirelessLan 3881 || PhMedium == NdisPhysicalMediumNative802_11 3882 || PhMedium == NdisPhysicalMediumBluetooth) 3883 { 3884 Log(("this is a wireless adapter")); 3885 rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true); 3886 RC_CHECK(); 3887 Log(("Set SharedMacOnWire\n")); 3888 } 3889 else 3890 { 3891 Log(("this is NOT a wireless adapter")); 3892 } 3893 } 3894 else 3895 { 3896 int winEr = GetLastError(); 3897 LogRel(("Console::configConstructor: DeviceIoControl failed, err (0x%x), ignoring\n", winEr)); 3898 Assert(winEr == ERROR_INVALID_PARAMETER || winEr == ERROR_NOT_SUPPORTED || winEr == ERROR_BAD_COMMAND); 3899 } 3900 3901 CloseHandle(hDevice); 3902 } 3903 else 3904 { 3905 int winEr = GetLastError(); 3906 LogRel(("Console::configConstructor: CreateFile failed, err (0x%x), ignoring\n", winEr)); 3907 AssertBreakpoint(); 3908 } 3909 3910 CoTaskMemFree(pswzBindName); 3911 3912 pAdaptorComponent.setNull(); 3913 /* release the pNc finally */ 3914 VBoxNetCfgWinReleaseINetCfg( pNc, FALSE ); 3915 # else 3916 /** @todo PORTME: wireless detection */ 3917 # endif 3918 3919 # if defined(RT_OS_SOLARIS) 3920 # if 0 /* bird: this is a bit questionable and might cause more trouble than its worth. */ 3921 /* Zone access restriction, don't allow snopping the global zone. */ 3922 zoneid_t ZoneId = getzoneid(); 3923 if (ZoneId != GLOBAL_ZONEID) 3924 { 3925 rc = CFGMR3InsertInteger(pCfg, "IgnoreAllPromisc", true); RC_CHECK(); 3926 } 3927 # endif 3928 # endif 3929 3930 #elif defined(RT_OS_WINDOWS) /* not defined NetFlt */ 3931 /* NOTHING TO DO HERE */ 3932 #elif defined(RT_OS_LINUX) 3933 /// @todo aleksey: is there anything to be done here? 3934 #elif defined(RT_OS_FREEBSD) 3935 /** @todo FreeBSD: Check out this later (HIF networking). */ 3936 #else 3937 # error "Port me" 3938 #endif 3939 break; 3940 } 3941 3942 case NetworkAttachmentType_Internal: 3943 { 3944 hrc = aNetworkAdapter->COMGETTER(InternalNetwork)(&str); 3945 H(); 3946 if (str) 3947 { 3948 STR_CONV(); 3949 if (psz && *psz) 3950 { 3951 if (fSniffer) 3952 { 3953 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); 3954 RC_CHECK(); 3955 } 3956 else 3957 { 3958 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); 3959 RC_CHECK(); 3960 } 3961 rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet"); 3962 RC_CHECK(); 3963 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); 3964 RC_CHECK(); 3965 rc = CFGMR3InsertString(pCfg, "Network", psz); 3966 RC_CHECK(); 3967 rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_WhateverNone); 3968 RC_CHECK(); 3969 networkName = Bstr(psz); 3970 trunkType = Bstr(TRUNKTYPE_WHATEVER); 3971 } 3972 STR_FREE(); 3973 } 3974 break; 3975 } 3976 3977 case NetworkAttachmentType_HostOnly: 3978 { 3979 if (fSniffer) 3980 { 3981 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0); 3982 RC_CHECK(); 3983 } 3984 else 3985 { 3986 rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0); 3987 RC_CHECK(); 3988 } 3989 3990 rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet"); 3991 RC_CHECK(); 3992 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); 3993 RC_CHECK(); 3994 #if defined(RT_OS_WINDOWS) 3995 # ifndef VBOX_WITH_NETFLT 3996 hrc = E_NOTIMPL; 3997 LogRel(("NetworkAttachmentType_HostOnly: Not Implemented")); 3998 H(); 3999 # else 4000 Bstr HifName; 4001 hrc = networkAdapter->COMGETTER(HostInterface)(HifName.asOutParam()); 4002 if(FAILED(hrc)) 4003 { 4004 LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc)); 4005 H(); 4006 } 4007 4008 Utf8Str HifNameUtf8(HifName); 4009 const char *pszHifName = HifNameUtf8.raw(); 4010 ComPtr<IHostNetworkInterface> hostInterface; 4011 rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam()); 4012 if (!SUCCEEDED(rc)) 4013 { 4014 AssertBreakpoint(); 4015 LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)", rc)); 4016 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS, 4017 N_("Inexistent host networking interface, name '%ls'"), 4018 HifName.raw()); 4019 } 4020 4021 HostNetworkInterfaceType_T ifType; 4022 hrc = hostInterface->COMGETTER(InterfaceType)(&ifType); 4023 if(FAILED(hrc)) 4024 { 4025 LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc)); 4026 H(); 4027 } 4028 4029 if(ifType != HostNetworkInterfaceType_HostOnly) 4030 { 4031 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS, 4032 N_("Interface ('%ls') is not a Host-Only Adapter interface"), 4033 HifName.raw()); 4034 } 4035 4036 4037 Bstr hostIFGuid_; 4038 hrc = hostInterface->COMGETTER(Id)(hostIFGuid_.asOutParam()); 4039 if(FAILED(hrc)) 4040 { 4041 LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(Id) failed, hrc (0x%x)", hrc)); 4042 H(); 4043 } 4044 Guid hostIFGuid(hostIFGuid_); 4045 4046 INetCfg *pNc; 4047 ComPtr<INetCfgComponent> pAdaptorComponent; 4048 LPWSTR lpszApp; 4049 int rc = VERR_INTNET_FLT_IF_NOT_FOUND; 4050 4051 hrc = VBoxNetCfgWinQueryINetCfg(FALSE, 4052 L"VirtualBox", 4053 &pNc, 4054 &lpszApp); 4055 Assert(hrc == S_OK); 4056 if(hrc == S_OK) 4057 { 4058 /* get the adapter's INetCfgComponent*/ 4059 hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam()); 4060 if(hrc != S_OK) 4061 { 4062 VBoxNetCfgWinReleaseINetCfg( pNc, FALSE ); 4063 LogRel(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc)); 4064 H(); 4065 } 4066 } 4067 #define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\" 4068 char szTrunkName[INTNET_MAX_TRUNK_NAME]; 4069 char *pszTrunkName = szTrunkName; 4070 wchar_t * pswzBindName; 4071 hrc = pAdaptorComponent->GetBindName(&pswzBindName); 4072 Assert(hrc == S_OK); 4073 if (hrc == S_OK) 4074 { 4075 int cwBindName = (int)wcslen(pswzBindName) + 1; 4076 int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX); 4077 if(sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName) 4078 { 4079 strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX); 4080 pszTrunkName += cbFullBindNamePrefix-1; 4081 if(!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName, 4082 sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL)) 4083 { 4084 Assert(0); 4085 DWORD err = GetLastError(); 4086 hrc = HRESULT_FROM_WIN32(err); 4087 AssertMsgFailed(("%hrc=%Rhrc %#x\n", hrc, hrc)); 4088 LogRel(("NetworkAttachmentType_HostOnly: WideCharToMultiByte failed, hr=%Rhrc (0x%x)\n", hrc, hrc)); 4089 } 4090 } 4091 else 4092 { 4093 Assert(0); 4094 LogRel(("NetworkAttachmentType_HostOnly: insufficient szTrunkName buffer space\n")); 4095 /** @todo set appropriate error code */ 4096 hrc = E_FAIL; 4097 } 4098 4099 if(hrc != S_OK) 4100 { 4101 Assert(0); 4102 CoTaskMemFree(pswzBindName); 4103 VBoxNetCfgWinReleaseINetCfg( pNc, FALSE ); 4104 H(); 4105 } 4106 } 4107 else 4108 { 4109 Assert(0); 4110 VBoxNetCfgWinReleaseINetCfg( pNc, FALSE ); 4111 LogRel(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc)); 4112 H(); 4113 } 4114 4115 4116 CoTaskMemFree(pswzBindName); 4117 4118 pAdaptorComponent.setNull(); 4119 /* release the pNc finally */ 4120 VBoxNetCfgWinReleaseINetCfg( pNc, FALSE ); 4121 4122 const char *pszTrunk = szTrunkName; 4123 4124 4125 /* TODO: set the proper Trunk and Network values, currently the driver uses the first adapter instance */ 4126 rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp); 4127 RC_CHECK(); 4128 rc = CFGMR3InsertString(pCfg, "Trunk", pszTrunk); 4129 RC_CHECK(); 4130 char szNetwork[80]; 4131 RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName); 4132 rc = CFGMR3InsertString(pCfg, "Network", szNetwork); 4133 RC_CHECK(); 4134 networkName = Bstr(szNetwork); 4135 trunkName = Bstr(pszTrunk); 4136 trunkType = TRUNKTYPE_NETADP; 4137 # endif /* defined VBOX_WITH_NETFLT*/ 4138 #elif defined(RT_OS_DARWIN) 4139 rc = CFGMR3InsertString(pCfg, "Trunk", "vboxnet0"); 4140 RC_CHECK(); 4141 rc = CFGMR3InsertString(pCfg, "Network", "HostInterfaceNetworking-vboxnet0"); 4142 RC_CHECK(); 4143 rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp); 4144 RC_CHECK(); 4145 networkName = Bstr("HostInterfaceNetworking-vboxnet0"); 4146 trunkName = Bstr("vboxnet0"); 4147 trunkType = TRUNKTYPE_NETADP; 4148 #else 4149 rc = CFGMR3InsertString(pCfg, "Trunk", "vboxnet0"); 4150 RC_CHECK(); 4151 rc = CFGMR3InsertString(pCfg, "Network", "HostInterfaceNetworking-vboxnet0"); 4152 RC_CHECK(); 4153 rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt); 4154 RC_CHECK(); 4155 networkName = Bstr("HostInterfaceNetworking-vboxnet0"); 4156 trunkName = Bstr("vboxnet0"); 4157 trunkType = TRUNKTYPE_NETFLT; 4158 #endif 4159 #if !defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT) 4160 Bstr HifName; 4161 hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam()); 4162 if(FAILED(hrc)) 4163 { 4164 LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc)); 4165 H(); 4166 } 4167 4168 LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface): ", hrc)); 4169 Utf8Str HifNameUtf8(HifName); 4170 const char *pszHifName = HifNameUtf8.raw(); 4171 ComPtr<IHostNetworkInterface> hostInterface; 4172 rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam()); 4173 if (!SUCCEEDED(rc)) 4174 { 4175 LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)", rc)); 4176 return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS, 4177 N_("Inexistent host networking interface, name '%ls'"), 4178 HifName.raw()); 4179 } 4180 Bstr tmpAddr, tmpMask; 4181 hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPAddress"), tmpAddr.asOutParam()); 4182 if (SUCCEEDED(hrc) && !tmpAddr.isNull()) 4183 { 4184 hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPNetMask"), tmpMask.asOutParam()); 4185 if (SUCCEEDED(hrc) && !tmpAddr.isEmpty()) 4186 hrc = hostInterface->EnableStaticIpConfig(tmpAddr, tmpMask); 4187 } 4188 else 4189 hrc = hostInterface->EnableStaticIpConfig(Bstr(VBOXNET_IPV4ADDR_DEFAULT), 4190 Bstr(VBOXNET_IPV4MASK_DEFAULT)); 4191 4192 4193 hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPV6Address"), tmpAddr.asOutParam()); 4194 if (SUCCEEDED(hrc)) 4195 hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPV6NetMask"), tmpMask.asOutParam()); 4196 if (SUCCEEDED(hrc) && !tmpAddr.isEmpty()) 4197 hrc = hostInterface->EnableStaticIpConfigV6(tmpAddr, Utf8Str(tmpMask).toUInt32()); 4198 #endif 4199 break; 4200 } 4201 4202 default: 4203 AssertMsgFailed(("should not get here!\n")); 4204 break; 4205 } 4206 4207 /* 4208 * Attempt to attach the driver. 4209 */ 4210 switch (eAttachmentType) 4211 { 4212 case NetworkAttachmentType_Null: 4213 break; 4214 4215 case NetworkAttachmentType_Bridged: 4216 case NetworkAttachmentType_Internal: 4217 case NetworkAttachmentType_HostOnly: 4218 case NetworkAttachmentType_NAT: 4219 { 4220 if (SUCCEEDED(hrc) && SUCCEEDED(rc)) 4221 { 4222 rc = PDMR3DeviceAttach (pVM, pszDevice, uInstance, uLun, NULL); 4223 AssertRC (rc); 4224 4225 if(!networkName.isNull()) 4226 { 4227 /* 4228 * Until we implement service reference counters DHCP Server will be stopped 4229 * by DHCPServerRunner destructor. 4230 */ 4231 ComPtr<IDHCPServer> dhcpServer; 4232 hrc = virtualBox->FindDHCPServerByNetworkName(networkName.mutableRaw(), dhcpServer.asOutParam()); 4233 if(SUCCEEDED(hrc)) 4234 { 4235 /* there is a DHCP server available for this network */ 4236 BOOL bEnabled; 4237 hrc = dhcpServer->COMGETTER(Enabled)(&bEnabled); 4238 if(FAILED(hrc)) 4239 { 4240 LogRel(("DHCP svr: COMGETTER(Enabled) failed, hrc (0x%x)", hrc)); 4241 H(); 4242 } 4243 4244 if(bEnabled) 4245 hrc = dhcpServer->Start(networkName, trunkName, trunkType); 4246 } 4247 else 4248 { 4249 hrc = S_OK; 4250 } 4251 } 4252 } 4253 4254 break; 4255 } 4256 4257 default: 4258 AssertMsgFailed(("should not get here!\n")); 4259 break; 4260 } 4261 4262 *meAttachmentType = eAttachmentType; 4263 } 4264 while (0); 4265 4266 #undef STR_FREE 4267 #undef STR_CONV 4268 #undef H 4269 #undef RC_CHECK 4270 4271 rcfailed: 4272 /* 4273 * Resume the VM if necessary. 4274 */ 4275 if (fResume) 4276 { 4277 LogFlowFunc (("Resuming the VM...\n")); 4278 /* disable the callback to prevent Console-level state change */ 4279 pThis->mVMStateChangeCallbackDisabled = true; 4280 rc = VMR3Resume (pVM); 4281 pThis->mVMStateChangeCallbackDisabled = false; 4282 AssertRC (rc); 4283 if (VBOX_FAILURE (rc)) 4284 { 4285 /* too bad, we failed. try to sync the console state with the VMM state */ 4286 vmstateChangeCallback (pVM, VMSTATE_SUSPENDED, enmVMState, pThis); 4287 } 4288 /// @todo (r=dmik) if we failed with drive mount, then the VMR3Resume 4289 // error (if any) will be hidden from the caller. For proper reporting 4290 // of such multiple errors to the caller we need to enhance the 4291 // IVirtualBoxError interface. For now, give the first error the higher 4292 // priority. 4293 if (VBOX_SUCCESS (rcRet)) 4294 rcRet = rc; 4295 } 4296 4297 LogFlowFunc (("Returning %Rrc\n", rcRet)); 4298 return rcRet; 4299 } 4300 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 4301 3248 4302 3249 4303 /** -
trunk/src/VBox/Main/ConsoleImpl2.cpp
r20501 r20521 1364 1364 { 1365 1365 case NetworkAttachmentType_Null: 1366 #ifdef VBOX_DYNAMIC_NET_ATTACH 1367 pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Null; 1368 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 1366 1369 break; 1367 1370 … … 1412 1415 STR_FREE(); 1413 1416 } 1417 #ifdef VBOX_DYNAMIC_NET_ATTACH 1418 pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_NAT; 1419 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 1414 1420 break; 1415 1421 } … … 1745 1751 # error "Port me" 1746 1752 #endif 1753 #ifdef VBOX_DYNAMIC_NET_ATTACH 1754 pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Bridged; 1755 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 1747 1756 } 1748 1757 else … … 1793 1802 STR_FREE(); 1794 1803 } 1804 #ifdef VBOX_DYNAMIC_NET_ATTACH 1805 pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Internal; 1806 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 1795 1807 break; 1796 1808 } … … 2004 2016 hrc = hostInterface->EnableStaticIpConfigV6(tmpAddr, Utf8Str(tmpMask).toUInt32()); 2005 2017 #endif 2018 #ifdef VBOX_DYNAMIC_NET_ATTACH 2019 pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_HostOnly; 2020 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 2006 2021 break; 2007 2022 } -
trunk/src/VBox/Main/Makefile.kmk
r20501 r20521 563 563 VBoxC_DEFS += VBOX_WITH_VIDEOHWACCEL 564 564 endif 565 566 ifdef VBOX_DYNAMIC_NET_ATTACH 567 VBoxC_DEFS += VBOX_DYNAMIC_NET_ATTACH 568 endif 569 565 570 VBoxC_DEFS.darwin.x86 = VBOX_WITH_2X_4GB_ADDR_SPACE 566 571 VBoxC_DEFS.win.x86 += _WIN32_WINNT=0x0500 -
trunk/src/VBox/Main/include/ConsoleImpl.h
r19239 r20521 27 27 #include "VirtualBoxBase.h" 28 28 #include "ProgressImpl.h" 29 30 #ifdef VBOX_DYNAMIC_NET_ATTACH 31 # include "SchemaDefs.h" 32 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 29 33 30 34 class Guest; … … 439 443 DriveState_T eState, DriveState_T *peState, 440 444 const char *pszPath, bool fPassthrough); 445 #ifdef VBOX_DYNAMIC_NET_ATTACH 446 HRESULT doNetworkAdapterChange (const char *pszDevice, unsigned uInstance, 447 unsigned uLun, NetworkAttachmentType_T eAttachmentType, 448 NetworkAttachmentType_T *meAttachmentType, 449 INetworkAdapter *aNetworkAdapter); 450 static DECLCALLBACK(int) changeNetworkAttachment (Console *pThis, const char *pszDevice, 451 unsigned uInstance, unsigned uLun, 452 NetworkAttachmentType_T eAttachmentType, 453 NetworkAttachmentType_T *meAttachmentType, 454 INetworkAdapter *aNetworkAdapter); 455 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 441 456 442 457 #ifdef VBOX_WITH_USB … … 539 554 * This does not have to match the state maintained in the Floppy. */ 540 555 DriveState_T meFloppyState; 556 #ifdef VBOX_DYNAMIC_NET_ATTACH 557 /** The current network attachment type in the VM. 558 * This does not have to match the state maintained in the NetworkAdapter. */ 559 NetworkAttachmentType_T meAttachmentType[SchemaDefs::NetworkAdapterCount]; 560 #endif /* VBOX_DYNAMIC_NET_ATTACH */ 541 561 542 562 VMMDev * const mVMMDev;
Note:
See TracChangeset
for help on using the changeset viewer.