NATNetworkImpl.cpp revision 152b12e401b58b34fbdbf2a4510152b67884ee89
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/* $Id$ */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/** @file
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * VirtualBox COM class implementation
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * Copyright (C) 2013 Oracle Corporation
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * This file is part of VirtualBox Open Source Edition (OSE), as
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * available from http://www.virtualbox.org. This file is free software;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * you can redistribute it and/or modify it under the terms of the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * General Public License (GPL) as published by the Free Software
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * Foundation, in version 2 as it comes in the "COPYING" file of the
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "NetworkServiceRunner.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "DHCPServerImpl.h"
a0166609f782da91710dea9183d1bf138538db37Tom Gundersen#include "NATNetworkImpl.h"
71d35b6b5563817dfbe757ab9e3b9f018b2db491Thomas Hindoe Paaboel Andersen#include "AutoCaller.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "Logging.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering#include <iprt/asm.h>
71d35b6b5563817dfbe757ab9e3b9f018b2db491Thomas Hindoe Paaboel Andersen#include <iprt/cpp/utils.h>
71d35b6b5563817dfbe757ab9e3b9f018b2db491Thomas Hindoe Paaboel Andersen#include <iprt/cidr.h>
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering#include <iprt/net.h>
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering#include <VBox/com/array.h>
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering#include <VBox/com/ptr.h>
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering#include <VBox/settings.h>
51323288fc628a5cac50914df915545d685b793eLennart Poettering
71d35b6b5563817dfbe757ab9e3b9f018b2db491Thomas Hindoe Paaboel Andersen#include "EventImpl.h"
71d35b6b5563817dfbe757ab9e3b9f018b2db491Thomas Hindoe Paaboel Andersen#include "VBoxEvents.h"
71d35b6b5563817dfbe757ab9e3b9f018b2db491Thomas Hindoe Paaboel Andersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "VirtualBoxImpl.h"
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering// constructor / destructor
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering/////////////////////////////////////////////////////////////////////////////
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poetteringstruct NATNetwork::Data
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering{
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering Data() :
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fEnabled(FALSE),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fIPv6Enabled(FALSE),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fAdvertiseDefaultIPv6Route(FALSE),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fNeedDhcpServer(FALSE)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering IPv4Gateway.setNull();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering IPv4NetworkCidr.setNull();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering IPv6Prefix.setNull();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering IPv4DhcpServer.setNull();
a0166609f782da91710dea9183d1bf138538db37Tom Gundersen IPv4NetworkMask.setNull();
c73ce96b569e2f10dff64b7dc0bd271972674c2aLennart Poettering IPv4DhcpServerLowerIp.setNull();
c73ce96b569e2f10dff64b7dc0bd271972674c2aLennart Poettering IPv4DhcpServerUpperIp.setNull();
c73ce96b569e2f10dff64b7dc0bd271972674c2aLennart Poettering }
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering virtual ~Data(){}
c73ce96b569e2f10dff64b7dc0bd271972674c2aLennart Poettering const ComObjPtr<EventSource> pEventSource;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering#ifdef VBOX_WITH_NAT_SERVICE
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering NATNetworkServiceRunner NATRunner;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering ComObjPtr<IDHCPServer> dhcpServer;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering#endif
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen Bstr IPv4Gateway;
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen Bstr IPv4NetworkCidr;
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen Bstr IPv4NetworkMask;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Bstr IPv4DhcpServer;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Bstr IPv4DhcpServerLowerIp;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Bstr IPv4DhcpServerUpperIp;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering BOOL fEnabled;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering BOOL fIPv6Enabled;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Bstr IPv6Prefix;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering BOOL fAdvertiseDefaultIPv6Route;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering BOOL fNeedDhcpServer;
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering NATRuleMap mapName2PortForwardRule4;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering NATRuleMap mapName2PortForwardRule6;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering};
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart PoetteringNATNetwork::NATNetwork()
d75acfb059ece4512278b8820a9103664996f1e5Lennart Poettering : mVirtualBox(NULL)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering{
dc61b7e45d89a69f0469ab7b3289cdde7fcc55abTorstein Husebø}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart PoetteringNATNetwork::~NATNetwork()
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering{
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
a407657425a3e47fd2b559cd3bc800f791303f63Lennart PoetteringHRESULT NATNetwork::FinalConstruct()
9c491563837983385bf9fa244590e76e142f4fa3Daniel Mack{
9c491563837983385bf9fa244590e76e142f4fa3Daniel Mack return BaseFinalConstruct();
9c491563837983385bf9fa244590e76e142f4fa3Daniel Mack}
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poetteringvoid NATNetwork::FinalRelease()
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering{
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering uninit ();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering BaseFinalRelease();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringvoid NATNetwork::uninit()
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering{
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Enclose the state transition Ready->InUninit->NotReady */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering AutoUninitSpan autoUninitSpan(this);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (autoUninitSpan.uninitDone())
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering delete m;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unconst(mVirtualBox) = NULL;
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering}
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart PoetteringHRESULT NATNetwork::init(VirtualBox *aVirtualBox, IN_BSTR aName)
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack{
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering AssertReturn(aName != NULL, E_INVALIDARG);
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack AutoInitSpan autoInitSpan(this);
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack AssertReturn(autoInitSpan.isOk(), E_FAIL);
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering /* share VirtualBox weakly (parent remains NULL so far) */
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering unconst(mVirtualBox) = aVirtualBox;
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering unconst(mName) = aName;
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering m = new Data();
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering m->IPv4Gateway = "10.0.2.2";
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering m->IPv4NetworkCidr = "10.0.2.0/24";
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering m->IPv6Prefix = "fe80::/64";
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering m->fEnabled = FALSE;
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack RecalculateIpv4AddressAssignments();
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack HRESULT hrc = unconst(m->pEventSource).createObject();
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack if (FAILED(hrc)) throw hrc;
8b757a38611006a751c90933d1810cccaa47e1afDaniel Mack
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering hrc = m->pEventSource->init(static_cast<INATNetwork *>(this));
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering if (FAILED(hrc)) throw hrc;
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering /* Confirm a successful initialization */
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering autoInitSpan.setSucceeded();
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering
f0258e473667f44f4656dde49597b2badb9f598aLennart Poettering return S_OK;
f0258e473667f44f4656dde49597b2badb9f598aLennart Poettering}
f0258e473667f44f4656dde49597b2badb9f598aLennart Poettering
f0258e473667f44f4656dde49597b2badb9f598aLennart Poettering
f0258e473667f44f4656dde49597b2badb9f598aLennart PoetteringHRESULT NATNetwork::init(VirtualBox *aVirtualBox,
f0258e473667f44f4656dde49597b2badb9f598aLennart Poettering const settings::NATNetwork &data)
f0258e473667f44f4656dde49597b2badb9f598aLennart Poettering{
f0258e473667f44f4656dde49597b2badb9f598aLennart Poettering /* Enclose the state transition NotReady->InInit->Ready */
f0258e473667f44f4656dde49597b2badb9f598aLennart Poettering AutoInitSpan autoInitSpan(this);
3cb10d3a0b1b6a7c44f307f2abb5215104e16941Lennart Poettering AssertReturn(autoInitSpan.isOk(), E_FAIL);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering /* share VirtualBox weakly (parent remains NULL so far) */
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering unconst(mVirtualBox) = aVirtualBox;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering unconst(mName) = data.strNetworkName;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering m = new Data();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->IPv4NetworkCidr = data.strNetwork;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering m->fEnabled = data.fEnabled;
24710c48ed16be5fa461fbb303a744a907541dafLennart Poettering m->fAdvertiseDefaultIPv6Route = data.fAdvertiseDefaultIPv6Route;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->fNeedDhcpServer = data.fNeedDhcpServer;
dbfbb6e776d613cb9be76d13de076d08450c9d29Daniel Mack
dbfbb6e776d613cb9be76d13de076d08450c9d29Daniel Mack RecalculateIpv4AddressAssignments();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* IPv4 port-forward rules */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->mapName2PortForwardRule4.clear();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (settings::NATRuleList::const_iterator it = data.llPortForwardRules4.begin();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering it != data.llPortForwardRules4.end(); ++it)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->mapName2PortForwardRule4.insert(std::make_pair(it->strName.c_str(), *it));
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
8af5b883227ac8dfa796742b9edcc1647a5d4d6cLennart Poettering /* IPv6 port-forward rules */
8af5b883227ac8dfa796742b9edcc1647a5d4d6cLennart Poettering m->mapName2PortForwardRule6.clear();
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering for (settings::NATRuleList::const_iterator it = data.llPortForwardRules6.begin();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering it != data.llPortForwardRules6.end(); ++it)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering m->mapName2PortForwardRule6.insert(std::make_pair(it->strName, *it));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering
a3db237b8f1b97867395e1419f39b8ba5749b777Lennart Poettering HRESULT hrc = unconst(m->pEventSource).createObject();
a3db237b8f1b97867395e1419f39b8ba5749b777Lennart Poettering if (FAILED(hrc)) throw hrc;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering hrc = m->pEventSource->init(static_cast<INATNetwork *>(this));
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering if (FAILED(hrc)) throw hrc;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
9c5e12a4314e7192e834e1b855e5e80111e636a6Tom Gundersen autoInitSpan.setSucceeded();
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
9c5e12a4314e7192e834e1b855e5e80111e636a6Tom Gundersen return S_OK;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#ifdef NAT_XML_SERIALIZATION
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringHRESULT NATNetwork::saveSettings(settings::NATNetwork &data)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering{
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering AutoCaller autoCaller(this);
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering if (FAILED(autoCaller.rc())) return autoCaller.rc();
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering
d2579eec5e1b845b2cf29caddc951dc22f2abb91Lennart Poettering AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d2579eec5e1b845b2cf29caddc951dc22f2abb91Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering data.strNetworkName = mName;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering data.strNetwork = m->IPv4NetworkCidr;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering data.fEnabled = RT_BOOL(m->fEnabled);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering data.fAdvertiseDefaultIPv6Route = RT_BOOL(m->fAdvertiseDefaultIPv6Route);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering data.fNeedDhcpServer = RT_BOOL(m->fNeedDhcpServer);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering data.fIPv6 = RT_BOOL(m->fIPv6Enabled);
d830ebbdf67d8cb32d33d8fdd47cf467fd6d3815Lennart Poettering data.strIPv6Prefix = m->IPv6Prefix;
d830ebbdf67d8cb32d33d8fdd47cf467fd6d3815Lennart Poettering
d830ebbdf67d8cb32d33d8fdd47cf467fd6d3815Lennart Poettering /* saving ipv4 port-forward Rules*/
d830ebbdf67d8cb32d33d8fdd47cf467fd6d3815Lennart Poettering data.llPortForwardRules4.clear();
d830ebbdf67d8cb32d33d8fdd47cf467fd6d3815Lennart Poettering for (NATRuleMap::iterator it = m->mapName2PortForwardRule4.begin();
d830ebbdf67d8cb32d33d8fdd47cf467fd6d3815Lennart Poettering it != m->mapName2PortForwardRule4.end(); ++it)
d830ebbdf67d8cb32d33d8fdd47cf467fd6d3815Lennart Poettering data.llPortForwardRules4.push_back(it->second);
d830ebbdf67d8cb32d33d8fdd47cf467fd6d3815Lennart Poettering
f3abbe25403444688e1a1a23b9dbcc9aeefc0507Lennart Poettering /* saving ipv6 port-forward Rules*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering data.llPortForwardRules6.clear();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (NATRuleMap::iterator it = m->mapName2PortForwardRule6.begin();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering it != m->mapName2PortForwardRule6.end(); ++it)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering data.llPortForwardRules4.push_back(it->second);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* XXX: should we do here a copy of params */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* XXX: should we unlock here? */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mVirtualBox->onNATNetworkSetting(mName.raw(),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering data.fEnabled ? TRUE : FALSE,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->IPv4NetworkCidr.raw(),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->IPv4Gateway.raw(),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering data.fAdvertiseDefaultIPv6Route ? TRUE : FALSE,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering data.fNeedDhcpServer ? TRUE : FALSE);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return S_OK;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#endif
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringSTDMETHODIMP NATNetwork::COMGETTER(EventSource)(IEventSource ** aEventSource)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering{
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering CheckComArgOutPointerValid(aEventSource);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering AutoCaller autoCaller(this);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (FAILED(autoCaller.rc())) return autoCaller.rc();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* event source is const, no need to lock */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering m->pEventSource.queryInterfaceTo(aEventSource);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return S_OK;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart PoetteringSTDMETHODIMP NATNetwork::COMGETTER(NetworkName) (BSTR *aName)
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek{
0db4c90afd7d9c7c8884bf8b3ec459edc74a03daDaniel Mack CheckComArgOutPointerValid(aName);
b6c5d46b23a28b5b03601ee1e8162b1bc7c7be25Daniel Mack
0db4c90afd7d9c7c8884bf8b3ec459edc74a03daDaniel Mack AutoCaller autoCaller(this);
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering if (FAILED(autoCaller.rc())) return autoCaller.rc();
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering mName.cloneTo(aName);
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering return S_OK;
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering}
51323288fc628a5cac50914df915545d685b793eLennart Poettering
106784ebb7b303ae471851100a773ad2aebf5b80Daniel MackSTDMETHODIMP NATNetwork::COMSETTER(NetworkName) (IN_BSTR aName)
106784ebb7b303ae471851100a773ad2aebf5b80Daniel Mack{
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering CheckComArgOutPointerValid(aName);
51323288fc628a5cac50914df915545d685b793eLennart Poettering
106784ebb7b303ae471851100a773ad2aebf5b80Daniel Mack HRESULT rc = S_OK;
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering AutoCaller autoCaller(this);
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (FAILED(autoCaller.rc())) return autoCaller.rc();
4e5bf5e15899de3f9d11c2ddfe9721d9f8b07a37Daniel Mack AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
4e5bf5e15899de3f9d11c2ddfe9721d9f8b07a37Daniel Mack unconst(mName) = aName;
4e5bf5e15899de3f9d11c2ddfe9721d9f8b07a37Daniel Mack
106784ebb7b303ae471851100a773ad2aebf5b80Daniel Mack alock.release();
106784ebb7b303ae471851100a773ad2aebf5b80Daniel Mack
106784ebb7b303ae471851100a773ad2aebf5b80Daniel Mack#ifdef NAT_XML_SERIALIZATION
106784ebb7b303ae471851100a773ad2aebf5b80Daniel Mack AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
51323288fc628a5cac50914df915545d685b793eLennart Poettering rc = mVirtualBox->saveSettings();
51323288fc628a5cac50914df915545d685b793eLennart Poettering#endif
return rc;
}
STDMETHODIMP NATNetwork::COMGETTER(Enabled) (BOOL *aEnabled)
{
CheckComArgOutPointerValid(aEnabled);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
*aEnabled = m->fEnabled;
RecalculateIpv4AddressAssignments();
return S_OK;
}
STDMETHODIMP NATNetwork::COMSETTER(Enabled) (BOOL aEnabled)
{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
HRESULT rc = S_OK;
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
m->fEnabled = aEnabled;
// save the global settings; for that we should hold only the VirtualBox lock
alock.release();
#ifdef NAT_XML_SERIALIZATION
AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
rc = mVirtualBox->saveSettings();
#endif
return rc;
}
STDMETHODIMP NATNetwork::COMGETTER(Gateway) (BSTR *aIPv4Gateway)
{
CheckComArgOutPointerValid(aIPv4Gateway);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
m->IPv4Gateway.cloneTo(aIPv4Gateway);
return S_OK;
}
STDMETHODIMP NATNetwork::COMGETTER(Network) (BSTR *aIPv4NetworkCidr)
{
CheckComArgOutPointerValid(aIPv4NetworkCidr);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
m->IPv4NetworkCidr.cloneTo(aIPv4NetworkCidr);
return S_OK;
}
STDMETHODIMP NATNetwork::COMSETTER(Network) (IN_BSTR aIPv4NetworkCidr)
{
CheckComArgOutPointerValid(aIPv4NetworkCidr);
HRESULT rc = S_OK;
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
/* silently ignore network cidr update */
if (m->mapName2PortForwardRule4.empty())
{
unconst(m->IPv4NetworkCidr) = Bstr(aIPv4NetworkCidr);
RecalculateIpv4AddressAssignments();
alock.release();
#ifdef NAT_XML_SERIALIZATION
AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
rc = mVirtualBox->saveSettings();
#endif
}
return rc;
}
STDMETHODIMP NATNetwork::COMGETTER(IPv6Enabled)(BOOL *aAdvertiseDefaultIPv6Route)
{
CheckComArgOutPointerValid(aAdvertiseDefaultIPv6Route);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
*aAdvertiseDefaultIPv6Route = m->fAdvertiseDefaultIPv6Route;
return S_OK;
}
STDMETHODIMP NATNetwork::COMSETTER(IPv6Enabled)(BOOL aAdvertiseDefaultIPv6Route)
{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
HRESULT rc = S_OK;
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
m->fAdvertiseDefaultIPv6Route = aAdvertiseDefaultIPv6Route;
// save the global settings; for that we should hold only the VirtualBox lock
alock.release();
#ifdef NAT_XML_SERIALIZATION
AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
rc = mVirtualBox->saveSettings();
#endif
return rc;
}
STDMETHODIMP NATNetwork::COMGETTER(IPv6Prefix) (BSTR *aIPv6Prefix)
{
CheckComArgOutPointerValid(aIPv6Prefix);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
return S_OK;
}
STDMETHODIMP NATNetwork::COMSETTER(IPv6Prefix) (IN_BSTR aIPv6Prefix)
{
CheckComArgOutPointerValid(aIPv6Prefix);
HRESULT rc = S_OK;
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
/* silently ignore network cidr update */
if (m->mapName2PortForwardRule6.empty())
{
unconst(m->IPv6Prefix) = Bstr(aIPv6Prefix);
/* @todo: do we need recalculation ? */
alock.release();
#ifdef NAT_XML_SERIALIZATION
AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
rc = mVirtualBox->saveSettings();
#endif
}
return rc;
}
STDMETHODIMP NATNetwork::COMGETTER(AdvertiseDefaultIPv6RouteEnabled)(BOOL *aAdvertiseDefaultIPv6Route)
{
CheckComArgOutPointerValid(aAdvertiseDefaultIPv6Route);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
*aAdvertiseDefaultIPv6Route = m->fAdvertiseDefaultIPv6Route;
return S_OK;
}
STDMETHODIMP NATNetwork::COMSETTER(AdvertiseDefaultIPv6RouteEnabled)(BOOL aAdvertiseDefaultIPv6Route)
{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
HRESULT rc = S_OK;
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
m->fAdvertiseDefaultIPv6Route = aAdvertiseDefaultIPv6Route;
// save the global settings; for that we should hold only the VirtualBox lock
alock.release();
#ifdef NAT_XML_SERIALIZATION
AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
rc = mVirtualBox->saveSettings();
#endif
return rc;
}
STDMETHODIMP NATNetwork::COMGETTER(NeedDhcpServer)(BOOL *aNeedDhcpServer)
{
CheckComArgOutPointerValid(aNeedDhcpServer);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
*aNeedDhcpServer = m->fNeedDhcpServer;
return S_OK;
}
STDMETHODIMP NATNetwork::COMSETTER(NeedDhcpServer)(BOOL aNeedDhcpServer)
{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
HRESULT rc = S_OK;
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
m->fNeedDhcpServer = aNeedDhcpServer;
RecalculateIpv4AddressAssignments();
// save the global settings; for that we should hold only the VirtualBox lock
alock.release();
#ifdef NAT_XML_SERIALIZATION
AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
rc = mVirtualBox->saveSettings();
#endif
return rc;
}
STDMETHODIMP NATNetwork::COMGETTER(PortForwardRules4)(ComSafeArrayOut(BSTR, aPortForwardRules4))
{
CheckComArgOutSafeArrayPointerValid(aPortForwardRules4);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
GetPortForwardRulesFromMap(ComSafeArrayInArg(aPortForwardRules4),
m->mapName2PortForwardRule4);
alock.release();
return S_OK;
}
STDMETHODIMP NATNetwork::COMGETTER(PortForwardRules6)(ComSafeArrayOut(BSTR,
aPortForwardRules6))
{
CheckComArgOutSafeArrayPointerValid(aPortForwardRules6);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
GetPortForwardRulesFromMap(ComSafeArrayInArg(aPortForwardRules6), m->mapName2PortForwardRule6);
return S_OK;
}
STDMETHODIMP NATNetwork::AddPortForwardRule(BOOL aIsIpv6,
IN_BSTR aPortForwardRuleName,
NATProtocol_T aProto,
IN_BSTR aHostIp,
USHORT aHostPort,
IN_BSTR aGuestIp,
USHORT aGuestPort)
{
int rc = S_OK;
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
Utf8Str name = aPortForwardRuleName;
Utf8Str proto;
settings::NATRule r;
NATRuleMap& mapRules = aIsIpv6 ? m->mapName2PortForwardRule6 : m->mapName2PortForwardRule4;
switch (aProto)
{
case NATProtocol_TCP:
proto = "tcp";
break;
case NATProtocol_UDP:
proto = "udp";
break;
default:
return E_INVALIDARG;
}
if (name.isEmpty())
name = Utf8StrFmt("%s_[%s]%%%d_[%s]%%%d", proto.c_str(),
Utf8Str(aHostIp).c_str(), aHostPort,
Utf8Str(aGuestIp).c_str(), aGuestPort);
NATRuleMap::iterator it;
for (it = mapRules.begin(); it != mapRules.end(); ++it)
{
r = it->second;
if (it->first == name)
return setError(E_INVALIDARG,
tr("A NAT rule of this name already exists"));
if ( r.strHostIP == Utf8Str(aHostIp)
&& r.u16HostPort == aHostPort
&& r.proto == aProto)
return setError(E_INVALIDARG,
tr("A NAT rule for this host port and this host IP already exists"));
}
r.strName = name.c_str();
r.proto = aProto;
r.strHostIP = aHostIp;
r.u16HostPort = aHostPort;
r.strGuestIP = aGuestIp;
r.u16GuestPort = aGuestPort;
mapRules.insert(std::make_pair(name, r));
alock.release();
mVirtualBox->onNATNetworkPortForward(mName.raw(), TRUE, aIsIpv6,
aPortForwardRuleName, aProto,
aHostIp, aHostPort,
aGuestIp, aGuestPort);
/* Notify listerners listening on this network only */
fireNATNetworkPortForwardEvent(m->pEventSource, mName.raw(), TRUE,
aIsIpv6, aPortForwardRuleName, aProto,
aHostIp, aHostPort,
aGuestIp, aGuestPort);
#ifdef NAT_XML_SERIALIZATION
AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
rc = mVirtualBox->saveSettings();
#endif
return rc;
}
STDMETHODIMP NATNetwork::RemovePortForwardRule(BOOL aIsIpv6, IN_BSTR aPortForwardRuleName)
{
int rc = S_OK;
Utf8Str strHostIP, strGuestIP;
uint16_t u16HostPort, u16GuestPort;
NATProtocol_T proto = NATProtocol_TCP;
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
NATRuleMap& mapRules = aIsIpv6 ? m->mapName2PortForwardRule6 : m->mapName2PortForwardRule4;
NATRuleMap::iterator it = mapRules.find(aPortForwardRuleName);
if (it == mapRules.end())
return E_INVALIDARG;
strHostIP = it->second.strHostIP;
strGuestIP = it->second.strGuestIP;
u16HostPort = it->second.u16HostPort;
u16GuestPort = it->second.u16GuestPort;
proto = it->second.proto;
mapRules.erase(it);
alock.release();
mVirtualBox->onNATNetworkPortForward(mName.raw(), FALSE, aIsIpv6,
aPortForwardRuleName, proto,
Bstr(strHostIP).raw(), u16HostPort,
Bstr(strGuestIP).raw(), u16GuestPort);
/* Notify listerners listening on this network only */
fireNATNetworkPortForwardEvent(m->pEventSource, mName.raw(), FALSE,
aIsIpv6, aPortForwardRuleName, proto,
Bstr(strHostIP).raw(), u16HostPort,
Bstr(strGuestIP).raw(), u16GuestPort);
#ifdef NAT_XML_SERIALIZATION
AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
rc = mVirtualBox->saveSettings();
#endif
return rc;
}
STDMETHODIMP NATNetwork::Start(IN_BSTR aTrunkType)
{
#ifdef VBOX_WITH_NAT_SERVICE
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
if (!m->fEnabled) return S_OK;
m->NATRunner.setOption(NETCFG_NETNAME, mName, true);
m->NATRunner.setOption(NETCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
m->NATRunner.setOption(NETCFG_IPADDRESS, m->IPv4Gateway, true);
m->NATRunner.setOption(NETCFG_NETMASK, m->IPv4NetworkMask, true);
/* No portforwarding rules from command-line, all will be fetched via API */
if (m->fNeedDhcpServer)
{
/**
* Just to as idea... via API (on creation user pass the cidr of network and)
* and we calculate it's addreses (mutable?).
*/
/*
* Configuration and running DHCP server:
* 1. find server first createDHCPServer
* 2. if return status is E_INVALARG => server already exists just find and start.
* 3. if return status neither E_INVALRG nor S_OK => return E_FAIL
* 4. if return status S_OK proceed to DHCP server configuration
* 5. call setConfiguration() and pass all required parameters
* 6. start dhcp server.
*/
int rc = mVirtualBox->FindDHCPServerByNetworkName(mName.raw(),
m->dhcpServer.asOutParam());
switch (rc)
{
case E_INVALIDARG:
/* server haven't beeen found let create it then */
rc = mVirtualBox->CreateDHCPServer(mName.raw(),
m->dhcpServer.asOutParam());
if (FAILED(rc))
return E_FAIL;
/* breakthrough */
{
LogFunc(("gateway: %s, dhcpserver:%s, dhcplowerip:%s, dhcpupperip:%s\n",
Utf8Str(m->IPv4Gateway.raw()).c_str(),
Utf8Str(m->IPv4DhcpServer.raw()).c_str(),
Utf8Str(m->IPv4DhcpServerLowerIp.raw()).c_str(),
Utf8Str(m->IPv4DhcpServerUpperIp.raw()).c_str()));
m->dhcpServer->AddGlobalOption(DhcpOpt_Router, m->IPv4Gateway.raw());
rc = m->dhcpServer->SetEnabled(true);
BSTR dhcpip = NULL;
BSTR netmask = NULL;
BSTR lowerip = NULL;
BSTR upperip = NULL;
m->IPv4DhcpServer.cloneTo(&dhcpip);
m->IPv4NetworkMask.cloneTo(&netmask);
m->IPv4DhcpServerLowerIp.cloneTo(&lowerip);
m->IPv4DhcpServerUpperIp.cloneTo(&upperip);
rc = m->dhcpServer->SetConfiguration(dhcpip,
netmask,
lowerip,
upperip);
}
case S_OK:
break;
default:
return E_FAIL;
}
rc = m->dhcpServer->Start(mName.raw(), Bstr("").raw(), aTrunkType);
if (FAILED(rc))
{
m->dhcpServer.setNull();
return E_FAIL;
}
}
if (RT_SUCCESS(m->NATRunner.start()))
{
mVirtualBox->onNATNetworkStartStop(mName.raw(), TRUE);
return S_OK;
}
else return E_FAIL;
#else
NOREF(aTrunkType);
ReturnComNotImplemented();
#endif
}
STDMETHODIMP NATNetwork::Stop()
{
#ifdef VBOX_WITH_NAT_SERVICE
if (RT_SUCCESS(m->NATRunner.stop()))
{
mVirtualBox->onNATNetworkStartStop(mName.raw(), FALSE);
return S_OK;
}
else return E_FAIL;
#else
ReturnComNotImplemented();
#endif
}
void NATNetwork::GetPortForwardRulesFromMap(ComSafeArrayOut(BSTR, aPortForwardRules), NATRuleMap& aRules)
{
com::SafeArray<BSTR> sf(aRules.size());
size_t i = 0;
NATRuleMap::const_iterator it;
for (it = aRules.begin();
it != aRules.end(); ++it, ++i)
{
settings::NATRule r = it->second;
BstrFmt bstr("%s:%s:[%s]:%d:[%s]:%d",
r.strName.c_str(),
(r.proto == NATProtocol_TCP? "tcp" : "udp"),
r.strHostIP.c_str(),
r.u16HostPort,
r.strGuestIP.c_str(),
r.u16GuestPort);
bstr.detachTo(&sf[i]);
}
sf.detachTo(ComSafeArrayOutArg(aPortForwardRules));
}
int NATNetwork::RecalculateIpv4AddressAssignments()
{
RTNETADDRIPV4 network, netmask, gateway;
char aszGatewayIp[16], aszNetmask[16];
RT_ZERO(aszNetmask);
int rc = RTCidrStrToIPv4(Utf8Str(m->IPv4NetworkCidr.raw()).c_str(),
&network,
&netmask);
AssertRCReturn(rc, rc);
/* I don't remember the reason CIDR calcualted in host */
gateway.u = network.u;
gateway.u += 1;
gateway.u = RT_H2N_U32(gateway.u);
RTStrPrintf(aszGatewayIp, 16, "%RTnaipv4", gateway);
m->IPv4Gateway = RTStrDup(aszGatewayIp);
if (m->fNeedDhcpServer)
{
RTNETADDRIPV4 dhcpserver,
dhcplowerip,
dhcpupperip;
char aszNetwork[16],
aszDhcpIp[16],
aszDhcpLowerIp[16],
aszDhcpUpperIp[16];
RT_ZERO(aszNetwork);
RT_ZERO(aszDhcpIp);
RT_ZERO(aszDhcpLowerIp);
RT_ZERO(aszDhcpUpperIp);
dhcpserver.u = network.u;
dhcpserver.u += 2;
/* XXX: adding more services should change the math here */
dhcplowerip.u = RT_H2N_U32(dhcpserver.u + 1);
dhcpupperip.u = RT_H2N_U32((network.u | (~netmask.u)) -1);
dhcpserver.u = RT_H2N_U32(dhcpserver.u);
network.u = RT_H2N_U32(network.u);
RTStrPrintf(aszNetwork, 16, "%RTnaipv4", network);
RTStrPrintf(aszDhcpLowerIp, 16, "%RTnaipv4", dhcplowerip);
RTStrPrintf(aszDhcpUpperIp, 16, "%RTnaipv4", dhcpupperip);
RTStrPrintf(aszDhcpIp, 16, "%RTnaipv4", dhcpserver);
m->IPv4DhcpServer = aszDhcpIp;
m->IPv4DhcpServerLowerIp = aszDhcpLowerIp;
m->IPv4DhcpServerUpperIp = aszDhcpUpperIp;
LogFunc(("network: %RTnaipv4, dhcpserver:%RTnaipv4, dhcplowerip:%RTnaipv4, dhcpupperip:%RTnaipv4\n",
network,
dhcpserver,
dhcplowerip,
dhcpupperip));
}
/* we need IPv4NetworkMask for NAT's gw service start */
netmask.u = RT_H2N_U32(netmask.u);
RTStrPrintf(aszNetmask, 16, "%RTnaipv4", netmask);
m->IPv4NetworkMask = aszNetmask;
LogFlowFunc(("getaway:%RTnaipv4, netmask:%RTnaipv4\n", gateway, netmask));
return VINF_SUCCESS;
}