Commit 7e2204f4 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[992]: Initial implementation of DHCPv4 server component

parent f76fdc8d
......@@ -840,6 +840,8 @@ AC_CONFIG_FILES([Makefile
src/bin/auth/benchmarks/Makefile
src/bin/dhcp6/Makefile
src/bin/dhcp6/tests/Makefile
src/bin/dhcp4/Makefile
src/bin/dhcp4/tests/Makefile
src/bin/resolver/Makefile
src/bin/resolver/tests/Makefile
src/bin/sockcreator/Makefile
......@@ -978,6 +980,7 @@ AC_OUTPUT([doc/version.ent
src/bin/msgq/run_msgq.sh
src/bin/auth/auth.spec.pre
src/bin/auth/spec_config.h.pre
src/bin/dhcp4/spec_config.h.pre
src/bin/dhcp6/spec_config.h.pre
src/bin/tests/process_rename_test.py
src/lib/config/tests/data_def_unittests_config.h
......
SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
usermgr zonemgr stats tests resolver sockcreator dhcp6
usermgr zonemgr stats tests resolver sockcreator dhcp6 dhcp4
check-recursive: all-recursive
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
pkglibexecdir = $(libexecdir)/@PACKAGE@
man_MANS = b10-dhcp4.8
EXTRA_DIST = $(man_MANS) dhcp4.spec
if ENABLE_MAN
b10-dhcp4.8: b10-dhcp4.xml
xsltproc --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/b10-dhcp4.xml
endif
spec_config.h: spec_config.h.pre
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
BUILT_SOURCES = spec_config.h
pkglibexec_PROGRAMS = b10-dhcp4
b10_dhcp4_SOURCES = main.cc dhcp4_srv.cc dhcp4_srv.h
b10_dhcp4_LDADD = $(top_builddir)/src/lib/dhcp/libdhcp.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/log/liblog.la
# TODO: This is ugly hack. iface_mgr should be moved to src/lib/dhcp
b10_dhcp4_LDADD += $(top_builddir)/src/bin/dhcp6/iface_mgr.o
# TODO: config.h.in is wrong because doesn't honor pkgdatadir
# and can't use @datadir@ because doesn't expand default ${prefix}
b10_dhcp4dir = $(pkgdatadir)
b10_dhcp4_DATA = dhcp4.spec
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- Copyright (C) 2011 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.
-->
<refentry>
<refentryinfo>
<date>October 27, 2011</date>
</refentryinfo>
<refmeta>
<refentrytitle>b10-dhcp4</refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo>BIND10</refmiscinfo>
</refmeta>
<refnamediv>
<refname>b10-dhcp4</refname>
<refpurpose>DHCPv4 server in BIND 10 architecture</refpurpose>
</refnamediv>
<docinfo>
<copyright>
<year>2011</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
<refsynopsisdiv>
<cmdsynopsis>
<command>b10-dhcp4</command>
<arg><option>-v</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>
The <command>b10-dhcp4</command> daemon will provide the
DHCPv4 server implementation when it becomes functional.
</para>
</refsect1>
<refsect1>
<title>ARGUMENTS</title>
<para>The arguments are as follows:</para>
<variablelist>
<varlistentry>
<term><option>-v</option></term>
<listitem><para>
Enable verbose mode.
<!-- TODO: what does this do? -->
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>SEE ALSO</title>
<para>
<citerefentry>
<refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>.
</para>
</refsect1>
<refsect1>
<title>HISTORY</title>
<para>
The <command>b10-dhcp4</command> daemon was first coded in
November 2011 by Tomek Mrugalski.
</para>
</refsect1>
</refentry><!--
- Local variables:
- mode: sgml
- End:
-->
{
"module_spec": {
"module_name": "dhcp4",
"module_description": "DHCPv4 daemon",
"config_data": [
{ "item_name": "interface",
"item_type": "string",
"item_optional": false,
"item_default": "eth0"
}
],
"commands": []
}
}
// Copyright (C) 2011 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.
#include <dhcp/dhcp4.h>
#include <dhcp/pkt4.h>
#include <dhcp6/iface_mgr.h>
#include <dhcp4/dhcp4_srv.h>
#include <asiolink/io_address.h>
using namespace std;
using namespace isc;
using namespace isc::dhcp;
using namespace isc::asiolink;
Dhcpv4Srv::Dhcpv4Srv() {
cout << "Initialization" << endl;
// first call to instance() will create IfaceMgr (it's a singleton)
// it may throw something if things go wrong
IfaceMgr::instance();
/// @todo: instantiate LeaseMgr here once it is imlpemented.
setServerID();
shutdown = false;
}
Dhcpv4Srv::~Dhcpv4Srv() {
cout << "DHCPv4 server shutdown." << endl;
}
bool
Dhcpv4Srv::run() {
while (!shutdown) {
boost::shared_ptr<Pkt4> query; // client's message
boost::shared_ptr<Pkt4> rsp; // server's response
#if 0
query = IfaceMgr::instance().receive4();
#endif
if (query) {
if (!query->unpack()) {
cout << "Failed to parse incoming packet" << endl;
continue;
}
switch (query->getType()) {
case DHCPDISCOVER:
rsp = processDiscover(query);
break;
case DHCPREQUEST:
rsp = processRequest(query);
break;
case DHCPRELEASE:
processRelease(query);
break;
case DHCPDECLINE:
processDecline(query);
break;
case DHCPINFORM:
processInform(query);
break;
default:
cout << "Unknown pkt type received:"
<< query->getType() << endl;
}
cout << "Received " << query->len() << " bytes packet type="
<< query->getType() << endl;
/// DEBUG
cout << query->toText();
if (rsp) {
#if 0
rsp->remote_addr_ = query->remote_addr_;
rsp->local_addr_ = query->local_addr_;
rsp->remote_port_ = DHCP6_CLIENT_PORT;
rsp->local_port_ = DHCP6_SERVER_PORT;
rsp->ifindex_ = query->ifindex_;
rsp->iface_ = query->iface_;
#endif
cout << "Replying with:" << rsp->getType() << endl;
cout << rsp->toText();
cout << "----" << endl;
if (rsp->pack()) {
cout << "#### pack successful." << endl;
}
#if 0
IfaceMgr::instance().send4(rsp);
#endif
}
}
// TODO add support for config session (see src/bin/auth/main.cc)
// so this daemon can be controlled from bob
}
return (true);
}
void
Dhcpv4Srv::setServerID() {
/// TODO implement this for real once interface detection is done.
/// Use hardcoded server-id for now
#if 0
IOAddress srvId("127.0.0.1");
serverid_ = boost::shared_ptr<Option>(
new Option4AddrLst(Option::V4, DHO_DHCP_SERVER_IDENTIFIER, srvId));
#endif
}
boost::shared_ptr<Pkt4>
Dhcpv4Srv::processDiscover(boost::shared_ptr<Pkt4> discover) {
/// TODO: Echo mode. Implement this for real
return (discover);
}
boost::shared_ptr<Pkt4>
Dhcpv4Srv::processRequest(boost::shared_ptr<Pkt4> request) {
/// TODO: Echo mode. Implement this for real
return (request);
}
void Dhcpv4Srv::processRelease(boost::shared_ptr<Pkt4> release) {
/// TODO: Implement this.
cout << "Received RELEASE on " << release->getIface() << " interface." << endl;
}
void Dhcpv4Srv::processDecline(boost::shared_ptr<Pkt4> decline) {
/// TODO: Implement this.
cout << "Received DECLINE on " << decline->getIface() << " interface." << endl;
}
boost::shared_ptr<Pkt4> processInform(boost::shared_ptr<Pkt4> inform) {
/// TODO: Echo mode. Implement this for real
return (inform);
}
// Copyright (C) 2011 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.
#ifndef DHCPV4_SRV_H
#define DHCPV4_SRV_H
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <dhcp/pkt4.h>
#include <dhcp/option.h>
#include <iostream>
namespace isc {
namespace dhcp {
/// @brief DHCPv4 server service.
///
/// This singleton class represents DHCPv4 server. It contains all
/// top-level methods and routines necessary for server operation.
/// In particular, it instantiates IfaceMgr, loads or generates DUID
/// that is going to be used as server-identifier, receives incoming
/// packets, processes them, manages leases assignment and generates
/// appropriate responses.
class Dhcpv4Srv : public boost::noncopyable {
public:
/// @brief Default constructor.
///
/// Instantiates necessary services, required to run DHCPv6 server.
/// In particular, creates IfaceMgr that will be responsible for
/// network interaction. Will instantiate lease manager, and load
/// old or create new DUID.
Dhcpv4Srv();
/// @brief Destructor. Used during DHCPv6 service shutdown.
~Dhcpv4Srv();
/// @brief Main server processing loop.
///
/// Main server processing loop. Receives incoming packets, verifies
/// their correctness, generates appropriate answer (if needed) and
/// transmits respones.
///
/// @return true, if being shut down gracefully, fail if experienced
/// critical error.
bool run();
protected:
/// @brief Processes incoming DISCOVER and returns response.
///
/// Processes received DISCOVER message and verifies that its sender
/// should be served. In particular, a lease is selected and sent
/// as an offer to a client if it should be served.
///
/// @param solicit DISCOVER message received from client
///
/// @return OFFER message or NULL
boost::shared_ptr<Pkt4>
processDiscover(boost::shared_ptr<Pkt4> discover);
/// @brief Processes incoming REQUEST and returns REPLY response.
///
/// Processes incoming REQUEST message and verifies that its sender
/// should be served. In particular, verifies that requested lease
/// is valid, not expired, not reserved, not used by other client and
/// that requesting client is allowed to use it.
///
/// Returns ACK message, NACK message, or NULL
///
/// @param request a message received from client
///
/// @return ACK or NACK message
boost::shared_ptr<Pkt4> processRequest(boost::shared_ptr<Pkt4> request);
/// @brief Stub function that will handle incoming RELEASE messages.
///
/// In DHCPv4, server does not respond to RELEASE messages, therefore
/// this function does not return anything.
///
/// @param release message received from client
void processRelease(boost::shared_ptr<Pkt4> release);
/// @brief Stub function that will handle incoming DHCPDECLINE messages.
///
/// @param decline message received from client
void processDecline(boost::shared_ptr<Pkt4> decline);
/// @brief Stub function that will handle incoming INFORM messages.
///
/// @param infRequest message received from client
boost::shared_ptr<Pkt4> processInform(boost::shared_ptr<Pkt4> inform);
/// @brief Returns server-intentifier option
///
/// @return server-id option
boost::shared_ptr<isc::dhcp::Option>
getServerID() { return serverid_; }
/// @brief Sets server-identifier.
///
/// This method attempts to set server-identifier DUID. It tries to
/// load previously stored IP from configuration. If there is no previously
/// stored server identifier, it will pick up one address from configured
/// and supported network interfaces.
///
/// @throws isc::Unexpected Failed to obtain server identifier (i.e. no
// previously stored configuration and no network interfaces available)
void setServerID();
/// server DUID (to be sent in server-identifier option)
boost::shared_ptr<isc::dhcp::Option> serverid_;
/// indicates if shutdown is in progress. Setting it to true will
/// initiate server shutdown procedure.
volatile bool shutdown;
};
}; // namespace isc::dhcp
}; // namespace isc
#endif // DHCP4_SRV_H
// Copyright (C) 2009-2011 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.
#include <config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <cassert>
#include <iostream>
#include <exceptions/exceptions.h>
#if 0
// TODO cc is not used yet. It should be eventually
#include <cc/session.h>
#include <config/ccsession.h>
#endif
#include <util/buffer.h>
#include <log/dummylog.h>
#include <dhcp4/spec_config.h>
#include <dhcp4/dhcp4_srv.h>
using namespace std;
using namespace isc::util;
using namespace isc;
using namespace isc::dhcp;
namespace {
bool verbose_mode = false;
void
usage() {
cerr << "Usage: b10-dhcp4 [-v]"
<< endl;
cerr << "\t-v: verbose output" << endl;
exit(1);
}
} // end of anonymous namespace
int
main(int argc, char* argv[]) {
int ch;
while ((ch = getopt(argc, argv, ":v")) != -1) {
switch (ch) {
case 'v':
verbose_mode = true;
isc::log::denabled = true;
break;
case ':':
default:
usage();
}
}
cout << "My pid=" << getpid() << endl;
if (argc - optind > 0) {
usage();
}
int ret = 0;
// TODO remainder of auth to dhcp6 code copy. We need to enable this in
// dhcp6 eventually
#if 0
Session* cc_session = NULL;
Session* statistics_session = NULL;
ModuleCCSession* config_session = NULL;
#endif
try {
string specfile;
if (getenv("B10_FROM_BUILD")) {
specfile = string(getenv("B10_FROM_BUILD")) +
"/src/bin/auth/dhcp4.spec";
} else {
specfile = string(DHCP4_SPECFILE_LOCATION);
}
cout << "[b10-dhcp4] Initiating DHCPv4 server operation." << endl;
Dhcpv4Srv* srv = new Dhcpv4Srv();
srv->run();
} catch (const std::exception& ex) {
cerr << "[b10-dhcp6] Server failed: " << ex.what() << endl;
ret = 1;
}
return (ret);
}
// Copyright (C) 2011 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.
#define DHCP4_SPECFILE_LOCATION "@prefix@/share/@PACKAGE@/dhcp4.spec"
{
"module_spec": {
"module_name": "dhcp6",
"module_description": "DHCPv6 daemon",
"module_name": "dhcp4",
"module_description": "DHCPv4 daemon",
"config_data": [
{ "item_name": "interface",
"item_type": "string",
......
......@@ -303,6 +303,14 @@ public:
boost::shared_ptr<Option>
getOption(uint8_t opt_type);
/// @brief Returns interface name.
///
/// Returns interface name over which packet was received or is
/// going to be transmitted.
///
/// @return interface name
std::string getIface() { return iface_; };
protected:
/// converts DHCP message type to BOOTP op type
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment