VirtualBox

Changeset 33825 in vbox for trunk/src


Ignore:
Timestamp:
Nov 8, 2010 10:16:25 AM (14 years ago)
Author:
vboxsync
Message:

Main,NAT: Managing port-forwarding at runtime. (xTracker/#4835).

Location:
trunk/src/VBox
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r33540 r33825  
    131131    /** The network interface. */
    132132    PDMINETWORKUP           INetworkUp;
     133    /** The network NAT Engine configureation. */
     134    PDMINETWORKNATCONFIG    INetworkNATCfg;
    133135    /** The port we're attached to. */
    134136    PPDMINETWORKDOWN        pIAboveNet;
     
    650652}
    651653
     654static void drvNATNotifyApplyPortForwardCommand(PDRVNAT pThis,bool fRemove,
     655                                                const char *pNatRuleName, bool fUdp, const char *pHostIp,
     656                                                uint16_t u16HostPort, const char *pGuestIp, uint16_t u16GuestPort)
     657{
     658    RTMAC Mac;
     659    RT_ZERO(Mac); /* can't get MAC here */
     660    if (pThis->pIAboveConfig)
     661        pThis->pIAboveConfig->pfnGetMac(pThis->pIAboveConfig, &Mac);
     662
     663    struct in_addr guestIp, hostIp;
     664
     665    if (   pHostIp == NULL
     666        || inet_aton(pHostIp, &hostIp) == 0)
     667        hostIp.s_addr = INADDR_ANY;
     668
     669    if (   pGuestIp == NULL
     670        || inet_aton(pGuestIp, &guestIp) == 0)
     671        guestIp.s_addr = pThis->GuestIP;
     672
     673    if (fRemove)
     674        slirp_remove_redirect(pThis->pNATState, fUdp, hostIp, u16HostPort, guestIp, u16GuestPort);
     675    else
     676        slirp_add_redirect(pThis->pNATState, fUdp, hostIp, u16HostPort, guestIp, u16GuestPort, Mac.au8);
     677}
     678
     679DECLCALLBACK(int) drvNATNetworkNatConfig_RedirectRuleCommand(PPDMINETWORKNATCONFIG pInterface, bool fRemove,
     680                                                   const char *pNatRuleName, bool fUdp, const char *pHostIp,
     681                                                   uint16_t u16HostPort, const char *pGuestIp, uint16_t u16GuestPort)
     682{
     683    LogFlow(("drvNATNetworkNatConfig_ApplyNatCommand: cRules=%s\n", (pNatRuleName ? pNatRuleName: "")));
     684    PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkNATCfg);
     685    PRTREQ pReq;
     686    int rc = RTReqCallEx(pThis->pSlirpReqQueue, &pReq, 0 /*cMillies*/, RTREQFLAGS_VOID,
     687                         (PFNRT)drvNATNotifyApplyPortForwardCommand, 8, pThis, fRemove,
     688                          pNatRuleName, fUdp, pHostIp, u16HostPort, pGuestIp, u16GuestPort);
     689    if (RT_LIKELY(rc == VERR_TIMEOUT))
     690    {
     691        drvNATNotifyNATThread(pThis, "drvNATNetworkNatConfig_RedirectRuleCommand");
     692        rc = RTReqWait(pReq, RT_INDEFINITE_WAIT);
     693        AssertRC(rc);
     694    }
     695    else
     696        AssertRC(rc);
     697   
     698    RTReqFree(pReq);
     699    port_forwarding_done:
     700    return rc;
     701}
     702
    652703/**
    653704 * NAT thread handling the slirp stuff.
     
    896947    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
    897948    PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUp);
     949    PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKNATCONFIG, &pThis->INetworkNATCfg);
    898950    return NULL;
    899951}
     
    10061058        struct in_addr BindIP;
    10071059        GETIP_DEF(rc, pThis, pNode, BindIP, INADDR_ANY);
    1008         if (slirp_redir(pThis->pNATState, fUDP, BindIP, iHostPort, GuestIP, iGuestPort, Mac.au8) < 0)
     1060        if (slirp_add_redirect(pThis->pNATState, fUDP, BindIP, iHostPort, GuestIP, iGuestPort, Mac.au8) < 0)
    10091061            return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_NAT_REDIR_SETUP, RT_SRC_POS,
    10101062                                       N_("NAT#%d: configuration error: failed to set up "
     
    11111163    pThis->INetworkUp.pfnSetPromiscuousMode = drvNATNetworkUp_SetPromiscuousMode;
    11121164    pThis->INetworkUp.pfnNotifyLinkChanged  = drvNATNetworkUp_NotifyLinkChanged;
     1165
     1166    /* NAT engine configuration */
     1167    pThis->INetworkNATCfg.pfnRedirectRuleCommand = drvNATNetworkNatConfig_RedirectRuleCommand;
    11131168
    11141169    /*
  • trunk/src/VBox/Devices/Network/slirp/libslirp.h

    r30421 r33825  
    7272void slirp_post_sent(PNATState pData, void *pvArg);
    7373
    74 int slirp_redir(PNATState pData, int is_udp, struct in_addr host_addr,
     74int slirp_add_redirect(PNATState pData, int is_udp, struct in_addr host_addr,
    7575                int host_port, struct in_addr guest_addr,
    7676                int guest_port, const uint8_t *);
     77int slirp_remove_redirect(PNATState pData, int is_udp, struct in_addr host_addr,
     78                int host_port, struct in_addr guest_addr,
     79                int guest_port);
    7780int slirp_add_exec(PNATState pData, int do_pty, const char *args, int addr_low_byte,
    7881                   int guest_port);
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r32846 r33825  
    16571657
    16581658#if !defined(VBOX_WITH_NAT_SERVICE)
    1659         if (rule->guest_addr.s_addr != guest_addr)
     1659        if (   rule->guest_addr.s_addr != guest_addr
     1660            && rule->guest_addr.s_addr != INADDR_ANY)
    16601661            continue;
     1662        if (rule->guest_addr.s_addr == INADDR_ANY)
     1663            rule->guest_addr.s_addr = guest_addr;
    16611664#endif
    16621665
     
    17031706        so->so_la = lib;
    17041707        rule->activated = 1;
     1708        rule->so = so;
    17051709        pData->cRedirectionsActive++;
    17061710        continue;
     
    17271731 * corresponding port-forwarding
    17281732 */
    1729 int slirp_redir(PNATState pData, int is_udp, struct in_addr host_addr, int host_port,
     1733int slirp_add_redirect(PNATState pData, int is_udp, struct in_addr host_addr, int host_port,
    17301734                struct in_addr guest_addr, int guest_port, const uint8_t *ethaddr)
    17311735{
    17321736    struct port_forward_rule *rule = NULL;
    1733     Assert(memcmp(ethaddr, zerro_ethaddr, ETH_ALEN) == 0);
     1737    Assert(ethaddr);
     1738    LIST_FOREACH(rule, &pData->port_forward_rule_head, list)
     1739    {
     1740        if (   rule->proto == (is_udp ? IPPROTO_UDP : IPPROTO_TCP)
     1741            && rule->host_port == host_port
     1742            && rule->bind_ip.s_addr == host_addr.s_addr
     1743            && rule->guest_port == guest_port
     1744#ifndef VBOX_WITH_NAT_SERVICE
     1745            && rule->guest_addr.s_addr == guest_addr.s_addr
     1746#endif
     1747            )
     1748                return 0; /* rule has been already registered */
     1749    }
    17341750
    17351751    rule = RTMemAllocZ(sizeof(struct port_forward_rule));
     
    17481764    LIST_INSERT_HEAD(&pData->port_forward_rule_head, rule, list);
    17491765    pData->cRedirectionsStored++;
     1766    /* activate port-forwarding if guest has already got assigned IP */
     1767    if (memcmp(ethaddr, zerro_ethaddr, ETH_ALEN))
     1768        activate_port_forwarding(pData, ethaddr);
     1769    return 0;
     1770}
     1771
     1772int slirp_remove_redirect(PNATState pData, int is_udp, struct in_addr host_addr, int host_port,
     1773                struct in_addr guest_addr, int guest_port)
     1774{
     1775    struct port_forward_rule *rule = NULL;
     1776    LIST_FOREACH(rule, &pData->port_forward_rule_head, list)
     1777    {
     1778        if (   rule->proto == (is_udp ? IPPROTO_UDP : IPPROTO_TCP)
     1779            && rule->host_port == host_port
     1780            && rule->guest_port == guest_port
     1781            && rule->bind_ip.s_addr == host_addr.s_addr
     1782#ifndef VBOX_WITH_NAT_SERVICE
     1783            && rule->guest_addr.s_addr == guest_addr.s_addr
     1784#endif
     1785            && rule->activated)
     1786        {
     1787            LibAliasUninit(rule->so->so_la);
     1788            if (is_udp)
     1789            {
     1790                udp_detach(pData, rule->so);
     1791            }
     1792            else
     1793            {
     1794                tcp_close(pData, sototcpcb(rule->so));
     1795            }
     1796            LIST_REMOVE(rule, list);
     1797            RTMemFree(rule);
     1798            pData->cRedirectionsStored--;
     1799            break;
     1800        }
     1801       
     1802    }
    17501803    return 0;
    17511804}
     
    20192072        mtu = 1500;
    20202073    }
     2074    /* MTU is maximum transition unit on */
    20212075    if_mtu =
    20222076    if_mru = mtu;
  • trunk/src/VBox/Devices/Network/slirp/slirp_state.h

    r31097 r33825  
    8585    uint8_t mac_address[6]; /*need ETH_ALEN here */
    8686    int activated;
     87    struct socket *so;
    8788    LIST_ENTRY(port_forward_rule) list;
    8889};
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp

    r33590 r33825  
    394394            }
    395395        }
     396        else if(   a->argc > 2
     397                && !strncmp(a->argv[1], "natpf", 5))
     398        {
     399            /* Get the number of network adapters */
     400            ULONG NetworkAdapterCount = 0;
     401            ComPtr <ISystemProperties> info;
     402            ComPtr<INATEngine> engine;
     403            CHECK_ERROR_BREAK(a->virtualBox, COMGETTER(SystemProperties)(info.asOutParam()));
     404            CHECK_ERROR_BREAK(info, COMGETTER(NetworkAdapterCount)(&NetworkAdapterCount));
     405            unsigned n = parseNum(&a->argv[1][5], NetworkAdapterCount, "NIC");
     406            if (!n)
     407            {
     408                rc = E_FAIL;
     409                break;
     410            }
     411            if (a->argc <= 2)
     412            {
     413                errorArgument("Missing argument to '%s'", a->argv[1]);
     414                rc = E_FAIL;
     415                break;
     416            }
     417
     418            /* get the corresponding network adapter */
     419            ComPtr<INetworkAdapter> adapter;
     420            CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
     421            if (!adapter)
     422            {
     423                rc = E_FAIL;
     424                break;
     425            }
     426            CHECK_ERROR(adapter, COMGETTER(NatDriver)(engine.asOutParam()));
     427            if (!engine)
     428            {
     429                rc = E_FAIL;
     430                break;
     431            }
     432
     433            if (!strcmp(a->argv[2], "delete"))
     434            {
     435                if (a->argc >= 3)
     436                    CHECK_ERROR(engine, RemoveRedirect(Bstr(a->argv[3]).raw()));
     437            }
     438            else
     439            {
     440#define ITERATE_TO_NEXT_TERM(ch)                                           \
     441    do {                                                                   \
     442        while (*ch != ',')                                                 \
     443        {                                                                  \
     444            if (*ch == 0)                                                  \
     445            {                                                              \
     446                return errorSyntax(USAGE_CONTROLVM,                         \
     447                                   "Missing or Invalid argument to '%s'",  \
     448                                    a->argv[1]);                           \
     449            }                                                              \
     450            ch++;                                                          \
     451        }                                                                  \
     452        *ch = '\0';                                                        \
     453        ch++;                                                              \
     454    } while(0)
     455
     456                char *strName;
     457                char *strProto;
     458                char *strHostIp;
     459                char *strHostPort;
     460                char *strGuestIp;
     461                char *strGuestPort;
     462                char *strRaw = RTStrDup(a->argv[2]);
     463                char *ch = strRaw;
     464                strName = RTStrStrip(ch);
     465                ITERATE_TO_NEXT_TERM(ch);
     466                strProto = RTStrStrip(ch);
     467                ITERATE_TO_NEXT_TERM(ch);
     468                strHostIp = RTStrStrip(ch);
     469                ITERATE_TO_NEXT_TERM(ch);
     470                strHostPort = RTStrStrip(ch);
     471                ITERATE_TO_NEXT_TERM(ch);
     472                strGuestIp = RTStrStrip(ch);
     473                ITERATE_TO_NEXT_TERM(ch);
     474                strGuestPort = RTStrStrip(ch);
     475                NATProtocol_T proto;
     476                if (RTStrICmp(strProto, "udp") == 0)
     477                    proto = NATProtocol_UDP;
     478                else if (RTStrICmp(strProto, "tcp") == 0)
     479                    proto = NATProtocol_TCP;
     480                CHECK_ERROR(engine, AddRedirect(Bstr(strName).raw(), proto, Bstr(strHostIp).raw(),
     481                        RTStrToUInt16(strHostPort), Bstr(strGuestIp).raw(), RTStrToUInt16(strGuestPort)));
     482#undef ITERATE_TO_NEXT_TERM
     483            }
     484            /* commit changes */
     485            if (SUCCEEDED(rc))
     486                CHECK_ERROR(sessionMachine, SaveSettings());
     487        }
    396488        else if (!strncmp(a->argv[1], "nic", 3))
    397489        {
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r33766 r33825  
    391391                     "                            nictrace<1-N> on|off\n"
    392392                     "                            nictracefile<1-N> <filename>\n"
     393                     "                            natpf<1-N> [<rulename>],tcp|udp,[<hostip>],\n"
     394                     "                                          <hostport>,[<guestip>],<guestport>\n"
     395                     "                            natpf<1-N> delete <rulename>\n"
    393396                     "                            guestmemoryballoon <balloonsize in MB>]\n"
    394397                     "                            gueststatisticsinterval <seconds>]\n"
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r33806 r33825  
    10921092uint32_t Console::sSSMConsoleVer = 0x00010001;
    10931093
     1094inline static const char *networkAdapterTypeToName(NetworkAdapterType_T adapterType)
     1095{
     1096    switch (adapterType)
     1097    {
     1098        case NetworkAdapterType_Am79C970A:
     1099        case NetworkAdapterType_Am79C973:
     1100            return "pcnet";
     1101#ifdef VBOX_WITH_E1000
     1102        case NetworkAdapterType_I82540EM:
     1103        case NetworkAdapterType_I82543GC:
     1104        case NetworkAdapterType_I82545EM:
     1105            return "e1000";
     1106#endif
     1107#ifdef VBOX_WITH_VIRTIO
     1108        case NetworkAdapterType_Virtio:
     1109            return "virtio-net";
     1110#endif
     1111        default:
     1112            AssertFailed();
     1113            return "unknown";
     1114    }
     1115    return NULL;
     1116}
     1117
    10941118/**
    10951119 * Loads various console data stored in the saved state file.
     
    34153439            {
    34163440                /*
    3417                  * Find the pcnet instance, get the config interface and update
     3441                 * Find the adapter instance, get the config interface and update
    34183442                 * the link state.
    34193443                 */
     
    34213445                rc = aNetworkAdapter->COMGETTER(AdapterType)(&adapterType);
    34223446                AssertComRC(rc);
    3423                 const char *pszAdapterName = NULL;
    3424                 switch (adapterType)
    3425                 {
    3426                     case NetworkAdapterType_Am79C970A:
    3427                     case NetworkAdapterType_Am79C973:
    3428                         pszAdapterName = "pcnet";
    3429                         break;
    3430 #ifdef VBOX_WITH_E1000
    3431                     case NetworkAdapterType_I82540EM:
    3432                     case NetworkAdapterType_I82543GC:
    3433                     case NetworkAdapterType_I82545EM:
    3434                         pszAdapterName = "e1000";
    3435                         break;
    3436 #endif
    3437 #ifdef VBOX_WITH_VIRTIO
    3438                     case NetworkAdapterType_Virtio:
    3439                         pszAdapterName = "virtio-net";
    3440                         break;
    3441 #endif
    3442                     default:
    3443                         AssertFailed();
    3444                         pszAdapterName = "unknown";
    3445                         break;
    3446                 }
    3447 
     3447                const char *pszAdapterName = networkAdapterTypeToName(adapterType);
    34483448                PPDMIBASE pBase;
    34493449                int vrc = PDMR3QueryDeviceLun(mpVM, pszAdapterName, ulInstance, 0, &pBase);
     
    34963496        CONSOLE_DO_CALLBACKS1(OnNetworkAdapterChanged, aNetworkAdapter);
    34973497
     3498    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     3499    return rc;
     3500}
     3501
     3502/**
     3503 * Called by IInternalSessionControl::OnNATEngineChange().
     3504 *
     3505 * @note Locks this object for writing.
     3506 */
     3507HRESULT Console::onNATRedirectRuleChange(INetworkAdapter *aNetworkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName,
     3508                                 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
     3509{
     3510    LogFlowThisFunc(("\n"));
     3511
     3512    AutoCaller autoCaller(this);
     3513    AssertComRCReturnRC(autoCaller.rc());
     3514
     3515    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3516
     3517    HRESULT rc = S_OK;
     3518    int vrc = VINF_SUCCESS;
     3519    PPDMINETWORKNATCONFIG pNetNatCfg = NULL;
     3520    /* don't trigger nat engine change if the VM isn't running */
     3521    if (mpVM)
     3522    {
     3523        /* protect mpVM */
     3524        AutoVMCaller autoVMCaller(this);
     3525        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     3526        ULONG ulInstance;
     3527        rc = aNetworkAdapter->COMGETTER(Slot)(&ulInstance);
     3528        AssertComRC(rc);
     3529        if (FAILED(rc))
     3530            goto done;
     3531        /*
     3532         * Find the adapter instance, get the config interface and update
     3533         * the link state.
     3534         */
     3535        NetworkAdapterType_T adapterType;
     3536        rc = aNetworkAdapter->COMGETTER(AdapterType)(&adapterType);
     3537        AssertComRC(rc);
     3538        if (FAILED(rc))
     3539        {
     3540            rc = E_FAIL;
     3541            goto done;
     3542        }
     3543
     3544        const char *pszAdapterName = networkAdapterTypeToName(adapterType);
     3545        PPDMIBASE pBase;
     3546        vrc = PDMR3QueryLun(mpVM, pszAdapterName, ulInstance, 0, &pBase);
     3547        ComAssertRC(vrc);
     3548        if (RT_FAILURE(vrc))
     3549        {
     3550            rc = E_FAIL;
     3551            goto done;
     3552        }
     3553        NetworkAttachmentType_T attachmentType;
     3554        vrc = aNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType);
     3555
     3556        if (   RT_FAILURE(vrc)
     3557            || attachmentType != NetworkAttachmentType_NAT)
     3558        {
     3559            rc = (RT_FAILURE(vrc)) ? E_FAIL: rc;
     3560            goto done;
     3561        }
     3562       
     3563        /* look down for PDMINETWORKNATCONFIG interface */
     3564        while (pBase)
     3565        {
     3566            if ((pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID)))
     3567                break;
     3568            PPDMDRVINS drvins = PDMIBASE_2_PDMDRV(pBase);
     3569            pBase = drvins->pDownBase;
     3570        }
     3571        if (!pNetNatCfg)
     3572            goto done;
     3573        bool fUdp = (aProto == NATProtocol_UDP);
     3574        vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, Utf8Str(aRuleName).c_str(), fUdp,
     3575                                                 Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(),
     3576                                                 aGuestPort);
     3577        if (RT_FAILURE(vrc))
     3578            rc = E_FAIL;
     3579    }
     3580done:
    34983581    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
    34993582    return rc;
  • trunk/src/VBox/Main/MachineImpl.cpp

    r33731 r33825  
    1092610926 *  @note Locks this object for reading.
    1092710927 */
     10928HRESULT SessionMachine::onNATRedirectRuleChange(INetworkAdapter *networkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName,
     10929                                 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
     10930{
     10931    LogFlowThisFunc(("\n"));
     10932
     10933    AutoCaller autoCaller(this);
     10934    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
     10935
     10936    ComPtr<IInternalSessionControl> directControl;
     10937    {
     10938        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     10939        directControl = mData->mSession.mDirectControl;
     10940    }
     10941
     10942    /* ignore notifications sent after #OnSessionEnd() is called */
     10943    if (!directControl)
     10944        return S_OK;
     10945
     10946    return directControl->OnNATRedirectRuleChange(networkAdapter, aNatRuleRemove, aRuleName, aProto, aHostIp, aHostPort, aGuestIp, aGuestPort);
     10947}
     10948
     10949/**
     10950 *  @note Locks this object for reading.
     10951 */
    1092810952HRESULT SessionMachine::onSerialPortChange(ISerialPort *serialPort)
    1092910953{
  • trunk/src/VBox/Main/NATEngineImpl.cpp

    r33517 r33825  
    3232////////////////////////////////////////////////////////////////////////////////
    3333
    34 NATEngine::NATEngine():mParent(NULL){}
     34NATEngine::NATEngine():mParent(NULL), mAdapter(NULL){}
    3535NATEngine::~NATEngine(){}
    3636
     
    4040}
    4141
    42 HRESULT NATEngine::init(Machine *aParent)
     42HRESULT NATEngine::init(Machine *aParent, INetworkAdapter *aAdapter)
    4343{
    4444    AutoInitSpan autoInitSpan(this);
     
    5050    mData->mBindIP.setNull();
    5151    unconst(mParent) = aParent;
    52     return S_OK;
    53 }
    54 
    55 HRESULT NATEngine::init(Machine *aParent, NATEngine *aThat)
     52    unconst(mAdapter) = aAdapter;
     53    return S_OK;
     54}
     55
     56HRESULT NATEngine::init(Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat)
    5657{
    5758    AutoInitSpan autoInitSpan(this);
     
    7273    }
    7374    unconst(mParent) = aParent;
     75    unconst(mAdapter) = aAdapter;
    7476    unconst(mPeer) = aThat;
    7577    autoInitSpan.setSucceeded();
     
    7779}
    7880
    79 HRESULT NATEngine::initCopy (Machine *aParent, NATEngine *aThat)
     81HRESULT NATEngine::initCopy (Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat)
    8082{
    8183    AutoInitSpan autoInitSpan(this);
     
    9698        mNATRules.insert(std::make_pair(it->first, it->second));
    9799    }
     100    unconst(mAdapter) = aAdapter;
    98101    unconst(mParent) = aParent;
    99102    autoInitSpan.setSucceeded();
     
    265268    Utf8Str name = aName;
    266269    settings::NATRule r;
     270    const char *proto;
     271    switch (aProto)
     272    {
     273        case NATProtocol_TCP:
     274            proto = "tcp";
     275            break;
     276        case NATProtocol_UDP:
     277            proto = "udp";
     278            break;
     279        default:
     280            return E_INVALIDARG;
     281    }
    267282    if (name.isEmpty())
    268     {
    269         const char *proto;
    270         switch (aProto)
    271         {
    272             case NATProtocol_TCP:
    273                 proto = "tcp";
    274                 break;
    275             case NATProtocol_UDP:
    276                 proto = "udp";
    277                 break;
    278             default:
    279                 return E_INVALIDARG;
    280         }
    281283        name = Utf8StrFmt("%s_%d_%d", proto, aHostPort, aGuestPort);
    282     }
    283284    r.strName = name.c_str();
    284285    r.u32Proto = aProto;
     
    290291    mParent->setModified(Machine::IsModified_NetworkAdapters);
    291292    m_fModified = true;
     293    alock.release();
     294    mParent->onNATRedirectRuleChange(mAdapter, FALSE, Bstr(name).raw(), aProto, Bstr(r.strHostIP).raw(), r.u16HostPort, Bstr(r.strGuestIP).raw(), r.u16GuestPort);
    292295    return S_OK;
    293296}
     
    300303
    301304    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    302     Utf8Str rule;
    303305    NATRuleMap::iterator it = mNATRules.find(aName);
    304306    if (it == mNATRules.end())
    305307        return E_INVALIDARG;
    306308    mData.backup();
     309    settings::NATRule r = it->second;
     310    Utf8Str strHostIP = r.strHostIP;
     311    Utf8Str strGuestIP = r.strGuestIP;
     312    NATProtocol_T proto = r.u32Proto;
     313    uint16_t u16HostPort = r.u16HostPort;
     314    uint16_t u16GuestPort = r.u16GuestPort;
     315                                                   
    307316    mNATRules.erase(it);
    308317    mParent->setModified(Machine::IsModified_NetworkAdapters);
    309318    m_fModified = true;
     319    alock.release();
     320    mParent->onNATRedirectRuleChange(mAdapter, TRUE, aName, proto, Bstr(strHostIP).raw(), u16HostPort, Bstr(strGuestIP).raw(), u16GuestPort);
    310321    return S_OK;
    311322}
  • trunk/src/VBox/Main/NetworkAdapterImpl.cpp

    r33540 r33825  
    7575    unconst(mParent) = aParent;
    7676    unconst(mNATEngine).createObject();
    77     mNATEngine->init(aParent);
     77    mNATEngine->init(aParent, this);
    7878    /* mPeer is left null */
    7979
     
    125125    unconst(mPeer) = aThat;
    126126    unconst(mNATEngine).createObject();
    127     mNATEngine->init(aParent, aThat->mNATEngine);
     127    mNATEngine->init(aParent, this, aThat->mNATEngine);
    128128
    129129    AutoCaller thatCaller (aThat);
     
    160160
    161161    unconst(mNATEngine).createObject();
    162     mNATEngine->initCopy(aParent, aThat->mNATEngine);
     162    mNATEngine->initCopy(aParent, this, aThat->mNATEngine);
    163163
    164164    AutoCaller thatCaller (aThat);
  • trunk/src/VBox/Main/SessionImpl.cpp

    r33540 r33825  
    524524
    525525    return mConsole->onNetworkAdapterChange(networkAdapter, changeAdapter);
     526}
     527
     528STDMETHODIMP Session::OnNATRedirectRuleChange(INetworkAdapter *networkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName,
     529                                 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
     530{
     531    LogFlowThisFunc(("\n"));
     532
     533    AutoCaller autoCaller(this);
     534    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
     535
     536    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     537    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
     538    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
     539
     540    return mConsole->onNATRedirectRuleChange(networkAdapter, aNatRuleRemove, aRuleName, aProto, aHostIp, aHostPort, aGuestIp, aGuestPort);
    526541}
    527542
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r33776 r33825  
    1269512695    </method>
    1269612696
     12697    <method name="onNATRedirectRuleChange">
     12698      <desc>
     12699        Triggered on adding/removing of NAT Engine redirection rule of the
     12700        associated virtual machine.
     12701
     12702        <result name="VBOX_E_INVALID_VM_STATE">
     12703          Session state prevents operation.
     12704        </result>
     12705        <result name="VBOX_E_INVALID_OBJECT_STATE">
     12706          Session type prevents operation.
     12707        </result>
     12708
     12709      </desc>
     12710      <param name="networkAdapter" type="INetworkAdapter" dir="in"/>
     12711      <param name="natRedirectRemove" type="boolean" dir="in"/>
     12712      <param name="natRuleName" type="wstring" dir="in"/>
     12713      <param name="natProto" type="NATProtocol" dir="in"/>
     12714      <param name="natHostIp" type="wstring" dir="in"/>
     12715      <param name="natHostPort" type="long" dir="in"/>
     12716      <param name="natGuestIp" type="wstring" dir="in"/>
     12717      <param name="natGuestPort" type="long" dir="in"/>
     12718    </method>
     12719
    1269712720    <method name="onSerialPortChange">
    1269812721      <desc>
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r33784 r33825  
    180180    // events from IInternalSessionControl
    181181    HRESULT onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL changeAdapter);
     182    HRESULT onNATRedirectRuleChange(INetworkAdapter *networkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName,
     183                                 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort);
     184    HRESULT onNATEngineChange(INetworkAdapter *aNetworkAdapter, BOOL aNatReset);
    182185    HRESULT onSerialPortChange(ISerialPort *aSerialPort);
    183186    HRESULT onParallelPortChange(IParallelPort *aParallelPort);
  • trunk/src/VBox/Main/include/MachineImpl.h

    r33708 r33825  
    613613    // callback handlers
    614614    virtual HRESULT onNetworkAdapterChange(INetworkAdapter * /* networkAdapter */, BOOL /* changeAdapter */) { return S_OK; }
     615    virtual HRESULT onNATRedirectRuleChange(INetworkAdapter * /* networkAdapter */, BOOL /* Remove */, IN_BSTR /* Rule name */,
     616                                 NATProtocol_T /* proto */, IN_BSTR /* host ip */, LONG /* host port */, IN_BSTR /* guest ip */, LONG /* guest port */) { return S_OK; }
    615617    virtual HRESULT onSerialPortChange(ISerialPort * /* serialPort */) { return S_OK; }
    616618    virtual HRESULT onParallelPortChange(IParallelPort * /* parallelPort */) { return S_OK; }
     
    954956
    955957    HRESULT onNetworkAdapterChange(INetworkAdapter *networkAdapter, BOOL changeAdapter);
     958    HRESULT onNATRedirectRuleChange(INetworkAdapter *networkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName,
     959                                 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort);
    956960    HRESULT onStorageControllerChange();
    957961    HRESULT onMediumChange(IMediumAttachment *aMediumAttachment, BOOL aForce);
  • trunk/src/VBox/Main/include/NATEngineImpl.h

    r30764 r33825  
    8282
    8383    HRESULT FinalConstruct();
    84     HRESULT init(Machine *aParent);
    85     HRESULT init(Machine *aParent, NATEngine *aThat);
    86     HRESULT initCopy(Machine *aParent, NATEngine *aThat);
     84    HRESULT init(Machine *aParent, INetworkAdapter *aAdapter);
     85    HRESULT init(Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat);
     86    HRESULT initCopy(Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat);
    8787    bool isModified();
    8888    bool isReallyModified();
     
    130130    Machine * const mParent;
    131131    NATRuleMap mNATRules;
     132    INetworkAdapter * const mAdapter;
    132133};
    133134#endif
  • trunk/src/VBox/Main/include/SessionImpl.h

    r33386 r33825  
    8585    STDMETHOD(Uninitialize)();
    8686    STDMETHOD(OnNetworkAdapterChange)(INetworkAdapter *networkAdapter, BOOL changeAdapter);
     87    STDMETHOD(OnNATRedirectRuleChange)(INetworkAdapter *networkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName,
     88                                 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort);
    8789    STDMETHOD(OnSerialPortChange)(ISerialPort *serialPort);
    8890    STDMETHOD(OnParallelPortChange)(IParallelPort *parallelPort);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette