VirtualBox

Changeset 45138 in vbox for trunk


Ignore:
Timestamp:
Mar 22, 2013 11:52:24 AM (12 years ago)
Author:
vboxsync
Message:

Main/NATNetworks: API+XML serialization for NATNetworks.

Location:
trunk
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/settings.h

    r45117 r45138  
    185185
    186186/**
     187 *
     188 */
     189 struct NATRule
     190 {
     191     NATRule()
     192         : proto(NATProtocol_TCP),
     193           u16HostPort(0),
     194           u16GuestPort(0)
     195     {}
     196
     197     bool operator==(const NATRule &r) const
     198     {
     199         return strName == r.strName
     200             && proto == r.proto
     201             && u16HostPort == r.u16HostPort
     202             && strHostIP == r.strHostIP
     203             && u16GuestPort == r.u16GuestPort
     204             && strGuestIP == r.strGuestIP;
     205     }
     206
     207     com::Utf8Str            strName;
     208     NATProtocol_T           proto;
     209     uint16_t                u16HostPort;
     210     com::Utf8Str            strHostIP;
     211     uint16_t                u16GuestPort;
     212     com::Utf8Str            strGuestIP;
     213 };
     214 typedef std::list<NATRule> NATRuleList;
     215
     216/**
    187217 * Common base class for both MainConfigFile and MachineConfigFile
    188218 * which contains some common logic for both.
     
    291321};
    292322typedef std::list<DHCPServer> DHCPServersList;
     323
     324
     325/**
     326 * Nat Networking settings (NAT service).
     327 */
     328struct NATNetwork
     329{
     330    com::Utf8Str strNetworkName;
     331    bool         fEnabled;
     332    com::Utf8Str strNetwork;
     333    bool         fIPv6;
     334    com::Utf8Str strIPv6Prefix;
     335    bool         fAdvertiseDefaultIPv6Route;
     336    bool         fNeedDhcpServer;
     337    NATRuleList  llPortForwardRules4;
     338    NATRuleList  llPortForwardRules6;
     339    NATNetwork():fEnabled(false),
     340      fAdvertiseDefaultIPv6Route(false),
     341      fNeedDhcpServer(false)
     342      {}
     343    bool operator==(const NATNetwork &n) const
     344    {
     345        return    strNetworkName == n.strNetworkName
     346               && strNetwork == n.strNetwork;
     347    }
     348     
     349};
     350typedef std::list<NATNetwork> NATNetworksList;
    293351
    294352
  • trunk/src/VBox/Main/Makefile.kmk

    r45119 r45138  
    4545# Construct VBOX_MAIN_DEFS
    4646## @todo eliminate or expand VBOX_MAIN_DEFS.
    47 VBOX_MAIN_DEFS   =
     47VBOX_MAIN_DEFS   = 
    4848ifneq ($(KBUILD_TARGET),win)
    4949 ifndef VBOX_WITH_XPCOM
     
    238238        $(if $(VBOX_WITH_VUSB),VBOX_WITH_VUSB,) \
    239239        $(if $(VBOX_WITH_S3),VBOX_WITH_S3,) \
    240         $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,)
     240        $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \
     241        $(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE,)
    241242ifdef VBOX_WITH_USB
    242243 VBoxSVC_DEFS += \
     
    306307        src-server/DHCPServerImpl.cpp \
    307308        src-server/DHCPServerRunner.cpp \
     309        src-server/NATNetworkImpl.cpp \
     310        $(if $(VBOX_WITH_NAT_SERVICE),src-server/NATNetworkServiceRunner.cpp,) \
    308311        src-server/GuestOSTypeImpl.cpp \
    309312        src-server/HostImpl.cpp \
     
    528531        $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \
    529532        $(if $(VBOX_WITH_VPX),VBOX_WITH_VPX,)
     533
    530534
    531535VBoxC_DEFS.darwin.x86 = VBOX_WITH_2X_4GB_ADDR_SPACE
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r45119 r45138  
    235235<library
    236236  name="VirtualBox"
    237   uuid="46137EEC-703B-4fe5-AFD4-7C9BBBBA0259"
     237  uuid="d7569351-1750-46f0-936e-bd127d5bc264"
    238238  version="1.3"
    239239  desc="VirtualBox Type Library"
     
    13161316  /////////////////////////////////////////////////////////////////////////
    13171317  -->
     1318  <!-- This is experimental interface to LWIP based NAT server -->
     1319  <interface name="INATNetwork" extends="$unknown"
     1320    uuid="03DFD6F7-1B78-48A3-8345-C785281E9523"
     1321    wsmap="managed">
     1322    <attribute name="NetworkName" type="wstring">
     1323      <desc>
     1324        TBD: the idea, technically we can start any number of the NAT networks,
     1325        but we should expect that at some point we will get collisions because of
     1326        port-forwanding rules. so perhaps we should support only single instance of NAT
     1327        network.
     1328      </desc>
     1329    </attribute>
     1330    <attribute name="enabled" type="boolean"/>
     1331    <attribute name="network" type="wstring">
     1332      <desc>
     1333        This is CIDR IPv4 string. Specifiying it user defines IPv4 addresses
     1334        of gateway (low address + 1) and dhcp server (= low address + 2).
     1335        Note: if there're defined IPv4 port-forward rules update of network
     1336        will be ignored (because new assignment could break existing rules).
     1337      </desc>
     1338    </attribute>
     1339    <attribute name="gateway" type="wstring" readonly="yes">
     1340      <desc>
     1341        This attribute is read-only. It's recalculated on changing
     1342        network attribute (low address of network + 1).
     1343      </desc>
     1344    </attribute>
     1345    <attribute name="IPv6Enabled" type="boolean">
     1346      <desc>
     1347        This attribute define whether gateway will support IPv6 or not.
     1348      </desc>
     1349    </attribute>
     1350    <attribute name="IPv6Prefix" type="wstring">
     1351      <desc>
     1352        This a CIDR IPv6 defining prefix for link-local addresses autoconfiguration     within network. Note: ignored if attribute ipv6enabled is false.
     1353      </desc>
     1354    </attribute>
     1355    <attribute name="advertiseDefaultIPv6RouteEnabled" type="boolean"/>
     1356    <attribute name="needDhcpServer" type="boolean"/>
     1357    <attribute name="eventSource" type="IEventSource" readonly="yes"/>
     1358    <attribute name="portForwardRules4" type="wstring" readonly="yes" safearray="yes">
     1359      <desc>Array of NAT port-forwarding rules in string representation,
     1360      in the following format:
     1361      "name:protocolid:[host ip]:host port:[guest ip]:guest port".
     1362      </desc>
     1363    </attribute>
     1364    <attribute name="portForwardRules6" type="wstring" readonly="yes" safearray="yes">
     1365      <desc>Array of NAT port-forwarding rules in string representation, in the
     1366      following format: "name:protocolid:[host ip]:host port:[guest ip]:guest port".
     1367      </desc>
     1368    </attribute>
     1369    <method name="addPortForwardRule">
     1370      <param name="isIpv6" type="boolean" dir="in"/>
     1371      <param name="ruleName" type="wstring" dir="in"/>
     1372      <param name="proto" type="NATProtocol" dir="in">
     1373        <desc>Protocol handled with the rule.</desc>
     1374      </param>
     1375      <param name="hostIP" type="wstring" dir="in">
     1376        <desc>IP of the host interface to which the rule should apply.
     1377        An empty ip address is acceptable, in which case the NAT engine
     1378        binds the handling socket to any interface.
     1379        </desc>
     1380      </param>
     1381      <param name="hostPort" type="unsigned short" dir="in">
     1382        <desc>The port number to listen on.</desc>
     1383      </param>
     1384      <param name="guestIP" type="wstring" dir="in">
     1385        <desc>The IP address of the guest which the NAT engine will forward
     1386        matching packets to. An empty IP address is not acceptable.</desc>
     1387        </param>
     1388        <param name="guestPort" type="unsigned short" dir="in">
     1389          <desc>The port number to forward.</desc>
     1390        </param>
     1391    </method>
     1392    <method name="removePortForwardRule">
     1393      <param name="iSipv6" type="boolean" dir="in"/>
     1394      <param name="ruleName" type="wstring" dir="in"/>
     1395    </method>
     1396    <method name="start">
     1397      <param name="trunkType" type="wstring" dir="in">
     1398        <desc>
     1399          Type of internal network trunk.
     1400        </desc>
     1401      </param>
     1402    </method>
     1403    <method name="stop"/>
     1404  </interface>
    13181405
    13191406  <interface
     
    14301517  <interface
    14311518    name="IVirtualBox" extends="$unknown"
    1432     uuid="3b2f08eb-b810-4715-bee0-bb06b9880ad2"
     1519    uuid="fafa4e17-1ee2-4905-a10e-fe7c18bf5554"
    14331520    wsmap="managed"
    14341521    >
     
    15981685      </desc>
    15991686    </attribute>
     1687    <!-- Array of NAT networks -->
     1688    <attribute name="NATNetworks" type="INATNetwork" safearray="yes" readonly="yes"/>
    16001689
    16011690    <attribute name="eventSource" type="IEventSource" readonly="yes">
     
    22752364    </method>
    22762365
     2366    <!-- bunch of metods to create NAT -->
     2367    <method name="createNATNetwork">
     2368      <!-- Here we create a record in NAT network array with name
     2369           and gateway/network parameters this information should
     2370           be enough for VBoxNet[Lwip]NAT and VBoxNetDHCP for
     2371           servicing the guests.
     2372      -->
     2373      <param name="networkName" type="wstring" dir="in"/>
     2374      <param name="network" type="INATNetwork" dir="return"/>
     2375    </method>
     2376 
     2377     <!--
     2378          Returns the NATNetwork by name, e.g. for adding porforward rule or delition.
     2379      -->
     2380     <method name="findNATNetworkByName">
     2381      <param name="networkName" type="wstring" dir="in"/>
     2382      <param name="network" type="INATNetwork" dir="return"/>
     2383    </method>
     2384    <!--
     2385        Deletes given NAT network.
     2386     -->
     2387    <method name="removeNATNetwork">
     2388       <param name="network" type="INATNetwork" dir="in"/>
     2389    </method>
    22772390
    22782391    <method name="checkFirmwarePresent">
     
    1872418837      </desc>
    1872518838    </const>
     18839    <const name="OnNATNetworkChanged" value="74">
     18840      <desc>
     18841        See <link to="INATNetworkChangedEvent">INATNetworkChangedEvent</link>.
     18842      </desc>
     18843    </const>
     18844    <const name="OnNATNetworkStartStop" value="75">
     18845      <desc>
     18846        See <link to="INATNetworkStartStopEvent">INATNetworkStartStopEvent</link>.
     18847      </desc>
     18848    </const>
     18849    <const name="OnNATNetworkAlter" value="76">
     18850      <desc>
     18851        See <link to="INATNetworkAlterEvent">INATNetworkAlterEvent</link>.
     18852      </desc>
     18853    </const>
     18854    <const name="OnNATNetworkCreationDeletion" value="77">
     18855      <desc>
     18856        See <link to="INATNetworkCreationDeletionEvent">INATNetworkCreationDeletionEvent</link>.
     18857      </desc>
     18858    </const>
     18859    <const name="OnNATNetworkSetting" value="78">
     18860      <desc>
     18861        See <link to="INATNetworkSettingEvent">INATNetworkSettingEvent</link>.
     18862      </desc>
     18863    </const>
     18864    <const name="OnNATNetworkPortForward" value="79">
     18865      <desc>
     18866        See <link to="INATNetworkPortForwardEvent">INATNetworkPortForwardEvent</link>.
     18867      </desc>
     18868    </const>
    1872618869
    1872718870    <!-- Last event marker -->
    18728     <const name="Last" value="74">
     18871    <const name="Last" value="80">
    1872918872      <desc>
    1873018873        Must be last event, used for iterations and structures relying on numerical event values.
     
    2018220325    </attribute>
    2018320326  </interface>
    20184 
     20327  <interface
     20328    name="INATNetworkChangedEvent" extends="IEvent"
     20329    uuid="101ae042-1a29-4a19-92cf-02285773f3b5"
     20330    wsmap="managed" autogen="VBoxEvent" id="OnNATNetworkChanged"
     20331    >
     20332    <!-- network name is common setting for all event types -->
     20333    <attribute name="NetworkName" type="wstring" readonly="yes"/>
     20334  </interface>
     20335  <!-- base class for start/stop events -->
     20336  <interface name="INATNetworkStartStopEvent" extends="INATNetworkChangedEvent"
     20337             uuid="269d8f6b-fa1e-4cee-91c7-6d8496bea3c1"
     20338             wsmap="managed" autogen="VBoxEvent" id="OnNATNetworkStartStop">
     20339    <attribute name="startEvent" type="boolean" readonly="yes">
     20340      <desc>
     20341        IsStartEvent is true when NAT network is started and false on stopping.
     20342      </desc>
     20343    </attribute>
     20344  </interface>
     20345 
     20346  <!-- base class for modification events -->
     20347  <interface name="INATNetworkAlterEvent" extends="INATNetworkChangedEvent"
     20348             uuid="3f5a0822-163a-43b1-ad16-8d58b0ef6e75"
     20349             wsmap="managed" autogen="VBoxEvent" id="OnNATNetworkAlter"/>
     20350 
     20351  <interface name="INATNetworkCreationDeletionEvent" extends="INATNetworkAlterEvent"
     20352             uuid="8d984a7e-b855-40b8-ab0c-44d3515b4528"
     20353             wsmap="managed" autogen="VBoxEvent" id="OnNATNetworkCreationDeletion">
     20354    <attribute name="creationEvent" type="boolean" readonly="yes"/>
     20355  </interface>
     20356  <interface name="INATNetworkSettingEvent" extends="INATNetworkAlterEvent"
     20357             uuid="9db3a9e6-7f29-4aae-a627-5a282c83092c"
     20358             wsmap="managed" autogen="VBoxEvent" id="OnNATNetworkSetting">
     20359    <attribute name="enabled" type="boolean" readonly="yes"/>
     20360    <attribute name="network" type="wstring" readonly="yes"/>
     20361    <attribute name="gateway" type="wstring" readonly="yes"/>
     20362    <attribute name="advertiseDefaultIPv6RouteEnabled" type="boolean" readonly="yes"/>
     20363    <attribute name="needDhcpServer" type="boolean" readonly="yes"/>
     20364  </interface>
     20365  <interface name="INATNetworkPortForwardEvent" extends="INATNetworkAlterEvent"
     20366             uuid="2514881b-23d0-430a-a7ff-7ed7f05534bc"
     20367             wsmap="managed" autogen="VBoxEvent" id="OnNATNetworkPortForward">
     20368    <attribute name="create" type="boolean" readonly="yes"/>
     20369    <attribute name="ipv6" type="boolean" readonly="yes"/>
     20370    <attribute name="name"  type="wstring" readonly="yes"/>
     20371    <attribute name="proto"  type="NATProtocol" readonly="yes"/>
     20372    <attribute name="hostIp"  type="wstring" readonly="yes"/>
     20373    <attribute name="hostPort"  type="long" readonly="yes"/>
     20374    <attribute name="guestIp"  type="wstring" readonly="yes"/>
     20375    <attribute name="guestPort"  type="long" readonly="yes"/>
     20376  </interface>
     20377 
    2018520378  <module name="VBoxSVC" context="LocalServer">
    2018620379    <class name="VirtualBox" uuid="B1A7A4F2-47B9-4A1E-82B2-07CCD5323C3F"
  • trunk/src/VBox/Main/include/VirtualBoxImpl.h

    r45119 r45138  
    4444#endif
    4545class AutostartDb;
     46class NATNetwork;
     47
    4648
    4749typedef std::list<ComObjPtr<SessionMachine> > SessionMachinesList;
     
    121123    STDMETHOD(COMGETTER(PerformanceCollector))(IPerformanceCollector **aPerformanceCollector);
    122124    STDMETHOD(COMGETTER(DHCPServers))(ComSafeArrayOut(IDHCPServer *, aDHCPServers));
     125    STDMETHOD(COMGETTER(NATNetworks))(ComSafeArrayOut(INATNetwork *, aNATNetworks));
    123126    STDMETHOD(COMGETTER(EventSource))(IEventSource ** aEventSource);
    124127    STDMETHOD(COMGETTER(ExtensionPackManager))(IExtPackManager **aExtPackManager);
     
    161164    STDMETHOD(FindDHCPServerByNetworkName)(IN_BSTR aName, IDHCPServer ** aServer);
    162165    STDMETHOD(RemoveDHCPServer)(IDHCPServer * aServer);
     166
     167    STDMETHOD(CreateNATNetwork)(IN_BSTR aName, INATNetwork ** aNATNetworks);
     168    STDMETHOD(FindNATNetworkByName)(IN_BSTR aName, INATNetwork ** aNATNetworks);
     169    STDMETHOD(RemoveNATNetwork)(INATNetwork * aNATNetwork);
     170
    163171    STDMETHOD(CheckFirmwarePresent)(FirmwareType_T aFirmwareType, IN_BSTR aVersion,
    164172                                    BSTR * aUrl, BSTR * aFile, BOOL * aResult);
     
    212220                                   NATProtocol_T aProto, IN_BSTR aHostIp, uint16_t aHostPort,
    213221                                   IN_BSTR aGuestIp, uint16_t aGuestPort);
     222    void onNATNetworkChange(IN_BSTR aNetworkName);
     223    void onNATNetworkStartStop(IN_BSTR aNetworkName, BOOL aStart);
     224    void onNATNetworkSetting(IN_BSTR aNetworkName, BOOL aEnabled, IN_BSTR aNetwork,
     225                             IN_BSTR aGateway, BOOL aAdvertiseDefaultIpv6RouteEnabled,
     226                             BOOL fNeedDhcpServer);
     227    void onNATNetworkPortForward(IN_BSTR aNetworkName, BOOL create, BOOL fIpv6,
     228                                 IN_BSTR aRuleName, NATProtocol_T proto,
     229                                 IN_BSTR aHostIp, LONG aHostPort,
     230                                 IN_BSTR aGuestIp, LONG aGuestPort);
    214231
    215232    ComObjPtr<GuestOSType> getUnknownOSType();
     
    318335    HRESULT unregisterDHCPServer(DHCPServer *aDHCPServer,
    319336                                 bool aSaveRegistry = true);
    320 
     337    HRESULT registerNATNetwork(NATNetwork *aNATNetwork,
     338                               bool aSaveRegistry = true);
     339    HRESULT unregisterNATNetwork(NATNetwork *aNATNetwork,
     340                                 bool aSaveRegistry = true);
    321341    HRESULT checkMediaForConflicts(const Guid &aId,
    322342                                   const Utf8Str &aLocation,
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r45119 r45138  
    6363#include "DHCPServerRunner.h"
    6464#include "DHCPServerImpl.h"
     65#include "NATNetworkImpl.h"
    6566#ifdef VBOX_WITH_RESOURCE_USAGE_API
    6667# include "PerformanceImpl.h"
     
    182183typedef ObjectsList<SharedFolder> SharedFoldersOList;
    183184typedef ObjectsList<DHCPServer> DHCPServersOList;
     185typedef ObjectsList<NATNetwork> NATNetworksOList;
    184186
    185187typedef std::map<Guid, ComPtr<IProgress> > ProgressMap;
     
    209211          lockDHCPServers(LOCKCLASS_LISTOFOTHEROBJECTS),
    210212          allDHCPServers(lockDHCPServers),
     213          lockNATNetworks(LOCKCLASS_LISTOFOTHEROBJECTS),
     214          allNATNetworks(lockNATNetworks),
    211215          mtxProgressOperations(LOCKCLASS_PROGRESSLIST),
    212216          updateReq(UPDATEREQARG),
     
    286290    RWLockHandle                        lockDHCPServers;
    287291    DHCPServersOList                    allDHCPServers;
     292   
     293    RWLockHandle                         lockNATNetworks;
     294    NATNetworksOList                     allNATNetworks;
    288295
    289296    RWLockHandle                        mtxProgressOperations;
     
    486493#endif
    487494
    488         /* net services */
     495        /* net services - dhcp services */
    489496        for (settings::DHCPServersList::const_iterator it = m->pMainConfigFile->llDhcpServers.begin();
    490497             it != m->pMainConfigFile->llDhcpServers.end();
     
    499506
    500507            rc = registerDHCPServer(pDhcpServer, false /* aSaveRegistry */);
     508            if (FAILED(rc)) throw rc;
     509        }
     510
     511        /* net services - nat networks */
     512        for (settings::NATNetworksList::const_iterator it = m->pMainConfigFile->llNATNetworks.begin();
     513             it != m->pMainConfigFile->llNATNetworks.end();
     514             ++it)
     515        {
     516            const settings::NATNetwork &net = *it;
     517
     518            ComObjPtr<NATNetwork> pNATNetwork;
     519            if (SUCCEEDED(rc = pNATNetwork.createObject()))
     520                rc = pNATNetwork->init(this, net);
     521            if (FAILED(rc)) throw rc;
     522
     523            rc = registerNATNetwork(pNATNetwork, false /* aSaveRegistry */);
    501524            if (FAILED(rc)) throw rc;
    502525        }
     
    11481171    return S_OK;
    11491172}
     1173
     1174
     1175STDMETHODIMP
     1176VirtualBox::COMGETTER(NATNetworks)(ComSafeArrayOut(INATNetwork *, aNATNetworks))
     1177{
     1178#ifdef VBOX_WITH_NAT_SERVICE
     1179    CheckComArgOutSafeArrayPointerValid(aNATNetworks);
     1180
     1181    AutoCaller autoCaller(this);
     1182    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     1183
     1184    AutoReadLock al(m->allNATNetworks.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     1185    SafeIfaceArray<INATNetwork> nets(m->allNATNetworks.getList());
     1186    nets.detachTo(ComSafeArrayOutArg(aNATNetworks));
     1187
     1188    return S_OK;
     1189#else
     1190    NOREF(aNATNetworks);
     1191    NOREF(aNATNetworksSize);
     1192    return E_NOTIMPL;
     1193#endif
     1194}
     1195
    11501196
    11511197STDMETHODIMP
     
    31233169}
    31243170
     3171void VirtualBox::onNATNetworkChange(IN_BSTR aName)
     3172{
     3173    fireNATNetworkChangedEvent(m->pEventSource, aName);
     3174}
     3175
     3176void VirtualBox::onNATNetworkStartStop(IN_BSTR aName, BOOL fStart)
     3177{
     3178    fireNATNetworkStartStopEvent(m->pEventSource, aName, fStart);
     3179}
     3180void VirtualBox::onNATNetworkSetting(IN_BSTR aNetworkName, BOOL aEnabled,
     3181                                     IN_BSTR aNetwork, IN_BSTR aGateway,
     3182                                     BOOL aAdvertiseDefaultIpv6RouteEnabled,
     3183                                     BOOL fNeedDhcpServer)
     3184{
     3185    fireNATNetworkSettingEvent(m->pEventSource, aNetworkName, aEnabled,
     3186                               aNetwork, aGateway,
     3187                               aAdvertiseDefaultIpv6RouteEnabled, fNeedDhcpServer);
     3188}
     3189
     3190void VirtualBox::onNATNetworkPortForward(IN_BSTR aNetworkName, BOOL create, BOOL fIpv6,
     3191                                         IN_BSTR aRuleName, NATProtocol_T proto,
     3192                                         IN_BSTR aHostIp, LONG aHostPort,
     3193                                         IN_BSTR aGuestIp, LONG aGuestPort)
     3194{
     3195    fireNATNetworkPortForwardEvent(m->pEventSource, aNetworkName, create,
     3196                                   fIpv6, aRuleName, proto,
     3197                                   aHostIp, aHostPort,
     3198                                   aGuestIp, aGuestPort);
     3199}
     3200
    31253201/**
    31263202 *  @note Locks this object for reading.
     
    41994275            }
    42004276        }
     4277
     4278#ifdef VBOX_WITH_NAT_SERVICE
     4279        /* Saving NAT Network configuration */
     4280        m->pMainConfigFile->llNATNetworks.clear();
     4281        {
     4282            AutoReadLock natNetworkLock(m->allNATNetworks.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     4283            for (NATNetworksOList::const_iterator it = m->allNATNetworks.begin();
     4284                 it != m->allNATNetworks.end();
     4285                 ++it)
     4286            {
     4287                settings::NATNetwork n;
     4288                rc = (*it)->saveSettings(n);
     4289                if (FAILED(rc)) throw rc;
     4290                m->pMainConfigFile->llNATNetworks.push_back(n);
     4291            }
     4292        }
     4293#endif
    42014294
    42024295        // leave extra data alone, it's still in the config file
     
    54935586}
    54945587
     5588
     5589/**
     5590 * NAT Network
     5591 */
     5592
     5593STDMETHODIMP VirtualBox::CreateNATNetwork(IN_BSTR aName, INATNetwork ** aNatNetwork)
     5594{
     5595#ifdef VBOX_WITH_NAT_SERVICE
     5596    CheckComArgStrNotEmptyOrNull(aName);
     5597    CheckComArgNotNull(aNatNetwork);
     5598
     5599    AutoCaller autoCaller(this);
     5600    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     5601
     5602    ComObjPtr<NATNetwork> natNetwork;
     5603    natNetwork.createObject();
     5604    HRESULT rc = natNetwork->init(this, aName);
     5605    if (FAILED(rc)) return rc;
     5606
     5607    rc = registerNATNetwork(natNetwork, true);
     5608    if (FAILED(rc)) return rc;
     5609
     5610    natNetwork.queryInterfaceTo(aNatNetwork);
     5611
     5612    fireNATNetworkCreationDeletionEvent(m->pEventSource, aName, TRUE);
     5613    return rc;
     5614#else
     5615    NOREF(aName);
     5616    NOREF(aNatNetwork);
     5617    return E_NOTIMPL;
     5618#endif
     5619}
     5620
     5621STDMETHODIMP VirtualBox::FindNATNetworkByName(IN_BSTR aName, INATNetwork ** aNetwork)
     5622{
     5623#ifdef VBOX_WITH_NAT_SERVICE
     5624    CheckComArgStrNotEmptyOrNull(aName);
     5625    CheckComArgNotNull(aNetwork);
     5626
     5627    AutoCaller autoCaller(this);
     5628    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     5629
     5630    HRESULT rc;
     5631    Bstr bstr;
     5632    ComPtr<NATNetwork> found;
     5633
     5634    AutoReadLock alock(m->allNATNetworks.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     5635
     5636    for (NATNetworksOList::const_iterator it = m->allNATNetworks.begin();
     5637         it != m->allNATNetworks.end();
     5638         ++it)
     5639    {
     5640        rc = (*it)->COMGETTER(NetworkName)(bstr.asOutParam());
     5641        if (FAILED(rc)) return rc;
     5642
     5643        if (bstr == aName)
     5644        {
     5645            found = *it;
     5646            break;
     5647        }
     5648    }
     5649
     5650    if (!found)
     5651        return E_INVALIDARG;
     5652
     5653    return found.queryInterfaceTo(aNetwork);
     5654#else
     5655    NOREF(aName);
     5656    NOREF(aNetwork);
     5657    return E_NOTIMPL;
     5658#endif
     5659}
     5660
     5661STDMETHODIMP VirtualBox::RemoveNATNetwork(INATNetwork * aNetwork)
     5662{
     5663#ifdef VBOX_WITH_NAT_SERVICE
     5664    CheckComArgNotNull(aNetwork);
     5665
     5666    AutoCaller autoCaller(this);
     5667    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     5668    Bstr name;
     5669    HRESULT rc;
     5670    NATNetwork *network = static_cast<NATNetwork *>(aNetwork);
     5671    rc = network->COMGETTER(NetworkName)(name.asOutParam());
     5672    rc = unregisterNATNetwork(network, true);
     5673    fireNATNetworkCreationDeletionEvent(m->pEventSource, name.raw(), FALSE);
     5674    return rc;
     5675#else
     5676    NOREF(aNetwork);
     5677    return E_NOTIMPL;
     5678#endif
     5679
     5680}
     5681/**
     5682 * Remembers the given NAT network in the settings.
     5683 *
     5684 * @param aNATNetwork    NAT Network object to remember.
     5685 * @param aSaveSettings @c true to save settings to disk (default).
     5686 *
     5687 *
     5688 * @note Locks this object for writing and @a aNATNetwork for reading.
     5689 */
     5690HRESULT VirtualBox::registerNATNetwork(NATNetwork *aNATNetwork,
     5691                                       bool aSaveSettings /*= true*/)
     5692{
     5693#ifdef VBOX_WITH_NAT_SERVICE
     5694    AssertReturn(aNATNetwork != NULL, E_INVALIDARG);
     5695
     5696    AutoCaller autoCaller(this);
     5697    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
     5698
     5699    AutoCaller natNetworkCaller(aNATNetwork);
     5700    AssertComRCReturn(natNetworkCaller.rc(), natNetworkCaller.rc());
     5701
     5702    Bstr name;
     5703    HRESULT rc;
     5704    rc = aNATNetwork->COMGETTER(NetworkName)(name.asOutParam());
     5705    if (FAILED(rc)) return rc;
     5706
     5707    ComPtr<INATNetwork> existing;
     5708    rc = FindNATNetworkByName(name.raw(), existing.asOutParam());
     5709    if (SUCCEEDED(rc))
     5710        return E_INVALIDARG;
     5711
     5712    rc = S_OK;
     5713
     5714    m->allNATNetworks.addChild(aNATNetwork);
     5715
     5716    if (aSaveSettings)
     5717    {
     5718        AutoWriteLock vboxLock(this COMMA_LOCKVAL_SRC_POS);
     5719        rc = saveSettings();
     5720        vboxLock.release();
     5721
     5722        if (FAILED(rc))
     5723            unregisterNATNetwork(aNATNetwork, false /* aSaveSettings */);
     5724    }
     5725
     5726    return rc;
     5727#else
     5728    NOREF(aNATNetwork);
     5729    NOREF(aSaveSettings);
     5730    return E_NOTIMPL;
     5731#endif
     5732}
     5733
     5734/**
     5735 * Removes the given NAT network from the settings.
     5736 *
     5737 * @param aNATNetwork   NAT network object to remove.
     5738 * @param aSaveSettings @c true to save settings to disk (default).
     5739 *
     5740 * When @a aSaveSettings is @c true, this operation may fail because of the
     5741 * failed #saveSettings() method it calls. In this case, the DHCP server
     5742 * will NOT be removed from the settingsi when this method returns.
     5743 *
     5744 * @note Locks this object for writing.
     5745 */
     5746HRESULT VirtualBox::unregisterNATNetwork(NATNetwork *aNATNetwork,
     5747                                         bool aSaveSettings /*= true*/)
     5748{
     5749#ifdef VBOX_WITH_NAT_SERVICE
     5750    AssertReturn(aNATNetwork != NULL, E_INVALIDARG);
     5751
     5752    AutoCaller autoCaller(this);
     5753    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
     5754
     5755    AutoCaller natNetworkCaller(aNATNetwork);
     5756    AssertComRCReturn(natNetworkCaller.rc(), natNetworkCaller.rc());
     5757
     5758    m->allNATNetworks.removeChild(aNATNetwork);
     5759
     5760    HRESULT rc = S_OK;
     5761
     5762    if (aSaveSettings)
     5763    {
     5764        AutoWriteLock vboxLock(this COMMA_LOCKVAL_SRC_POS);
     5765        rc = saveSettings();
     5766        vboxLock.release();
     5767
     5768        if (FAILED(rc))
     5769            registerNATNetwork(aNATNetwork, false /* aSaveSettings */);
     5770    }
     5771
     5772    return rc;
     5773#else
     5774    NOREF(aNATNetwork);
     5775    NOREF(aSaveSettings);
     5776    return E_NOTIMPL;
     5777#endif
     5778}
    54955779/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/src-server/xpcom/server.cpp

    r45119 r45138  
    9696# include "ExtPackManagerImpl.h"
    9797#endif
     98# include "NATNetworkImpl.h"
     99
    98100
    99101/* implement nsISupports parts of our objects with support for nsIClassInfo */
     
    152154NS_DECL_CLASSINFO(DHCPServer)
    153155NS_IMPL_THREADSAFE_ISUPPORTS1_CI(DHCPServer, IDHCPServer)
     156
     157NS_DECL_CLASSINFO(NATNetwork)
     158NS_IMPL_THREADSAFE_ISUPPORTS1_CI(NATNetwork, INATNetwork)
    154159
    155160NS_DECL_CLASSINFO(GuestOSType)
  • trunk/src/VBox/Main/xml/Settings.cpp

    r45119 r45138  
    812812
    813813/**
     814 * This is common version for reading NAT port forward rule in per-_machine's_adapter_ and
     815 * per-network approaches.
     816 * Note: this function doesn't in fill given list from xml::ElementNodesList, because there is conflicting
     817 * deaclration in ovmfreader.h.
     818 */
     819void ConfigFileBase::readNATForwardRuleList(const xml::ElementNode &elmParent, NATRuleList &llRules)
     820{
     821    xml::ElementNodesList plstRules;
     822    elmParent.getChildElements(plstRules, "Forwarding");
     823    for (xml::ElementNodesList::iterator pf = plstRules.begin(); pf != plstRules.end(); ++pf)
     824    {
     825        NATRule rule;
     826        uint32_t port = 0;
     827        (*pf)->getAttributeValue("name", rule.strName);
     828        (*pf)->getAttributeValue("proto", (uint32_t&)rule.proto);
     829        (*pf)->getAttributeValue("hostip", rule.strHostIP);
     830        (*pf)->getAttributeValue("hostport", port);
     831        rule.u16HostPort = port;
     832        (*pf)->getAttributeValue("guestip", rule.strGuestIP);
     833        (*pf)->getAttributeValue("guestport", port);
     834        rule.u16GuestPort = port;
     835        llRules.push_back(rule);
     836    }
     837}
     838
     839/**
    814840 * Adds a "version" attribute to the given XML element with the
    815841 * VirtualBox settings version (e.g. "1.10-linux"). Used by
     
    11411167
    11421168/**
     1169 * Serialize NAT port-forwarding rules in parent container.
     1170 * Note: it's responsibility of caller to create parent of the list tag.
     1171 * because this method used for serializing per-_mahine's_adapter_ and per-network approaches.
     1172 */
     1173void ConfigFileBase::buildNATForwardRuleList(xml::ElementNode &elmParent, const NATRuleList &natRuleList)
     1174{
     1175    for (NATRuleList::const_iterator r = natRuleList.begin();
     1176         r != natRuleList.end(); ++r)
     1177      {
     1178          xml::ElementNode *pelmPF;
     1179          pelmPF = elmParent.createChild("Forwarding");
     1180          if ((*r).strName.length())
     1181            pelmPF->setAttribute("name", (*r).strName);
     1182          pelmPF->setAttribute("proto", (*r).proto);
     1183          if ((*r).strHostIP.length())
     1184            pelmPF->setAttribute("hostip", (*r).strHostIP);
     1185          if ((*r).u16HostPort)
     1186            pelmPF->setAttribute("hostport", (*r).u16HostPort);
     1187          if ((*r).strGuestIP.length())
     1188            pelmPF->setAttribute("guestip", (*r).strGuestIP);
     1189          if ((*r).u16GuestPort)
     1190            pelmPF->setAttribute("guestport", (*r).u16GuestPort);
     1191      }
     1192}
     1193/**
    11431194 * Cleans up memory allocated by the internal XML parser. To be called by
    11441195 * descendant classes when they're done analyzing the DOM tree to discard it.
     
    12581309            else
    12591310                throw ConfigFileError(this, pelmServer, N_("Required DHCPServer/@networkName, @IPAddress, @networkMask, @lowerIP, @upperIP or @enabled attribute is missing"));
     1311        }
     1312    }
     1313}
     1314
     1315/**
     1316 * Reads in the <NATNetworks> chunk.
     1317 * @param elmNATNetworks
     1318 */
     1319void MainConfigFile::readNATNetworks(const xml::ElementNode &elmNATNetworks)
     1320{
     1321    xml::NodesLoop nl1(elmNATNetworks);
     1322    const xml::ElementNode *pelmNet;
     1323    while ((pelmNet = nl1.forAllNodes()))
     1324    {
     1325        if (pelmNet->nameEquals("NATNetwork"))
     1326        {
     1327            NATNetwork net;
     1328            if (    (pelmNet->getAttributeValue("networkName", net.strNetworkName))
     1329                 && (pelmNet->getAttributeValue("enabled", net.fEnabled))
     1330                 && (pelmNet->getAttributeValue("network", net.strNetwork))
     1331                 && (pelmNet->getAttributeValue("ipv6", net.fIPv6))
     1332                 && (pelmNet->getAttributeValue("ipv6prefix", net.strIPv6Prefix))
     1333                 && (pelmNet->getAttributeValue("advertiseDefaultIPv6Route", net.fAdvertiseDefaultIPv6Route))
     1334                 && (pelmNet->getAttributeValue("needDhcp", net.fNeedDhcpServer))
     1335               )
     1336              {
     1337                  const xml::ElementNode *pelmPortForwardRules4;
     1338                  if ((pelmPortForwardRules4 = pelmNet->findChildElement("PortForwarding4")))
     1339                    readNATForwardRuleList(*pelmPortForwardRules4,
     1340                                            net.llPortForwardRules4);             
     1341                 
     1342                  const xml::ElementNode *pelmPortForwardRules6;
     1343                  if ((pelmPortForwardRules6 = pelmNet->findChildElement("PortForwarding6")))
     1344                    readNATForwardRuleList(*pelmPortForwardRules6,
     1345                                            net.llPortForwardRules6);             
     1346                 
     1347                  llNATNetworks.push_back(net);
     1348              }
     1349            else
     1350                throw ConfigFileError(this, pelmNet, N_("Required NATNetwork/@networkName, @gateway, @network,@advertiseDefaultIpv6Route , @needDhcp or @enabled attribute is missing"));
    12601351        }
    12611352    }
     
    13231414                            if (pelmLevel4Child->nameEquals("DHCPServers"))
    13241415                                readDHCPServers(*pelmLevel4Child);
     1416                            if (pelmLevel4Child->nameEquals("NATNetworks"))
     1417                                readNATNetworks(*pelmLevel4Child);
    13251418                        }
    13261419                    }
     
    14011494        pelmThis->setAttribute("enabled", (d.fEnabled) ? 1 : 0);        // too bad we chose 1 vs. 0 here
    14021495    }
     1496    /* TODO: bump main version ? */
     1497    xml::ElementNode *pelmNATNetworks;
     1498    /* don't create entry if no NAT networks are registered. */
     1499    if (!llNATNetworks.empty())
     1500    {
     1501        pelmNATNetworks = pelmNetserviceRegistry->createChild("NATNetworks");
     1502        for (NATNetworksList::const_iterator it = llNATNetworks.begin();
     1503             it != llNATNetworks.end();
     1504             ++it)
     1505        {
     1506            const NATNetwork &n = *it;
     1507            xml::ElementNode *pelmThis = pelmNATNetworks->createChild("NATNetwork");
     1508            pelmThis->setAttribute("networkName", n.strNetworkName);
     1509            pelmThis->setAttribute("network", n.strNetwork);
     1510            pelmThis->setAttribute("ipv6", n.fIPv6 ? 1 : 0);
     1511            pelmThis->setAttribute("ipv6prefix", n.strIPv6Prefix);
     1512            pelmThis->setAttribute("advertiseDefaultIPv6Route", (n.fAdvertiseDefaultIPv6Route)? 1 : 0);
     1513            pelmThis->setAttribute("needDhcp", (n.fNeedDhcpServer) ? 1 : 0);
     1514            pelmThis->setAttribute("enabled", (n.fEnabled) ? 1 : 0);        // too bad we chose 1 vs. 0 here
     1515            if (n.llPortForwardRules4.size())
     1516            {
     1517                xml::ElementNode *pelmPf4 = pelmThis->createChild("PortForwarding4");
     1518                buildNATForwardRuleList(*pelmPf4, n.llPortForwardRules4);
     1519            }
     1520            if (n.llPortForwardRules6.size())
     1521            {
     1522                xml::ElementNode *pelmPf6 = pelmThis->createChild("PortForwarding6");
     1523                buildNATForwardRuleList(*pelmPf6, n.llPortForwardRules6);
     1524            }
     1525        }
     1526    }
     1527
    14031528
    14041529    xml::ElementNode *pelmSysProps = pelmGlobal->createChild("SystemProperties");
     
    20842209            pelmTFTP->getAttributeValue("next-server", nic.nat.strTFTPNextServer);
    20852210        }
    2086         xml::ElementNodesList plstNatPF;
    2087         elmMode.getChildElements(plstNatPF, "Forwarding");
    2088         for (xml::ElementNodesList::iterator pf = plstNatPF.begin(); pf != plstNatPF.end(); ++pf)
    2089         {
    2090             NATRule rule;
    2091             uint32_t port = 0;
    2092             (*pf)->getAttributeValue("name", rule.strName);
    2093             (*pf)->getAttributeValue("proto", (uint32_t&)rule.proto);
    2094             (*pf)->getAttributeValue("hostip", rule.strHostIP);
    2095             (*pf)->getAttributeValue("hostport", port);
    2096             rule.u16HostPort = port;
    2097             (*pf)->getAttributeValue("guestip", rule.strGuestIP);
    2098             (*pf)->getAttributeValue("guestport", port);
    2099             rule.u16GuestPort = port;
    2100             nic.nat.llRules.push_back(rule);
    2101         }
     2211       
     2212        readNATForwardRuleList(elmMode, nic.nat.llRules);
    21022213    }
    21032214    else if (   (elmMode.nameEquals("HostInterface"))
     
    43104421                    pelmTFTP->setAttribute("next-server", nic.nat.strTFTPNextServer);
    43114422            }
    4312             for (NATRuleList::const_iterator rule = nic.nat.llRules.begin();
    4313                     rule != nic.nat.llRules.end(); ++rule)
    4314             {
    4315                 xml::ElementNode *pelmPF;
    4316                 pelmPF = pelmNAT->createChild("Forwarding");
    4317                 if ((*rule).strName.length())
    4318                     pelmPF->setAttribute("name", (*rule).strName);
    4319                 pelmPF->setAttribute("proto", (*rule).proto);
    4320                 if ((*rule).strHostIP.length())
    4321                     pelmPF->setAttribute("hostip", (*rule).strHostIP);
    4322                 if ((*rule).u16HostPort)
    4323                     pelmPF->setAttribute("hostport", (*rule).u16HostPort);
    4324                 if ((*rule).strGuestIP.length())
    4325                     pelmPF->setAttribute("guestip", (*rule).strGuestIP);
    4326                 if ((*rule).u16GuestPort)
    4327                     pelmPF->setAttribute("guestport", (*rule).u16GuestPort);
    4328             }
     4423            buildNATForwardRuleList(*pelmNAT, nic.nat.llRules);
    43294424            break;
    43304425
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