VirtualBox

Changeset 45559 in vbox for trunk/src


Ignore:
Timestamp:
Apr 16, 2013 6:11:59 AM (12 years ago)
Author:
vboxsync
Message:

NAT/Lwip-service: Main client now, dynamic port-forward + managment.

Location:
trunk/src/VBox
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk

    r45156 r45559  
    5656        VBoxManageStorageController.cpp \
    5757        VBoxManageUSB.cpp \
    58         $(if $(VBOX_WITH_NAT_SERVICE),VBoxManageNATNetwork.cpp,)
     58        $(if $(VBOX_WITH_NAT_SERVICE),VBoxManageNATNetwork.cpp,) \
     59        $(if $(VBOX_WITH_NAT_SERVICE),../../NetworkServices/NetLib/VBoxNetPortForwardString.cpp,)
    5960VBoxManage_LIBS      += $(LIB_DDU)
    6061
     
    8283        $(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE)
    8384
     85# VBoxNetPortForwardString.h
     86VBoxManageNATNetwork.cpp_INCS += ../../NetworkServices/NetLib/
     87
    8488ifneq ($(KBUILD_TARGET),win)
    8589 # Workaround for buggy gcc-4.3 compilers, see
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageNATNetwork.cpp

    r45356 r45559  
    2020*******************************************************************************/
    2121#ifndef VBOX_ONLY_DOCS
     22
     23
    2224#include <VBox/com/com.h>
    2325#include <VBox/com/array.h>
     
    2931#endif /* !VBOX_ONLY_DOCS */
    3032
     33#include <netinet/in.h>
     34
     35#define IPv6
     36
     37#include <iprt/cdefs.h>
    3138#include <iprt/cidr.h>
    3239#include <iprt/param.h>
     
    4047#include <VBox/log.h>
    4148
     49#include <vector>
     50
    4251#include "VBoxManage.h"
     52#include "VBoxPortForwardString.h"
    4353
    4454#ifndef VBOX_ONLY_DOCS
     55
    4556using namespace com;
    4657
     
    6273        { "--enable",           'e', RTGETOPT_REQ_NOTHING },
    6374        { "--disable",          'd', RTGETOPT_REQ_NOTHING },
    64 
     75        { "--port-forward-4",   'p', RTGETOPT_REQ_STRING },
     76        { "--port-forward-6",   'P', RTGETOPT_REQ_STRING },
    6577      };
     78
     79typedef struct PFNAME2DELETE
     80{
     81    char aszName[PF_NAMELEN];
     82    bool fIPv6;
     83} PFNAME2DELETE, *PPFNAME2DELETE;
     84
     85typedef std::vector<PFNAME2DELETE> VPF2DELETE;
     86typedef VPF2DELETE::const_iterator VPF2DELETEITERATOR;
     87
     88typedef std::vector<PORTFORWARDRULE> VPF2ADD;
     89typedef VPF2ADD::const_iterator VPF2ADDITERATOR;
     90
    6691
    6792static int handleOp(HandlerArg *a, OPCODE enmCode, int iStart, int *pcProcessed)
     
    79104    int ipv6 = -1;
    80105
     106    VPF2DELETE vPfName2Delete;
     107    VPF2ADD vPf2Add;
     108
    81109    int c;
    82110    RTGETOPTUNION ValueUnion;
    83111    RTGETOPTSTATE GetState;
     112
    84113    RTGetOptInit(&GetState,
    85114                 a->argc,
     
    101130                }
    102131            break;
     132
    103133            case 'n':   // --network
    104134                if(pNetworkCidr)
     
    109139                }
    110140            break;
     141
    111142            case 'e':   // --enable
    112143                if(enable >= 0)
     
    117148                }
    118149            break;
     150
    119151            case 'd':   // --disable
    120152                if(enable >= 0)
     
    125157                }
    126158            break;
    127             case VINF_GETOPT_NOT_OPTION:
    128                 return errorSyntax(USAGE_NATNETWORK, "unhandled parameter: %s", ValueUnion.psz);
    129             break;
     159           
    130160            case 'h':
    131161                if (dhcp != -1)
     
    133163                dhcp = ValueUnion.f;
    134164                break;
     165
    135166            case '6':
    136167                if (ipv6 != -1)
     
    138169                ipv6 = ValueUnion.f;
    139170                break;
     171
     172            case 'P': /* ipv6 portforwarding*/
     173            case 'p': /* ipv4 portforwarding */
     174            {
     175                if (RTStrCmp(ValueUnion.psz, "delete") != 0)
     176                {
     177                    PORTFORWARDRULE Pfr;
     178
     179                    /* netPfStrToPf will clean up the Pfr */
     180                    int irc = netPfStrToPf(ValueUnion.psz, (c == 'P'), &Pfr);
     181                    if (RT_FAILURE(irc))
     182                        return errorSyntax(USAGE_NATNETWORK,
     183                                           "Invalid port-forward rule %s\n",
     184                                           ValueUnion.psz);
     185                   
     186                    vPf2Add.push_back(Pfr);
     187                }
     188                else
     189                {
     190                    int vrc;
     191                    RTGETOPTUNION NamePf2DeleteUnion;
     192                    PFNAME2DELETE Name2Delete;
     193
     194                    if (enmCode != OP_MODIFY)
     195                        return errorSyntax(USAGE_NATNETWORK,
     196                                           "Port-forward could be deleted on modify \n");
     197
     198                    vrc = RTGetOptFetchValue(&GetState,
     199                                             &NamePf2DeleteUnion,
     200                                             RTGETOPT_REQ_STRING);
     201                    if (RT_FAILURE(vrc))
     202                        return errorSyntax(USAGE_NATNETWORK,
     203                                           "Not enough parmaters\n");
     204                   
     205                    if (strlen(NamePf2DeleteUnion.psz) > PF_NAMELEN)
     206                        return errorSyntax(USAGE_NATNETWORK,
     207                                           "Port-forward rule name is too long\n");
     208
     209                    RT_ZERO(Name2Delete);
     210                    RTStrCopy(Name2Delete.aszName,
     211                              PF_NAMELEN,
     212                              NamePf2DeleteUnion.psz);
     213                    Name2Delete.fIPv6 = (c == 'P');
     214
     215                    vPfName2Delete.push_back(Name2Delete);
     216                }
     217                break;
     218            }
     219
     220            case VINF_GETOPT_NOT_OPTION:
     221                return errorSyntax(USAGE_NATNETWORK,
     222                                   "unhandled parameter: %s",
     223                                   ValueUnion.psz);
     224            break;
     225
    140226            default:
    141227                if (c > 0)
    142228                {
    143229                    if (RT_C_IS_GRAPH(c))
    144                         return errorSyntax(USAGE_NATNETWORK, "unhandled option: -%c", c);
     230                        return errorSyntax(USAGE_NATNETWORK,
     231                                           "unhandled option: -%c", c);
    145232                    else
    146                         return errorSyntax(USAGE_NATNETWORK, "unhandled option: %i", c);
     233                        return errorSyntax(USAGE_NATNETWORK,
     234                                           "unhandled option: %i", c);
    147235                }
    148236                else if (c == VERR_GETOPT_UNKNOWN_OPTION)
    149                     return errorSyntax(USAGE_NATNETWORK, "unknown option: %s", ValueUnion.psz);
     237                    return errorSyntax(USAGE_NATNETWORK,
     238                                       "unknown option: %s", ValueUnion.psz);
    150239                else if (ValueUnion.pDef)
    151                     return errorSyntax(USAGE_NATNETWORK, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
     240                    return errorSyntax(USAGE_NATNETWORK,
     241                                       "%s: %Rrs", ValueUnion.pDef->pszLong, c);
    152242                else
    153243                    return errorSyntax(USAGE_NATNETWORK, "%Rrs", c);
     
    218308              if(FAILED(rc))
    219309                return errorArgument("Failed to set configuration");
     310        }
     311       
     312        if (!vPfName2Delete.empty())
     313        {
     314            VPF2DELETEITERATOR it;
     315            for (it = vPfName2Delete.begin(); it != vPfName2Delete.end(); ++it)
     316            {
     317                CHECK_ERROR(net, RemovePortForwardRule((BOOL)(*it).fIPv6,
     318                                                       Bstr((*it).aszName).raw()));
     319                if(FAILED(rc))
     320                    return errorArgument("Failed to delete pf");
     321
     322            }
     323        }
     324
     325        if (!vPf2Add.empty())
     326        {
     327            VPF2ADDITERATOR it;
     328            for(it = vPf2Add.begin(); it != vPf2Add.end(); ++it)
     329            {
     330                NATProtocol_T proto = NATProtocol_TCP;
     331                if ((*it).iPfrProto == IPPROTO_TCP)
     332                    proto = NATProtocol_TCP;
     333                else if ((*it).iPfrProto == IPPROTO_UDP)
     334                    proto = NATProtocol_UDP;
     335                else
     336                    continue; /* XXX: warning here. */
     337
     338                CHECK_ERROR(net, AddPortForwardRule(
     339                              (BOOL)(*it).fPfrIPv6,
     340                              Bstr((*it).aszPfrName).raw(),
     341                              proto,
     342                              Bstr((*it).aszPfrHostAddr).raw(),
     343                              (*it).u16PfrHostPort,
     344                              Bstr((*it).aszPfrGuestAddr).raw(),
     345                              (*it).u16PfrGuestPort));
     346                if(FAILED(rc))
     347                    return errorArgument("Failed to add pf");
     348
     349            }
    220350        }
    221351       
  • trunk/src/VBox/Main/include/NATNetworkImpl.h

    r45138 r45559  
    112112private:
    113113    int RecalculateIpv4AddressAssignments();
     114
    114115    typedef std::map<Utf8Str, settings::NATRule> NATRuleMap;
     116    typedef NATRuleMap::const_iterator constNATRuleMapIterator;
     117
    115118    void GetPortForwardRulesFromMap(ComSafeArrayOut(BSTR, aPortForwardRules), NATRuleMap& aRules);
    116119    /** weak VirtualBox parent */
     
    120123    struct Data;
    121124    struct Data *m;
    122    
    123125
    124126};
  • trunk/src/VBox/Main/src-server/NATNetworkImpl.cpp

    r45141 r45559  
    3333
    3434#include "EventImpl.h"
     35#include "VBoxEvents.h"
     36
    3537#include "NATNetworkServiceRunner.h"
    3638#include "VirtualBoxImpl.h"
     
    119121    /* share VirtualBox weakly (parent remains NULL so far) */
    120122    unconst(mVirtualBox) = aVirtualBox;
    121 
    122123    unconst(mName) = aName;
    123124    m = new Data();
     
    126127    m->IPv6Prefix = "fe80::/64";
    127128    m->fEnabled = FALSE;
     129
     130   
     131   
    128132    RecalculateIpv4AddressAssignments();
     133
     134    HRESULT hrc = unconst(m->pEventSource).createObject();
     135    if (FAILED(hrc)) throw hrc;
     136
     137    hrc = m->pEventSource->init(static_cast<INATNetwork *>(this));
     138    if (FAILED(hrc)) throw hrc;
     139       
    129140    /* Confirm a successful initialization */
    130141    autoInitSpan.setSucceeded();
     
    150161    m->fAdvertiseDefaultIPv6Route = data.fAdvertiseDefaultIPv6Route;
    151162    m->fNeedDhcpServer = data.fNeedDhcpServer;
     163
    152164    RecalculateIpv4AddressAssignments();
     165
    153166    /* IPv4 port-forward rules */
    154167    m->mapName2PortForwardRule4.clear();
     
    156169        it != data.llPortForwardRules4.end(); ++it)
    157170    {
    158         m->mapName2PortForwardRule4.insert(std::make_pair(it->strName, *it));
     171        m->mapName2PortForwardRule4.insert(std::make_pair(it->strName.c_str(), *it));
    159172    }
    160173
     
    166179        m->mapName2PortForwardRule6.insert(std::make_pair(it->strName, *it));
    167180    }
     181
     182    HRESULT hrc = unconst(m->pEventSource).createObject();
     183    if (FAILED(hrc)) throw hrc;
     184
     185    hrc = m->pEventSource->init(static_cast<INATNetwork *>(this));
     186    if (FAILED(hrc)) throw hrc;
    168187   
    169188    autoInitSpan.setSucceeded();
     
    199218         it != m->mapName2PortForwardRule6.end(); ++it)
    200219      data.llPortForwardRules4.push_back(it->second);
     220
    201221    /* XXX: should we do here a copy of params */
    202222    /* XXX: should we unlock here? */
     
    247267
    248268    alock.release();
     269
    249270#ifdef NAT_XML_SERIALIZATION
    250271    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     
    322343        RecalculateIpv4AddressAssignments();
    323344        alock.release();
     345
    324346#ifdef NAT_XML_SERIALIZATION
    325347        AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     
    352374    // save the global settings; for that we should hold only the VirtualBox lock
    353375    alock.release();
     376
    354377#ifdef NAT_XML_SERIALIZATION
    355378    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     
    381404
    382405        unconst(m->IPv6Prefix) = Bstr(aIPv6Prefix);
    383         /* @todo: do we need recalcualtion ? */
     406        /* @todo: do we need recalculation ? */
    384407        alock.release();
     408
    385409#ifdef NAT_XML_SERIALIZATION
    386410        AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     
    413437    // save the global settings; for that we should hold only the VirtualBox lock
    414438    alock.release();
     439
    415440#ifdef NAT_XML_SERIALIZATION
    416441    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     
    439464    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    440465    m->fNeedDhcpServer = aNeedDhcpServer;
     466
    441467    RecalculateIpv4AddressAssignments();
     468
    442469    // save the global settings; for that we should hold only the VirtualBox lock
    443470    alock.release();
     471
    444472#ifdef NAT_XML_SERIALIZATION
    445473    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     
    457485
    458486    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    459     GetPortForwardRulesFromMap(ComSafeArrayInArg(aPortForwardRules4), m->mapName2PortForwardRule4);
     487    GetPortForwardRulesFromMap(ComSafeArrayInArg(aPortForwardRules4),
     488                               m->mapName2PortForwardRule4);
    460489    alock.release();
    461490    return S_OK;
    462491}
    463492
    464 STDMETHODIMP NATNetwork::COMGETTER(PortForwardRules6)(ComSafeArrayOut(BSTR, aPortForwardRules6))
     493STDMETHODIMP NATNetwork::COMGETTER(PortForwardRules6)(ComSafeArrayOut(BSTR,
     494                                                                      aPortForwardRules6))
    465495{
    466496    CheckComArgOutSafeArrayPointerValid(aPortForwardRules6);
     
    503533    }
    504534    if (name.isEmpty())
    505       name = Utf8StrFmt("%s_%s:%d_%s:%d", proto.c_str(),
    506                         Utf8Str(aHostIp).c_str(), aHostPort, 
     535      name = Utf8StrFmt("%s_[%s]%%%d_[%s]%%%d", proto.c_str(),
     536                        Utf8Str(aHostIp).c_str(), aHostPort,
    507537                        Utf8Str(aGuestIp).c_str(), aGuestPort);
    508538
    509539    NATRuleMap::iterator it;
     540
    510541    for (it = mapRules.begin(); it != mapRules.end(); ++it)
    511542    {
     
    534565                                         aHostIp, aHostPort,
    535566                                         aGuestIp, aGuestPort);
     567
     568    /* Notify listerners listening on this network only */
     569    fireNATNetworkPortForwardEvent(m->pEventSource, mName.raw(), TRUE,
     570                                   aIsIpv6, aPortForwardRuleName, aProto,
     571                                   aHostIp, aHostPort,
     572                                   aGuestIp, aGuestPort);
     573
    536574#ifdef NAT_XML_SERIALIZATION
    537575    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
    538576    rc = mVirtualBox->saveSettings();
    539577#endif
    540     /* @todo: fire the event */
    541578    return rc;
    542579}
     
    545582{
    546583    int rc = S_OK;
     584    Utf8Str strHostIP, strGuestIP;
     585    uint16_t u16HostPort, u16GuestPort;
     586    NATProtocol_T proto = NATProtocol_TCP;
     587
    547588    AutoCaller autoCaller(this);
    548589    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    551592    NATRuleMap& mapRules = aIsIpv6 ? m->mapName2PortForwardRule6 : m->mapName2PortForwardRule4;
    552593    NATRuleMap::iterator it = mapRules.find(aPortForwardRuleName);
     594   
    553595    if (it == mapRules.end())
    554596        return E_INVALIDARG;
    555    
     597   
     598    strHostIP = it->second.strHostIP;
     599    strGuestIP = it->second.strGuestIP;
     600    u16HostPort = it->second.u16HostPort;
     601    u16GuestPort = it->second.u16GuestPort;
     602    proto = it->second.proto;
     603
    556604    mapRules.erase(it);
    557605   
    558606    alock.release();
    559     /* we need only name here, it supposed to be uniq within IP version protocols */
     607
    560608    mVirtualBox->onNATNetworkPortForward(mName.raw(), FALSE, aIsIpv6,
    561                                          aPortForwardRuleName, NATProtocol_TCP,
    562                                          Bstr().raw(), 0,
    563                                          Bstr().raw(), 0);
     609                                         aPortForwardRuleName, proto,
     610                                         Bstr(strHostIP).raw(), u16HostPort,
     611                                         Bstr(strGuestIP).raw(), u16GuestPort);
     612
     613    /* Notify listerners listening on this network only */
     614    fireNATNetworkPortForwardEvent(m->pEventSource, mName.raw(), FALSE,
     615                                   aIsIpv6, aPortForwardRuleName, proto,
     616                                   Bstr(strHostIP).raw(), u16HostPort,
     617                                   Bstr(strGuestIP).raw(), u16GuestPort);
    564618#ifdef NAT_XML_SERIALIZATION
    565619    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
    566620    rc = mVirtualBox->saveSettings();
    567621#endif
    568     /* @todo: fire the event */
     622
    569623    return rc;
    570624}
     
    582636    m->NATRunner.setOption(NATSCCFG_IPADDRESS, m->IPv4Gateway, true);
    583637    m->NATRunner.setOption(NATSCCFG_NETMASK, m->IPv4NetworkMask, true);
     638   
     639    /* port-forwarding */
     640   
     641    for (constNATRuleMapIterator it = m->mapName2PortForwardRule4.begin();
     642         it != m->mapName2PortForwardRule4.end(); ++it)
     643    {
     644        settings::NATRule r = it->second;
     645        m->NATRunner.setOption(NATSCCFG_PORTFORWARD4,
     646                               Bstr(Utf8StrFmt("%s:%d:[%s]:%d:[%s]:%d",
     647                                               r.strName.c_str(),
     648                                               r.proto,
     649                                               r.strHostIP.isEmpty() ?
     650                                                      "0.0.0.0" :
     651                                                       r.strHostIP.c_str(),
     652                                               r.u16HostPort,
     653                                               r.strGuestIP.c_str(),
     654                                               r.u16GuestPort)), true);
     655    }
    584656
    585657    if (m->fNeedDhcpServer)
     
    684756      {
    685757        settings::NATRule r = it->second;
    686         BstrFmt bstr("%s,%d,%s,%d,%s,%d",
     758        BstrFmt bstr("%s:%s:[%s]:%d:[%s]:%d",
    687759                     r.strName.c_str(),
    688                      r.proto,
     760                     (r.proto == NATProtocol_TCP? "tcp" : "udp"),
    689761                     r.strHostIP.c_str(),
    690762                     r.u16HostPort,
     
    698770int NATNetwork::RecalculateIpv4AddressAssignments()
    699771{
    700     /**
    701      * We assume that port-forwarding rules set is empty!
    702      * possible scenarious on change of CIDR we clean up (1) pfs
    703      * or (2) rewrite all rules to new network.
    704      */
    705     AssertReturn(m->mapName2PortForwardRule4.empty(), VERR_INTERNAL_ERROR);
    706772    RTNETADDRIPV4 network, netmask, gateway;
    707773    char aszGatewayIp[16], aszNetmask[16];
  • trunk/src/VBox/NetworkServices/NAT/Makefile.kmk

    r44824 r45559  
    6969PROGRAMS += VBoxNetLwipNAT
    7070VBoxNetLwipNAT_TEMPLATE =
    71 VBoxNetLwipNAT_TEMPLATE := VBOXR3$(if-expr defined(VBOX_WITH_HARDENING),,EXE)
    72 #VBoxNetLwipNAT_INCS += ${LWIP_INCS}
     71VBoxNetLwipNAT_TEMPLATE := VBOXMAINCLIENTEXE
    7372VBoxNetLwipNAT_INCS += ../../Devices/Network \
    7473        ../../Devices/Network/lwip-new/vbox # testproxy.h
     
    7675VBoxNetLwipNAT_SOURCES += VBoxNetLwipNAT.cpp    \
    7776        ../NetLib/VBoxNetBaseService.cpp \
     77        ../NetLib/VBoxNetPortForwardString.cpp \
    7878        ../../Devices/Network/VBoxLwipCore.cpp
    7979VBoxNetLwipNAT_LIBS = \
     
    9090endif
    9191
     92PROGRAMS += tstNetPfAddressPortPairParse
     93
     94tstNetPfAddressPortPairParse_TEMPLATE = VBOXR3TSTEXE
     95#tstNetPfAddressPortPairParse_INSTTYPE = none
     96tstNetPfAddressPortPairParse_SOURCES =  ../NetLib/testcase/tstNetPfAddressPortPairParse.cpp \
     97        ../NetLib/VBoxNetPortForwardString.cpp
     98
     99
    92100include $(FILE_KBUILD_SUB_FOOTER)
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