VirtualBox

Changeset 48098 in vbox for trunk/src


Ignore:
Timestamp:
Aug 27, 2013 5:08:10 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
88473
Message:

Main/NATNetwork: loopback mappings registration/deletion and modification.

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/NATNetworkImpl.h

    r47894 r48098  
    130130private:
    131131    int RecalculateIpv4AddressAssignments();
     132    int findFirstAvailableOffset(uint32_t *);
    132133
    133134    typedef std::map<Utf8Str, settings::NATRule> NATRuleMap;
  • trunk/src/VBox/Main/src-server/NATNetworkImpl.cpp

    r47965 r48098  
    3636
    3737#include "VirtualBoxImpl.h"
     38#include <algorithm>
     39#include <list>
     40
     41#ifndef RT_OS_WINDOWS
     42#include <netinet/in.h>
     43#else
     44# include <ws2def.h>
     45# define IN_LOOPBACKNET 127
     46#endif
    3847
    3948
     
    7786    NATRuleMap mapName2PortForwardRule4;
    7887    NATRuleMap mapName2PortForwardRule6;
     88    settings::NATLoopbackOffsetList llNATLoopbackOffsetList;
     89    uint32_t u32LoopbackIp6;
     90    uint32_t u32GatewayOffset;
     91    uint32_t u32DhcpOffset;
    7992};
    8093
     
    122135    unconst(mName) = aName;
    123136    m = new Data();
    124     m->IPv4Gateway = "10.0.2.2";
     137    m->u32GatewayOffset = 1;
    125138    m->IPv4NetworkCidr = "10.0.2.0/24";
    126139    m->IPv6Prefix = "fe80::/64";
    127140    m->fEnabled = FALSE;
    128141
    129 
     142    settings::NATHostLoopbackOffset off;
     143    off.strLoopbackHostAddress = "127.0.0.1";
     144    off.u32Offset = (uint32_t)2;
     145    m->llNATLoopbackOffsetList.push_back(off);
    130146
    131147    RecalculateIpv4AddressAssignments();
     
    160176    m->fAdvertiseDefaultIPv6Route = data.fAdvertiseDefaultIPv6Route;
    161177    m->fNeedDhcpServer = data.fNeedDhcpServer;
     178
     179    m->u32LoopbackIp6 = data.u32HostLoopback6Offset;
     180
     181    m->llNATLoopbackOffsetList.clear();
     182    m->llNATLoopbackOffsetList.assign(data.llHostLoopbackOffsetList.begin(),
     183                               data.llHostLoopbackOffsetList.end());
    162184
    163185    RecalculateIpv4AddressAssignments();
     
    218240      data.llPortForwardRules4.push_back(it->second);
    219241
    220     /* XXX: should we do here a copy of params */
    221     /* XXX: should we unlock here? */
     242    data.u32HostLoopback6Offset = m->u32LoopbackIp6;
     243   
     244    data.llHostLoopbackOffsetList.clear();
     245    data.llHostLoopbackOffsetList.assign(m->llNATLoopbackOffsetList.begin(),
     246                                         m->llNATLoopbackOffsetList.end());
     247
    222248    mVirtualBox->onNATNetworkSetting(mName.raw(),
    223249                                     data.fEnabled ? TRUE : FALSE,
     
    226252                                     data.fAdvertiseDefaultIPv6Route ? TRUE : FALSE,
    227253                                     data.fNeedDhcpServer ? TRUE : FALSE);
     254
    228255    return S_OK;
    229256}
     
    387414    AutoCaller autoCaller(this);
    388415    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     416    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     417
     418    m->IPv6Prefix.cloneTo(aIPv6Prefix);
     419
    389420    return S_OK;
    390421}
     
    398429    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    399430    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     431
    400432    /* silently ignore network cidr update */
    401433    if (m->mapName2PortForwardRule6.empty())
     
    476508}
    477509
     510
    478511STDMETHODIMP NATNetwork::COMGETTER(LocalMappings)(ComSafeArrayOut(BSTR, aLocalMappings))
    479512{
    480     NOREF(aLocalMappings);
    481 #ifndef RT_OS_WINDOWS
    482     NOREF(aLocalMappingsSize);
    483 #endif
    484     return E_NOTIMPL;
    485 }
     513    CheckComArgOutSafeArrayPointerValid(aLocalMappings);
     514
     515    AutoCaller autoCaller(this);
     516    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     517    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     518
     519    com::SafeArray<BSTR> sf(m->llNATLoopbackOffsetList.size());
     520
     521    size_t i = 0;
     522    settings::NATLoopbackOffsetList::const_iterator it;
     523
     524    for (it = m->llNATLoopbackOffsetList.begin();
     525         it != m->llNATLoopbackOffsetList.end(); ++it, ++i)
     526      {
     527          BstrFmt bstr("%s;%d",
     528                       (*it).strLoopbackHostAddress.c_str(),
     529                       (*it).u32Offset);
     530        bstr.detachTo(&sf[i]);
     531    }
     532    sf.detachTo(ComSafeArrayOutArg(aLocalMappings));
     533
     534    return S_OK;
     535}
     536
    486537
    487538STDMETHODIMP NATNetwork::AddLocalMapping(IN_BSTR aHostId, LONG aOffset)
    488539{
    489     NOREF(aHostId); NOREF(aOffset);
    490     return E_NOTIMPL;
    491 }
     540    AutoCaller autoCaller(this);
     541    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     542
     543    //AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     544
     545    RTNETADDRIPV4 addr, net, mask;
     546
     547    int rc = RTNetStrToIPv4Addr(Utf8Str(aHostId).c_str(), &addr);
     548    if (RT_FAILURE(rc))
     549        return E_INVALIDARG;
     550   
     551    /* check against 127/8 */
     552    if ((RT_N2H_U32(addr.u) >> IN_CLASSA_NSHIFT) != IN_LOOPBACKNET)
     553        return E_INVALIDARG;
     554   
     555    /* check against networkid vs network mask */
     556    rc = RTCidrStrToIPv4(Utf8Str(m->IPv4NetworkCidr).c_str(), &net, &mask);
     557    if (RT_FAILURE(rc))
     558        return E_INVALIDARG;
     559
     560    if (((net.u + aOffset) & mask.u) != net.u)
     561        return E_INVALIDARG;
     562
     563    settings::NATLoopbackOffsetList::iterator it;
     564
     565    it = std::find(m->llNATLoopbackOffsetList.begin(),
     566                   m->llNATLoopbackOffsetList.end(),
     567                   Utf8Str(aHostId).c_str());
     568
     569    if (it != m->llNATLoopbackOffsetList.end())
     570    {
     571        if (aOffset == 0) /* erase */
     572            m->llNATLoopbackOffsetList.erase(it, it);
     573        else /* modify */
     574        {
     575            settings::NATLoopbackOffsetList::iterator it1;
     576            it1 = std::find(m->llNATLoopbackOffsetList.begin(),
     577                           m->llNATLoopbackOffsetList.end(),
     578                           (uint32_t)aOffset);
     579            if (it1 != m->llNATLoopbackOffsetList.end())
     580                return E_INVALIDARG; /* this offset is already registered. */
     581
     582            (*it).u32Offset = aOffset;
     583        }
     584
     585        AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     586        return mVirtualBox->saveSettings();
     587    }
     588
     589    /* injection */
     590    it = std::find(m->llNATLoopbackOffsetList.begin(),
     591                   m->llNATLoopbackOffsetList.end(),
     592                   (uint32_t)aOffset);
     593
     594    if (it != m->llNATLoopbackOffsetList.end())
     595        return E_INVALIDARG; /* offset is already registered. */
     596
     597    settings::NATHostLoopbackOffset off;
     598    off.strLoopbackHostAddress = aHostId;
     599    off.u32Offset = (uint32_t)aOffset;
     600    m->llNATLoopbackOffsetList.push_back(off);
     601
     602    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     603    return mVirtualBox->saveSettings();
     604}
     605
    492606
    493607STDMETHODIMP NATNetwork::COMGETTER(LoopbackIp6)(LONG *aLoopbackIp6)
    494608{
    495     NOREF(aLoopbackIp6);
    496     return E_NOTIMPL;
    497 }
     609    AutoCaller autoCaller(this);
     610    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     611    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     612
     613    *aLoopbackIp6 = m->u32LoopbackIp6;
     614    return S_OK;
     615}
     616
    498617
    499618STDMETHODIMP NATNetwork::COMSETTER(LoopbackIp6)(LONG aLoopbackIp6)
    500619{
    501     NOREF(aLoopbackIp6);
    502     return E_NOTIMPL;
     620    AutoCaller autoCaller(this);
     621    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     622    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     623
     624    m->u32LoopbackIp6 = aLoopbackIp6;
     625   
     626    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     627    return mVirtualBox->saveSettings();
    503628}
    504629
     
    784909}
    785910
     911
     912int NATNetwork::findFirstAvailableOffset(uint32_t *pu32Offset)
     913{
     914    uint32_t offset;
     915    RTNETADDRIPV4 network, netmask;
     916
     917    int rc = RTCidrStrToIPv4(Utf8Str(m->IPv4NetworkCidr.raw()).c_str(),
     918                             &network,
     919                             &netmask);
     920    AssertRCReturn(rc, rc);
     921
     922    settings::NATLoopbackOffsetList::iterator it;
     923    for (offset = 1; offset < (network.u & (~netmask.u)); ++offset)
     924    {
     925        bool skip = false;
     926
     927        if (offset == m->u32GatewayOffset)
     928            continue;
     929
     930        if (offset == m->u32DhcpOffset)
     931            continue;
     932       
     933        for (it = m->llNATLoopbackOffsetList.begin();
     934             it != m->llNATLoopbackOffsetList.end();
     935             ++it)
     936        {
     937            if ((*it).u32Offset == offset)
     938            {
     939                skip = true;
     940                break;
     941            }
     942
     943        }
     944       
     945        if(!skip)
     946            break;
     947    }
     948   
     949    if (pu32Offset)
     950        *pu32Offset = offset;
     951   
     952    return VINF_SUCCESS;
     953}
     954
    786955int NATNetwork::RecalculateIpv4AddressAssignments()
    787956{
     
    794963    AssertRCReturn(rc, rc);
    795964
     965    findFirstAvailableOffset(&m->u32GatewayOffset);
     966    if (m->fNeedDhcpServer)
     967        findFirstAvailableOffset(&m->u32DhcpOffset);
     968
    796969    /* I don't remember the reason CIDR calcualted in host */
    797970    gateway.u = network.u;
    798971
    799     gateway.u += 1;
     972    gateway.u += m->u32GatewayOffset;
    800973    gateway.u = RT_H2N_U32(gateway.u);
    801974    RTStrPrintf(aszGatewayIp, 16, "%RTnaipv4", gateway);
     975
    802976    m->IPv4Gateway = RTStrDup(aszGatewayIp);
     977
    803978    if (m->fNeedDhcpServer)
    804979    {
     
    817992
    818993        dhcpserver.u = network.u;
    819         dhcpserver.u += 2;
     994        dhcpserver.u += m->u32GatewayOffset;
    820995
    821996
Note: See TracChangeset for help on using the changeset viewer.

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