NATNetworkImpl.cpp revision c29157dbe5c257b3b0865ba1cfb419e4e2135681
/* $Id$ */
/** @file
*
* VirtualBox COM class implementation
*/
/*
* Copyright (C) 2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "NetworkServiceRunner.h"
#include "DHCPServerImpl.h"
#include "NATNetworkImpl.h"
#include "AutoCaller.h"
#include "Logging.h"
#include <VBox/settings.h>
#include "EventImpl.h"
#include "VBoxEvents.h"
#include "VirtualBoxImpl.h"
// constructor / destructor
/////////////////////////////////////////////////////////////////////////////
struct NATNetwork::Data
{
Data() :
{
}
virtual ~Data(){}
#ifdef VBOX_WITH_NAT_SERVICE
#endif
};
: mVirtualBox(NULL)
{
}
NATNetwork::~NATNetwork()
{
}
{
return BaseFinalConstruct();
}
void NATNetwork::FinalRelease()
{
uninit ();
}
void NATNetwork::uninit()
{
/* Enclose the state transition Ready->InUninit->NotReady */
AutoUninitSpan autoUninitSpan(this);
if (autoUninitSpan.uninitDone())
return;
delete m;
m = NULL;
}
{
AutoInitSpan autoInitSpan(this);
/* share VirtualBox weakly (parent remains NULL so far) */
m = new Data();
m->IPv4Gateway = "10.0.2.2";
m->IPv4NetworkCidr = "10.0.2.0/24";
m->IPv6Prefix = "fe80::/64";
/* Confirm a successful initialization */
return S_OK;
}
{
/* Enclose the state transition NotReady->InInit->Ready */
AutoInitSpan autoInitSpan(this);
/* share VirtualBox weakly (parent remains NULL so far) */
m = new Data();
/* IPv4 port-forward rules */
{
}
/* IPv6 port-forward rules */
{
}
return S_OK;
}
#ifdef NAT_XML_SERIALIZATION
{
AutoCaller autoCaller(this);
/* saving ipv4 port-forward Rules*/
/* saving ipv6 port-forward Rules*/
/* XXX: should we do here a copy of params */
/* XXX: should we unlock here? */
m->IPv4NetworkCidr.raw(),
m->IPv4Gateway.raw(),
return S_OK;
}
#endif
{
AutoCaller autoCaller(this);
/* event source is const, no need to lock */
return S_OK;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
#ifdef NAT_XML_SERIALIZATION
#endif
return rc;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
// save the global settings; for that we should hold only the VirtualBox lock
#ifdef NAT_XML_SERIALIZATION
#endif
return rc;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
/* silently ignore network cidr update */
if (m->mapName2PortForwardRule4.empty())
{
#ifdef NAT_XML_SERIALIZATION
#endif
}
return rc;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
// save the global settings; for that we should hold only the VirtualBox lock
#ifdef NAT_XML_SERIALIZATION
#endif
return rc;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
/* silently ignore network cidr update */
if (m->mapName2PortForwardRule6.empty())
{
/* @todo: do we need recalculation ? */
#ifdef NAT_XML_SERIALIZATION
#endif
}
return rc;
}
STDMETHODIMP NATNetwork::COMGETTER(AdvertiseDefaultIPv6RouteEnabled)(BOOL *aAdvertiseDefaultIPv6Route)
{
AutoCaller autoCaller(this);
return S_OK;
}
STDMETHODIMP NATNetwork::COMSETTER(AdvertiseDefaultIPv6RouteEnabled)(BOOL aAdvertiseDefaultIPv6Route)
{
AutoCaller autoCaller(this);
// save the global settings; for that we should hold only the VirtualBox lock
#ifdef NAT_XML_SERIALIZATION
#endif
return rc;
}
{
AutoCaller autoCaller(this);
*aNeedDhcpServer = m->fNeedDhcpServer;
return S_OK;
}
{
AutoCaller autoCaller(this);
// save the global settings; for that we should hold only the VirtualBox lock
#ifdef NAT_XML_SERIALIZATION
#endif
return rc;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
switch (aProto)
{
case NATProtocol_TCP:
proto = "tcp";
break;
case NATProtocol_UDP:
proto = "udp";
break;
default:
return E_INVALIDARG;
}
{
return setError(E_INVALIDARG,
tr("A NAT rule of this name already exists"));
&& r.u16HostPort == aHostPort
return setError(E_INVALIDARG,
tr("A NAT rule for this host port and this host IP already exists"));
}
r.u16HostPort = aHostPort;
r.strGuestIP = aGuestIp;
r.u16GuestPort = aGuestPort;
/* Notify listerners listening on this network only */
#ifdef NAT_XML_SERIALIZATION
#endif
return rc;
}
{
AutoCaller autoCaller(this);
return E_INVALIDARG;
/* Notify listerners listening on this network only */
#ifdef NAT_XML_SERIALIZATION
#endif
return rc;
}
{
#ifdef VBOX_WITH_NAT_SERVICE
AutoCaller autoCaller(this);
/* 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.
*/
m->dhcpServer.asOutParam());
switch (rc)
{
case E_INVALIDARG:
/* server haven't beeen found let create it then */
m->dhcpServer.asOutParam());
return E_FAIL;
/* breakthrough */
{
LogFunc(("gateway: %s, dhcpserver:%s, dhcplowerip:%s, dhcpupperip:%s\n",
upperip);
}
case S_OK:
break;
default:
return E_FAIL;
}
{
m->dhcpServer.setNull();
return E_FAIL;
}
}
{
return S_OK;
}
else return E_FAIL;
#else
#endif
}
{
#ifdef VBOX_WITH_NAT_SERVICE
{
return S_OK;
}
else return E_FAIL;
#else
#endif
}
void NATNetwork::GetPortForwardRulesFromMap(ComSafeArrayOut(BSTR, aPortForwardRules), NATRuleMap& aRules)
{
size_t i = 0;
{
r.u16HostPort,
r.strGuestIP.c_str(),
r.u16GuestPort);
}
}
{
&network,
&netmask);
/* I don't remember the reason CIDR calcualted in host */
gateway.u += 1;
if (m->fNeedDhcpServer)
{
char aszNetwork[16],
aszDhcpIp[16],
aszDhcpLowerIp[16],
aszDhcpUpperIp[16];
dhcpserver.u = network.u;
dhcpserver.u += 2;
/* XXX: adding more services should change the math here */
m->IPv4DhcpServer = aszDhcpIp;
LogFunc(("network: %RTnaipv4, dhcpserver:%RTnaipv4, dhcplowerip:%RTnaipv4, dhcpupperip:%RTnaipv4\n",
dhcpupperip));
}
/* we need IPv4NetworkMask for NAT's gw service start */
m->IPv4NetworkMask = aszNetmask;
return VINF_SUCCESS;
}