Config.h revision fc2936cb0bee5f5a4fa2d1aa50d72d9f31d69555
f0ab104f070bc7f569404826fea1828ed985638cvboxsync/* $Id$ */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync/** @file
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * Config.h
f0ab104f070bc7f569404826fea1828ed985638cvboxsync */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync/*
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * Copyright (C) 2013 Oracle Corporation
f0ab104f070bc7f569404826fea1828ed985638cvboxsync *
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * available from http://www.virtualbox.org. This file is free software;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * General Public License (GPL) as published by the Free Software
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
f0ab104f070bc7f569404826fea1828ed985638cvboxsync */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#ifndef _CONFIG_H_
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#define _CONFIG_H_
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#include <iprt/asm-math.h>
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#include <iprt/cpp/utils.h>
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#include <VBox/com/ptr.h>
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#include <VBox/com/string.h>
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#include <VBox/com/VirtualBox.h>
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#include "../NetLib/cpp/utils.h"
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncstatic bool operator > (const RTNETADDRIPV4& a, const RTNETADDRIPV4& b)
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync return (b < a);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync}
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass RawOption
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncpublic:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync RawOption()
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync RT_ZERO(*this);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
f0ab104f070bc7f569404826fea1828ed985638cvboxsync uint8_t u8OptId;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync uint8_t cbRawOpt;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync uint8_t au8RawOpt[255];
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ClientData;
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass Client;
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass Lease;
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass BaseConfigEntity;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass NetworkConfigEntity;
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass HostConfigEntity;
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ClientMatchCriteria;
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ConfigurationManager;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync/*
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * it's a basic representation of
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * of out undestanding what client is
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * XXX: Client might sends Option 61 (RFC2132 9.14 "Client-identifier") signalling
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * that we may identify it in special way
f0ab104f070bc7f569404826fea1828ed985638cvboxsync *
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * XXX: Client might send Option 60 (RFC2132 9.13 "Vendor class undentifier")
f0ab104f070bc7f569404826fea1828ed985638cvboxsync * in response it's expected server sends Option 43 (RFC2132 8.4. "Vendor Specific Information")
f0ab104f070bc7f569404826fea1828ed985638cvboxsync */
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass Client
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync friend class Lease;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync friend class ConfigurationManager;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync public:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync Client();
f0ab104f070bc7f569404826fea1828ed985638cvboxsync void initWithMac(const RTMAC& mac);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync bool operator== (const RTMAC& mac) const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync const RTMAC& getMacAddress() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync /** Dumps client query */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync void dump();
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync Lease lease();
f0ab104f070bc7f569404826fea1828ed985638cvboxsync const Lease lease() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync public:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync static const Client NullClient;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync private:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync Client(ClientData *);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync SharedPtr<ClientData> m;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncbool operator== (const Lease&, const Lease&);
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncbool operator!= (const Lease&, const Lease&);
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncbool operator< (const Lease&, const Lease&);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef std::map<uint8_t, RawOption> MapOptionId2RawOption;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef MapOptionId2RawOption::iterator MapOptionId2RawOptionIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef MapOptionId2RawOption::const_iterator MapOptionId2RawOptionConstIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef MapOptionId2RawOption::value_type MapOptionId2RawOptionValue;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncnamespace xml {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync class ElementNode;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync}
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass Lease
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync friend class Client;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync friend bool operator== (const Lease&, const Lease&);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync //friend int ConfigurationManager::loadFromFile(const std::string&);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync friend class ConfigurationManager;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync public:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync Lease();
f0ab104f070bc7f569404826fea1828ed985638cvboxsync Lease(const Client&);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync bool isExpired() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync void expire();
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync /* Depending on phase *Expiration and phaseStart initialize different values. */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync void bindingPhase(bool);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync void phaseStart(uint64_t u64Start);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync bool isInBindingPhase() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync /* returns 0 if in binding state */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync uint64_t issued() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync void setExpiration(uint32_t);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync uint32_t getExpiration() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync RTNETADDRIPV4 getAddress() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync void setAddress(RTNETADDRIPV4);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync const NetworkConfigEntity *getConfig() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync void setConfig(NetworkConfigEntity *);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync const MapOptionId2RawOption& options() const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync bool toXML(xml::ElementNode *) const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync bool fromXML(const xml::ElementNode *);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync public:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync static const Lease NullLease;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync private:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync Lease(ClientData *);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync SharedPtr<ClientData> m;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef std::vector<Client> VecClient;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef VecClient::iterator VecClientIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef VecClient::const_iterator VecClientConstIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef std::vector<RTMAC> MacAddressContainer;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef MacAddressContainer::iterator MacAddressIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef std::vector<RTNETADDRIPV4> Ipv4AddressContainer;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef Ipv4AddressContainer::iterator Ipv4AddressIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef Ipv4AddressContainer::const_iterator Ipv4AddressConstIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef std::map<Lease, RTNETADDRIPV4> MapLease2Ip4Address;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef MapLease2Ip4Address::iterator MapLease2Ip4AddressIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef MapLease2Ip4Address::const_iterator MapLease2Ip4AddressConstIterator;
f0ab104f070bc7f569404826fea1828ed985638cvboxsynctypedef MapLease2Ip4Address::value_type MapLease2Ip4AddressPair;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync/**
f0ab104f070bc7f569404826fea1828ed985638cvboxsync *
f0ab104f070bc7f569404826fea1828ed985638cvboxsync */
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ClientMatchCriteria
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync public:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual bool check(const Client&) const {return false;};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ORClientMatchCriteria: ClientMatchCriteria
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync ClientMatchCriteria* m_left;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync ClientMatchCriteria* m_right;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync ORClientMatchCriteria(ClientMatchCriteria *left, ClientMatchCriteria *right)
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_left = left;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_right = right;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual bool check(const Client& client) const
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync return (m_left->check(client) || m_right->check(client));
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ANDClientMatchCriteria: ClientMatchCriteria
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncpublic:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync ANDClientMatchCriteria(ClientMatchCriteria *left, ClientMatchCriteria *right)
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_left = left;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_right = right;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual bool check(const Client& client) const
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync return (m_left->check(client) && m_right->check(client));
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncprivate:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync ClientMatchCriteria* m_left;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync ClientMatchCriteria* m_right;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass AnyClientMatchCriteria: public ClientMatchCriteria
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncpublic:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual bool check(const Client&) const
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync return true;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass MACClientMatchCriteria: public ClientMatchCriteria
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncpublic:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync MACClientMatchCriteria(const RTMAC& mac):m_mac(mac){}
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual bool check(const Client& client) const;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncprivate:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync RTMAC m_mac;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#if 0
f0ab104f070bc7f569404826fea1828ed985638cvboxsync/* XXX: Later */
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass VmSlotClientMatchCriteria: public ClientMatchCriteria
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync str::string VmName;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync uint8_t u8Slot;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual bool check(const Client& client)
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync return ( client.VmName == VmName
f0ab104f070bc7f569404826fea1828ed985638cvboxsync && ( u8Slot == (uint8_t)~0 /* any */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync || client.u8Slot == u8Slot));
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync#endif
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync/* Option 60 */
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ClassClientMatchCriteria: ClientMatchCriteria{};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync/* Option 61 */
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ClientIdentifierMatchCriteria: ClientMatchCriteria{};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass BaseConfigEntity
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync public:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync BaseConfigEntity(const ClientMatchCriteria *criteria = NULL,
f0ab104f070bc7f569404826fea1828ed985638cvboxsync int matchingLevel = 0)
f0ab104f070bc7f569404826fea1828ed985638cvboxsync : m_criteria(criteria),
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_MatchLevel(matchingLevel){};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual ~BaseConfigEntity(){};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync /* XXX */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync int add(BaseConfigEntity *cfg)
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_children.push_back(cfg);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync return 0;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync /* Should return how strong matching */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual int match(Client& client, BaseConfigEntity **cfg);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual uint32_t expirationPeriod() const = 0;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync protected:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync const ClientMatchCriteria *m_criteria;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync int m_MatchLevel;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync std::vector<BaseConfigEntity *> m_children;
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass NullConfigEntity: public BaseConfigEntity
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync public:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync NullConfigEntity(){}
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual ~NullConfigEntity(){}
f0ab104f070bc7f569404826fea1828ed985638cvboxsync int add(BaseConfigEntity *) const { return 0;}
f0ab104f070bc7f569404826fea1828ed985638cvboxsync virtual uint32_t expirationPeriod() const {return 0;}
f0ab104f070bc7f569404826fea1828ed985638cvboxsync};
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsync
f0ab104f070bc7f569404826fea1828ed985638cvboxsyncclass ConfigEntity: public BaseConfigEntity
f0ab104f070bc7f569404826fea1828ed985638cvboxsync{
f0ab104f070bc7f569404826fea1828ed985638cvboxsync public:
f0ab104f070bc7f569404826fea1828ed985638cvboxsync /* range */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync /* match conditions */
f0ab104f070bc7f569404826fea1828ed985638cvboxsync ConfigEntity(std::string& name,
f0ab104f070bc7f569404826fea1828ed985638cvboxsync const BaseConfigEntity *cfg,
f0ab104f070bc7f569404826fea1828ed985638cvboxsync const ClientMatchCriteria *criteria,
f0ab104f070bc7f569404826fea1828ed985638cvboxsync int matchingLevel = 0):
f0ab104f070bc7f569404826fea1828ed985638cvboxsync BaseConfigEntity(criteria, matchingLevel),
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_name(name),
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_parentCfg(cfg),
f0ab104f070bc7f569404826fea1828ed985638cvboxsync m_u32ExpirationPeriod(0)
f0ab104f070bc7f569404826fea1828ed985638cvboxsync {
f0ab104f070bc7f569404826fea1828ed985638cvboxsync unconst(m_parentCfg)->add(this);
f0ab104f070bc7f569404826fea1828ed985638cvboxsync }
virtual uint32_t expirationPeriod() const
{
if (!m_u32ExpirationPeriod)
return m_parentCfg->expirationPeriod();
else
return m_u32ExpirationPeriod;
}
/* XXX: private:*/
std::string m_name;
const BaseConfigEntity *m_parentCfg;
uint32_t m_u32ExpirationPeriod;
};
/**
* Network specific entries
*/
class NetworkConfigEntity:public ConfigEntity
{
public:
/* Address Pool matching with network declaration */
NetworkConfigEntity(std::string name,
const BaseConfigEntity *cfg,
const ClientMatchCriteria *criteria,
int matchlvl,
const RTNETADDRIPV4& networkID,
const RTNETADDRIPV4& networkMask,
const RTNETADDRIPV4& lowerIP,
const RTNETADDRIPV4& upperIP):
ConfigEntity(name, cfg, criteria, matchlvl),
m_NetworkID(networkID),
m_NetworkMask(networkMask),
m_UpperIP(upperIP),
m_LowerIP(lowerIP)
{
};
NetworkConfigEntity(std::string name,
const BaseConfigEntity *cfg,
const ClientMatchCriteria *criteria,
const RTNETADDRIPV4& networkID,
const RTNETADDRIPV4& networkMask):
ConfigEntity(name, cfg, criteria, 5),
m_NetworkID(networkID),
m_NetworkMask(networkMask)
{
m_UpperIP.u = m_NetworkID.u | (~m_NetworkMask.u);
m_LowerIP.u = m_NetworkID.u;
};
const RTNETADDRIPV4& upperIp() const {return m_UpperIP;}
const RTNETADDRIPV4& lowerIp() const {return m_LowerIP;}
const RTNETADDRIPV4& networkId() const {return m_NetworkID;}
const RTNETADDRIPV4& netmask() const {return m_NetworkMask;}
private:
RTNETADDRIPV4 m_NetworkID;
RTNETADDRIPV4 m_NetworkMask;
RTNETADDRIPV4 m_UpperIP;
RTNETADDRIPV4 m_LowerIP;
};
/**
* Host specific entry
* Address pool is contains one element
*/
class HostConfigEntity: public NetworkConfigEntity
{
public:
HostConfigEntity(const RTNETADDRIPV4& addr,
std::string name,
const NetworkConfigEntity *cfg,
const ClientMatchCriteria *criteria):
NetworkConfigEntity(name,
static_cast<const ConfigEntity*>(cfg), criteria, 10,
cfg->networkId(), cfg->netmask(), addr, addr)
{
/* upper addr == lower addr */
}
};
class RootConfigEntity: public NetworkConfigEntity
{
public:
RootConfigEntity(std::string name, uint32_t expirationPeriod);
virtual ~RootConfigEntity(){};
};
#if 0
/**
* Shared regions e.g. some of configured networks declarations
* are cover each other.
* XXX: Shared Network is join on Network config entities with possible
* overlaps in address pools. for a moment we won't configure and use them them
*/
class SharedNetworkConfigEntity: public NetworkEntity
{
public:
SharedNetworkConfigEntity(){}
int match(const Client& client) const { return m_criteria.match(client)? 3 : 0;}
SharedNetworkConfigEntity(NetworkEntity& network)
{
Networks.push_back(network);
}
virtual ~SharedNetworkConfigEntity(){}
std::vector<NetworkConfigEntity> Networks;
};
#endif
class ConfigurationManager
{
public:
static ConfigurationManager* getConfigurationManager();
static int extractRequestList(PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& rawOpt);
int loadFromFile(const com::Utf8Str&);
int saveToFile();
/**
*
*/
Client getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg);
/**
* XXX: it's could be done on DHCPOFFER or on DHCPACK (rfc2131 gives freedom here
* 3.1.2, what is strict that allocation should do address check before real
* allocation)...
*/
Lease allocateLease4Client(const Client& client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg);
/**
* We call this before DHCPACK sent and after DHCPREQUEST received ...
* when requested configuration is acceptable.
*/
int commitLease4Client(Client& client);
/**
* Expires client lease.
*/
int expireLease4Client(Client& client);
static int findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& opt);
NetworkConfigEntity *addNetwork(NetworkConfigEntity *pCfg,
const RTNETADDRIPV4& networkId,
const RTNETADDRIPV4& netmask,
RTNETADDRIPV4& UpperAddress,
RTNETADDRIPV4& LowerAddress);
HostConfigEntity *addHost(NetworkConfigEntity*, const RTNETADDRIPV4&, ClientMatchCriteria*);
int addToAddressList(uint8_t u8OptId, RTNETADDRIPV4& address);
int flushAddressList(uint8_t u8OptId);
int setString(uint8_t u8OptId, const std::string& str);
const std::string& getString(uint8_t u8OptId);
const Ipv4AddressContainer& getAddressList(uint8_t u8OptId);
private:
ConfigurationManager():m(NULL){}
void init();
~ConfigurationManager();
bool isAddressTaken(const RTNETADDRIPV4& addr, Lease& lease);
bool isAddressTaken(const RTNETADDRIPV4& addr);
public:
/* nulls */
const Ipv4AddressContainer m_empty;
const std::string m_noString;
private:
struct Data;
Data *m;
};
class NetworkManager
{
public:
static NetworkManager *getNetworkManager(ComPtr<IDHCPServer> aDhcpServer = ComPtr<IDHCPServer>());
const RTNETADDRIPV4& getOurAddress() const;
const RTNETADDRIPV4& getOurNetmask() const;
const RTMAC& getOurMac() const;
void setOurAddress(const RTNETADDRIPV4& aAddress);
void setOurNetmask(const RTNETADDRIPV4& aNetmask);
void setOurMac(const RTMAC& aMac);
bool handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb);
bool handleDhcpReqRequest(PCRTNETBOOTP pDhcpMsg, size_t cb);
bool handleDhcpReqDecline(PCRTNETBOOTP pDhcpMsg, size_t cb);
bool handleDhcpReqRelease(PCRTNETBOOTP pDhcpMsg, size_t cb);
void setService(const VBoxNetHlpUDPService *);
private:
NetworkManager();
~NetworkManager();
int offer4Client(const Client& lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList);
int ack(const Client& lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList);
int nak(const Client& lease, uint32_t u32Xid);
int prepareReplyPacket4Client(const Client& client, uint32_t u32Xid);
int doReply(const Client& client, const std::vector<RawOption>& extra);
int processParameterReqList(const Client& client, const uint8_t *pu8ReqList, int cReqList, std::vector<RawOption>& extra);
private:
static NetworkManager *g_NetworkManager;
private:
struct Data;
Data *m;
};
extern const ClientMatchCriteria *g_AnyClient;
extern RootConfigEntity *g_RootConfig;
extern const NullConfigEntity *g_NullConfig;
/**
* Helper class for stuffing DHCP options into a reply packet.
*/
class VBoxNetDhcpWriteCursor
{
private:
uint8_t *m_pbCur; /**< The current cursor position. */
uint8_t *m_pbEnd; /**< The end the current option space. */
uint8_t *m_pfOverload; /**< Pointer to the flags of the overload option. */
uint8_t m_fUsed; /**< Overload fields that have been used. */
PRTNETDHCPOPT m_pOpt; /**< The current option. */
PRTNETBOOTP m_pDhcp; /**< The DHCP packet. */
bool m_fOverflowed; /**< Set if we've overflowed, otherwise false. */
public:
/** Instantiate an option cursor for the specified DHCP message. */
VBoxNetDhcpWriteCursor(PRTNETBOOTP pDhcp, size_t cbDhcp) :
m_pbCur(&pDhcp->bp_vend.Dhcp.dhcp_opts[0]),
m_pbEnd((uint8_t *)pDhcp + cbDhcp),
m_pfOverload(NULL),
m_fUsed(0),
m_pOpt(NULL),
m_pDhcp(pDhcp),
m_fOverflowed(false)
{
AssertPtr(pDhcp);
Assert(cbDhcp > RT_UOFFSETOF(RTNETBOOTP, bp_vend.Dhcp.dhcp_opts[10]));
}
/** Destructor. */
~VBoxNetDhcpWriteCursor()
{
m_pbCur = m_pbEnd = m_pfOverload = NULL;
m_pOpt = NULL;
m_pDhcp = NULL;
}
/**
* Try use the bp_file field.
* @returns true if not overloaded, false otherwise.
*/
bool useBpFile(void)
{
if ( m_pfOverload
&& (*m_pfOverload & 1))
return false;
m_fUsed |= 1 /* bp_file flag*/;
return true;
}
/**
* Try overload more BOOTP fields
*/
bool overloadMore(void)
{
/* switch option area. */
uint8_t *pbNew;
uint8_t *pbNewEnd;
uint8_t fField;
if (!(m_fUsed & 1))
{
fField = 1;
pbNew = &m_pDhcp->bp_file[0];
pbNewEnd = &m_pDhcp->bp_file[sizeof(m_pDhcp->bp_file)];
}
else if (!(m_fUsed & 2))
{
fField = 2;
pbNew = &m_pDhcp->bp_sname[0];
pbNewEnd = &m_pDhcp->bp_sname[sizeof(m_pDhcp->bp_sname)];
}
else
return false;
if (!m_pfOverload)
{
/* Add an overload option. */
*m_pbCur++ = RTNET_DHCP_OPT_OPTION_OVERLOAD;
*m_pbCur++ = fField;
m_pfOverload = m_pbCur;
*m_pbCur++ = 1; /* bp_file flag */
}
else
*m_pfOverload |= fField;
/* pad current option field */
while (m_pbCur != m_pbEnd)
*m_pbCur++ = RTNET_DHCP_OPT_PAD; /** @todo not sure if this stuff is at all correct... */
/* switch */
m_pbCur = pbNew;
m_pbEnd = pbNewEnd;
return true;
}
/**
* Begin an option.
*
* @returns true on success, false if we're out of space.
*
* @param uOption The option number.
* @param cb The amount of data.
*/
bool begin(uint8_t uOption, size_t cb)
{
/* Check that the data of the previous option has all been written. */
Assert( !m_pOpt
|| (m_pbCur - m_pOpt->dhcp_len == (uint8_t *)(m_pOpt + 1)));
AssertMsg(cb <= 255, ("%#x\n", cb));
/* Check if we need to overload more stuff. */
if ((uintptr_t)(m_pbEnd - m_pbCur) < cb + 2 + (m_pfOverload ? 1 : 3))
{
m_pOpt = NULL;
if (!overloadMore())
{
m_fOverflowed = true;
AssertMsgFailedReturn(("%u %#x\n", uOption, cb), false);
}
if ((uintptr_t)(m_pbEnd - m_pbCur) < cb + 2 + 1)
{
m_fOverflowed = true;
AssertMsgFailedReturn(("%u %#x\n", uOption, cb), false);
}
}
/* Emit the option header. */
m_pOpt = (PRTNETDHCPOPT)m_pbCur;
m_pOpt->dhcp_opt = uOption;
m_pOpt->dhcp_len = (uint8_t)cb;
m_pbCur += 2;
return true;
}
/**
* Puts option data.
*
* @param pvData The data.
* @param cb The amount to put.
*/
void put(void const *pvData, size_t cb)
{
Assert(m_pOpt || m_fOverflowed);
if (RT_LIKELY(m_pOpt))
{
Assert((uintptr_t)m_pbCur - (uintptr_t)(m_pOpt + 1) + cb <= (size_t)m_pOpt->dhcp_len);
memcpy(m_pbCur, pvData, cb);
m_pbCur += cb;
}
}
/**
* Puts an IPv4 Address.
*
* @param IPv4Addr The address.
*/
void putIPv4Addr(RTNETADDRIPV4 IPv4Addr)
{
put(&IPv4Addr, 4);
}
/**
* Adds an IPv4 address option.
*
* @returns true/false just like begin().
*
* @param uOption The option number.
* @param IPv4Addr The address.
*/
bool optIPv4Addr(uint8_t uOption, RTNETADDRIPV4 IPv4Addr)
{
if (!begin(uOption, 4))
return false;
putIPv4Addr(IPv4Addr);
return true;
}
/**
* Adds an option taking 1 or more IPv4 address.
*
* If the vector contains no addresses, the option will not be added.
*
* @returns true/false just like begin().
*
* @param uOption The option number.
* @param rIPv4Addrs Reference to the address vector.
*/
bool optIPv4Addrs(uint8_t uOption, std::vector<RTNETADDRIPV4> const &rIPv4Addrs)
{
size_t const c = rIPv4Addrs.size();
if (!c)
return true;
if (!begin(uOption, 4*c))
return false;
for (size_t i = 0; i < c; i++)
putIPv4Addr(rIPv4Addrs[i]);
return true;
}
/**
* Puts an 8-bit integer.
*
* @param u8 The integer.
*/
void putU8(uint8_t u8)
{
put(&u8, 1);
}
/**
* Adds an 8-bit integer option.
*
* @returns true/false just like begin().
*
* @param uOption The option number.
* @param u8 The integer
*/
bool optU8(uint8_t uOption, uint8_t u8)
{
if (!begin(uOption, 1))
return false;
putU8(u8);
return true;
}
/**
* Puts an 32-bit integer (network endian).
*
* @param u32Network The integer.
*/
void putU32(uint32_t u32)
{
put(&u32, 4);
}
/**
* Adds an 32-bit integer (network endian) option.
*
* @returns true/false just like begin().
*
* @param uOption The option number.
* @param u32Network The integer.
*/
bool optU32(uint8_t uOption, uint32_t u32)
{
if (!begin(uOption, 4))
return false;
putU32(u32);
return true;
}
/**
* Puts a std::string.
*
* @param rStr Reference to the string.
*/
void putStr(std::string const &rStr)
{
put(rStr.c_str(), rStr.size());
}
/**
* Adds an std::string option if the string isn't empty.
*
* @returns true/false just like begin().
*
* @param uOption The option number.
* @param rStr Reference to the string.
*/
bool optStr(uint8_t uOption, std::string const &rStr)
{
const size_t cch = rStr.size();
if (!cch)
return true;
if (!begin(uOption, cch))
return false;
put(rStr.c_str(), cch);
return true;
}
/**
* Whether we've overflowed.
*
* @returns true on overflow, false otherwise.
*/
bool hasOverflowed(void) const
{
return m_fOverflowed;
}
/**
* Adds the terminating END option.
*
* The END will always be added as we're reserving room for it, however, we
* might have dropped previous options due to overflows and that is what the
* return status indicates.
*
* @returns true on success, false on a (previous) overflow.
*/
bool optEnd(void)
{
Assert((uintptr_t)(m_pbEnd - m_pbCur) < 4096);
*m_pbCur++ = RTNET_DHCP_OPT_END;
return !hasOverflowed();
}
};
#endif