Index: trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- trunk/src/VBox/Devices/Makefile.kmk	(revision 20519)
+++ trunk/src/VBox/Devices/Makefile.kmk	(revision 20521)
@@ -286,4 +286,8 @@
 	Serial/DevSerial.cpp \
 	Parallel/DevParallel.cpp
+
+ifdef VBOX_DYNAMIC_NET_ATTACH
+ DevicesR3_DEFS += VBOX_DYNAMIC_NET_ATTACH
+endif
 
 ifdef VBOX_WITH_E1000
@@ -466,4 +470,8 @@
 	Parallel/DevParallel.cpp
 
+ifdef VBOX_DYNAMIC_NET_ATTACH
+ VBoxDDGC_DEFS += VBOX_DYNAMIC_NET_ATTACH
+endif
+
 ifdef VBOX_WITH_E1000
  VBoxDDGC_DEFS         += VBOX_WITH_E1000
@@ -548,4 +556,8 @@
 	Serial/DevSerial.cpp \
 	Parallel/DevParallel.cpp
+
+ifdef VBOX_DYNAMIC_NET_ATTACH
+ VBoxDDR0_DEFS += VBOX_DYNAMIC_NET_ATTACH
+endif
 
 ifdef VBOX_WITH_E1000
Index: trunk/src/VBox/Devices/Network/DevPCNet.cpp
===================================================================
--- trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 20519)
+++ trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 20521)
@@ -4651,4 +4651,101 @@
 
 
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+/**
+ * Detach notification.
+ *
+ * One network card at one port has been unplugged.
+ * The VM is suspended at this point.
+ *
+ * @param   pDevIns     The device instance.
+ * @param   iLUN        The logical unit which is being detached.
+ */
+static DECLCALLBACK(void) pcnetDetach(PPDMDEVINS pDevIns, unsigned iLUN)
+{
+    PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
+
+    Log(("%s:\n", __FUNCTION__));
+
+    int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+    AssertReleaseRC(rc);
+
+    /* @todo: r=pritesh still need to check if i missed
+     * to clean something in this function
+     */
+
+    /*
+     * Zero some important members.
+     */
+    pThis->pDrvBase = NULL;
+    pThis->pDrv = NULL;
+
+    PDMCritSectLeave(&pThis->CritSect);
+}
+
+
+/**
+ * Attach the Network attachment.
+ *
+ * @returns VBox status code.
+ * @param   pDevIns     The device instance.
+ * @param   iLUN        The logical unit which is being detached.
+ */
+static DECLCALLBACK(int)  pcnetAttach(PPDMDEVINS pDevIns, unsigned iLUN)
+{
+    PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
+    int         rc    = VINF_SUCCESS;
+
+    Log(("%s:\n", __FUNCTION__));
+
+    rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+    AssertReleaseRC(rc);
+
+    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Network Port");
+    if (RT_SUCCESS(rc))
+    {
+        if (rc == VINF_NAT_DNS)
+        {
+#ifdef RT_OS_LINUX
+            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
+                                       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"));
+#else
+            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
+                                       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"));
+#endif
+        }
+        pThis->pDrv = (PPDMINETWORKCONNECTOR)
+            pThis->pDrvBase->pfnQueryInterface(pThis->pDrvBase, PDMINTERFACE_NETWORK_CONNECTOR);
+        if (!pThis->pDrv)
+        {
+            AssertMsgFailed(("Failed to obtain the PDMINTERFACE_NETWORK_CONNECTOR interface!\n"));
+            return VERR_PDM_MISSING_INTERFACE_BELOW;
+        }
+    }
+    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+        Log(("No attached driver!\n"));
+    else
+        return rc;
+
+    /*
+     * Temporary set the link down if it was up so that the guest
+     * will know that we have change the configuration of the
+     * network card
+     */
+    if (pThis->fLinkUp)
+    {
+        pThis->fLinkTempDown = true;
+        pThis->cLinkDownReported = 0;
+        pThis->aCSR[0] |= RT_BIT(15) | RT_BIT(13); /* ERR | CERR (this is probably wrong) */
+        pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1;
+        TMTimerSetMillies(pThis->pTimerRestore, 20000);
+    }
+    PDMCritSectLeave(&pThis->CritSect);
+
+    return rc;
+
+}
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
+
+
 /**
  * @copydoc FNPDMDEVSUSPEND
@@ -5163,8 +5260,15 @@
     /* pfnResume */
     NULL,
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+    /* pfnAttach */
+    pcnetAttach,
+    /* pfnDetach */
+    pcnetDetach,
+#else /* !VBOX_DYNAMIC_NET_ATTACH */
     /* pfnAttach */
     NULL,
     /* pfnDetach */
     NULL,
+#endif /* !VBOX_DYNAMIC_NET_ATTACH */
     /* pfnQueryInterface. */
     NULL,
Index: trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk	(revision 20519)
+++ trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk	(revision 20521)
@@ -47,4 +47,7 @@
  	$(if $(VBOX_WITH_HOSTNETIF_API), VBOX_WITH_HOSTNETIF_API)
  VBoxManage_DEFS.win   = _WIN32_WINNT=0x0500
+ifdef VBOX_DYNAMIC_NET_ATTACH
+ VBoxManage_DEFS += VBOX_DYNAMIC_NET_ATTACH
+endif
 ifdef VBOX_WITH_NETFLT
  VBoxManage_DEFS += VBOX_WITH_NETFLT
Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 20519)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 20521)
@@ -751,4 +751,95 @@
             }
         }
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+        else if (!strncmp(a->argv[1], "nic", 3))
+        {
+            /* Get the number of network adapters */
+            ULONG NetworkAdapterCount = 0;
+            ComPtr <ISystemProperties> info;
+            CHECK_ERROR_BREAK (a->virtualBox, COMGETTER(SystemProperties) (info.asOutParam()));
+            CHECK_ERROR_BREAK (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount));
+
+            unsigned n = parseNum(&a->argv[1][3], NetworkAdapterCount, "NIC");
+            if (!n)
+            {
+                rc = E_FAIL;
+                break;
+            }
+            if (a->argc <= 1 + 1)
+            {
+                errorArgument("Missing argument to '%s'", a->argv[1]);
+                rc = E_FAIL;
+                break;
+            }
+
+            /* get the corresponding network adapter */
+            ComPtr<INetworkAdapter> adapter;
+            CHECK_ERROR_BREAK (sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+            if (adapter)
+            {
+                if (!strcmp(a->argv[2], "none"))
+                {
+                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (FALSE), 1);
+                }
+                else if (!strcmp(a->argv[2], "null"))
+                {
+                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
+                    CHECK_ERROR_RET(adapter, Detach(), 1);
+                }
+                else if (!strcmp(a->argv[2], "nat"))
+                {
+                    if (a->argc == 3)
+                        CHECK_ERROR_RET(adapter, COMSETTER(NATNetwork)(Bstr(a->argv[3])), 1);
+                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
+                    CHECK_ERROR_RET(adapter, AttachToNAT(), 1);
+                }
+                else if (  !strcmp(a->argv[2], "bridged")
+                        || !strcmp(a->argv[2], "hostif")) /* backward compatibility */
+                {
+                    if (a->argc <= 1 + 2)
+                    {
+                        errorArgument("Missing argument to '%s'", a->argv[2]);
+                        rc = E_FAIL;
+                        break;
+                    }
+                    CHECK_ERROR_RET(adapter, COMSETTER(HostInterface)(Bstr(a->argv[3])), 1);
+                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
+                    CHECK_ERROR_RET(adapter, AttachToBridgedInterface(), 1);
+                }
+                else if (!strcmp(a->argv[2], "intnet"))
+                {
+                    if (a->argc <= 1 + 2)
+                    {
+                        errorArgument("Missing argument to '%s'", a->argv[2]);
+                        rc = E_FAIL;
+                        break;
+                    }
+                    CHECK_ERROR_RET(adapter, COMSETTER(InternalNetwork)(Bstr(a->argv[3])), 1);
+                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
+                    CHECK_ERROR_RET(adapter, AttachToInternalNetwork(), 1);
+                }
+#if defined(VBOX_WITH_NETFLT)
+                else if (!strcmp(a->argv[2], "hostonly"))
+                {
+                    if (a->argc <= 1 + 2)
+                    {
+                        errorArgument("Missing argument to '%s'", a->argv[2]);
+                        rc = E_FAIL;
+                        break;
+                    }
+                    CHECK_ERROR_RET(adapter, COMSETTER(HostInterface)(Bstr(a->argv[3])), 1);
+                    CHECK_ERROR_RET(adapter, COMSETTER(Enabled) (TRUE), 1);
+                    CHECK_ERROR_RET(adapter, AttachToHostOnlyInterface(), 1);
+                }
+#endif
+                else
+                {
+                    errorArgument("Invalid type '%s' specfied for NIC %lu", Utf8Str(a->argv[2]).raw(), n + 1);
+                    rc = E_FAIL;
+                    break;
+                }
+            }
+        }
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
 #ifdef VBOX_WITH_VRDP
         else if (!strcmp(a->argv[1], "vrdp"))
Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 20519)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 20521)
@@ -278,4 +278,13 @@
                  "                            injectnmi|\n"
                  "                            setlinkstate<1-N> on|off |\n"
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+#if defined(VBOX_WITH_NETFLT)
+                 "                            nic<1-N> none|null|nat|bridged|intnet|hostonly\n"
+                 "                                     [<devicename>] |\n"
+#else /* !RT_OS_LINUX && !RT_OS_DARWIN */
+                 "                            nic<1-N> none|null|nat|bridged|intnet\n"
+                 "                                     [<devicename>] |\n"
+#endif /* !RT_OS_LINUX && !RT_OS_DARWIN  */
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
                  "                            usbattach <uuid>|<address> |\n"
                  "                            usbdetach <uuid>|<address> |\n"
Index: trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 20519)
+++ trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 20521)
@@ -30,5 +30,7 @@
 #   include <sys/types.h>
 #   include <sys/wait.h>
+#ifndef VBOX_DYNAMIC_NET_ATTACH
 #   include <net/if.h>
+#endif /* !VBOX_DYNAMIC_NET_ATTACH */
 #   include <linux/if_tun.h>
 #   include <stdio.h>
@@ -89,4 +91,30 @@
 # include <VBox/com/array.h>
 #endif
+
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+#include <VBox/intnet.h>
+
+#if defined(RT_OS_LINUX) && defined(VBOX_WITH_NETFLT)
+# include <unistd.h>
+# include <sys/ioctl.h>
+# include <sys/socket.h>
+# include <linux/types.h>
+# include <linux/if.h>
+# include <linux/wireless.h>
+#endif
+
+#if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
+# include <VBox/WinNetConfig.h>
+# include <Ntddndis.h>
+# include <devguid.h>
+#endif
+
+#if !defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
+# include <HostNetworkInterfaceImpl.h>
+# include <netif.h>
+#endif
+
+#include "DHCPServerRunner.h"
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
 
 #include <set>
@@ -249,4 +277,7 @@
     memset(&mapUSBLed, 0, sizeof(mapUSBLed));
     memset(&mapSharedFolderLed, 0, sizeof(mapSharedFolderLed));
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+    memset(&meAttachmentType, 0, sizeof(meAttachmentType));
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
 
     return S_OK;
@@ -3181,7 +3212,20 @@
     CheckComRCReturnRC (autoVMCaller.rc());
 
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+    /* Get the current network attachment type */
+    HRESULT rc;
+    NetworkAttachmentType_T eAttachmentType;
+
+    rc = aNetworkAdapter->COMGETTER (AttachmentType) (&eAttachmentType);
+    ComAssertComRCRetRC (rc);
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
+
     /* Get the properties we need from the adapter */
     BOOL fCableConnected;
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+    rc = aNetworkAdapter->COMGETTER(CableConnected) (&fCableConnected);
+#else /* !VBOX_DYNAMIC_NET_ATTACH */
     HRESULT rc = aNetworkAdapter->COMGETTER(CableConnected) (&fCableConnected);
+#endif /* !VBOX_DYNAMIC_NET_ATTACH */
     AssertComRC(rc);
     if (SUCCEEDED(rc))
@@ -3230,4 +3274,18 @@
             }
 
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+            if (VBOX_SUCCESS (vrc) &&
+                !((eAttachmentType == meAttachmentType[ulInstance]) ||
+                  (eAttachmentType == NetworkAttachmentType_Null &&
+                   meAttachmentType[ulInstance] == NetworkAttachmentType_Null)))
+            {
+                rc = doNetworkAdapterChange(cszAdapterName,
+                                            ulInstance, 0,
+                                            eAttachmentType,
+                                            &meAttachmentType[ulInstance],
+                                            aNetworkAdapter);
+            }
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
+
             if (VBOX_FAILURE (vrc))
                 rc = E_FAIL;
@@ -3246,4 +3304,1000 @@
     return rc;
 }
+
+
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+/**
+ * Process a network adaptor change.
+ *
+ * @returns COM status code.
+ *
+ * @param   pszDevice       The PDM device name.
+ * @param   uInstance       The PDM device instance.
+ * @param   uLun            The PDM LUN number of the drive.
+ * @param   aAttachmentType The attachment type.
+ *
+ * @note Locks this object for writing.
+ */
+HRESULT Console::doNetworkAdapterChange (const char *pszDevice, unsigned uInstance,
+                                         unsigned uLun, NetworkAttachmentType_T eAttachmentType,
+                                         NetworkAttachmentType_T *meAttachmentType,
+                                         INetworkAdapter *aNetworkAdapter)
+{
+    LogFlowThisFunc (("pszDevice=%p:{%s} uInstance=%u uLun=%u eAttachmentType=%d "
+                      "meAttachmentType=%p:{%d} aNetworkAdapter=%p\n",
+                      pszDevice, pszDevice, uInstance, uLun, eAttachmentType,
+                      meAttachmentType, *meAttachmentType, aNetworkAdapter));
+
+    AutoCaller autoCaller (this);
+    AssertComRCReturnRC (autoCaller.rc());
+
+    /* We will need to release the write lock before calling EMT */
+    AutoWriteLock alock (this);
+
+    /* protect mpVM */
+    AutoVMCaller autoVMCaller (this);
+    CheckComRCReturnRC (autoVMCaller.rc());
+
+    /*
+     * Call worker in EMT, that's faster and safer than doing everything
+     * using VM3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
+     * here to make requests from under the lock in order to serialize them.
+     */
+    PVMREQ pReq;
+    int vrc = VMR3ReqCall (mpVM, VMCPUID_ANY, &pReq, 0 /* no wait! */,
+                           (PFNRT) Console::changeNetworkAttachment, 7,
+                           this, pszDevice, uInstance, uLun, eAttachmentType,
+                           meAttachmentType, aNetworkAdapter);
+    /// @todo (r=dmik) bird, it would be nice to have a special VMR3Req method
+    //  for that purpose, that doesn't return useless VERR_TIMEOUT
+    if (vrc == VERR_TIMEOUT)
+        vrc = VINF_SUCCESS;
+
+    /* leave the lock before waiting for a result (EMT will call us back!) */
+    alock.leave();
+
+    if (VBOX_SUCCESS (vrc))
+    {
+        vrc = VMR3ReqWait (pReq, RT_INDEFINITE_WAIT);
+        AssertRC (vrc);
+        if (VBOX_SUCCESS (vrc))
+            vrc = pReq->iStatus;
+    }
+    VMR3ReqFree (pReq);
+
+    if (VBOX_SUCCESS (vrc))
+    {
+        LogFlowThisFunc (("Returns S_OK\n"));
+        return S_OK;
+    }
+
+    return setError (E_FAIL,
+        tr ("Could not change the network adaptor attachement type (%Rrc)"), vrc);
+}
+
+
+/**
+ * Performs the Network Adaptor change in EMT.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pThis           Pointer to the Console object.
+ * @param   pszDevice       The PDM device name.
+ * @param   uInstance       The PDM device instance.
+ * @param   uLun            The PDM LUN number of the drive.
+ * @param   aAttachmentType The attachment type.
+ *
+ * @thread  EMT
+ * @note Locks the Console object for writing.
+ */
+DECLCALLBACK(int) Console::changeNetworkAttachment (Console *pThis, const char *pszDevice,
+                                                    unsigned uInstance, unsigned uLun,
+                                                    NetworkAttachmentType_T eAttachmentType,
+                                                    NetworkAttachmentType_T *meAttachmentType,
+                                                    INetworkAdapter *aNetworkAdapter)
+{
+    LogFlowFunc (("pThis=%p pszDevice=%p:{%s} uInstance=%u uLun=%u eAttachmentType=%d "
+                  "meAttachmentType=%p{%d} aNetworkAdapter=%p\n",
+                  pThis, pszDevice, pszDevice, uInstance, uLun, eAttachmentType,
+                  meAttachmentType, *meAttachmentType, aNetworkAdapter));
+
+    AssertReturn (pThis, VERR_INVALID_PARAMETER);
+
+    AssertMsg (   (!strcmp (pszDevice, "pcnet") && uLun == 0 && uInstance < 8)
+               || (!strcmp (pszDevice, "e1000") && uLun == 0 && uInstance < 8),
+               ("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
+    Log(("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
+
+    AutoCaller autoCaller (pThis);
+    AssertComRCReturn (autoCaller.rc(), VERR_ACCESS_DENIED);
+
+    /*
+     * Locking the object before doing VMR3* calls is quite safe here, since
+     * we're on EMT. Write lock is necessary because we indirectly modify the
+     * meAttachmentType member.
+     */
+    AutoWriteLock alock (pThis);
+
+    /* protect mpVM */
+    AutoVMCaller autoVMCaller (pThis);
+    CheckComRCReturnRC (autoVMCaller.rc());
+
+    PVM pVM = pThis->mpVM;
+
+    /*
+     * Suspend the VM first.
+     *
+     * The VM must not be running since it might have pending I/O to
+     * the drive which is being changed.
+     */
+    bool fResume;
+    VMSTATE enmVMState = VMR3GetState (pVM);
+    switch (enmVMState)
+    {
+        case VMSTATE_RESETTING:
+        case VMSTATE_RUNNING:
+        {
+            LogFlowFunc (("Suspending the VM...\n"));
+            /* disable the callback to prevent Console-level state change */
+            pThis->mVMStateChangeCallbackDisabled = true;
+            int rc = VMR3Suspend (pVM);
+            pThis->mVMStateChangeCallbackDisabled = false;
+            AssertRCReturn (rc, rc);
+            fResume = true;
+            break;
+        }
+
+        case VMSTATE_SUSPENDED:
+        case VMSTATE_CREATED:
+        case VMSTATE_OFF:
+            fResume = false;
+            break;
+
+        default:
+            AssertMsgFailedReturn (("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED);
+    }
+
+    int rc = VINF_SUCCESS;
+    int rcRet = VINF_SUCCESS;
+
+#define STR_CONV()  do { rc = RTUtf16ToUtf8(str, &psz); RC_CHECK(); } while (0)
+#define STR_FREE()  do { if (str) { SysFreeString(str); str = NULL; } if (psz) { RTStrFree(psz); psz = NULL; } } while (0)
+#define RC_CHECK()  do { if (RT_FAILURE(rc)) { AssertMsgFailed(("rc=%Rrc\n", rc)); rcRet = rc; goto rcfailed; } } while (0)
+#define H()         do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%#x\n", hrc)); rcRet = VERR_GENERAL_FAILURE; goto rcfailed; } } while (0)
+    do
+    {
+        HRESULT hrc;
+        ComPtr <IMachine> pMachine = pThis->machine();
+
+        ComPtr<IVirtualBox> virtualBox;
+        hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam());
+        H();
+
+        ComPtr<IHost> host;
+        hrc = virtualBox->COMGETTER(Host)(host.asOutParam());
+        H();
+
+        BSTR      str = NULL;
+        char     *psz = NULL;
+
+        /*
+         * Detach the device train for the current network attachment.
+         */
+        rc = PDMR3DeviceDetach (pVM, pszDevice, uInstance, uLun);
+        if (rc == VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN)
+            rc = VINF_SUCCESS;
+        AssertRC (rc);
+
+        PCFGMNODE pCfg = NULL;          /* /Devices/Dev/.../Config/ */
+        PCFGMNODE pLunL0 = NULL;        /* /Devices/Dev/0/LUN#0/ */
+        PCFGMNODE pInst = CFGMR3GetChildF (CFGMR3GetRoot (pVM), "Devices/%s/%d/", pszDevice, uInstance);
+        AssertRelease (pInst);
+
+        /* nuke anything which might have been left behind. */
+        CFGMR3RemoveNode (CFGMR3GetChildF (pInst, "LUN#%d", uLun));
+
+        /*
+         * Enable the packet sniffer if requested.
+         */
+        BOOL fSniffer;
+        hrc = aNetworkAdapter->COMGETTER(TraceEnabled)(&fSniffer);
+        H();
+        if (fSniffer)
+        {
+            /* insert the sniffer filter driver. */
+            rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
+            RC_CHECK();
+            rc = CFGMR3InsertString(pLunL0, "Driver", "NetSniffer");
+            RC_CHECK();
+            rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
+            RC_CHECK();
+            hrc = aNetworkAdapter->COMGETTER(TraceFile)(&str);
+            H();
+            if (str) /* check convention for indicating default file. */
+            {
+                STR_CONV();
+                rc = CFGMR3InsertString(pCfg, "File", psz);
+                RC_CHECK();
+                STR_FREE();
+            }
+        }
+
+        Bstr networkName, trunkName, trunkType;
+        switch (eAttachmentType)
+        {
+            case NetworkAttachmentType_Null:
+                break;
+
+            case NetworkAttachmentType_NAT:
+            {
+                if (fSniffer)
+                {
+                    rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
+                    RC_CHECK();
+                }
+                else
+                {
+                    rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
+                    RC_CHECK();
+                }
+
+                rc = CFGMR3InsertString(pLunL0, "Driver", "NAT");
+                RC_CHECK();
+
+                rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
+                RC_CHECK();
+
+                /* Configure TFTP prefix and boot filename. */
+                hrc = virtualBox->COMGETTER(HomeFolder)(&str);
+                H();
+                STR_CONV();
+                if (psz && *psz)
+                {
+                    char *pszTFTPPrefix = NULL;
+                    RTStrAPrintf(&pszTFTPPrefix, "%s%c%s", psz, RTPATH_DELIMITER, "TFTP");
+                    rc = CFGMR3InsertString(pCfg, "TFTPPrefix", pszTFTPPrefix);
+                    RC_CHECK();
+                    RTStrFree(pszTFTPPrefix);
+                }
+                STR_FREE();
+                hrc = pMachine->COMGETTER(Name)(&str);
+                H();
+                STR_CONV();
+                char *pszBootFile = NULL;
+                RTStrAPrintf(&pszBootFile, "%s.pxe", psz);
+                STR_FREE();
+                rc = CFGMR3InsertString(pCfg, "BootFile", pszBootFile);
+                RC_CHECK();
+                RTStrFree(pszBootFile);
+
+                hrc = aNetworkAdapter->COMGETTER(NATNetwork)(&str);
+                H();
+                if (str)
+                {
+                    STR_CONV();
+                    if (psz && *psz)
+                    {
+                        rc = CFGMR3InsertString(pCfg, "Network", psz);
+                        RC_CHECK();
+                        /* NAT uses its own DHCP implementation */
+                        //networkName = Bstr(psz);
+                    }
+
+                    STR_FREE();
+                }
+                break;
+            }
+
+            case NetworkAttachmentType_Bridged:
+            {
+#if !defined(VBOX_WITH_NETFLT) && defined(RT_OS_LINUX)
+                Assert ((int)pConsole->maTapFD[ulInstance] >= 0);
+                if ((int)pConsole->maTapFD[ulInstance] >= 0)
+                {
+                    if (fSniffer)
+                    {
+                        rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
+                        RC_CHECK();
+                    }
+                    else
+                    {
+                        rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
+                        RC_CHECK();
+                    }
+                    rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface");
+                    RC_CHECK();
+                    rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
+                    RC_CHECK();
+                    rc = CFGMR3InsertInteger(pCfg, "FileHandle", pConsole->maTapFD[ulInstance]);
+                    RC_CHECK();
+                }
+#elif defined(VBOX_WITH_NETFLT)
+                /*
+                 * This is the new VBoxNetFlt+IntNet stuff.
+                 */
+                if (fSniffer)
+                {
+                    rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
+                    RC_CHECK();
+                }
+                else
+                {
+                    rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
+                    RC_CHECK();
+                }
+
+                Bstr HifName;
+                hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
+                if(FAILED(hrc))
+                {
+                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
+                    H();
+                }
+
+                Utf8Str HifNameUtf8(HifName);
+                const char *pszHifName = HifNameUtf8.raw();
+
+# if defined(RT_OS_DARWIN)
+                /* The name is on the form 'ifX: long name', chop it off at the colon. */
+                char szTrunk[8];
+                strncpy(szTrunk, pszHifName, sizeof(szTrunk));
+                char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
+                if (!pszColon)
+                {
+                    hrc = networkAdapter->Detach();
+                    H();
+                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+                                      N_("Malformed host interface networking name '%ls'"),
+                                      HifName.raw());
+                }
+                *pszColon = '\0';
+                const char *pszTrunk = szTrunk;
+
+# elif defined(RT_OS_SOLARIS)
+                /* The name is on the form format 'ifX[:1] - long name, chop it off at space. */
+                char szTrunk[256];
+                strlcpy(szTrunk, pszHifName, sizeof(szTrunk));
+                char *pszSpace = (char *)memchr(szTrunk, ' ', sizeof(szTrunk));
+
+                /*
+                 * Currently don't bother about malformed names here for the sake of people using
+                 * VBoxManage and setting only the NIC name from there. If there is a space we
+                 * chop it off and proceed, otherwise just use whatever we've got.
+                 */
+                if (pszSpace)
+                    *pszSpace = '\0';
+
+                /* Chop it off at the colon (zone naming eg: e1000g:1 we need only the e1000g) */
+                char *pszColon = (char *)memchr(szTrunk, ':', sizeof(szTrunk));
+                if (pszColon)
+                    *pszColon = '\0';
+
+                const char *pszTrunk = szTrunk;
+
+# elif defined(RT_OS_WINDOWS)
+                ComPtr<IHostNetworkInterface> hostInterface;
+                rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
+                if (!SUCCEEDED(rc))
+                {
+                    AssertBreakpoint();
+                    LogRel(("NetworkAttachmentType_Bridged: FindByName failed, rc (0x%x)", rc));
+                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+                                      N_("Inexistent host networking interface, name '%ls'"),
+                                      HifName.raw());
+                }
+
+                HostNetworkInterfaceType_T ifType;
+                hrc = hostInterface->COMGETTER(InterfaceType)(&ifType);
+                if(FAILED(hrc))
+                {
+                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc));
+                    H();
+                }
+
+                if(ifType != HostNetworkInterfaceType_Bridged)
+                {
+                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+                                                          N_("Interface ('%ls') is not a Bridged Adapter interface"),
+                                                          HifName.raw());
+                }
+
+                Bstr hostIFGuid_;
+                hrc = hostInterface->COMGETTER(Id)(hostIFGuid_.asOutParam());
+                if(FAILED(hrc))
+                {
+                    LogRel(("NetworkAttachmentType_Bridged: COMGETTER(Id) failed, hrc (0x%x)", hrc));
+                    H();
+                }
+                Guid hostIFGuid(hostIFGuid_);
+
+                INetCfg              *pNc;
+                ComPtr<INetCfgComponent> pAdaptorComponent;
+                LPWSTR               lpszApp;
+                int rc = VERR_INTNET_FLT_IF_NOT_FOUND;
+
+                hrc = VBoxNetCfgWinQueryINetCfg( FALSE,
+                                   L"VirtualBox",
+                                   &pNc,
+                                   &lpszApp );
+                Assert(hrc == S_OK);
+                if(hrc == S_OK)
+                {
+                    /* get the adapter's INetCfgComponent*/
+                    hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam());
+                    if(hrc != S_OK)
+                    {
+                        VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
+                        LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
+                        H();
+                    }
+                }
+#define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
+                char szTrunkName[INTNET_MAX_TRUNK_NAME];
+                char *pszTrunkName = szTrunkName;
+                wchar_t * pswzBindName;
+                hrc = pAdaptorComponent->GetBindName(&pswzBindName);
+                Assert(hrc == S_OK);
+                if (hrc == S_OK)
+                {
+                    int cwBindName = (int)wcslen(pswzBindName) + 1;
+                    int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX);
+                    if(sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName)
+                    {
+                        strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX);
+                        pszTrunkName += cbFullBindNamePrefix-1;
+                        if(!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName,
+                                sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL))
+                        {
+                            Assert(0);
+                            DWORD err = GetLastError();
+                            hrc = HRESULT_FROM_WIN32(err);
+                            AssertMsgFailed(("%hrc=%Rhrc %#x\n", hrc, hrc));
+                            LogRel(("NetworkAttachmentType_Bridged: WideCharToMultiByte failed, hr=%Rhrc (0x%x)\n", hrc, hrc));
+                        }
+                    }
+                    else
+                    {
+                        Assert(0);
+                        LogRel(("NetworkAttachmentType_Bridged: insufficient szTrunkName buffer space\n"));
+                        /** @todo set appropriate error code */
+                        hrc = E_FAIL;
+                    }
+
+                    if(hrc != S_OK)
+                    {
+                        Assert(0);
+                        CoTaskMemFree(pswzBindName);
+                        VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
+                        H();
+                    }
+
+                    /* we're not freeing the bind name since we'll use it later for detecting wireless*/
+                }
+                else
+                {
+                    Assert(0);
+                    VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
+                    LogRel(("NetworkAttachmentType_Bridged: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
+                    H();
+                }
+                const char *pszTrunk = szTrunkName;
+                /* we're not releasing the INetCfg stuff here since we use it later to figure out whether it is wireless */
+
+# elif defined(RT_OS_LINUX)
+                /* @todo Check for malformed names. */
+                const char *pszTrunk = pszHifName;
+
+# else
+#  error "PORTME (VBOX_WITH_NETFLT)"
+# endif
+
+                rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");
+                RC_CHECK();
+                rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
+                RC_CHECK();
+                rc = CFGMR3InsertString(pCfg, "Trunk", pszTrunk);
+                RC_CHECK();
+                rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);
+                RC_CHECK();
+                char szNetwork[80];
+                RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
+                rc = CFGMR3InsertString(pCfg, "Network", szNetwork);
+                RC_CHECK();
+                networkName = Bstr(szNetwork);
+                trunkName = Bstr(pszTrunk);
+                trunkType = Bstr(TRUNKTYPE_NETFLT);
+
+# if defined(RT_OS_DARWIN)
+                /** @todo Come up with a better deal here. Problem is that IHostNetworkInterface is completely useless here. */
+                if (    strstr(pszHifName, "Wireless")
+                    ||  strstr(pszHifName, "AirPort" ))
+                {
+                    rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);
+                    RC_CHECK();
+                }
+# elif defined(RT_OS_LINUX)
+                int iSock = socket(AF_INET, SOCK_DGRAM, 0);
+                if (iSock >= 0)
+                {
+                    struct iwreq WRq;
+
+                    memset(&WRq, 0, sizeof(WRq));
+                    strncpy(WRq.ifr_name, pszHifName, IFNAMSIZ);
+                    if (ioctl(iSock, SIOCGIWNAME, &WRq) >= 0)
+                    {
+                        rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);
+                        RC_CHECK();
+                        Log(("Set SharedMacOnWire\n"));
+                    }
+                    else
+                    {
+                        Log(("Failed to get wireless name\n"));
+                    }
+                    close(iSock);
+                }
+                else
+                {
+                    Log(("Failed to open wireless socket\n"));
+                }
+# elif defined(RT_OS_WINDOWS)
+#  define DEVNAME_PREFIX L"\\\\.\\"
+                /* we are getting the medium type via IOCTL_NDIS_QUERY_GLOBAL_STATS Io Control
+                 * there is a pretty long way till there though since we need to obtain the symbolic link name
+                 * for the adapter device we are going to query given the device Guid */
+
+
+                /* prepend the "\\\\.\\" to the bind name to obtain the link name */
+
+                wchar_t FileName[MAX_PATH];
+                wcscpy(FileName, DEVNAME_PREFIX);
+                wcscpy((wchar_t*)(((char*)FileName) + sizeof(DEVNAME_PREFIX) - sizeof(FileName[0])), pswzBindName);
+
+                /* open the device */
+                HANDLE hDevice = CreateFile(FileName,
+                                            GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                            NULL,
+                                            OPEN_EXISTING,
+                                            FILE_ATTRIBUTE_NORMAL,
+                                            NULL);
+
+                if (hDevice != INVALID_HANDLE_VALUE)
+                {
+                    /* now issue the OID_GEN_PHYSICAL_MEDIUM query */
+                    DWORD Oid = OID_GEN_PHYSICAL_MEDIUM;
+                    NDIS_PHYSICAL_MEDIUM PhMedium;
+                    DWORD cbResult;
+                    if (DeviceIoControl(hDevice,
+                                        IOCTL_NDIS_QUERY_GLOBAL_STATS,
+                                        &Oid,
+                                        sizeof(Oid),
+                                        &PhMedium,
+                                        sizeof(PhMedium),
+                                        &cbResult,
+                                        NULL))
+                    {
+                        /* that was simple, now examine PhMedium */
+                        if (   PhMedium == NdisPhysicalMediumWirelessWan
+                            || PhMedium == NdisPhysicalMediumWirelessLan
+                            || PhMedium == NdisPhysicalMediumNative802_11
+                            || PhMedium == NdisPhysicalMediumBluetooth)
+                        {
+                            Log(("this is a wireless adapter"));
+                            rc = CFGMR3InsertInteger(pCfg, "SharedMacOnWire", true);
+                            RC_CHECK();
+                            Log(("Set SharedMacOnWire\n"));
+                        }
+                        else
+                        {
+                            Log(("this is NOT a wireless adapter"));
+                        }
+                    }
+                    else
+                    {
+                        int winEr = GetLastError();
+                        LogRel(("Console::configConstructor: DeviceIoControl failed, err (0x%x), ignoring\n", winEr));
+                        Assert(winEr == ERROR_INVALID_PARAMETER || winEr == ERROR_NOT_SUPPORTED || winEr == ERROR_BAD_COMMAND);
+                    }
+
+                    CloseHandle(hDevice);
+                }
+                else
+                {
+                    int winEr = GetLastError();
+                    LogRel(("Console::configConstructor: CreateFile failed, err (0x%x), ignoring\n", winEr));
+                    AssertBreakpoint();
+                }
+
+                CoTaskMemFree(pswzBindName);
+
+                pAdaptorComponent.setNull();
+                /* release the pNc finally */
+                VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
+# else
+                /** @todo PORTME: wireless detection */
+# endif
+
+# if defined(RT_OS_SOLARIS)
+#  if 0 /* bird: this is a bit questionable and might cause more trouble than its worth.  */
+                /* Zone access restriction, don't allow snopping the global zone. */
+                zoneid_t ZoneId = getzoneid();
+                if (ZoneId != GLOBAL_ZONEID)
+                {
+                    rc = CFGMR3InsertInteger(pCfg, "IgnoreAllPromisc", true);   RC_CHECK();
+                }
+#  endif
+# endif
+
+#elif defined(RT_OS_WINDOWS) /* not defined NetFlt */
+                /* NOTHING TO DO HERE */
+#elif defined(RT_OS_LINUX)
+/// @todo aleksey: is there anything to be done here?
+#elif defined(RT_OS_FREEBSD)
+/** @todo FreeBSD: Check out this later (HIF networking). */
+#else
+# error "Port me"
+#endif
+                break;
+            }
+
+            case NetworkAttachmentType_Internal:
+            {
+                hrc = aNetworkAdapter->COMGETTER(InternalNetwork)(&str);
+                H();
+                if (str)
+                {
+                    STR_CONV();
+                    if (psz && *psz)
+                    {
+                        if (fSniffer)
+                        {
+                            rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
+                            RC_CHECK();
+                        }
+                        else
+                        {
+                            rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
+                            RC_CHECK();
+                        }
+                        rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");
+                        RC_CHECK();
+                        rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
+                        RC_CHECK();
+                        rc = CFGMR3InsertString(pCfg, "Network", psz);
+                        RC_CHECK();
+                        rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_WhateverNone);
+                        RC_CHECK();
+                        networkName = Bstr(psz);
+                        trunkType = Bstr(TRUNKTYPE_WHATEVER);
+                    }
+                    STR_FREE();
+                }
+                break;
+            }
+
+            case NetworkAttachmentType_HostOnly:
+            {
+                if (fSniffer)
+                {
+                    rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);
+                    RC_CHECK();
+                }
+                else
+                {
+                    rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);
+                    RC_CHECK();
+                }
+
+                rc = CFGMR3InsertString(pLunL0, "Driver", "IntNet");
+                RC_CHECK();
+                rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);
+                RC_CHECK();
+#if defined(RT_OS_WINDOWS)
+# ifndef VBOX_WITH_NETFLT
+                hrc = E_NOTIMPL;
+                LogRel(("NetworkAttachmentType_HostOnly: Not Implemented"));
+                H();
+# else
+                Bstr HifName;
+                hrc = networkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
+                if(FAILED(hrc))
+                {
+                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
+                    H();
+                }
+
+                Utf8Str HifNameUtf8(HifName);
+                const char *pszHifName = HifNameUtf8.raw();
+                ComPtr<IHostNetworkInterface> hostInterface;
+                rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
+                if (!SUCCEEDED(rc))
+                {
+                    AssertBreakpoint();
+                    LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)", rc));
+                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+                                      N_("Inexistent host networking interface, name '%ls'"),
+                                      HifName.raw());
+                }
+
+                HostNetworkInterfaceType_T ifType;
+                hrc = hostInterface->COMGETTER(InterfaceType)(&ifType);
+                if(FAILED(hrc))
+                {
+                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(InterfaceType) failed, hrc (0x%x)", hrc));
+                    H();
+                }
+
+                if(ifType != HostNetworkInterfaceType_HostOnly)
+                {
+                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+                                      N_("Interface ('%ls') is not a Host-Only Adapter interface"),
+                                      HifName.raw());
+                }
+
+
+                Bstr hostIFGuid_;
+                hrc = hostInterface->COMGETTER(Id)(hostIFGuid_.asOutParam());
+                if(FAILED(hrc))
+                {
+                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(Id) failed, hrc (0x%x)", hrc));
+                    H();
+                }
+                Guid hostIFGuid(hostIFGuid_);
+
+                INetCfg *pNc;
+                ComPtr<INetCfgComponent> pAdaptorComponent;
+                LPWSTR lpszApp;
+                int rc = VERR_INTNET_FLT_IF_NOT_FOUND;
+
+                hrc = VBoxNetCfgWinQueryINetCfg(FALSE,
+                                                L"VirtualBox",
+                                                &pNc,
+                                                &lpszApp);
+                Assert(hrc == S_OK);
+                if(hrc == S_OK)
+                {
+                    /* get the adapter's INetCfgComponent*/
+                    hrc = VBoxNetCfgWinGetComponentByGuid(pNc, &GUID_DEVCLASS_NET, (GUID*)hostIFGuid.ptr(), pAdaptorComponent.asOutParam());
+                    if(hrc != S_OK)
+                    {
+                        VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
+                        LogRel(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
+                        H();
+                    }
+                }
+#define VBOX_WIN_BINDNAME_PREFIX "\\DEVICE\\"
+                char szTrunkName[INTNET_MAX_TRUNK_NAME];
+                char *pszTrunkName = szTrunkName;
+                wchar_t * pswzBindName;
+                hrc = pAdaptorComponent->GetBindName(&pswzBindName);
+                Assert(hrc == S_OK);
+                if (hrc == S_OK)
+                {
+                    int cwBindName = (int)wcslen(pswzBindName) + 1;
+                    int cbFullBindNamePrefix = sizeof(VBOX_WIN_BINDNAME_PREFIX);
+                    if(sizeof(szTrunkName) > cbFullBindNamePrefix + cwBindName)
+                    {
+                        strcpy(szTrunkName, VBOX_WIN_BINDNAME_PREFIX);
+                        pszTrunkName += cbFullBindNamePrefix-1;
+                        if(!WideCharToMultiByte(CP_ACP, 0, pswzBindName, cwBindName, pszTrunkName,
+                                sizeof(szTrunkName) - cbFullBindNamePrefix + 1, NULL, NULL))
+                        {
+                            Assert(0);
+                            DWORD err = GetLastError();
+                            hrc = HRESULT_FROM_WIN32(err);
+                            AssertMsgFailed(("%hrc=%Rhrc %#x\n", hrc, hrc));
+                            LogRel(("NetworkAttachmentType_HostOnly: WideCharToMultiByte failed, hr=%Rhrc (0x%x)\n", hrc, hrc));
+                        }
+                    }
+                    else
+                    {
+                        Assert(0);
+                        LogRel(("NetworkAttachmentType_HostOnly: insufficient szTrunkName buffer space\n"));
+                        /** @todo set appropriate error code */
+                        hrc = E_FAIL;
+                    }
+
+                    if(hrc != S_OK)
+                    {
+                        Assert(0);
+                        CoTaskMemFree(pswzBindName);
+                        VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
+                        H();
+                    }
+                }
+                else
+                {
+                    Assert(0);
+                    VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
+                    LogRel(("NetworkAttachmentType_HostOnly: VBoxNetCfgWinGetComponentByGuid failed, hrc (0x%x)", hrc));
+                    H();
+                }
+
+
+                CoTaskMemFree(pswzBindName);
+
+                pAdaptorComponent.setNull();
+                /* release the pNc finally */
+                VBoxNetCfgWinReleaseINetCfg( pNc, FALSE );
+
+                const char *pszTrunk = szTrunkName;
+
+
+                /* TODO: set the proper Trunk and Network values, currently the driver uses the first adapter instance */
+                rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);
+                RC_CHECK();
+                rc = CFGMR3InsertString(pCfg, "Trunk", pszTrunk);
+                RC_CHECK();
+                char szNetwork[80];
+                RTStrPrintf(szNetwork, sizeof(szNetwork), "HostInterfaceNetworking-%s", pszHifName);
+                rc = CFGMR3InsertString(pCfg, "Network", szNetwork);
+                RC_CHECK();
+                networkName = Bstr(szNetwork);
+                trunkName   = Bstr(pszTrunk);
+                trunkType   = TRUNKTYPE_NETADP;
+# endif /* defined VBOX_WITH_NETFLT*/
+#elif defined(RT_OS_DARWIN)
+                rc = CFGMR3InsertString(pCfg, "Trunk", "vboxnet0");
+                RC_CHECK();
+                rc = CFGMR3InsertString(pCfg, "Network", "HostInterfaceNetworking-vboxnet0");
+                RC_CHECK();
+                rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetAdp);
+                RC_CHECK();
+                networkName = Bstr("HostInterfaceNetworking-vboxnet0");
+                trunkName   = Bstr("vboxnet0");
+                trunkType   = TRUNKTYPE_NETADP;
+#else
+                rc = CFGMR3InsertString(pCfg, "Trunk", "vboxnet0");
+                RC_CHECK();
+                rc = CFGMR3InsertString(pCfg, "Network", "HostInterfaceNetworking-vboxnet0");
+                RC_CHECK();
+                rc = CFGMR3InsertInteger(pCfg, "TrunkType", kIntNetTrunkType_NetFlt);
+                RC_CHECK();
+                networkName = Bstr("HostInterfaceNetworking-vboxnet0");
+                trunkName   = Bstr("vboxnet0");
+                trunkType   = TRUNKTYPE_NETFLT;
+#endif
+#if !defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
+                Bstr HifName;
+                hrc = aNetworkAdapter->COMGETTER(HostInterface)(HifName.asOutParam());
+                if(FAILED(hrc))
+                {
+                    LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface) failed, hrc (0x%x)", hrc));
+                    H();
+                }
+
+                LogRel(("NetworkAttachmentType_HostOnly: COMGETTER(HostInterface):  ", hrc));
+                Utf8Str HifNameUtf8(HifName);
+                const char *pszHifName = HifNameUtf8.raw();
+                ComPtr<IHostNetworkInterface> hostInterface;
+                rc = host->FindHostNetworkInterfaceByName(HifName, hostInterface.asOutParam());
+                if (!SUCCEEDED(rc))
+                {
+                    LogRel(("NetworkAttachmentType_HostOnly: FindByName failed, rc (0x%x)", rc));
+                    return VMSetError(pVM, VERR_INTERNAL_ERROR, RT_SRC_POS,
+                                      N_("Inexistent host networking interface, name '%ls'"),
+                                      HifName.raw());
+                }
+                Bstr tmpAddr, tmpMask;
+                hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPAddress"), tmpAddr.asOutParam());
+                if (SUCCEEDED(hrc) && !tmpAddr.isNull())
+                {
+                    hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPNetMask"), tmpMask.asOutParam());
+                    if (SUCCEEDED(hrc) && !tmpAddr.isEmpty())
+                        hrc = hostInterface->EnableStaticIpConfig(tmpAddr, tmpMask);
+                }
+                else
+                    hrc = hostInterface->EnableStaticIpConfig(Bstr(VBOXNET_IPV4ADDR_DEFAULT),
+                                                              Bstr(VBOXNET_IPV4MASK_DEFAULT));
+
+
+                hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPV6Address"), tmpAddr.asOutParam());
+                if (SUCCEEDED(hrc))
+                    hrc = virtualBox->GetExtraData(Bstr("HostOnly/vboxnet0/IPV6NetMask"), tmpMask.asOutParam());
+                if (SUCCEEDED(hrc) && !tmpAddr.isEmpty())
+                    hrc = hostInterface->EnableStaticIpConfigV6(tmpAddr, Utf8Str(tmpMask).toUInt32());
+#endif
+                break;
+            }
+
+            default:
+                AssertMsgFailed(("should not get here!\n"));
+                break;
+        }
+
+        /*
+         * Attempt to attach the driver.
+         */
+        switch (eAttachmentType)
+        {
+            case NetworkAttachmentType_Null:
+                break;
+
+            case NetworkAttachmentType_Bridged:
+            case NetworkAttachmentType_Internal:
+            case NetworkAttachmentType_HostOnly:
+            case NetworkAttachmentType_NAT:
+            {
+                if (SUCCEEDED(hrc) && SUCCEEDED(rc))
+                {
+                    rc = PDMR3DeviceAttach (pVM, pszDevice, uInstance, uLun, NULL);
+                    AssertRC (rc);
+
+                    if(!networkName.isNull())
+                    {
+                        /*
+                         * Until we implement service reference counters DHCP Server will be stopped
+                         * by DHCPServerRunner destructor.
+                         */
+                        ComPtr<IDHCPServer> dhcpServer;
+                        hrc = virtualBox->FindDHCPServerByNetworkName(networkName.mutableRaw(), dhcpServer.asOutParam());
+                        if(SUCCEEDED(hrc))
+                        {
+                            /* there is a DHCP server available for this network */
+                            BOOL bEnabled;
+                            hrc = dhcpServer->COMGETTER(Enabled)(&bEnabled);
+                            if(FAILED(hrc))
+                            {
+                                LogRel(("DHCP svr: COMGETTER(Enabled) failed, hrc (0x%x)", hrc));
+                                H();
+                            }
+
+                            if(bEnabled)
+                                hrc = dhcpServer->Start(networkName, trunkName, trunkType);
+                        }
+                        else
+                        {
+                            hrc = S_OK;
+                        }
+                    }
+                }
+
+                break;
+            }
+
+            default:
+                AssertMsgFailed(("should not get here!\n"));
+                break;
+        }
+
+        *meAttachmentType = eAttachmentType;
+    }
+    while (0);
+
+#undef STR_FREE
+#undef STR_CONV
+#undef H
+#undef RC_CHECK
+
+rcfailed:
+    /*
+     * Resume the VM if necessary.
+     */
+    if (fResume)
+    {
+        LogFlowFunc (("Resuming the VM...\n"));
+        /* disable the callback to prevent Console-level state change */
+        pThis->mVMStateChangeCallbackDisabled = true;
+        rc = VMR3Resume (pVM);
+        pThis->mVMStateChangeCallbackDisabled = false;
+        AssertRC (rc);
+        if (VBOX_FAILURE (rc))
+        {
+            /* too bad, we failed. try to sync the console state with the VMM state */
+            vmstateChangeCallback (pVM, VMSTATE_SUSPENDED, enmVMState, pThis);
+        }
+        /// @todo (r=dmik) if we failed with drive mount, then the VMR3Resume
+        //  error (if any) will be hidden from the caller. For proper reporting
+        //  of such multiple errors to the caller we need to enhance the
+        //  IVirtualBoxError interface. For now, give the first error the higher
+        //  priority.
+        if (VBOX_SUCCESS (rcRet))
+            rcRet = rc;
+    }
+
+    LogFlowFunc (("Returning %Rrc\n", rcRet));
+    return rcRet;
+}
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
+
 
 /**
Index: trunk/src/VBox/Main/ConsoleImpl2.cpp
===================================================================
--- trunk/src/VBox/Main/ConsoleImpl2.cpp	(revision 20519)
+++ trunk/src/VBox/Main/ConsoleImpl2.cpp	(revision 20521)
@@ -1364,4 +1364,7 @@
         {
             case NetworkAttachmentType_Null:
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+                pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Null;
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
                 break;
 
@@ -1412,4 +1415,7 @@
                     STR_FREE();
                 }
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+                pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_NAT;
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
                 break;
             }
@@ -1745,4 +1751,7 @@
 # error "Port me"
 #endif
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+                    pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Bridged;
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
                 }
                 else
@@ -1793,4 +1802,7 @@
                     STR_FREE();
                 }
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+                pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_Internal;
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
                 break;
             }
@@ -2004,4 +2016,7 @@
                     hrc = hostInterface->EnableStaticIpConfigV6(tmpAddr, Utf8Str(tmpMask).toUInt32());
 #endif
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+                pConsole->meAttachmentType[ulInstance] = NetworkAttachmentType_HostOnly;
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
                 break;
             }
Index: trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- trunk/src/VBox/Main/Makefile.kmk	(revision 20519)
+++ trunk/src/VBox/Main/Makefile.kmk	(revision 20521)
@@ -563,4 +563,9 @@
 VBoxC_DEFS += VBOX_WITH_VIDEOHWACCEL
 endif
+
+ifdef VBOX_DYNAMIC_NET_ATTACH
+VBoxC_DEFS += VBOX_DYNAMIC_NET_ATTACH
+endif
+
 VBoxC_DEFS.darwin.x86 = VBOX_WITH_2X_4GB_ADDR_SPACE
 VBoxC_DEFS.win.x86 += _WIN32_WINNT=0x0500
Index: trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 20519)
+++ trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 20521)
@@ -27,4 +27,8 @@
 #include "VirtualBoxBase.h"
 #include "ProgressImpl.h"
+
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+# include "SchemaDefs.h"
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
 
 class Guest;
@@ -439,4 +443,15 @@
                                           DriveState_T eState, DriveState_T *peState,
                                           const char *pszPath, bool fPassthrough);
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+    HRESULT doNetworkAdapterChange (const char *pszDevice, unsigned uInstance,
+                                    unsigned uLun, NetworkAttachmentType_T eAttachmentType,
+                                    NetworkAttachmentType_T *meAttachmentType,
+                                    INetworkAdapter *aNetworkAdapter);
+    static DECLCALLBACK(int) changeNetworkAttachment (Console *pThis, const char *pszDevice,
+                                                      unsigned uInstance, unsigned uLun,
+                                                      NetworkAttachmentType_T eAttachmentType,
+                                                      NetworkAttachmentType_T *meAttachmentType,
+                                                      INetworkAdapter *aNetworkAdapter);
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
 
 #ifdef VBOX_WITH_USB
@@ -539,4 +554,9 @@
      * This does not have to match the state maintained in the Floppy. */
     DriveState_T meFloppyState;
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+    /** The current network attachment type in the VM.
+     * This does not have to match the state maintained in the NetworkAdapter. */
+    NetworkAttachmentType_T meAttachmentType[SchemaDefs::NetworkAdapterCount];
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
 
     VMMDev * const mVMMDev;
