// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

/**
@page libdhcp libdhcp++

@section libdhcpIntro Libdhcp++ Library Introduction

libdhcp++ is an all-purpose DHCP-manipulation library, written in
C++. It offers packet parsing and assembly, DHCPv4 and DHCPv6
options parsing and ssembly, interface detection (currently on
Linux systems only) and socket operations. It is a generic purpose library that
can be used by server, client, relay, performance tools and other DHCP-related
tools. For server specific library, see \ref libdhcpsrv. Please do not
add any server-specific code to libdhcp++ and use \ref libdhcpsrv instead.

The following classes for packet manipulation are implemented:

- isc::dhcp::Pkt4 - represents DHCPv4 packet.
- isc::dhcp::Pkt6 - represents DHCPv6 packet.

There are two pointer types defined: Pkt4Ptr and Pkt6Ptr. They are
smart pointer and are using boost::shared_ptr. There are not const
versions defined, as we assume that hooks can modify any aspect of
the packet at almost any stage of processing.

Both packets use collection of Option objects to represent DHCPv4
and DHCPv6 options. The base class -- Option -- can be used to
represent generic option that contains collection of
bytes. Depending on if the option is instantiated as v4 or v6
option, it will adjust its header (DHCPv4 options use 1 octet for
type and 1 octet for length, while DHCPv6 options use 2 bytes for
each).

There are many specialized classes that are intended to handle options with
specific content:
- isc::dhcp::Option4AddrLst -- DHCPv4 option, contains one or more IPv4 addresses;
- isc::dhcp::Option6AddrLst -- DHCPv6 option, contains one or more IPv6 addresses;
- isc::dhcp::Option6IAAddr -- DHCPv6 option, represents IAADDR_OPTION (an option that
                    contains IPv6 address with extra parameters);
- isc::dhcp::Option6IA -- DHCPv6 option used to store IA_NA and its suboptions.

All options can store sub-options (i.e. options that are stored within option
rather than in a message directly). This functionality is commonly used in
DHCPv6, but is rarely used in DHCPv4. isc::dhcp::Option::addOption(),
isc::dhcp::Option::delOption(), isc::dhcp::Option::getOption() can be used
for that purpose.

@section libdhcpRelay Relay v6 support in Pkt6

DHCPv6 clients that are not connected to the same link as DHCPv6
servers need relays to reach the server. Each relay receives a message
on a client facing interface, encapsulates it into RELAY_MSG option
and sends as RELAY_FORW message towards the server (or the next relay,
which is closer to the server). This procedure can be repeated up to
32 times. Kea is able to support up to 32 relays. Each traversed relay
may add certain options.  The most obvious example is interface-id
option, but there may be other options as well. Each relay may add such
an option, regardless of whether other relays added it before. Thanks
to encapsulation, those options are separated and it is possible to
differentiate which relay inserted specific instance of an option.

Interface-id is used to identify a subnet (or interface) the original message
came from and is used for that purpose on two occasions. First, the server
uses the interface-id included by the first relay (the one closest to
the client) to select appropriate subnet for a given request. Server includes
that interface-id in its copy, when sending data back to the client.
This will be used by the relay to choose proper interface when forwarding
response towards the client.

Pkt6 class has a public Pkt6::relay_info_ field, which is of type Pkt6::RelayInfo.
This is a simple structure that represents the information in each RELAY_FORW
or RELAY_REPL message. It is important to understand the order in which
the data appear here. Consider the following network:

\verbatim
client-------relay1-----relay2-----relay3----server
\endverbatim

Client will transmit SOLICIT message. Relay1 will forward it as
RELAY_FORW with SOLICIT in it. Relay2 forward it as RELAY_FORW with
RELAY_FORW with SOLICIT in it. Finally the third relay will add yet
another RELAY_FORW around it. The server will parse the packet and
create Pkt6 object for it. Its relay_info_ will have 3
elements. Packet parsing is done in reverse order, compare to the
order the packet traversed in the network.  The first element
(relay_info_[0]) will represent relay3 information (the "last" relay or
in other words the one closest to the server). The second element
will represent relay2. The third element (relay_info_[2]) will represent
the first relay (relay1) or in other words the one closest to the client.

Packets sent by the server must maintain the same encapsulation order.
This is easy to do - just copy data from client's message object into
server's response object. See Pkt6::coyRelayInfo for details.

@section libdhcpIfaceMgr Interface Manager

Interface Manager (or IfaceMgr) is an abstraction layer about low-level
network operations. In particlar, it provides information about existing
network interfaces See isc::dhcp::IfaceMgr::Iface class and
isc::dhcp::IfaceMgr::detectIfaces() and isc::dhcp::IfaceMgr::getIface().

Currently there is interface detection is implemented in Linux only. There
are plans to implement such support for other OSes, but they remain low
priority for now.

Generic parts of the code are isc::dhcp::IfaceMgr class in
src/lib/dhcp/iface_mgr.cc file. OS-specific code is located in separate
files, e.g. iface_mgr_linux.cc. Such separation should be maintained when
additional code will be developed.

For systems that interface detection is not supported on, there is a stub
mechanism implemented. It assumes that interface name is read from a text
file. This is a temporary solution and will be removed as soon as proper
interface detection is implemented. It is not going to be developed further.
To use this feature, store interfaces.txt file. It uses a simple syntax.
Each line represents an interface name, followed by IPv4 or IPv6 address
that follows it. This is usually link-local IPv6 address that the server
should bind to. In theory this mechanism also supports IPv4, but it was
never tested. The code currently supports only a single interface defined
that way.

Another useful methods are dedicated to transmission
(isc::dhcp::IfaceMgr::send(), 2 overloads) and reception
(isc::dhcp::IfaceMgr::receive4() and isc::dhcp::IfaceMgr::receive6()).
Note that receive4() and receive6() methods may return NULL, e.g.
when timeout is reached or if dhcp daemon receives a signal.

*/
