BIND 10 master, updated. ba1568e6482268cea9dbf7f980a17423133c65eb Merge branch 'trac1224'
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Oct 25 09:11:12 UTC 2011
The branch, master has been updated
via ba1568e6482268cea9dbf7f980a17423133c65eb (commit)
via f7c85718e562f5cbbd6eafeb2549a21f358afba8 (commit)
via edffc4851f7373294b6486a5d6171f406f7e1de6 (commit)
via 1b328591b9bd5f366bc6e205aad0cde28e447442 (commit)
via 61488d93393fff47ea8cce1c2b41ac004802caaf (commit)
via 0a54d27ad889cc8931bc5a0b6549325c4fb3e45f (commit)
via 81c031de6abed68c9fb4a89b2a71474f36488b9b (commit)
from bad7607f03104c81cf7224f6fd71db009219ad51 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ba1568e6482268cea9dbf7f980a17423133c65eb
Merge: bad7607f03104c81cf7224f6fd71db009219ad51 f7c85718e562f5cbbd6eafeb2549a21f358afba8
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Tue Oct 25 10:39:40 2011 +0200
Merge branch 'trac1224'
-----------------------------------------------------------------------
Summary of changes:
src/lib/dhcp/Makefile.am | 3 +-
src/lib/dhcp/dhcp4.h | 191 +++++++++++++
src/lib/dhcp/pkt4.cc | 189 +++++++++++++
src/lib/dhcp/pkt4.h | 380 +++++++++++++++++++++++++
src/lib/dhcp/pkt6.cc | 3 +-
src/lib/dhcp/pkt6.h | 2 +-
src/lib/dhcp/tests/Makefile.am | 1 +
src/lib/dhcp/tests/option6_ia_unittest.cc | 4 +-
src/lib/dhcp/tests/pkt4_unittest.cc | 430 +++++++++++++++++++++++++++++
src/lib/dhcp/tests/pkt6_unittest.cc | 3 +-
10 files changed, 1201 insertions(+), 5 deletions(-)
create mode 100644 src/lib/dhcp/dhcp4.h
create mode 100644 src/lib/dhcp/pkt4.cc
create mode 100644 src/lib/dhcp/pkt4.h
create mode 100644 src/lib/dhcp/tests/pkt4_unittest.cc
-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am
index e146adb..64dda17 100644
--- a/src/lib/dhcp/Makefile.am
+++ b/src/lib/dhcp/Makefile.am
@@ -14,8 +14,9 @@ libdhcp_la_SOURCES += option.cc option.h
libdhcp_la_SOURCES += option6_ia.cc option6_ia.h
libdhcp_la_SOURCES += option6_iaaddr.cc option6_iaaddr.h
libdhcp_la_SOURCES += option6_addrlst.cc option6_addrlst.h
-libdhcp_la_SOURCES += dhcp6.h
+libdhcp_la_SOURCES += dhcp6.h dhcp4.h
libdhcp_la_SOURCES += pkt6.cc pkt6.h
+libdhcp_la_SOURCES += pkt4.cc pkt4.h
EXTRA_DIST = README
#EXTRA_DIST += log_messages.mes
diff --git a/src/lib/dhcp/dhcp4.h b/src/lib/dhcp/dhcp4.h
new file mode 100644
index 0000000..98381ac
--- /dev/null
+++ b/src/lib/dhcp/dhcp4.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ * Internet Systems Consortium, Inc.
+ * 950 Charter Street
+ * Redwood City, CA 94063
+ * <info at isc.org>
+ * https://www.isc.org/
+ *
+ * This software has been written for Internet Systems Consortium
+ * by Ted Lemon in cooperation with Vixie Enterprises. To learn more
+ * about Internet Systems Consortium, see ``https://www.isc.org''.
+ * To learn more about Vixie Enterprises, see ``http://www.vix.com''.
+ */
+
+/*
+ * NOTE: This files is imported from ISC DHCP. It uses C notation.
+ * Format kept for easier merge.
+ */
+
+#ifndef DHCP_H
+#define DHCP_H
+
+#include <stdint.h>
+
+namespace isc {
+namespace dhcp {
+
+/* BOOTP (rfc951) message types */
+enum BOOTPTypes {
+ BOOTREQUEST = 1,
+ BOOTREPLY = 2
+};
+
+/* Possible values for flags field... */
+static const uint16_t BOOTP_BROADCAST = 32768L;
+
+/* Possible values for hardware type (htype) field... */
+enum HType {
+ HTYPE_ETHER = 1, /* Ethernet 10Mbps */
+ HTYPE_IEEE802 = 6, /* IEEE 802.2 Token Ring */
+ HTYPE_FDDI = 8 /* FDDI */
+ /// TODO Add infiniband here
+};
+
+/* DHCP Option codes: */
+enum DHCPOptionType {
+ DHO_PAD = 0,
+ DHO_SUBNET_MASK = 1,
+ DHO_TIME_OFFSET = 2,
+ DHO_ROUTERS = 3,
+ DHO_TIME_SERVERS = 4,
+ DHO_NAME_SERVERS = 5,
+ DHO_DOMAIN_NAME_SERVERS = 6,
+ DHO_LOG_SERVERS = 7,
+ DHO_COOKIE_SERVERS = 8,
+ DHO_LPR_SERVERS = 9,
+ DHO_IMPRESS_SERVERS = 10,
+ DHO_RESOURCE_LOCATION_SERVERS = 11,
+ DHO_HOST_NAME = 12,
+ DHO_BOOT_SIZE = 13,
+ DHO_MERIT_DUMP = 14,
+ DHO_DOMAIN_NAME = 15,
+ DHO_SWAP_SERVER = 16,
+ DHO_ROOT_PATH = 17,
+ DHO_EXTENSIONS_PATH = 18,
+ DHO_IP_FORWARDING = 19,
+ DHO_NON_LOCAL_SOURCE_ROUTING = 20,
+ DHO_POLICY_FILTER = 21,
+ DHO_MAX_DGRAM_REASSEMBLY = 22,
+ DHO_DEFAULT_IP_TTL = 23,
+ DHO_PATH_MTU_AGING_TIMEOUT = 24,
+ DHO_PATH_MTU_PLATEAU_TABLE = 25,
+ DHO_INTERFACE_MTU = 26,
+ DHO_ALL_SUBNETS_LOCAL = 27,
+ DHO_BROADCAST_ADDRESS = 28,
+ DHO_PERFORM_MASK_DISCOVERY = 29,
+ DHO_MASK_SUPPLIER = 30,
+ DHO_ROUTER_DISCOVERY = 31,
+ DHO_ROUTER_SOLICITATION_ADDRESS = 32,
+ DHO_STATIC_ROUTES = 33,
+ DHO_TRAILER_ENCAPSULATION = 34,
+ DHO_ARP_CACHE_TIMEOUT = 35,
+ DHO_IEEE802_3_ENCAPSULATION = 36,
+ DHO_DEFAULT_TCP_TTL = 37,
+ DHO_TCP_KEEPALIVE_INTERVAL = 38,
+ DHO_TCP_KEEPALIVE_GARBAGE = 39,
+ DHO_NIS_DOMAIN = 40,
+ DHO_NIS_SERVERS = 41,
+ DHO_NTP_SERVERS = 42,
+ DHO_VENDOR_ENCAPSULATED_OPTIONS = 43,
+ DHO_NETBIOS_NAME_SERVERS = 44,
+ DHO_NETBIOS_DD_SERVER = 45,
+ DHO_NETBIOS_NODE_TYPE = 46,
+ DHO_NETBIOS_SCOPE = 47,
+ DHO_FONT_SERVERS = 48,
+ DHO_X_DISPLAY_MANAGER = 49,
+ DHO_DHCP_REQUESTED_ADDRESS = 50,
+ DHO_DHCP_LEASE_TIME = 51,
+ DHO_DHCP_OPTION_OVERLOAD = 52,
+ DHO_DHCP_MESSAGE_TYPE = 53,
+ DHO_DHCP_SERVER_IDENTIFIER = 54,
+ DHO_DHCP_PARAMETER_REQUEST_LIST = 55,
+ DHO_DHCP_MESSAGE = 56,
+ DHO_DHCP_MAX_MESSAGE_SIZE = 57,
+ DHO_DHCP_RENEWAL_TIME = 58,
+ DHO_DHCP_REBINDING_TIME = 59,
+ DHO_VENDOR_CLASS_IDENTIFIER = 60,
+ DHO_DHCP_CLIENT_IDENTIFIER = 61,
+ DHO_NWIP_DOMAIN_NAME = 62,
+ DHO_NWIP_SUBOPTIONS = 63,
+ DHO_USER_CLASS = 77,
+ DHO_FQDN = 81,
+ DHO_DHCP_AGENT_OPTIONS = 82,
+ DHO_AUTHENTICATE = 90, /* RFC3118, was 210 */
+ DHO_CLIENT_LAST_TRANSACTION_TIME = 91,
+ DHO_ASSOCIATED_IP = 92,
+ DHO_SUBNET_SELECTION = 118, /* RFC3011! */
+ DHO_DOMAIN_SEARCH = 119, /* RFC3397 */
+ DHO_VIVCO_SUBOPTIONS = 124,
+ DHO_VIVSO_SUBOPTIONS = 125,
+
+ DHO_END = 255
+};
+
+/* DHCP message types. */
+enum DHCPMessageType {
+ DHCPDISCOVER = 1,
+ DHCPOFFER = 2,
+ DHCPREQUEST = 3,
+ DHCPDECLINE = 4,
+ DHCPACK = 5,
+ DHCPNAK = 6,
+ DHCPRELEASE = 7,
+ DHCPINFORM = 8,
+ DHCPLEASEQUERY = 10,
+ DHCPLEASEUNASSIGNED = 11,
+ DHCPLEASEUNKNOWN = 12,
+ DHCPLEASEACTIVE = 13
+};
+
+static const uint16_t DHCP4_CLIENT_PORT = 68;
+static const uint16_t DHCP4_SERVER_PORT = 67;
+
+/// Magic cookie validating dhcp options field (and bootp vendor
+/// extensions field).
+///static const char* DHCP_OPTIONS_COOKIE = "\143\202\123\143";
+
+// TODO: Following are leftovers from dhcp.h import from ISC DHCP
+// They will be converted to C++-style defines once they will start
+// to be used.
+#if 0
+/* Relay Agent Information option subtypes: */
+#define RAI_CIRCUIT_ID 1
+#define RAI_REMOTE_ID 2
+#define RAI_AGENT_ID 3
+#define RAI_LINK_SELECT 5
+
+/* FQDN suboptions: */
+#define FQDN_NO_CLIENT_UPDATE 1
+#define FQDN_SERVER_UPDATE 2
+#define FQDN_ENCODED 3
+#define FQDN_RCODE1 4
+#define FQDN_RCODE2 5
+#define FQDN_HOSTNAME 6
+#define FQDN_DOMAINNAME 7
+#define FQDN_FQDN 8
+#define FQDN_SUBOPTION_COUNT 8
+
+/* Enterprise Suboptions: */
+#define VENDOR_ISC_SUBOPTIONS 2495
+
+#endif
+
+} // end of isc::dhcp namespace
+} // end of isc namespace
+
+#endif /* DHCP_H */
diff --git a/src/lib/dhcp/pkt4.cc b/src/lib/dhcp/pkt4.cc
new file mode 100644
index 0000000..9bc9948
--- /dev/null
+++ b/src/lib/dhcp/pkt4.cc
@@ -0,0 +1,189 @@
+// 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/pkt4.h>
+#include <dhcp/libdhcp.h>
+#include <dhcp/dhcp4.h>
+#include <exceptions/exceptions.h>
+#include <asiolink/io_address.h>
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+using namespace isc::dhcp;
+using namespace isc::asiolink;
+
+namespace isc {
+namespace dhcp {
+
+const IOAddress DEFAULT_ADDRESS("0.0.0.0");
+
+Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
+ :local_addr_(DEFAULT_ADDRESS),
+ remote_addr_(DEFAULT_ADDRESS),
+ iface_(""),
+ ifindex_(0),
+ local_port_(DHCP4_SERVER_PORT),
+ remote_port_(DHCP4_CLIENT_PORT),
+ op_(DHCPTypeToBootpType(msg_type)),
+ htype_(HTYPE_ETHER),
+ hlen_(0),
+ hops_(0),
+ transid_(transid),
+ secs_(0),
+ flags_(0),
+ ciaddr_(DEFAULT_ADDRESS),
+ yiaddr_(DEFAULT_ADDRESS),
+ siaddr_(DEFAULT_ADDRESS),
+ giaddr_(DEFAULT_ADDRESS),
+ bufferIn_(0), // not used, this is TX packet
+ bufferOut_(DHCPV4_PKT_HDR_LEN),
+ msg_type_(msg_type)
+{
+ /// TODO: fixed fields, uncomment in ticket #1224
+ memset(chaddr_, 0, MAX_CHADDR_LEN);
+ memset(sname_, 0, MAX_SNAME_LEN);
+ memset(file_, 0, MAX_FILE_LEN);
+}
+
+Pkt4::Pkt4(const uint8_t* data, size_t len)
+ :local_addr_(DEFAULT_ADDRESS),
+ remote_addr_(DEFAULT_ADDRESS),
+ iface_(""),
+ ifindex_(-1),
+ local_port_(DHCP4_SERVER_PORT),
+ remote_port_(DHCP4_CLIENT_PORT),
+ /// TODO Fixed fields, uncomment in ticket #1224
+ op_(BOOTREQUEST),
+ transid_(transid_),
+ secs_(0),
+ flags_(0),
+ ciaddr_(DEFAULT_ADDRESS),
+ yiaddr_(DEFAULT_ADDRESS),
+ siaddr_(DEFAULT_ADDRESS),
+ giaddr_(DEFAULT_ADDRESS),
+ bufferIn_(0), // not used, this is TX packet
+ bufferOut_(DHCPV4_PKT_HDR_LEN),
+ msg_type_(DHCPDISCOVER)
+{
+ if (len < DHCPV4_PKT_HDR_LEN) {
+ isc_throw(OutOfRange, "Truncated DHCPv4 packet (len=" << len
+ << " received, at least 236 bytes expected.");
+ }
+ bufferIn_.writeData(data, len);
+}
+
+size_t
+Pkt4::len() {
+ size_t length = DHCPV4_PKT_HDR_LEN; // DHCPv4 header
+
+ /// TODO: Include options here (ticket #1228)
+ return (length);
+}
+
+bool
+Pkt4::pack() {
+ /// TODO: Implement this (ticket #1227)
+
+ return (false);
+}
+bool
+Pkt4::unpack() {
+ /// TODO: Implement this (ticket #1226)
+
+ return (false);
+}
+
+std::string
+Pkt4::toText() {
+ stringstream tmp;
+ tmp << "localAddr=[" << local_addr_.toText() << "]:" << local_port_
+ << " remoteAddr=[" << remote_addr_.toText()
+ << "]:" << remote_port_ << endl;
+ tmp << "msgtype=" << msg_type_
+ << ", transid=0x" << hex << transid_ << dec
+ << endl;
+
+ return tmp.str();
+}
+
+void
+Pkt4::setHWAddr(uint8_t hType, uint8_t hlen,
+ const std::vector<uint8_t>& macAddr) {
+ /// TODO Rewrite this once support for client-identifier option
+ /// is implemented (ticket 1228?)
+ if (hlen>MAX_CHADDR_LEN) {
+ isc_throw(OutOfRange, "Hardware address (len=" << hlen
+ << " too long. Max " << MAX_CHADDR_LEN << " supported.");
+ }
+ if ( (macAddr.size() == 0) && (hlen > 0) ) {
+ isc_throw(OutOfRange, "Invalid HW Address specified");
+ }
+
+ htype_ = hType;
+ hlen_ = hlen;
+ memset(chaddr_, 0, MAX_CHADDR_LEN);
+ memcpy(chaddr_, &macAddr[0], hlen);
+}
+
+void
+Pkt4::setSname(const uint8_t* sname, size_t snameLen /*= MAX_SNAME_LEN*/) {
+ if (snameLen > MAX_SNAME_LEN) {
+ isc_throw(OutOfRange, "sname field (len=" << snameLen
+ << ") too long, Max " << MAX_SNAME_LEN << " supported.");
+ }
+ memset(sname_, 0, MAX_SNAME_LEN);
+ memcpy(sname_, sname, snameLen);
+
+ // no need to store snameLen as any empty space is filled with 0s
+}
+
+void
+Pkt4::setFile(const uint8_t* file, size_t fileLen /*= MAX_FILE_LEN*/) {
+ if (fileLen > MAX_FILE_LEN) {
+ isc_throw(OutOfRange, "file field (len=" << fileLen
+ << ") too long, Max " << MAX_FILE_LEN << " supported.");
+ }
+ memset(file_, 0, MAX_FILE_LEN);
+ memcpy(file_, file, fileLen);
+
+ // no need to store fileLen as any empty space is filled with 0s
+}
+
+uint8_t
+Pkt4::DHCPTypeToBootpType(uint8_t dhcpType) {
+ switch (dhcpType) {
+ case DHCPDISCOVER:
+ case DHCPREQUEST:
+ case DHCPDECLINE:
+ case DHCPRELEASE:
+ case DHCPINFORM:
+ case DHCPLEASEQUERY:
+ return (BOOTREQUEST);
+ case DHCPACK:
+ case DHCPNAK:
+ case DHCPOFFER:
+ case DHCPLEASEUNASSIGNED:
+ case DHCPLEASEUNKNOWN:
+ case DHCPLEASEACTIVE:
+ return (BOOTREPLY);
+ default:
+ isc_throw(OutOfRange, "Invalid message type: "
+ << static_cast<int>(dhcpType) );
+ }
+}
+
+} // end of namespace isc::dhcp
+
+} // end of namespace isc
diff --git a/src/lib/dhcp/pkt4.h b/src/lib/dhcp/pkt4.h
new file mode 100644
index 0000000..7ac0ca9
--- /dev/null
+++ b/src/lib/dhcp/pkt4.h
@@ -0,0 +1,380 @@
+// 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 PKT4_H
+#define PKT4_H
+
+#include <iostream>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include "asiolink/io_address.h"
+#include "util/buffer.h"
+#include "dhcp/option.h"
+
+namespace isc {
+
+namespace dhcp {
+
+class Pkt4 {
+public:
+
+ /// length of the CHADDR field in DHCPv4 message
+ const static size_t MAX_CHADDR_LEN = 16;
+
+ /// length of the SNAME field in DHCPv4 message
+ const static size_t MAX_SNAME_LEN = 64;
+
+ /// length of the FILE field in DHCPv4 message
+ const static size_t MAX_FILE_LEN = 128;
+
+ /// specifies DHCPv4 packet header length (fixed part)
+ const static size_t DHCPV4_PKT_HDR_LEN = 236;
+
+ /// Constructor, used in replying to a message.
+ ///
+ /// @param msg_type type of message (e.g. DHCPDISOVER=1)
+ /// @param transid transaction-id
+ Pkt4(uint8_t msg_type, uint32_t transid);
+
+ /// @brief Constructor, used in message reception.
+ ///
+ /// Creates new message. Pkt4 will copy data to bufferIn_
+ /// buffer on creation.
+ ///
+ /// @param data pointer to received data
+ /// @param len size of buffer to be allocated for this packet.
+ Pkt4(const uint8_t* data, size_t len);
+
+ /// @brief Prepares on-wire format of DHCPv4 packet.
+ ///
+ /// Prepares on-wire format of message and all its options.
+ /// Options must be stored in options_ field.
+ /// Output buffer will be stored in bufferOut_.
+ ///
+ /// @return true if packing procedure was successful
+ bool
+ pack();
+
+ /// @brief Parses on-wire form of DHCPv4 packet.
+ ///
+ /// Parses received packet, stored in on-wire format in bufferIn_.
+ ///
+ /// Will create a collection of option objects that will
+ /// be stored in options_ container.
+ ///
+ /// @return true, if parsing was successful
+ bool
+ unpack();
+
+ /// @brief Returns text representation of the packet.
+ ///
+ /// This function is useful mainly for debugging.
+ ///
+ /// @return string with text representation
+ std::string
+ toText();
+
+ /// @brief Returns the size of the required buffer to build the packet.
+ ///
+ /// Returns the size of the required buffer to build the packet with
+ /// the current set of packet options.
+ ///
+ /// @return number of bytes required to build this packet
+ size_t
+ len();
+
+ /// Sets hops field
+ ///
+ /// @param hops value to be set
+ void
+ setHops(uint8_t hops) { hops_ = hops; };
+
+ /// Returns hops field
+ ///
+ /// @return hops field
+ uint8_t
+ getHops() { return (hops_); };
+
+ // Note: There's no need to manipulate OP field directly,
+ // thus no setOp() method. See op_ comment.
+
+ /// Returns op field
+ ///
+ /// @return op field
+ uint8_t
+ getOp() { return (op_); };
+
+ /// Sets secs field
+ ///
+ /// @param secs value to be set
+ void
+ setSecs(uint16_t secs) { secs_ = secs; };
+
+ /// Returns secs field
+ ///
+ /// @return secs field
+ uint16_t
+ getSecs() { return (secs_); };
+
+ /// Sets flags field
+ ///
+ /// @param flags value to be set
+ void
+ setFlags(uint16_t flags) { flags_ = flags; };
+
+ /// Returns flags field
+ ///
+ /// @return flags field
+ uint16_t
+ getFlags() { return (flags_); };
+
+
+ /// Returns ciaddr field
+ ///
+ /// @return ciaddr field
+ isc::asiolink::IOAddress&
+ getCiaddr() { return (ciaddr_); };
+
+ /// Sets ciaddr field
+ ///
+ /// @param ciaddr value to be set
+ void
+ setCiaddr(const isc::asiolink::IOAddress& ciaddr) { ciaddr_ = ciaddr; };
+
+
+ /// Returns siaddr field
+ ///
+ /// @return siaddr field
+ isc::asiolink::IOAddress&
+ getSiaddr() { return (siaddr_); };
+
+ /// Sets siaddr field
+ ///
+ /// @param siaddr value to be set
+ void
+ setSiaddr(const isc::asiolink::IOAddress& siaddr) { siaddr_ = siaddr; };
+
+
+ /// Returns yiaddr field
+ ///
+ /// @return yiaddr field
+ isc::asiolink::IOAddress&
+ getYiaddr() { return (yiaddr_); };
+
+ /// Sets yiaddr field
+ ///
+ /// @param yiaddr value to be set
+ void
+ setYiaddr(const isc::asiolink::IOAddress& yiaddr) { yiaddr_ = yiaddr; };
+
+
+ /// Returns giaddr field
+ ///
+ /// @return giaddr field
+ isc::asiolink::IOAddress&
+ getGiaddr() { return (giaddr_); };
+
+ /// Sets giaddr field
+ ///
+ /// @param giaddr value to be set
+ void
+ setGiaddr(const isc::asiolink::IOAddress& giaddr) { giaddr_ = giaddr; };
+
+ /// Returns value of transaction-id field
+ ///
+ /// @return transaction-id
+ uint32_t getTransid() { return (transid_); };
+
+ /// Returns message type (e.g. 1 = DHCPDISCOVER)
+ ///
+ /// @return message type
+ uint8_t
+ getType() { return (msg_type_); }
+
+ /// Sets message type (e.g. 1 = DHCPDISCOVER)
+ ///
+ /// @param type message type to be set
+ void setType(uint8_t type) { msg_type_=type; };
+
+ /// @brief Returns sname field
+ ///
+ /// Note: This is 64 bytes long field. It doesn't have to be
+ /// null-terminated. Do not use strlen() or similar on it.
+ ///
+ /// @return sname field
+ const std::vector<uint8_t>
+ getSname() { return (std::vector<uint8_t>(sname_, &sname_[MAX_SNAME_LEN])); };
+
+ /// Sets sname field
+ ///
+ /// @param sname value to be set
+ void
+ setSname(const uint8_t* sname, size_t snameLen = MAX_SNAME_LEN);
+
+ /// @brief Returns file field
+ ///
+ /// Note: This is 128 bytes long field. It doesn't have to be
+ /// null-terminated. Do not use strlen() or similar on it.
+ ///
+ /// @return pointer to file field
+ const std::vector<uint8_t>
+ getFile() { return (std::vector<uint8_t>(file_, &file_[MAX_FILE_LEN])); };
+
+ /// Sets file field
+ ///
+ /// @param file value to be set
+ void
+ setFile(const uint8_t* file, size_t fileLen = MAX_FILE_LEN);
+
+ /// @brief Sets hardware address.
+ ///
+ /// Sets parameters of hardware address. hlen specifies
+ /// length of macAddr buffer. Content of macAddr buffer
+ /// will be copied to appropriate field.
+ ///
+ /// Note: macAddr must be a buffer of at least hlen bytes.
+ ///
+ /// @param hwType hardware type (will be sent in htype field)
+ /// @param hlen hardware length (will be sent in hlen field)
+ /// @param macAddr pointer to hardware address
+ void setHWAddr(uint8_t hType, uint8_t hlen,
+ const std::vector<uint8_t>& macAddr);
+
+ /// Returns htype field
+ ///
+ /// @return hardware type
+ uint8_t
+ getHtype() { return (htype_); };
+
+ /// Returns hlen field
+ ///
+ /// @return hardware address length
+ uint8_t
+ getHlen() { return (hlen_); };
+
+ /// @brief Returns chaddr field
+ ///
+ /// Note: This is 16 bytes long field. It doesn't have to be
+ /// null-terminated. Do no use strlen() or similar on it.
+ ///
+ /// @return pointer to hardware address
+ const uint8_t*
+ getChaddr() { return (chaddr_); };
+
+
+protected:
+
+ /// converts DHCP message type to BOOTP op type
+ ///
+ /// @param dhcpType DHCP message type (e.g. DHCPDISCOVER)
+ ///
+ /// @return BOOTP type (BOOTREQUEST or BOOTREPLY)
+ uint8_t
+ DHCPTypeToBootpType(uint8_t dhcpType);
+
+ /// local address (dst if receiving packet, src if sending packet)
+ isc::asiolink::IOAddress local_addr_;
+
+ /// remote address (src if receiving packet, dst if sending packet)
+ isc::asiolink::IOAddress remote_addr_;
+
+ /// name of the network interface the packet was received/to be sent over
+ std::string iface_;
+
+ /// @brief interface index
+ ///
+ /// Each network interface has assigned unique ifindex. It is functional
+ /// equvalent of name, but sometimes more useful, e.g. when using crazy
+ /// systems that allow spaces in interface names e.g. MS Windows)
+ int ifindex_;
+
+ /// local UDP port
+ int local_port_;
+
+ /// remote UDP port
+ int remote_port_;
+
+ /// @brief message operation code
+ ///
+ /// Note: This is legacy BOOTP field. There's no need to manipulate it
+ /// directly. Its value is set based on DHCP message type. Note that
+ /// DHCPv4 protocol reuses BOOTP message format, so this field is
+ /// kept due to BOOTP format. This is NOT DHCPv4 type (DHCPv4 message
+ /// type is kept in message type option).
+ uint8_t op_;
+
+ /// link-layer address type
+ uint8_t htype_;
+
+ /// link-layer address length
+ uint8_t hlen_;
+
+ /// Number of relay agents traversed
+ uint8_t hops_;
+
+ /// DHCPv4 transaction-id (32 bits, not 24 bits as in DHCPv6)
+ uint32_t transid_;
+
+ /// elapsed (number of seconds since beginning of transmission)
+ uint16_t secs_;
+
+ /// flags
+ uint16_t flags_;
+
+ /// ciaddr field (32 bits): Client's IP address
+ isc::asiolink::IOAddress ciaddr_;
+
+ /// yiaddr field (32 bits): Client's IP address ("your"), set by server
+ isc::asiolink::IOAddress yiaddr_;
+
+ /// siaddr field (32 bits): next server IP address in boot process(e.g.TFTP)
+ isc::asiolink::IOAddress siaddr_;
+
+ /// giaddr field (32 bits): Gateway IP address
+ isc::asiolink::IOAddress giaddr_;
+
+ /// Hardware address field (16 bytes)
+ uint8_t chaddr_[MAX_CHADDR_LEN];
+
+ /// sname field (64 bytes)
+ uint8_t sname_[MAX_SNAME_LEN];
+
+ /// file field (128 bytes)
+ uint8_t file_[MAX_FILE_LEN];
+
+ // end of real DHCPv4 fields
+
+ /// input buffer (used during message reception)
+ /// Note that it must be modifiable as hooks can modify incoming buffer),
+ /// thus OutputBuffer, not InputBuffer
+ isc::util::OutputBuffer bufferIn_;
+
+ /// output buffer (used during message
+ isc::util::OutputBuffer bufferOut_;
+
+ /// message type (e.g. 1=DHCPDISCOVER)
+ /// TODO: this will eventually be replaced with DHCP Message Type
+ /// option (option 53)
+ uint8_t msg_type_;
+
+ /// collection of options present in this message
+ isc::dhcp::Option::Option4Collection options_;
+}; // Pkt4 class
+
+} // isc::dhcp namespace
+
+} // isc namespace
+
+#endif
diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc
index 1e4a553..b00652a 100644
--- a/src/lib/dhcp/pkt6.cc
+++ b/src/lib/dhcp/pkt6.cc
@@ -124,7 +124,8 @@ Pkt6::packUDP() {
cout << "Packet build failed:" << e.what() << endl;
return (false);
}
- cout << "Packet built, len=" << len() << endl;
+ // Limited verbosity of this method
+ // cout << "Packet built, len=" << len() << endl;
return (true);
}
diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h
index 35bccbc..d089444 100644
--- a/src/lib/dhcp/pkt6.h
+++ b/src/lib/dhcp/pkt6.h
@@ -19,7 +19,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include "asiolink/io_address.h"
-#include "option.h"
+#include "dhcp/option.h"
namespace isc {
diff --git a/src/lib/dhcp/tests/Makefile.am b/src/lib/dhcp/tests/Makefile.am
index 3fce27e..41cabba 100644
--- a/src/lib/dhcp/tests/Makefile.am
+++ b/src/lib/dhcp/tests/Makefile.am
@@ -22,6 +22,7 @@ libdhcp_unittests_SOURCES += ../option6_ia.h ../option6_ia.cc option6_ia_unittes
libdhcp_unittests_SOURCES += ../option6_addrlst.h ../option6_addrlst.cc option6_addrlst_unittest.cc
libdhcp_unittests_SOURCES += ../option.h ../option.cc option_unittest.cc
libdhcp_unittests_SOURCES += ../pkt6.h ../pkt6.cc pkt6_unittest.cc
+libdhcp_unittests_SOURCES += ../pkt4.h ../pkt4.cc pkt4_unittest.cc
libdhcp_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
libdhcp_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
diff --git a/src/lib/dhcp/tests/option6_ia_unittest.cc b/src/lib/dhcp/tests/option6_ia_unittest.cc
index ac4127a..91aaba4 100644
--- a/src/lib/dhcp/tests/option6_ia_unittest.cc
+++ b/src/lib/dhcp/tests/option6_ia_unittest.cc
@@ -220,7 +220,9 @@ TEST_F(Option6IATest, suboptions_unpack) {
Option6IA* ia = 0;
EXPECT_NO_THROW({
ia = new Option6IA(D6O_IA_NA, buf, 128, 4, 44);
- cout << "Parsed option:" << endl << ia->toText() << endl;
+
+ // let's limit verbosity of this test
+ // cout << "Parsed option:" << endl << ia->toText() << endl;
});
ASSERT_TRUE(ia);
diff --git a/src/lib/dhcp/tests/pkt4_unittest.cc b/src/lib/dhcp/tests/pkt4_unittest.cc
new file mode 100644
index 0000000..11b6015
--- /dev/null
+++ b/src/lib/dhcp/tests/pkt4_unittest.cc
@@ -0,0 +1,430 @@
+// 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 <config.h>
+#include <iostream>
+#include <sstream>
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+#include <boost/static_assert.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+
+#include "io_address.h"
+#include "dhcp/pkt4.h"
+#include "dhcp/dhcp4.h"
+#include "exceptions/exceptions.h"
+
+using namespace std;
+using namespace isc;
+using namespace isc::asiolink;
+using namespace isc::dhcp;
+using namespace boost;
+
+// can't compare const to value directly, as it gives strange
+// linker errors in gtest.h
+
+static size_t DHCPV4_PKT_HDR_LEN = Pkt4::DHCPV4_PKT_HDR_LEN;
+
+namespace {
+
+TEST(Pkt4Test, constructor) {
+
+ ASSERT_EQ(236U, DHCPV4_PKT_HDR_LEN);
+ Pkt4* pkt = 0;
+
+ // minimal
+ uint8_t testData[250];
+ for (int i = 0; i < 250; i++) {
+ testData[i]=i;
+ }
+
+ // positive case1. Normal received packet
+ EXPECT_NO_THROW(
+ pkt = new Pkt4(testData, 236);
+ );
+
+ EXPECT_EQ(236, pkt->len());
+
+ EXPECT_NO_THROW(
+ delete pkt;
+ pkt = 0;
+ );
+
+ // positive case2. Normal outgoing packet
+ EXPECT_NO_THROW(
+ pkt = new Pkt4(DHCPDISCOVER, 0xffffffff);
+ );
+
+ // DHCPv4 packet must be at least 236 bytes long
+ EXPECT_EQ(DHCPV4_PKT_HDR_LEN, pkt->len());
+ EXPECT_EQ(DHCPDISCOVER, pkt->getType());
+ EXPECT_EQ(0xffffffff, pkt->getTransid());
+ EXPECT_NO_THROW(
+ delete pkt;
+ pkt = 0;
+ );
+
+ // negative case. Should drop truncated messages
+ EXPECT_THROW(
+ pkt = new Pkt4(testData, 235),
+ OutOfRange
+ );
+ if (pkt) {
+ // test failed. Exception should have been thrown, but
+ // object was created instead. Let's clean this up
+ delete pkt;
+ }
+}
+
+// a sample transaction-id
+const static uint32_t dummyTransid = 0x12345678;
+
+// a dummy MAC address
+const uint8_t dummyMacAddr[] = {0, 1, 2, 3, 4, 5};
+
+// a dummy MAC address, padded with 0s
+const uint8_t dummyChaddr[16] = {0, 1, 2, 3, 4, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 };
+
+// let's use some creative test content here (128 chars + \0)
+const uint8_t dummyFile[] = "Lorem ipsum dolor sit amet, consectetur "
+ "adipiscing elit. Proin mollis placerat metus, at "
+ "lacinia orci ornare vitae. Mauris amet.";
+
+// yet another type of test content (64 chars + \0)
+const uint8_t dummySname[] = "Lorem ipsum dolor sit amet, consectetur "
+ "adipiscing elit posuere.";
+
+BOOST_STATIC_ASSERT(sizeof(dummyFile) == Pkt4::MAX_FILE_LEN + 1);
+BOOST_STATIC_ASSERT(sizeof(dummySname) == Pkt4::MAX_SNAME_LEN + 1);
+
+/// Generates test packet
+///
+/// Allocates and generates test packet, with all fixed
+/// fields set to non-zero values. Content is not always
+/// reasonable.
+///
+/// See generateTestPacket2() function that returns
+/// exactly the same packet in on-wire format.
+///
+/// @return pointer to allocated Pkt4 object.
+boost::shared_ptr<Pkt4>
+generateTestPacket1() {
+
+ boost::shared_ptr<Pkt4> pkt(new Pkt4(DHCPDISCOVER, dummyTransid));
+
+ vector<uint8_t> vectorMacAddr(dummyMacAddr, dummyMacAddr
+ +sizeof(dummyMacAddr));
+
+ // hwType = 6(ETHERNET), hlen = 6(MAC address len)
+ pkt->setHWAddr(6, 6, vectorMacAddr);
+ pkt->setHops(13); // 13 relays. Wow!
+ // transaction-id is already set
+ pkt->setSecs(42);
+ pkt->setFlags(0xffffU); // all flags set
+ pkt->setCiaddr(IOAddress("192.0.2.1"));
+ pkt->setYiaddr(IOAddress("1.2.3.4"));
+ pkt->setSiaddr(IOAddress("192.0.2.255"));
+ pkt->setGiaddr(IOAddress("255.255.255.255"));
+ // chaddr already set with setHWAddr()
+ pkt->setSname(dummySname, 64);
+ pkt->setFile(dummyFile, 128);
+
+ return (pkt);
+}
+
+/// Generates test packet
+///
+/// Allocates and generates on-wire buffer that represents
+/// test packet, with all fixed fields set to non-zero values.
+/// Content is not always reasonable.
+///
+/// See generateTestPacket1() function that returns
+/// exactly the same packet as Pkt4 object.
+///
+/// @return pointer to allocated Pkt4 object
+// Returns a vector containing a DHCPv4 packet header.
+vector<uint8_t>
+generateTestPacket2() {
+
+ // That is only part of the header. It contains all "short" fields,
+ // larger fields are constructed separately.
+ uint8_t hdr[] = {
+ 1, 6, 6, 13, // op, htype, hlen, hops,
+ 0x12, 0x34, 0x56, 0x78, // transaction-id
+ 0, 42, 0xff, 0xff, // 42 secs, 0xffff flags
+ 192, 0, 2, 1, // ciaddr
+ 1, 2, 3, 4, // yiaddr
+ 192, 0, 2, 255, // siaddr
+ 255, 255, 255, 255, // giaddr
+ };
+
+ // Initialize the vector with the header fields defined above.
+ vector<uint8_t> buf(hdr, hdr + sizeof(hdr));
+
+ // Append the large header fields.
+ copy(dummyMacAddr, dummyMacAddr + Pkt4::MAX_CHADDR_LEN, back_inserter(buf));
+ copy(dummySname, dummySname + Pkt4::MAX_SNAME_LEN, back_inserter(buf));
+ copy(dummyFile, dummyFile + Pkt4::MAX_FILE_LEN, back_inserter(buf));
+
+ // Should now have all the header, so check. The "static_cast" is used
+ // to get round an odd bug whereby the linker appears not to find the
+ // definition of DHCPV4_PKT_HDR_LEN if it appears within an EXPECT_EQ().
+ EXPECT_EQ(static_cast<size_t>(Pkt4::DHCPV4_PKT_HDR_LEN), buf.size());
+
+ return (buf);
+}
+
+TEST(Pkt4Test, fixedFields) {
+
+ shared_ptr<Pkt4> pkt = generateTestPacket1();
+
+ // ok, let's check packet values
+ EXPECT_EQ(1, pkt->getOp());
+ EXPECT_EQ(6, pkt->getHtype());
+ EXPECT_EQ(6, pkt->getHlen());
+ EXPECT_EQ(13, pkt->getHops());
+ EXPECT_EQ(dummyTransid, pkt->getTransid());
+ EXPECT_EQ(42, pkt->getSecs());
+ EXPECT_EQ(0xffff, pkt->getFlags());
+
+ EXPECT_EQ(string("192.0.2.1"), pkt->getCiaddr().toText());
+ EXPECT_EQ(string("1.2.3.4"), pkt->getYiaddr().toText());
+ EXPECT_EQ(string("192.0.2.255"), pkt->getSiaddr().toText());
+ EXPECT_EQ(string("255.255.255.255"), pkt->getGiaddr().toText());
+
+ // chaddr is always 16 bytes long and contains link-layer addr (MAC)
+ EXPECT_EQ(0, memcmp(dummyChaddr, pkt->getChaddr(), 16));
+
+ EXPECT_EQ(0, memcmp(dummySname, &pkt->getSname()[0], 64));
+
+ EXPECT_EQ(0, memcmp(dummyFile, &pkt->getFile()[0], 128));
+
+ EXPECT_EQ(DHCPDISCOVER, pkt->getType());
+}
+
+#if 0
+/// TODO Uncomment when ticket #1227 is implemented
+TEST(Pkt4Test, fixedFieldsPack) {
+ shared_ptr<Pkt4> pkt = generateTestPacket1();
+ shared_array<uint8_t> expectedFormat = generateTestPacket2();
+
+ EXPECT_NO_THROW(
+ pkt->pack();
+ );
+
+ ASSERT_EQ(Pkt4::DHCPV4_PKT_HDR_LEN, pkt->len());
+
+ EXPECT_EQ(0, memcmp(&expectedFormat[0], pkt->getData(), pkt->len()));
+}
+
+/// TODO Uncomment when ticket #1226 is implemented
+TEST(Pkt4Test, fixedFieldsUnpack) {
+ shared_array<uint8_t> expectedFormat = generateTestPkt2();
+
+ shared_ptr<Pkt4> pkt(new Pkt4(&expectedFormat[0],
+ Pkt4::DHCPV4_PKT_HDR_LEN));
+
+ // ok, let's check packet values
+ EXPECT_EQ(1, pkt->getOp());
+ EXPECT_EQ(6, pkt->getHtype());
+ EXPECT_EQ(6, pkt->getHlen());
+ EXPECT_EQ(13, pkt->getHops());
+ EXPECT_EQ(transid, pkt->getTransid());
+ EXPECT_EQ(42, pkt->getSecs());
+ EXPECT_EQ(0xffff, pkt->getFlags());
+
+ EXPECT_EQ(string("192.0.2.1"), pkt->getCiaddr.toText());
+ EXPECT_EQ(string("1.2.3.4"), pkt->getYiaddr.toText());
+ EXPECT_EQ(string("192.0.2.255"), pkt->getSiaddr.toText());
+ EXPECT_EQ(string("255.255.255.255"), pkt->getGiaddr.toText());
+
+ // chaddr is always 16 bytes long and contains link-layer addr (MAC)
+ EXPECT_EQ(0, memcmp(expectedChaddr, pkt->getChaddr(), 16));
+
+ EXPECT_EQ(0, memcmp(expectedSname, pkt->getSname(), 64));
+
+ EXPECT_EQ(0, memcmp(expectedFile, pkt->getFile(), 128));
+
+ EXPECT_EQ(DHCPSOLICIT, pkt->getType());
+}
+#endif
+
+// this test is for hardware addresses (htype, hlen and chaddr fields)
+TEST(Pkt4Test, hwAddr) {
+
+ vector<uint8_t> mac;
+ uint8_t expectedChaddr[Pkt4::MAX_CHADDR_LEN];
+
+ mac.resize(Pkt4::MAX_CHADDR_LEN);
+
+ Pkt4* pkt = 0;
+ // let's test each hlen, from 0 till 16
+ for (int macLen=0; macLen < Pkt4::MAX_CHADDR_LEN; macLen++) {
+ for (int i=0; i < Pkt4::MAX_CHADDR_LEN; i++) {
+ mac[i] = 0;
+ expectedChaddr[i] = 0;
+ }
+ for (int i=0; i < macLen; i++) {
+ mac[i] = 128+i;
+ expectedChaddr[i] = 128+i;
+ }
+
+ // type and transaction doesn't matter in this test
+ pkt = new Pkt4(DHCPOFFER, 1234);
+ pkt->setHWAddr(255-macLen*10, // just weird htype
+ macLen,
+ mac);
+ EXPECT_EQ(0, memcmp(expectedChaddr, pkt->getChaddr(),
+ Pkt4::MAX_CHADDR_LEN));
+
+#if 0
+ /// TODO Uncomment when ticket #1227 is implemented)
+ EXPECT_NO_THROW(
+ pkt->pack();
+ );
+
+ // CHADDR starts at offset 28 in DHCP packet
+ EXPECT_EQ(0, memcmp(pkt->getData()+28, expectedChaddr,
+ Pkt4::MAX_CHADDR_LEN));
+#endif
+
+ delete pkt;
+ }
+
+ /// TODO: extend this test once options support is implemented. HW address
+ /// longer than 16 bytes should be stored in client-identifier option
+}
+
+TEST(Pkt4Test, msgTypes) {
+
+ struct msgType {
+ uint8_t dhcp;
+ uint8_t bootp;
+ };
+
+ msgType types[] = {
+ {DHCPDISCOVER, BOOTREQUEST},
+ {DHCPOFFER, BOOTREPLY},
+ {DHCPREQUEST, BOOTREQUEST},
+ {DHCPDECLINE, BOOTREQUEST},
+ {DHCPACK, BOOTREPLY},
+ {DHCPNAK, BOOTREPLY},
+ {DHCPRELEASE, BOOTREQUEST},
+ {DHCPINFORM, BOOTREQUEST},
+ {DHCPLEASEQUERY, BOOTREQUEST},
+ {DHCPLEASEUNASSIGNED, BOOTREPLY},
+ {DHCPLEASEUNKNOWN, BOOTREPLY},
+ {DHCPLEASEACTIVE, BOOTREPLY}
+ };
+
+ Pkt4* pkt = 0;
+ for (int i=0; i < sizeof(types)/sizeof(msgType); i++) {
+
+ pkt = new Pkt4(types[i].dhcp, 0);
+ EXPECT_EQ(types[i].dhcp, pkt->getType());
+
+ EXPECT_EQ(types[i].bootp, pkt->getOp());
+
+ delete pkt;
+ pkt = 0;
+ }
+
+ EXPECT_THROW(
+ pkt = new Pkt4(100, 0), // there's no message type 100
+ OutOfRange
+ );
+ if (pkt) {
+ delete pkt;
+ }
+}
+
+// this test verifies handling of sname field
+TEST(Pkt4Test, sname) {
+
+ uint8_t sname[Pkt4::MAX_SNAME_LEN];
+ uint8_t expectedSname[Pkt4::MAX_SNAME_LEN];
+
+ Pkt4* pkt = 0;
+ // let's test each sname length, from 0 till 64
+ for (int snameLen=0; snameLen < Pkt4::MAX_SNAME_LEN; snameLen++) {
+ for (int i=0; i < Pkt4::MAX_SNAME_LEN; i++) {
+ sname[i] = 0;
+ expectedSname[i] = 0;
+ }
+ for (int i=0; i < snameLen; i++) {
+ sname[i] = i;
+ expectedSname[i] = i;
+ }
+
+ // type and transaction doesn't matter in this test
+ pkt = new Pkt4(DHCPOFFER, 1234);
+ pkt->setSname(sname, snameLen);
+
+ EXPECT_EQ(0, memcmp(expectedSname, &pkt->getSname()[0], Pkt4::MAX_SNAME_LEN));
+
+#if 0
+ /// TODO Uncomment when ticket #1227 is implemented)
+ EXPECT_NO_THROW(
+ pkt->pack();
+ );
+
+ // SNAME starts at offset 44 in DHCP packet
+ EXPECT_EQ(0, memcmp(pkt->getData()+44, expectedChaddr, Pkt4::MAX_SNAME_LEN));
+#endif
+
+ delete pkt;
+ }
+}
+
+TEST(Pkt4Test, file) {
+
+ uint8_t file[Pkt4::MAX_FILE_LEN];
+ uint8_t expectedFile[Pkt4::MAX_FILE_LEN];
+
+ Pkt4* pkt = 0;
+ // let's test each file length, from 0 till 64
+ for (int fileLen=0; fileLen < Pkt4::MAX_FILE_LEN; fileLen++) {
+ for (int i=0; i < Pkt4::MAX_FILE_LEN; i++) {
+ file[i] = 0;
+ expectedFile[i] = 0;
+ }
+ for (int i=0; i < fileLen; i++) {
+ file[i] = i;
+ expectedFile[i] = i;
+ }
+
+ // type and transaction doesn't matter in this test
+ pkt = new Pkt4(DHCPOFFER, 1234);
+ pkt->setFile(file, fileLen);
+
+ EXPECT_EQ(0, memcmp(expectedFile, &pkt->getFile()[0], Pkt4::MAX_FILE_LEN));
+
+#if 0
+ /// TODO Uncomment when ticket #1227 is implemented)
+ EXPECT_NO_THROW(
+ pkt->pack();
+ );
+
+ // FILE starts at offset 44 in DHCP packet
+ EXPECT_EQ(0, memcmp(pkt->getData()+44, expectedChaddr, Pkt4::MAX_FILE_LEN));
+#endif
+
+ delete pkt;
+ }
+
+}
+
+} // end of anonymous namespace
diff --git a/src/lib/dhcp/tests/pkt6_unittest.cc b/src/lib/dhcp/tests/pkt6_unittest.cc
index 2819f7d..0f110ba 100644
--- a/src/lib/dhcp/tests/pkt6_unittest.cc
+++ b/src/lib/dhcp/tests/pkt6_unittest.cc
@@ -108,7 +108,8 @@ TEST_F(Pkt6Test, unpack_solicit1) {
EXPECT_FALSE(sol->getOption(D6O_IA_TA));
EXPECT_FALSE(sol->getOption(D6O_IAADDR));
- std::cout << sol->toText();
+ // let's limit verbosity of this test
+ // std::cout << sol->toText();
delete sol;
}
More information about the bind10-changes
mailing list