25#include <boost/date_time/posix_time/posix_time.hpp>
37using namespace boost::posix_time;
49 uint32_t
const wait_time =
options_.getExitWaitTime();
53 const ptime now = microsec_clock::universal_time();
57 exit_time_ = now + time_duration(microseconds(wait_time));
70 const uint8_t& ipversion =
options_.getIpVersion();
71 const std::vector<int>& num_request =
options_.getNumRequests();
72 const size_t& num_request_size = num_request.size();
74 if (num_request_size == 0) {
78 uint32_t responses = 0;
79 uint32_t requests = num_request[0];
80 if (num_request_size >= 2) {
81 requests += num_request[1];
92 return (responses == requests);
103 static boost::posix_time::ptime last_clean =
104 microsec_clock::universal_time();
107 time_period time_since_clean(last_clean,
108 microsec_clock::universal_time());
110 if (time_since_clean.length().total_seconds() >= 1) {
122 last_clean = microsec_clock::universal_time();
128 if (!pkt_from || !pkt_to) {
130 " for the copyIaOptions function");
138 " server's response");
140 pkt_to->addOption(option);
148 " server's response");
150 pkt_to->addOption(option);
160 <<
" to be created from Reply, expected DHCPREQUEST or"
166 auto msg_type_str = [=]() ->
const char* {
167 return (msg_type ==
DHCPREQUEST ?
"Request" :
"Release");
173 <<
" from a null DHCPACK message");
174 }
else if (ack->getYiaddr().isV4Zero()) {
178 <<
" from a DHCPACK message containing yiaddr of 0");
181 msg->setCiaddr(ack->getYiaddr());
182 msg->setHWAddr(ack->getHWAddr());
192 <<
"from the first packet which lacks the server "
193 "identifier option");
202 if (!server_identifier) {
206 <<
"from a DHCPACK message without the server "
207 "identifier option");
209 msg->addOption(server_identifier);
221 <<
" to be created from Reply, expected DHCPV6_RENEW or"
227 auto msg_type_str = [=]() ->
const char* {
228 return (msg_type ==
DHCPV6_RENEW ?
"Renew" :
"Release");
234 <<
" message from the Reply message because the instance of"
235 " the Reply message is NULL");
243 <<
" message because client id option has not been found"
244 " in the Reply message");
246 msg->addOption(opt_clientid);
251 <<
" because server id option has not been found in the"
254 msg->addOption(opt_serverid);
262 if (buf.size() == 2) {
264 }
else if (buf.size() == 0) {
269 "elapsed time option buffer size has to be 0 or 2");
283 const uint8_t buf_array[] = {
285 0, 0, 3600 >> 8, 3600 & 0xff,
286 0, 0, 5400 >> 8, 5400 & 0xff,
288 OptionBuffer buf_ia_na(buf_array, buf_array +
sizeof(buf_array));
289 for (
size_t i = 0; i < buf.size(); ++i) {
290 buf_ia_na.push_back(buf[i]);
299 static const uint8_t buf_array[] = {
301 0, 0, 3600 >> 8, 3600 & 0xff,
302 0, 0, 5400 >> 8, 5400 & 0xff,
304 OptionBuffer buf_ia_pd(buf_array, buf_array +
sizeof(buf_array));
306 buf_ia_pd.insert(buf_ia_pd.end(), buf.begin(), buf.end());
321 const uint8_t buf_array[] = {
325 OptionBuffer buf_with_options(buf_array, buf_array +
sizeof(buf_array));
334 const uint8_t buf_array[] = {
344 OptionBuffer buf_with_options(buf_array, buf_array +
sizeof(buf_array));
346 opt->setData(buf_with_options.begin(), buf_with_options.end());
354 if (macs.size() > 0) {
356 if (r >= macs.size()) {
363 uint32_t clients_num =
options_.getClientsNum();
364 if (clients_num < 2) {
368 std::vector<uint8_t> mac_addr(
options_.getMacTemplate());
375 for (std::vector<uint8_t>::iterator it = mac_addr.end() - 1;
376 it >= mac_addr.begin();
398 vector<uint8_t> client_id;
399 client_id.push_back(
static_cast<uint8_t
>(hwaddr->htype_));
400 for (uint8_t
const&
byte : hwaddr->hwaddr_) {
401 client_id.push_back(
byte);
412 if (macs.size() > 0) {
414 if (r >= macs.size()) {
417 std::vector<uint8_t> mac = macs[r];
431 uint8_t duid_ll[] = {0, 3, 0, 1, 0, 0, 0, 0, 0, 0};
433 std::vector<uint8_t> duid(duid_ll,
434 duid_ll +
sizeof(duid_ll) /
sizeof(duid_ll[0]));
436 std::copy(mac.begin(), mac.end(), duid.begin() + 4);
439 uint32_t clients_num =
options_.getClientsNum();
440 if ((clients_num == 0) || (clients_num == 1)) {
441 return (
options_.getDuidTemplate());
444 std::vector<uint8_t> duid(
options_.getDuidTemplate());
446 duid.resize(duid.size());
447 std::copy(mac_addr.begin(), mac_addr.end(),
448 duid.begin() + duid.size() - mac_addr.size());
455 int elp_offset =
options_.getIpVersion() == 4 ?
456 DHCPV4_ELAPSED_TIME_OFFSET : DHCPV6_ELAPSED_TIME_OFFSET;
457 if (
options_.getElapsedTimeOffset() > 0) {
458 elp_offset =
options_.getElapsedTimeOffset();
466 using namespace boost::posix_time;
467 ptime pkt1_time = pkt1->getTimestamp();
468 ptime pkt2_time = pkt2->getTimestamp();
469 if (pkt1_time.is_not_a_date_time() ||
470 pkt2_time.is_not_a_date_time()) {
473 time_period elapsed_period(pkt1_time, pkt2_time);
474 return (elapsed_period.is_null() ? 0 :
475 elapsed_period.length().total_milliseconds());
480 int rand_offset =
options_.getIpVersion() == 4 ?
481 DHCPV4_RANDOMIZATION_OFFSET : DHCPV6_RANDOMIZATION_OFFSET;
482 if (
options_.getRandomOffset().size() >
size_t(arg_idx)) {
483 rand_offset =
options_.getRandomOffset()[arg_idx];
485 return (rand_offset);
490 int rip_offset =
options_.getIpVersion() == 4 ?
491 DHCPV4_REQUESTED_IP_OFFSET : DHCPV6_IA_NA_OFFSET;
492 if (
options_.getRequestedIpOffset() > 0) {
493 rip_offset =
options_.getRequestedIpOffset();
500 int srvid_offset =
options_.getIpVersion() == 4 ?
501 DHCPV4_SERVERID_OFFSET : DHCPV6_SERVERID_OFFSET;
502 if (
options_.getServerIdOffset() > 0) {
503 srvid_offset =
options_.getServerIdOffset();
505 return (srvid_offset);
518 int xid_offset =
options_.getIpVersion() == 4 ?
519 DHCPV4_TRANSID_OFFSET : DHCPV6_TRANSID_OFFSET;
520 if (
options_.getTransactionIdOffset().size() >
size_t(arg_idx)) {
521 xid_offset =
options_.getTransactionIdOffset()[arg_idx];
529 while (wait3(&status, WNOHANG, NULL) > 0) {
544 std::vector<std::string> template_files =
options_.getTemplateFiles();
545 for (
auto const& it : template_files) {
552 const bool preload ) {
553 for (uint64_t i = packets_num; i > 0; --i) {
580 const uint64_t msg_num) {
581 for (uint64_t i = 0; i < msg_num; ++i) {
591 const uint64_t msg_num) {
592 for (uint64_t i = 0; i < msg_num; ++i) {
608 if (
options_.getDuidTemplate().size() > 0) {
622 std::map<uint8_t, dhcp::Pkt4Ptr>::const_iterator pkt_it =
626 hex_buf =
vector2Hex(pkt_it->second->getBuffer().getVector());
628 }
else if (
options_.getIpVersion() == 6) {
632 std::map<uint8_t, dhcp::Pkt6Ptr>::const_iterator pkt_it =
636 hex_buf =
vector2Hex(pkt_it->second->getBuffer().getVector());
640 std::cout <<
"random-offset=" <<
getRandomOffset(arg_idx) << std::endl;
647 std::cout <<
"contents: " << std::endl;
651 auto flags(std::cout.flags());
652 while (line_len == 32) {
653 if (hex_buf.length() - i < 32) {
654 line_len = hex_buf.length() - i;
657 std::cout << setfill(
'0') << setw(4) << std::hex << i << std::dec
658 <<
" " << hex_buf.substr(i, line_len) << std::endl;
663 std::cout.flags(flags);
664 std::cout << std::endl;
672 }
else if (
options_.getIpVersion() == 6) {
681 std::string exchange_name =
"4-way exchanges";
688 exchange_name =
"DISCOVER-OFFER";
690 }
else if (
options_.getIpVersion() == 6) {
695 exchange_name =
options_.isRapidCommit() ?
"Solicit-Reply" :
700 stats_mgr_.getTestPeriod().length().total_nanoseconds() / 1e9;
701 rate =
stats_mgr_.getRcvdPacketsNum(xchg_type) / duration;
702 std::ostringstream s;
703 s <<
"***Rate statistics***" << std::endl;
704 s <<
"Rate: " << rate <<
" " << exchange_name <<
"/second";
706 s <<
", expected rate: " <<
options_.getRate() << std::endl;
709 std::cout << s.str() << std::endl;
711 std::cout <<
"***Malformed Packets***" << std::endl
718 int delay =
options_.getReportDelay();
719 ptime now = microsec_clock::universal_time();
721 if (time_since_report.length().total_seconds() >= delay) {
723 options_.getCleanReportSeparator());
739 const std::string& separator ) {
742 for (
auto const& it : vec) {
746 vhex.append(separator);
757 std::ifstream temp_file;
758 temp_file.open(file_name.c_str(), ios::in | ios::binary | ios::ate);
759 if (!temp_file.is_open()) {
763 std::streampos pos = temp_file.tellg();
764 if (pos == std::streampos(0)) {
768 temp_file.seekg(0, ios::beg);
769 size_t temp_size =
static_cast<size_t>(pos);
770 std::vector<char> file_contents(temp_size);
771 temp_file.read(&file_contents[0], temp_size);
777 std::vector<char> hex_digits;
778 for (
size_t i = 0; i < file_contents.size(); ++i) {
779 if (isxdigit(file_contents[i])) {
780 hex_digits.push_back(file_contents[i]);
781 }
else if (!isxdigit(file_contents[i]) &&
782 !isspace(file_contents[i])) {
784 " hexadecimal digit");
788 if (hex_digits.size() % 2 != 0) {
790 }
else if (hex_digits.empty()) {
793 std::vector<uint8_t> binary_stream;
794 for (
size_t i = 0; i < hex_digits.size(); i += 2) {
796 s <<
"0x" << hex_digits[i] << hex_digits[i+1];
799 binary_stream.push_back(
static_cast<uint8_t
>(b));
809 Pkt4Ptr discover_pkt4(boost::dynamic_pointer_cast<Pkt4>(pkt));
820 }
else if (pkt4->getType() ==
DHCPACK) {
852 std::set<std::string> current;
855 for (
auto const& opt : pkt6->options_) {
856 switch (opt.second->getType()) {
860 auto ret = current.emplace(boost::dynamic_pointer_cast<
870 auto ret = current.emplace(boost::dynamic_pointer_cast<
892 std::set<std::string> current;
893 current.insert(pkt4->getYiaddr().toText());
910 iapref = boost::dynamic_pointer_cast<
914 iaaddr = boost::dynamic_pointer_cast<
918 bool address_and_prefix =
options_.getLeaseType().includes(
920 bool prefix_only =
options_.getLeaseType().includes(
922 bool address_only =
options_.getLeaseType().includes(
924 if ((address_and_prefix && iapref && iaaddr) ||
925 (prefix_only && iapref && !address_and_prefix) ||
926 (address_only && iaaddr && !address_and_prefix)) {
935 uint8_t packet_type = pkt6->getType();
938 Pkt6Ptr solicit_pkt6(boost::dynamic_pointer_cast<Pkt6>(pkt));
999 unsigned int pkt_count = 0;
1003 if (
options_.getIpVersion() == 4) {
1004 Pkt4Ptr pkt4 = boost::dynamic_pointer_cast<Pkt4>(pkt);
1007 Pkt6Ptr pkt6 = boost::dynamic_pointer_cast<Pkt6>(pkt);
1015 static bool factories_registered =
false;
1016 if (!factories_registered) {
1030 factories_registered =
true;
1035 static bool factories_registered =
false;
1036 if (!factories_registered) {
1069 factories_registered =
true;
1083 "before DHCP option factories can be registered");
1102 receiver_(socket, options.isSingleThreaded(), options.getIpVersion()),
1113 if (
options_.getIpVersion() == 0) {
1115 "command options must be parsed before running a test");
1116 }
else if (
options_.getIpVersion() == 4) {
1126 uint32_t clients_num =
options_.getClientsNum() == 0 ?
1141 time_period duration(from_iso_string(
"20111231T235959"),
1142 microsec_clock::universal_time());
1143 srandom(duration.length().total_seconds()
1144 + duration.length().fractional_seconds());
1152 if (!
options_.getWrapped().empty()) {
1158 }
else if (pid == 0) {
1159 execlp(
options_.getWrapped().c_str(), do_stop ?
"stop" :
"start", (
void*)0);
1185 uint8_t randomized = 0;
1211 pkt4->setHWAddr(
HTYPE_ETHER, mac_address.size(), mac_address);
1218 if (
options_.getIncreaseElapsedTime() &&
1219 stats_mgr_.getTestPeriod().length().total_seconds() >=
options_.getWaitForElapsedTime() &&
1220 stats_mgr_.getTestPeriod().length().total_seconds() <
options_.getWaitForElapsedTime() +
1221 options_.getIncreaseElapsedTime()) {
1224 uint32_t val =
stats_mgr_.getTestPeriod().length().total_seconds() -
options_.getWaitForElapsedTime() + 1;
1228 pkt4->setSecs(
static_cast<uint16_t
>(val));
1245 const bool preload ) {
1248 const uint8_t arg_idx = 0;
1250 uint8_t randomized = 0;
1263 std::vector<uint8_t> in_buf(template_buf.begin(),
1264 template_buf.end());
1274 pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
1280 socket_.send(boost::static_pointer_cast<Pkt4>(pkt4));
1284 boost::static_pointer_cast<Pkt4>(pkt4));
1295 "invalid message type "
1297 <<
" to be sent, expected DHCPREQUEST or DHCPRELEASE");
1311 msg->setGiaddr(ack->getGiaddr());
1334 <<
" to be sent, expected DHCPV6_RENEW or DHCPV6_RELEASE");
1364 const uint32_t transid = discover_pkt4->getTransid();
1376 if (!opt_serverid) {
1378 <<
"in OFFER message");
1383 pkt4->addOption(opt_serverid);
1388 if (!yiaddr.
isV4()) {
1395 opt_requested_address->setUint32(yiaddr.
toUint32());
1396 pkt4->addOption(opt_requested_address);
1399 pkt4->addOption(opt_parameter_list);
1403 pkt4->setGiaddr(offer_pkt4->getGiaddr());
1408 pkt4->setHWAddr(offer_pkt4->getHWAddr());
1413 pkt4->setSecs(
static_cast<uint16_t
>(elapsed_time / 1000));
1427 const uint8_t arg_idx = 1;
1429 const uint32_t transid = discover_pkt4->getTransid();
1437 std::vector<uint8_t> in_buf(template_buf.begin(),
1438 template_buf.end());
1450 HWAddrPtr hwaddr = offer_pkt4->getHWAddr();
1452 uint8_t hw_len = hwaddr->hwaddr_.size();
1454 memcpy(&mac_address[0], &hwaddr->hwaddr_[0],
1457 pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
1462 pkt4->writeValueAt<uint16_t>(elp_offset,
1463 static_cast<uint16_t
>(elapsed_time / 1000));
1471 boost::shared_ptr<LocalizedOption>
1476 pkt4->addOption(opt_serverid);
1482 if (!opt_serverid_offer) {
1484 <<
"in OFFER message");
1486 boost::shared_ptr<LocalizedOption>
1489 opt_serverid_offer->getData(),
1491 pkt4->addOption(opt_serverid);
1499 if (!yiaddr.
isV4()) {
1507 boost::shared_ptr<LocalizedOption>
1513 opt_requested_ip->setUint32(yiaddr.
toUint32());
1514 pkt4->addOption(opt_requested_ip);
1523 socket_.send(boost::static_pointer_cast<Pkt4>(pkt4));
1526 boost::static_pointer_cast<Pkt4>(pkt4));
1537 pkt6->addOption(opt_elapsed_time);
1540 if (!opt_clientid) {
1543 pkt6->addOption(opt_clientid);
1553 if (!opt_serverid) {
1559 pkt6->addOption(opt_serverid);
1584 const Pkt6Ptr& advertise_pkt6) {
1587 const uint8_t arg_idx = 1;
1593 transid_offset, transid));
1596 boost::shared_ptr<LocalizedOption>
1599 pkt6->addOption(opt_elapsed_time);
1607 boost::shared_ptr<LocalizedOption>
1612 pkt6->addOption(opt_serverid);
1619 if (!opt_serverid_advertise) {
1621 <<
"in ADVERTISE message");
1623 boost::shared_ptr<LocalizedOption>
1626 opt_serverid_advertise->getData(),
1628 pkt6->addOption(opt_serverid);
1635 if (!opt_ia_na_advertise) {
1640 boost::shared_ptr<LocalizedOption>
1642 if (!opt_ia_na->valid()) {
1645 pkt6->addOption(opt_ia_na);
1648 if (!opt_serverid_advertise) {
1653 boost::shared_ptr<LocalizedOption>
1655 opt_serverid_advertise->getData(),
1657 pkt6->addOption(opt_serverid);
1661 if (!opt_clientid_advertise) {
1664 rand_offset -= (opt_clientid_advertise->len() - 1);
1666 boost::shared_ptr<LocalizedOption>
1668 opt_clientid_advertise->getData(),
1670 pkt6->addOption(opt_clientid);
1698 uint8_t randomized = 0;
1709 if (
options_.getIncreaseElapsedTime() &&
1710 stats_mgr_.getTestPeriod().length().total_seconds() >=
options_.getWaitForElapsedTime() &&
1711 stats_mgr_.getTestPeriod().length().total_seconds() <
options_.getWaitForElapsedTime() +
1712 options_.getIncreaseElapsedTime()) {
1716 uint32_t val = (
stats_mgr_.getTestPeriod().length().total_seconds() -
options_.getWaitForElapsedTime() + 1)*100;
1721 pkt6->addOption(elapsed);
1761 const bool preload ) {
1762 const int arg_idx = 0;
1769 transid_offset, transid));
1777 uint8_t randomized = 0;
1779 if (rand_offset > template_buf.size()) {
1783 pkt6->writeAt(rand_offset - randomized + 1,
1784 duid.end() - randomized, duid.end());
1807 if (iface == NULL) {
1810 pkt->setIface(iface->getName());
1812 pkt->setIndex(
socket_.ifindex_);
1814 pkt->setLocalPort(DHCP4_CLIENT_PORT);
1817 pkt->setRemotePort(
options_.getRemotePort());
1819 pkt->setRemotePort(DHCP4_SERVER_PORT);
1824 pkt->setLocalAddr(
socket_.addr_);
1827 if (!
options_.checkMultiSubnet()) {
1828 pkt->setGiaddr(
socket_.addr_);
1840 if (iface == NULL) {
1843 pkt->setIface(iface->getName());
1845 pkt->setIndex(
socket_.ifindex_);
1847 pkt->setLocalPort(DHCP6_CLIENT_PORT);
1850 pkt->setRemotePort(
options_.getRemotePort());
1852 pkt->setRemotePort(DHCP6_SERVER_PORT);
1855 pkt->setLocalAddr(
socket_.addr_);
1873 pkt->addRelayInfo(relay_info);
1882 result.insert(result.end(), a.begin(), a.end());
1883 result.insert(result.end(), b.begin(), b.end());
1887static void mergeOptionIntoPacket(
Pkt4Ptr const& packet,
1889 uint16_t
const code(extra_option->getType());
1891 OptionPtr const& option(packet->getOption(code));
1896 packet->delOption(code);
1897 packet->addOption(boost::make_shared<Option>(
1899 concatenateBuffers(option->getData(),
1900 extra_option->getData())));
1908 packet->addOption(extra_option);
1917 for (
auto const& entry : extra_opts) {
1918 mergeOptionIntoPacket(pkt, entry.second);
1926 for (
auto const& entry : extra_opts) {
1927 pkt->addOption(entry.second);
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an object can not be found.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic).
std::string toText() const
Convert the address to a string.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV4() const
Convenience function to check for an IPv4 address.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
bool configureDHCPPacketQueue(const uint16_t family, data::ConstElementPtr queue_control)
Configures DHCP packet queue.
static void OptionFactoryRegister(Option::Universe u, uint16_t type, Option::Factory *factory)
Registers factory method that produces options of specific option types.
isc::asiolink::IOAddress getAddress() const
Returns address contained within this option.
Class that represents IAPREFIX option in DHCPv6.
Forward declaration to OptionInt.
static OptionPtr factory(Option::Universe u, uint16_t type, const OptionBuffer &buf)
Factory function to create instance of option.
Universe
defines option universe DHCPv4 or DHCPv6
Represents DHCPv4 packet.
Represents a DHCPv6 packet.
Socket wrapper structure.
ExchangeMode
2-way (cmd line param -i) or 4-way exchanges
std::vector< std::vector< uint8_t > > MacAddrsVector
A vector holding MAC addresses.
static int malformed_pkts_
DHCP option at specific offset.
PerfPkt4 (DHCPv4 packet).
PerfPkt6 (DHCPv6 packet).
Random numbers generator class.
Sequential numbers generator class.
void saveFirstPacket(const dhcp::Pkt4Ptr &pkt)
Save the first DHCPv4 sent packet of the specified type.
void address6Uniqueness(const dhcp::Pkt6Ptr &pkt6, ExchangeType xchg_type)
Process received v6 addresses uniqueness.
static const uint8_t HW_ETHER_LEN
Length of the Ethernet HW address (MAC) in bytes.
bool waitToExit()
Delay the exit by a fixed given time to catch up to all exchanges that were already started.
std::map< uint8_t, dhcp::Pkt4Ptr > template_packets_v4_
First packets send.
bool sendMessageFromReply(const uint16_t msg_type)
Send DHCPv6 Renew or Release message.
void addExtraOpts(const dhcp::Pkt4Ptr &pkt4)
Inserts extra options specified by user.
void printDiagnostics() const
Print main diagnostics data.
static void handleChild(int sig)
Handle child signal.
void registerOptionFactories4() const
Register option factory functions for DHCPv4.
NumberGeneratorPtr transid_gen_
Transaction id generator.
NumberGeneratorPtr macaddr_gen_
Numbers generator for MAC address.
int getRequestedIpOffset() const
Return requested ip offset in a packet.
NumberGeneratorPtr random_generator_
Generate uniformly distributed integers in range of [min, max].
boost::shared_ptr< NumberGenerator > NumberGeneratorPtr
The default generator pointer.
uint64_t sendMultipleMessages4(const uint32_t msg_type, const uint64_t msg_num)
Send number of DHCPREQUEST (renew) messages to a server.
bool validateIA(const dhcp::Pkt6Ptr &pkt6)
Process IA in received DHCPv6 packet.
dhcp::Pkt4Ptr createMessageFromAck(const uint16_t msg_type, const dhcp::Pkt4Ptr &ack)
Creates DHCPREQUEST from a DHCPACK message.
static bool interrupted_
Program interrupted flag.
void readPacketTemplate(const std::string &file_name)
Read DHCP message template from file.
TemplateBuffer getTemplateBuffer(const size_t idx) const
Return template buffer.
std::vector< uint8_t > generateMacAddress(uint8_t &randomized)
Generate MAC address.
void setDefaults4(const dhcp::Pkt4Ptr &pkt)
Set default DHCPv4 packet parameters.
boost::posix_time::ptime exit_time_
Initialized at first exit condition with the time perfdhcp should exit.
CommandOptions & options_
Command options.
Receiver receiver_
Receiver used to receive DHCP traffic.
static std::string vector2Hex(const std::vector< uint8_t > &vec, const std::string &separator="")
Convert vector in hexadecimal string.
uint64_t sendMultipleMessages6(const uint32_t msg_type, const uint64_t msg_num)
Send number of DHCPv6 Renew or Release messages to the server.
void setMacAddrGenerator(const NumberGeneratorPtr &generator)
Set new MAC address generator.
void setDefaults6(const dhcp::Pkt6Ptr &pkt)
Set default DHCPv6 packet parameters.
boost::posix_time::ptime last_report_
Last intermediate report time.
bool haveAllPacketsBeenReceived() const
Checks if all expected packets were already received.
void cleanCachedPackets()
Removes cached DHCPv6 Reply packets every second.
void processReceivedPacket4(const dhcp::Pkt4Ptr &pkt4)
Process received DHCPv4 packet.
void sendRequest6(const dhcp::Pkt6Ptr &advertise_pkt6)
Send DHCPv6 REQUEST message.
TestControl(CommandOptions &options, BasePerfSocket &socket)
Default constructor.
static dhcp::OptionPtr factoryOptionRequestOption6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ORO option.
void sendSolicit6(const bool preload=false)
Send DHCPv6 SOLICIT message.
static dhcp::OptionPtr factoryIapd6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create IA_PD option.
std::map< uint8_t, dhcp::Pkt6Ptr > template_packets_v6_
Template for v6.
static dhcp::OptionPtr factoryRapidCommit6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 RAPID_COMMIT option instance.
PacketStorage< dhcp::Pkt6 > reply_storage_
Storage for reply messages.
void registerOptionFactories6() const
Register option factory functions for DHCPv6.
void sendPackets(const uint64_t packets_num, const bool preload=false)
Send number of packets to initiate new exchanges.
void registerOptionFactories() const
Register option factory functions for DHCPv4 or DHCPv6.
std::vector< uint8_t > TemplateBuffer
Packet template buffer.
bool sendMessageFromAck(const uint16_t msg_type)
Send DHCPv4 renew (DHCPREQUEST).
void runWrapped(bool do_stop=false) const
Run wrapped command.
void processReceivedPacket6(const dhcp::Pkt6Ptr &pkt6)
Process received DHCPv6 packet.
uint32_t getElapsedTime(const T &pkt1, const T &pkt2)
Calculate elapsed time between two packets.
BasePerfSocket & socket_
Socket used for DHCP traffic.
void reset()
Resets internal state of the object.
void addUniqeAddr(const std::set< std::string > ¤t, ExchangeType xchg_type)
add unique address to already assigned list.
void address4Uniqueness(const dhcp::Pkt4Ptr &pkt4, ExchangeType xchg_type)
Process received v4 addresses uniqueness.
int getRandomOffset(const int arg_idx) const
Return randomization offset in a packet.
dhcp::Pkt6Ptr createMessageFromReply(const uint16_t msg_type, const dhcp::Pkt6Ptr &reply)
Creates DHCPv6 message from the Reply packet.
int getElapsedTimeOffset() const
Return elapsed time offset in a packet.
void printTemplates() const
Print templates information.
void sendRequest4(const dhcp::Pkt4Ptr &discover_pkt4, const dhcp::Pkt4Ptr &offer_pkt4)
Send DHCPv4 REQUEST message.
unsigned int consumeReceivedPackets()
Pull packets from receiver and process them.
TemplateBufferCollection template_buffers_
Packet template buffers.
StatsMgr stats_mgr_
Statistics Manager.
void printStats() const
Print performance statistics.
PacketStorage< dhcp::Pkt4 > ack_storage_
Storage for DHCPACK messages.
void copyIaOptions(const dhcp::Pkt6Ptr &pkt_from, dhcp::Pkt6Ptr &pkt_to)
Copies IA_NA or IA_PD option from one packet to another.
void setTransidGenerator(const NumberGeneratorPtr &generator)
Set new transaction id generator.
static dhcp::OptionPtr factoryGeneric(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create generic option.
static dhcp::OptionPtr factoryRequestList4(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv4 Request List option.
static dhcp::OptionPtr factoryElapsedTime6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ELAPSED_TIME option.
static void handleInterrupt(int sig)
Handle interrupt signal.
int getTransactionIdOffset(const int arg_idx) const
Return transaction id offset in a packet.
void initPacketTemplates()
Reads packet templates from files.
void printRate() const
Print rate statistics.
void printIntermediateStats()
Print intermediate statistics.
void printTemplate(const uint8_t packet_type) const
Print template information.
int getServerIdOffset() const
Return server id offset in a packet.
std::vector< uint8_t > generateDuid(uint8_t &randomized)
Generate DUID.
void sendDiscover4(const bool preload=false)
Send DHCPv4 DISCOVER message.
dhcp::OptionPtr generateClientId(const dhcp::HWAddrPtr &hwaddr) const
Generate DHCPv4 client identifier from HW address.
dhcp::OptionBuffer first_packet_serverid_
Buffer holding server id received in first packet.
uint32_t generateTransid()
generate transaction id.
static dhcp::OptionPtr factoryIana6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create IA_NA option.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
@ DHO_DOMAIN_NAME_SERVERS
@ DHO_DHCP_SERVER_IDENTIFIER
@ DHO_DHCP_CLIENT_IDENTIFIER
@ DHO_DHCP_REQUESTED_ADDRESS
@ DHO_DHCP_PARAMETER_REQUEST_LIST
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
@ HTYPE_ETHER
Ethernet 10Mbps.
boost::shared_ptr< Option > OptionPtr
boost::shared_ptr< PerfPkt4 > PerfPkt4Ptr
ExchangeType
DHCP packet exchange types.
@ SA
DHCPv6 SOLICIT-ADVERTISE.
@ RNA
DHCPv4 REQUEST-ACK (renewal).
@ RL
DHCPv6 RELEASE-REPLY.
@ DO
DHCPv4 DISCOVER-OFFER.
@ RR
DHCPv6 REQUEST-REPLY.
boost::shared_ptr< PerfPkt6 > PerfPkt6Ptr
const std::string & byteToHex(uint8_t byte)
Converts a byte to a two hex digit string.
Defines the logger used by the top-level component of kea-lfc.
structure that describes a single relay information
isc::dhcp::OptionCollection options_
options received from a specified relay, except relay-msg option
uint8_t msg_type_
message type (RELAY-FORW oro RELAY-REPL)
isc::asiolink::IOAddress linkaddr_
fixed field in relay-forw/relay-reply
uint8_t hop_count_
number of traversed relays (up to 32)
isc::asiolink::IOAddress peeraddr_
fixed field in relay-forw/relay-reply