namespace dhcp {
/* BOOTP (rfc951) message types */
- enum BOOTPTypes {
- BOOTREQUEST = 1,
- BOOTREPLY = 2 };
+enum BOOTPTypes {
+ BOOTREQUEST = 1,
+ BOOTREPLY = 2
+};
/* Possible values for flags field... */
- static const uint16_t BOOTP_BROADCAST = 32768L;
+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
- };
-
-/* Magic cookie validating dhcp options field (and bootp vendor
- extensions field). */
-#define DHCP_OPTIONS_COOKIE "\143\202\123\143"
+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
- };
+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
- };
-
+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
/* Enterprise Suboptions: */
#define VENDOR_ISC_SUBOPTIONS 2495
- static const uint16_t DHCP4_CLIENT_PORT = 68;
- static const uint16_t DHCP4_SERVER_PORT = 67;
+#endif
} // end of isc::dhcp namespace
} // end of isc namespace
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_(IOAddress("0.0.0.0")),
- remote_addr_(IOAddress("0.0.0.0")),
+ :local_addr_(DEFAULT_ADDRESS),
+ remote_addr_(DEFAULT_ADDRESS),
iface_(""),
ifindex_(0),
local_port_(DHCP4_SERVER_PORT),
}
Pkt4::Pkt4(const uint8_t* data, size_t len)
- :local_addr_(IOAddress("0.0.0.0")),
- remote_addr_(IOAddress("0.0.0.0")),
+ :local_addr_(DEFAULT_ADDRESS),
+ remote_addr_(DEFAULT_ADDRESS),
iface_(""),
ifindex_(-1),
local_port_(DHCP4_SERVER_PORT),
}
void
-Pkt4::setHWAddr(uint8_t hType, uint8_t hlen, const uint8_t* macAddr) {
+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) && (hlen > 0) ) {
+ 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, hlen);
+ memcpy(chaddr_, &macAddr[0], hlen);
}
void
}
}
-};
+} // end of namespace isc::dhcp
+
+} // end of namespace isc
/// @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 uint8_t* macAddr);
+ const std::vector<uint8_t>& macAddr);
/// Returns htype field
///
ASSERT_EQ(236U, DHCPV4_PKT_HDR_LEN);
Pkt4* pkt = 0;
- // minimal
+ // minimal
uint8_t testData[250];
for (int i = 0; i < 250; i++) {
- testData[i]=i;
+ testData[i]=i;
}
// positive case1. Normal received packet
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,
+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.";
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, dummyMacAddr);
+ pkt->setHWAddr(6, 6, vectorMacAddr);
pkt->setHops(13); // 13 relays. Wow!
// transaction-id is already set
pkt->setSecs(42);
pkt->setSiaddr(IOAddress("192.0.2.255"));
pkt->setGiaddr(IOAddress("255.255.255.255"));
// chaddr already set with setHWAddr()
- pkt->setSname(dummySname, 64);
+ 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.
+/// 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
-shared_array<uint8_t>
+// Returns a vector containing a DHCPv4 packet header.
+vector<uint8_t>
generateTestPacket2() {
- shared_array<uint8_t> buf(new uint8_t[Pkt4::DHCPV4_PKT_HDR_LEN]);
-
- // that is only part of the header. It contains all "short" fields,
- // larger fields are constructed separately
+ // 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,
+ 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
+ 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
};
- BOOST_STATIC_ASSERT(28 == sizeof(hdr));
-
- size_t offset = 0;
+ // Initialize the vector with the header fields defined above.
+ vector<uint8_t> buf(hdr, hdr + sizeof(hdr));
- memcpy(&buf[0] + offset, hdr, sizeof(hdr));
- offset += 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));
- memcpy(&buf[0] + offset, dummyMacAddr, 6); // chaddr is 16 bytes
- offset += Pkt4::MAX_CHADDR_LEN;
- memcpy(&buf[0] + offset, dummySname, 64); // sname is 64 bytes
- offset += Pkt4::MAX_SNAME_LEN;
- memcpy(&buf[0] + offset, dummyFile, 128);
- offset += Pkt4::MAX_FILE_LEN;
+ // 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, fixedFieldsUnpack) {
shared_array<uint8_t> expectedFormat = generateTestPkt2();
- shared_ptr<Pkt4> pkt(new Pkt4(&expectedFormat[0],
+ shared_ptr<Pkt4> pkt(new Pkt4(&expectedFormat[0],
Pkt4::DHCPV4_PKT_HDR_LEN));
// ok, let's check packet values
// this test is for hardware addresses (htype, hlen and chaddr fields)
TEST(Pkt4Test, hwAddr) {
- uint8_t mac[Pkt4::MAX_CHADDR_LEN];
+ 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++) {
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(),
+ EXPECT_EQ(0, memcmp(expectedChaddr, pkt->getChaddr(),
Pkt4::MAX_CHADDR_LEN));
#if 0
/// TODO Uncomment when ticket #1227 is implemented)
- EXPECT_NO_THROW(
+ EXPECT_NO_THROW(
pkt->pack();
);
// CHADDR starts at offset 28 in DHCP packet
- EXPECT_EQ(0, memcmp(pkt->getData()+28, expectedChaddr,
+ EXPECT_EQ(0, memcmp(pkt->getData()+28, expectedChaddr,
Pkt4::MAX_CHADDR_LEN));
#endif
sname[i] = i;
expectedSname[i] = i;
}
-
+
// type and transaction doesn't matter in this test
pkt = new Pkt4(DHCPOFFER, 1234);
pkt->setSname(sname, snameLen);
#if 0
/// TODO Uncomment when ticket #1227 is implemented)
- EXPECT_NO_THROW(
+ EXPECT_NO_THROW(
pkt->pack();
);
file[i] = i;
expectedFile[i] = i;
}
-
+
// type and transaction doesn't matter in this test
pkt = new Pkt4(DHCPOFFER, 1234);
pkt->setFile(file, fileLen);
#if 0
/// TODO Uncomment when ticket #1227 is implemented)
- EXPECT_NO_THROW(
+ EXPECT_NO_THROW(
pkt->pack();
);