Config.h revision ae6c6b63a02886bd9d58462eed8626899872f584
/* $Id$ */
/**
* This file contains declarations of DHCP config.
*/
#ifndef _CONFIG_H_
# define _CONFIG_H_
{
return (RT_N2H_U32(a.u) < RT_N2H_U32(b.u));
}
{
return (b < a);
}
typedef enum CLIENTSESSIONSTATE
{
/**
* defult state, session isn't operable, not initialized an so on.
*/
/** We've received dhcp discover =>
* Using XID (we record session)
* and response with DHCPOFFER
*/
/**
* We're ready to send DHCPOFFER
*/
/**
* This more, session state, we responsed, to
* client with DHCPOFFER using session's XID
*/
/**
* this is session's state, client's done DHCPREQUEST with (XID)
*/
/**
* We're ready to send DHCPACK or DHCPNAK
*/
/**
* We've been able to furfill client's request for (XID) session, erased others Client
* 's sessions ... and send DHCPACK (should be Lease bind at this point?)
*/
/**
* We couldn't furfill client's request -> destroy session.
*/
/**
* real client, don't want our DHCPOFFER, we're delating our client representation,
* and sessions objects.
*/
/**
* nice to have, but not mandatory.
*/
{
};
/**
* This class joins client and the lease ...
* at the begining client might request several address assignments...
*
* So session here is descriptor joining client to each of it's requests.
* When client finalizes its selection ... only single assignment is chosen,
* others are released.
*/
{
{
/* XXX: state ? Which is acceptable on initialization ?! */
addressHint.u = 0;
}
int switchTo(CLIENTSESSIONSTATE);
/* XXX private: */
/**/
/* We don't store the state in the client, because client might initiate several
* sessions.
*/
/**
* uniq identificator of session
*/
/* dhcp-opts: request address */
/* dhcp-opts: request parameter list */
/* Config for this session */
const BaseConfigEntity *m_pCfg;
};
/*
* it's a basic representation of
* of out undestanding what client is
* XXX: Client might sends Option 61 (RFC2132 9.14 "Client-identifier") signalling
* that we may identify it in special way
*
* XXX: Client might send Option 60 (RFC2132 9.13 "Vendor class undentifier")
* in response it's expected server sends Option 43 (RFC2132 8.4. "Vendor Specific Information")
*/
{
/* XXX: Option 60 and 61 */
{
}
/** Dumps client query */
void dump();
/* XXX! private: */
/* XXX: it's logically per session object, but some client broke XIDness */
/* XXX: we're using it as stack */
};
{
static SessionManager* getSessionManager();
/**
* This method we call on every DHCP packet we've received.
*/
/* XXX: DHCPDECLINE */
/* XXX: DHCPRELEASE */
SessionManager(){}
virtual ~SessionManager(){}
};
{
static ConfigurationManager* getConfigurationManager();
/**
* We call this on DHCPDISCOVER
*/
/**
* 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)...
*/
/*
* We call this before DHCPACK sent and after DHCPREQUEST received ...
* when requested configuration is acceptable.
*/
const RTNETADDRIPV4& networkId,
const RTNETADDRIPV4& netmask,
/* XXX: from config */
{
switch(u8OptId)
{
case RTNET_DHCP_OPT_DNS:
break;
case RTNET_DHCP_OPT_ROUTERS:
break;
default:
}
return VINF_SUCCESS;
}
{
switch(u8OptId)
{
case RTNET_DHCP_OPT_DNS:
break;
case RTNET_DHCP_OPT_ROUTERS:
break;
default:
}
return VINF_SUCCESS;
}
{
switch(u8OptId)
{
case RTNET_DHCP_OPT_DNS:
return m_nameservers;
case RTNET_DHCP_OPT_ROUTERS:
return m_routers;
}
/* XXX: Grrr !!! */
return m_empty;
}
/*
*
*/
};
{
static NetworkManager *getNetworkManager();
/* XXX: artifacts should be hidden or removed from here. */
union {
int cbBooPReplyMsg;
NetworkManager(){}
virtual ~NetworkManager(){}
};
/**
*
*/
{
};
{
{
}
{
}
};
{
{
}
{
}
};
{
{
return true;
}
};
{
{
}
};
#if 0
/* XXX: Later */
{
{
}
};
#endif
/* Option 60 */
/* Option 61 */
/**
* This is basic representation of leased address. we map it in 1:1 relation to
* Client
*/
{
};
/**
* It's representation of our lease db.
*/
{
int matchingLevel = 0)
: m_criteria(criteria),
virtual ~BaseConfigEntity(){};
/* XXX */
{
return 0;
}
/* Should return how strong matching */
{
if (m_children.empty())
{
if (iMatch > 0)
{
return iMatch;
}
}
else
{
/* XXX: hack */
int matchingLevel = m_MatchLevel;
++it)
{
if (iMatch > matchingLevel)
{
}
}
return matchingLevel;
}
return iMatch;
}
const ClientMatchCriteria *m_criteria;
int m_MatchLevel;
};
{
NullConfigEntity(){}
virtual ~NullConfigEntity(){}
{
return 0;
}
};
{
/* range */
/* match conditions */
const BaseConfigEntity *cfg,
const ClientMatchCriteria *criteria,
int matchingLevel = 0):
{
}
const BaseConfigEntity *m_parentCfg;
};
/**
* Network specific entries
*/
{
/* Address Pool matching with network declaration */
const BaseConfigEntity *cfg,
const ClientMatchCriteria *criteria,
int matchlvl,
const RTNETADDRIPV4& networkID,
const RTNETADDRIPV4& networkMask,
const RTNETADDRIPV4& lowerIP,
const RTNETADDRIPV4& upperIP):
{
};
const BaseConfigEntity *cfg,
const ClientMatchCriteria *criteria,
const RTNETADDRIPV4& networkID,
const RTNETADDRIPV4& networkMask):
{
m_LowerIP.u = m_NetworkID.u;
};
};
/**
* Host specific entry
* Address pool is contains one element
*/
{
const NetworkConfigEntity *cfg,
const ClientMatchCriteria *criteria):
10,
addr,
addr)
{
/* upper addr == lower addr */
}
{
}
};
{
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
*/
{
{
}
};
#endif
{
static const LeaseGenerator *getGenerator();
/** returns already allocated lease or NULL */
/** generates new lease by client query and configuration rules */
LeaseGenerator(){}
virtual ~LeaseGenerator(){}
};
extern const ClientMatchCriteria *g_AnyClient;
extern const RootConfigEntity *g_RootConfig;
extern const NullConfigEntity *g_NullConfig;
/**
* Helper class for stuffing DHCP options into a reply packet.
*/
{
bool m_fOverflowed; /**< Set if we've overflowed, otherwise false. */
/** Instantiate an option cursor for the specified DHCP message. */
m_fUsed(0),
m_fOverflowed(false)
{
}
/** Destructor. */
{
}
/**
* Try use the bp_file field.
* @returns true if not overloaded, false otherwise.
*/
bool useBpFile(void)
{
if ( m_pfOverload
&& (*m_pfOverload & 1))
return false;
return true;
}
/**
* Try overload more BOOTP fields
*/
bool overloadMore(void)
{
/* switch option area. */
if (!(m_fUsed & 1))
{
fField = 1;
}
else if (!(m_fUsed & 2))
{
fField = 2;
}
else
return false;
if (!m_pfOverload)
{
/* Add an overload option. */
}
else
*m_pfOverload |= fField;
/* pad current option field */
/* switch */
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.
*/
{
/* Check that the data of the previous option has all been written. */
/* Check if we need to overload more stuff. */
{
if (!overloadMore())
{
m_fOverflowed = true;
}
{
m_fOverflowed = true;
}
}
/* Emit the option header. */
m_pbCur += 2;
return true;
}
/**
* Puts option data.
*
* @param pvData The data.
* @param cb The amount to put.
*/
{
{
}
}
/**
* Puts an IPv4 Address.
*
* @param IPv4Addr The address.
*/
{
}
/**
* Adds an IPv4 address option.
*
*
* @param uOption The option number.
* @param IPv4Addr The address.
*/
{
return false;
return true;
}
/**
* Adds an option taking 1 or more IPv4 address.
*
* If the vector contains no addresses, the option will not be added.
*
*
* @param uOption The option number.
* @param rIPv4Addrs Reference to the address vector.
*/
{
if (!c)
return true;
return false;
for (size_t i = 0; i < c; i++)
putIPv4Addr(rIPv4Addrs[i]);
return true;
}
/**
* Puts an 8-bit integer.
*
* @param u8 The integer.
*/
{
}
/**
* Adds an 8-bit integer option.
*
*
* @param uOption The option number.
* @param u8 The integer
*/
{
return false;
return true;
}
/**
* Puts an 32-bit integer (network endian).
*
* @param u32Network The integer.
*/
{
}
/**
* Adds an 32-bit integer (network endian) option.
*
*
* @param uOption The option number.
* @param u32Network The integer.
*/
{
return false;
return true;
}
/**
* Puts a std::string.
*
* @param rStr Reference to the string.
*/
{
}
/**
* Adds an std::string option if the string isn't empty.
*
*
* @param uOption The option number.
* @param rStr Reference to the string.
*/
{
if (!cch)
return true;
return false;
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)
{
*m_pbCur++ = RTNET_DHCP_OPT_END;
return !hasOverflowed();
}
};
#endif