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);
156 const int b1 = b / 16;
157 const int b0 = b % 16;
158 ostringstream stream;
159 stream << std::hex << b1 << b0 << std::dec;
160 return (stream.str());
169 <<
" to be created from Reply, expected DHCPREQUEST or"
175 auto msg_type_str = [=]() ->
const char* {
176 return (msg_type ==
DHCPREQUEST ?
"Request" :
"Release");
182 <<
" from a null DHCPACK message");
183 }
else if (ack->getYiaddr().isV4Zero()) {
187 <<
" from a DHCPACK message containing yiaddr of 0");
190 msg->setCiaddr(ack->getYiaddr());
191 msg->setHWAddr(ack->getHWAddr());
201 <<
"from the first packet which lacks the server "
202 "identifier option");
211 if (!server_identifier) {
215 <<
"from a DHCPACK message without the server "
216 "identifier option");
218 msg->addOption(server_identifier);
230 <<
" to be created from Reply, expected DHCPV6_RENEW or"
236 auto msg_type_str = [=]() ->
const char* {
237 return (msg_type ==
DHCPV6_RENEW ?
"Renew" :
"Release");
243 <<
" message from the Reply message because the instance of"
244 " the Reply message is NULL");
252 <<
" message because client id option has not been found"
253 " in the Reply message");
255 msg->addOption(opt_clientid);
260 <<
" because server id option has not been found in the"
263 msg->addOption(opt_serverid);
271 if (buf.size() == 2) {
273 }
else if (buf.size() == 0) {
278 "elapsed time option buffer size has to be 0 or 2");
292 const uint8_t buf_array[] = {
294 0, 0, 3600 >> 8, 3600 & 0xff,
295 0, 0, 5400 >> 8, 5400 & 0xff,
297 OptionBuffer buf_ia_na(buf_array, buf_array +
sizeof(buf_array));
298 for (
size_t i = 0; i < buf.size(); ++i) {
299 buf_ia_na.push_back(buf[i]);
308 static const uint8_t buf_array[] = {
310 0, 0, 3600 >> 8, 3600 & 0xff,
311 0, 0, 5400 >> 8, 5400 & 0xff,
313 OptionBuffer buf_ia_pd(buf_array, buf_array +
sizeof(buf_array));
315 buf_ia_pd.insert(buf_ia_pd.end(), buf.begin(), buf.end());
330 const uint8_t buf_array[] = {
334 OptionBuffer buf_with_options(buf_array, buf_array +
sizeof(buf_array));
343 const uint8_t buf_array[] = {
353 OptionBuffer buf_with_options(buf_array, buf_array +
sizeof(buf_array));
355 opt->setData(buf_with_options.begin(), buf_with_options.end());
363 if (macs.size() > 0) {
365 if (r >= macs.size()) {
372 uint32_t clients_num =
options_.getClientsNum();
373 if (clients_num < 2) {
377 std::vector<uint8_t> mac_addr(
options_.getMacTemplate());
384 for (std::vector<uint8_t>::iterator it = mac_addr.end() - 1;
385 it >= mac_addr.begin();
407 vector<uint8_t> client_id;
408 client_id.push_back(
static_cast<uint8_t
>(hwaddr->htype_));
409 for (uint8_t
const&
byte : hwaddr->hwaddr_) {
410 client_id.push_back(
byte);
421 if (macs.size() > 0) {
423 if (r >= macs.size()) {
426 std::vector<uint8_t> mac = macs[r];
440 uint8_t duid_ll[] = {0, 3, 0, 1, 0, 0, 0, 0, 0, 0};
442 std::vector<uint8_t> duid(duid_ll,
443 duid_ll +
sizeof(duid_ll) /
sizeof(duid_ll[0]));
445 std::copy(mac.begin(), mac.end(), duid.begin() + 4);
448 uint32_t clients_num =
options_.getClientsNum();
449 if ((clients_num == 0) || (clients_num == 1)) {
450 return (
options_.getDuidTemplate());
453 std::vector<uint8_t> duid(
options_.getDuidTemplate());
455 duid.resize(duid.size());
456 std::copy(mac_addr.begin(), mac_addr.end(),
457 duid.begin() + duid.size() - mac_addr.size());
464 int elp_offset =
options_.getIpVersion() == 4 ?
465 DHCPV4_ELAPSED_TIME_OFFSET : DHCPV6_ELAPSED_TIME_OFFSET;
466 if (
options_.getElapsedTimeOffset() > 0) {
467 elp_offset =
options_.getElapsedTimeOffset();
475 using namespace boost::posix_time;
476 ptime pkt1_time = pkt1->getTimestamp();
477 ptime pkt2_time = pkt2->getTimestamp();
478 if (pkt1_time.is_not_a_date_time() ||
479 pkt2_time.is_not_a_date_time()) {
482 time_period elapsed_period(pkt1_time, pkt2_time);
483 return (elapsed_period.is_null() ? 0 :
484 elapsed_period.length().total_milliseconds());
489 int rand_offset =
options_.getIpVersion() == 4 ?
490 DHCPV4_RANDOMIZATION_OFFSET : DHCPV6_RANDOMIZATION_OFFSET;
491 if (
options_.getRandomOffset().size() >
size_t(arg_idx)) {
492 rand_offset =
options_.getRandomOffset()[arg_idx];
494 return (rand_offset);
499 int rip_offset =
options_.getIpVersion() == 4 ?
500 DHCPV4_REQUESTED_IP_OFFSET : DHCPV6_IA_NA_OFFSET;
501 if (
options_.getRequestedIpOffset() > 0) {
502 rip_offset =
options_.getRequestedIpOffset();
509 int srvid_offset =
options_.getIpVersion() == 4 ?
510 DHCPV4_SERVERID_OFFSET : DHCPV6_SERVERID_OFFSET;
511 if (
options_.getServerIdOffset() > 0) {
512 srvid_offset =
options_.getServerIdOffset();
514 return (srvid_offset);
527 int xid_offset =
options_.getIpVersion() == 4 ?
528 DHCPV4_TRANSID_OFFSET : DHCPV6_TRANSID_OFFSET;
529 if (
options_.getTransactionIdOffset().size() >
size_t(arg_idx)) {
530 xid_offset =
options_.getTransactionIdOffset()[arg_idx];
538 while (wait3(&status, WNOHANG, NULL) > 0) {
553 std::vector<std::string> template_files =
options_.getTemplateFiles();
554 for (
auto const& it : template_files) {
561 const bool preload ) {
562 for (uint64_t i = packets_num; i > 0; --i) {
589 const uint64_t msg_num) {
590 for (uint64_t i = 0; i < msg_num; ++i) {
600 const uint64_t msg_num) {
601 for (uint64_t i = 0; i < msg_num; ++i) {
617 if (
options_.getDuidTemplate().size() > 0) {
631 std::map<uint8_t, dhcp::Pkt4Ptr>::const_iterator pkt_it =
635 hex_buf =
vector2Hex(pkt_it->second->getBuffer().getVector());
637 }
else if (
options_.getIpVersion() == 6) {
641 std::map<uint8_t, dhcp::Pkt6Ptr>::const_iterator pkt_it =
645 hex_buf =
vector2Hex(pkt_it->second->getBuffer().getVector());
649 std::cout <<
"random-offset=" <<
getRandomOffset(arg_idx) << std::endl;
656 std::cout <<
"contents: " << std::endl;
659 while (line_len == 32) {
660 if (hex_buf.length() - i < 32) {
661 line_len = hex_buf.length() - i;
664 std::cout << setfill(
'0') << setw(4) << std::hex << i << std::dec
665 <<
" " << hex_buf.substr(i, line_len) << std::endl;
669 std::cout << std::endl;
677 }
else if (
options_.getIpVersion() == 6) {
686 std::string exchange_name =
"4-way exchanges";
693 exchange_name =
"DISCOVER-OFFER";
695 }
else if (
options_.getIpVersion() == 6) {
700 exchange_name =
options_.isRapidCommit() ?
"Solicit-Reply" :
705 stats_mgr_.getTestPeriod().length().total_nanoseconds() / 1e9;
706 rate =
stats_mgr_.getRcvdPacketsNum(xchg_type) / duration;
707 std::ostringstream s;
708 s <<
"***Rate statistics***" << std::endl;
709 s <<
"Rate: " << rate <<
" " << exchange_name <<
"/second";
711 s <<
", expected rate: " <<
options_.getRate() << std::endl;
714 std::cout << s.str() << std::endl;
716 std::cout <<
"***Malformed Packets***" << std::endl
723 int delay =
options_.getReportDelay();
724 ptime now = microsec_clock::universal_time();
726 if (time_since_report.length().total_seconds() >= delay) {
728 options_.getCleanReportSeparator());
744 const std::string& separator ) {
745 std::ostringstream stream;
747 for (
auto const& it : vec) {
752 stream << separator <<
byte2Hex(it);
755 return (stream.str());
760 std::ifstream temp_file;
761 temp_file.open(file_name.c_str(), ios::in | ios::binary | ios::ate);
762 if (!temp_file.is_open()) {
766 std::streampos temp_size = temp_file.tellg();
767 if (temp_size == std::streampos(0)) {
771 temp_file.seekg(0, ios::beg);
772 std::vector<char> file_contents(temp_size);
773 temp_file.read(&file_contents[0], temp_size);
779 std::vector<char> hex_digits;
780 for (
size_t i = 0; i < file_contents.size(); ++i) {
781 if (isxdigit(file_contents[i])) {
782 hex_digits.push_back(file_contents[i]);
783 }
else if (!isxdigit(file_contents[i]) &&
784 !isspace(file_contents[i])) {
786 " hexadecimal digit");
790 if (hex_digits.size() % 2 != 0) {
792 }
else if (hex_digits.empty()) {
795 std::vector<uint8_t> binary_stream;
796 for (
size_t i = 0; i < hex_digits.size(); i += 2) {
798 s <<
"0x" << hex_digits[i] << hex_digits[i+1];
801 binary_stream.push_back(
static_cast<uint8_t
>(b));
811 Pkt4Ptr discover_pkt4(boost::dynamic_pointer_cast<Pkt4>(pkt));
822 }
else if (pkt4->getType() ==
DHCPACK) {
854 std::set<std::string> current;
857 for (
auto const& opt : pkt6->options_) {
858 switch (opt.second->getType()) {
862 auto ret = current.emplace(boost::dynamic_pointer_cast<
872 auto ret = current.emplace(boost::dynamic_pointer_cast<
894 std::set<std::string> current;
895 current.insert(pkt4->getYiaddr().toText());
912 iapref = boost::dynamic_pointer_cast<
916 iaaddr = boost::dynamic_pointer_cast<
920 bool address_and_prefix =
options_.getLeaseType().includes(
922 bool prefix_only =
options_.getLeaseType().includes(
924 bool address_only =
options_.getLeaseType().includes(
926 if ((address_and_prefix && iapref && iaaddr) ||
927 (prefix_only && iapref && !address_and_prefix) ||
928 (address_only && iaaddr && !address_and_prefix)) {
937 uint8_t packet_type = pkt6->getType();
940 Pkt6Ptr solicit_pkt6(boost::dynamic_pointer_cast<Pkt6>(pkt));
1001 unsigned int pkt_count = 0;
1005 if (
options_.getIpVersion() == 4) {
1006 Pkt4Ptr pkt4 = boost::dynamic_pointer_cast<Pkt4>(pkt);
1009 Pkt6Ptr pkt6 = boost::dynamic_pointer_cast<Pkt6>(pkt);
1017 static bool factories_registered =
false;
1018 if (!factories_registered) {
1032 factories_registered =
true;
1037 static bool factories_registered =
false;
1038 if (!factories_registered) {
1071 factories_registered =
true;
1085 "before DHCP option factories can be registered");
1104 receiver_(socket, options.isSingleThreaded(), options.getIpVersion()),
1115 if (
options_.getIpVersion() == 0) {
1117 "command options must be parsed before running a test");
1118 }
else if (
options_.getIpVersion() == 4) {
1128 uint32_t clients_num =
options_.getClientsNum() == 0 ?
1143 time_period duration(from_iso_string(
"20111231T235959"),
1144 microsec_clock::universal_time());
1145 srandom(duration.length().total_seconds()
1146 + duration.length().fractional_seconds());
1154 if (!
options_.getWrapped().empty()) {
1160 }
else if (pid == 0) {
1161 execlp(
options_.getWrapped().c_str(), do_stop ?
"stop" :
"start", (
void*)0);
1187 uint8_t randomized = 0;
1213 pkt4->setHWAddr(
HTYPE_ETHER, mac_address.size(), mac_address);
1220 if (
options_.getIncreaseElapsedTime() &&
1221 stats_mgr_.getTestPeriod().length().total_seconds() >=
options_.getWaitForElapsedTime() &&
1222 stats_mgr_.getTestPeriod().length().total_seconds() <
options_.getWaitForElapsedTime() +
1223 options_.getIncreaseElapsedTime()) {
1226 uint32_t val =
stats_mgr_.getTestPeriod().length().total_seconds() -
options_.getWaitForElapsedTime() + 1;
1230 pkt4->setSecs(
static_cast<uint16_t
>(val));
1247 const bool preload ) {
1250 const uint8_t arg_idx = 0;
1252 uint8_t randomized = 0;
1265 std::vector<uint8_t> in_buf(template_buf.begin(),
1266 template_buf.end());
1276 pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
1282 socket_.send(boost::static_pointer_cast<Pkt4>(pkt4));
1286 boost::static_pointer_cast<Pkt4>(pkt4));
1297 "invalid message type "
1299 <<
" to be sent, expected DHCPREQUEST or DHCPRELEASE");
1313 msg->setGiaddr(ack->getGiaddr());
1336 <<
" to be sent, expected DHCPV6_RENEW or DHCPV6_RELEASE");
1366 const uint32_t transid = discover_pkt4->getTransid();
1378 if (!opt_serverid) {
1380 <<
"in OFFER message");
1385 pkt4->addOption(opt_serverid);
1390 if (!yiaddr.
isV4()) {
1397 opt_requested_address->setUint32(yiaddr.
toUint32());
1398 pkt4->addOption(opt_requested_address);
1401 pkt4->addOption(opt_parameter_list);
1405 pkt4->setGiaddr(offer_pkt4->getGiaddr());
1410 pkt4->setHWAddr(offer_pkt4->getHWAddr());
1415 pkt4->setSecs(
static_cast<uint16_t
>(elapsed_time / 1000));
1429 const uint8_t arg_idx = 1;
1431 const uint32_t transid = discover_pkt4->getTransid();
1439 std::vector<uint8_t> in_buf(template_buf.begin(),
1440 template_buf.end());
1452 HWAddrPtr hwaddr = offer_pkt4->getHWAddr();
1454 uint8_t hw_len = hwaddr->hwaddr_.size();
1456 memcpy(&mac_address[0], &hwaddr->hwaddr_[0],
1459 pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
1464 pkt4->writeValueAt<uint16_t>(elp_offset,
1465 static_cast<uint16_t
>(elapsed_time / 1000));
1473 boost::shared_ptr<LocalizedOption>
1478 pkt4->addOption(opt_serverid);
1484 if (!opt_serverid_offer) {
1486 <<
"in OFFER message");
1488 boost::shared_ptr<LocalizedOption>
1491 opt_serverid_offer->getData(),
1493 pkt4->addOption(opt_serverid);
1501 if (!yiaddr.
isV4()) {
1509 boost::shared_ptr<LocalizedOption>
1515 opt_requested_ip->setUint32(yiaddr.
toUint32());
1516 pkt4->addOption(opt_requested_ip);
1525 socket_.send(boost::static_pointer_cast<Pkt4>(pkt4));
1528 boost::static_pointer_cast<Pkt4>(pkt4));
1539 pkt6->addOption(opt_elapsed_time);
1542 if (!opt_clientid) {
1545 pkt6->addOption(opt_clientid);
1555 if (!opt_serverid) {
1561 pkt6->addOption(opt_serverid);
1586 const Pkt6Ptr& advertise_pkt6) {
1589 const uint8_t arg_idx = 1;
1595 transid_offset, transid));
1598 boost::shared_ptr<LocalizedOption>
1601 pkt6->addOption(opt_elapsed_time);
1609 boost::shared_ptr<LocalizedOption>
1614 pkt6->addOption(opt_serverid);
1621 if (!opt_serverid_advertise) {
1623 <<
"in ADVERTISE message");
1625 boost::shared_ptr<LocalizedOption>
1628 opt_serverid_advertise->getData(),
1630 pkt6->addOption(opt_serverid);
1637 if (!opt_ia_na_advertise) {
1642 boost::shared_ptr<LocalizedOption>
1644 if (!opt_ia_na->valid()) {
1647 pkt6->addOption(opt_ia_na);
1650 if (!opt_serverid_advertise) {
1655 boost::shared_ptr<LocalizedOption>
1657 opt_serverid_advertise->getData(),
1659 pkt6->addOption(opt_serverid);
1663 if (!opt_clientid_advertise) {
1666 rand_offset -= (opt_clientid_advertise->len() - 1);
1668 boost::shared_ptr<LocalizedOption>
1670 opt_clientid_advertise->getData(),
1672 pkt6->addOption(opt_clientid);
1700 uint8_t randomized = 0;
1711 if (
options_.getIncreaseElapsedTime() &&
1712 stats_mgr_.getTestPeriod().length().total_seconds() >=
options_.getWaitForElapsedTime() &&
1713 stats_mgr_.getTestPeriod().length().total_seconds() <
options_.getWaitForElapsedTime() +
1714 options_.getIncreaseElapsedTime()) {
1718 uint32_t val = (
stats_mgr_.getTestPeriod().length().total_seconds() -
options_.getWaitForElapsedTime() + 1)*100;
1723 pkt6->addOption(elapsed);
1763 const bool preload ) {
1764 const int arg_idx = 0;
1771 transid_offset, transid));
1779 uint8_t randomized = 0;
1781 if (rand_offset > template_buf.size()) {
1785 pkt6->writeAt(rand_offset - randomized + 1,
1786 duid.end() - randomized, duid.end());
1809 if (iface == NULL) {
1812 pkt->setIface(iface->getName());
1814 pkt->setIndex(
socket_.ifindex_);
1816 pkt->setLocalPort(DHCP4_CLIENT_PORT);
1819 pkt->setRemotePort(
options_.getRemotePort());
1821 pkt->setRemotePort(DHCP4_SERVER_PORT);
1826 pkt->setLocalAddr(
socket_.addr_);
1829 if (!
options_.checkMultiSubnet()) {
1830 pkt->setGiaddr(
socket_.addr_);
1842 if (iface == NULL) {
1845 pkt->setIface(iface->getName());
1847 pkt->setIndex(
socket_.ifindex_);
1849 pkt->setLocalPort(DHCP6_CLIENT_PORT);
1852 pkt->setRemotePort(
options_.getRemotePort());
1854 pkt->setRemotePort(DHCP6_SERVER_PORT);
1857 pkt->setLocalAddr(
socket_.addr_);
1875 pkt->addRelayInfo(relay_info);
1891 uint16_t
const code(extra_option->getType());
1899 packet->addOption(boost::make_shared<Option>(
1901 concatenateBuffers(option->getData(),
1902 extra_option->getData())));
1910 packet->addOption(extra_option);
1919 for (
auto const& entry : extra_opts) {
1920 mergeOptionIntoPacket(pkt, entry.second);
1928 for (
auto const& entry : extra_opts) {
1929 pkt->addOption(entry.second);
when the call the UDPServer carries on at the same position As a result
read_packet FORK if not parent: break YIELD answer=DNSLookup(packet, this) response=DNSAnswer(answer) YIELD send(response) At each "YIELD" point, the coroutine initiates an asynchronous operation, then pauses and turns over control to some other task on the ASIO service queue. When the operation completes, the coroutine resumes. The DNSLookup and DNSAnswer define callback methods used by a DNS Server to communicate with the module that called it. They are abstract-only classes whose concrete implementations are supplied by the calling module. The DNSLookup callback always runs asynchronously. Concrete implementations must be sure to call the server 's "resume" method when it is finished. In an authoritative server, the DNSLookup implementation would examine the query, look up the answer, then call "resume"(See the diagram in doc/auth_process.jpg). In a recursive server, the DNSLookup implementation would initiate a DNSQuery, which in turn would be responsible for calling the server 's "resume" method(See the diagram in doc/recursive_process.jpg). A DNSQuery object is intended to handle resolution of a query over the network when the local authoritative data sources or cache are not sufficient. The plan is that it will make use of subsidiary DNSFetch calls to get data from particular authoritative servers, and when it has gotten a complete answer, it calls "resume". In current form, however, DNSQuery is much simpler packet
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.
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.
static std::string byte2Hex(const uint8_t b)
Convert binary value to hex string.
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
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