21#include <boost/date_time/posix_time/posix_time.hpp>
22#include <boost/foreach.hpp>
35using namespace boost::posix_time;
54 static ptime exit_time = ptime(not_a_date_time);
60 const ptime now = microsec_clock::universal_time();
63 if (exit_time.is_not_a_date_time()) {
64 exit_time = now + time_duration(microseconds(wait_time));
68 return (now < exit_time);
80 const size_t& num_request_size = num_request.size();
82 if (num_request_size == 0) {
86 uint32_t responses = 0;
87 uint32_t requests = num_request[0];
88 if (num_request_size >= 2) {
89 requests += num_request[1];
100 return (responses == requests);
105 ifindex_(0), valid_(true) {
116 iface->delSocket(sockfd_);
121TestControl::TestControlSocket::initSocketData() {
123 BOOST_FOREACH(
SocketInfo s, iface->getSockets()) {
125 ifindex_ = iface->getIndex();
132 "descriptor not found");
138 return (test_control);
170 static boost::posix_time::ptime last_clean =
171 microsec_clock::universal_time();
174 time_period time_since_clean(last_clean,
175 microsec_clock::universal_time());
177 if (time_since_clean.length().total_seconds() >= 1) {
189 last_clean = microsec_clock::universal_time();
195 if (!pkt_from || !pkt_to) {
197 " for the copyIaOptions function");
205 " server's response");
207 pkt_to->addOption(option);
215 " server's response");
217 pkt_to->addOption(option);
225 const int b1 = b / 16;
226 const int b0 = b % 16;
227 ostringstream stream;
228 stream << std::hex << b1 << b0 << std::dec;
229 return (stream.str());
238 bool test_period_reached =
false;
243 if (period.length().total_seconds() >= options.
getPeriod()) {
244 test_period_reached =
true;
248 if (period.length().total_seconds() >= options.
getPeriod()) {
249 test_period_reached =
true;
253 if (test_period_reached) {
255 std::cout <<
"reached test-period." << std::endl;
262 bool max_requests =
false;
293 std::cout <<
"Reached max requests limit." << std::endl;
301 bool max_drops =
false;
331 std::cout <<
"Reached maximum drops number." << std::endl;
339 bool max_pdrops =
false;
378 std::cout <<
"Reached maximum percentage of drops." << std::endl;
391 " null DHCPACK message");
392 }
else if (ack->getYiaddr().isV4Zero()) {
394 " DHCPACK message containing yiaddr of 0");
397 msg->setCiaddr(ack->getYiaddr());
398 msg->setHWAddr(ack->getHWAddr());
409 <<
" to be created from Reply, expected DHCPV6_RENEW or"
414 const char* msg_type_str = (msg_type ==
DHCPV6_RENEW ?
"Renew" :
"Release");
418 <<
" message from the Reply message because the instance of"
419 " the Reply message is NULL");
427 <<
" message because client id option has not been found"
428 " in the Reply message");
430 msg->addOption(opt_clientid);
435 <<
" because server id option has not been found in the"
438 msg->addOption(opt_serverid);
446 if (buf.size() == 2) {
448 }
else if (buf.size() == 0) {
453 "elapsed time option buffer size has to be 0 or 2");
467 const uint8_t buf_array[] = {
469 0, 0, 3600 >> 8, 3600 & 0xff,
470 0, 0, 5400 >> 8, 5400 & 0xff,
472 OptionBuffer buf_ia_na(buf_array, buf_array +
sizeof(buf_array));
473 for (
size_t i = 0; i < buf.size(); ++i) {
474 buf_ia_na.push_back(buf[i]);
483 static const uint8_t buf_array[] = {
485 0, 0, 3600 >> 8, 3600 & 0xff,
486 0, 0, 5400 >> 8, 5400 & 0xff,
488 OptionBuffer buf_ia_pd(buf_array, buf_array +
sizeof(buf_array));
490 buf_ia_pd.insert(buf_ia_pd.end(), buf.begin(), buf.end());
505 const uint8_t buf_array[] = {
509 OptionBuffer buf_with_options(buf_array, buf_array +
sizeof(buf_array));
518 const uint8_t buf_array[] = {
528 OptionBuffer buf_with_options(buf_array, buf_array +
sizeof(buf_array));
530 opt->setData(buf_with_options.begin(), buf_with_options.end());
540 if (macs.size() > 0) {
542 if (r >= macs.size()) {
550 if (clients_num < 2) {
561 for (std::vector<uint8_t>::iterator it = mac_addr.end() - 1;
562 it >= mac_addr.begin();
584 std::vector<uint8_t> client_id(1,
static_cast<uint8_t
>(hwaddr->htype_));
585 client_id.insert(client_id.end(), hwaddr->hwaddr_.begin(),
586 hwaddr->hwaddr_.end());
597 if (macs.size() > 0) {
599 if (r >= macs.size()) {
602 std::vector<uint8_t> mac = macs[r];
616 uint8_t duid_ll[] = {0, 3, 0, 1, 0, 0, 0, 0, 0, 0};
618 std::vector<uint8_t> duid(duid_ll,
619 duid_ll +
sizeof(duid_ll) /
sizeof(duid_ll[0]));
621 std::copy(mac.begin(), mac.end(), duid.begin() + 4);
625 if ((clients_num == 0) || (clients_num == 1)) {
631 duid.resize(duid.size());
632 std::copy(mac_addr.begin(), mac_addr.end(),
633 duid.begin() + duid.size() - mac_addr.size());
641 ptime now(microsec_clock::universal_time());
665 return (time_period(now, due).length().total_microseconds());
671 DHCPV4_ELAPSED_TIME_OFFSET : DHCPV6_ELAPSED_TIME_OFFSET;
681 using namespace boost::posix_time;
682 ptime pkt1_time = pkt1->getTimestamp();
683 ptime pkt2_time = pkt2->getTimestamp();
684 if (pkt1_time.is_not_a_date_time() ||
685 pkt2_time.is_not_a_date_time()) {
688 time_period elapsed_period(pkt1_time, pkt2_time);
689 return (elapsed_period.is_null() ? 0 :
690 elapsed_period.length().total_milliseconds());
696 DHCPV4_RANDOMIZATION_OFFSET : DHCPV6_RANDOMIZATION_OFFSET;
700 return (rand_offset);
706 DHCPV4_REQUESTED_IP_OFFSET : DHCPV6_IA_NA_OFFSET;
716 if (ip_version == 4) {
717 return (
stats_mgr4_->getRcvdPacketsNum(xchg_type));
726 if (ip_version == 4) {
727 return (
stats_mgr4_->getSentPacketsNum(xchg_type));
736 DHCPV4_SERVERID_OFFSET : DHCPV6_SERVERID_OFFSET;
740 return (srvid_offset);
754 DHCPV4_TRANSID_OFFSET : DHCPV6_TRANSID_OFFSET;
764 while (wait3(&status, WNOHANG, NULL) > 0) {
781 for (std::vector<std::string>::const_iterator it = template_files.begin();
782 it != template_files.end(); ++it) {
793 const bool archive_mode =
testDiags(
't') ? true :
false;
825 stats_mgr4_->addCustomCounter(
"latesend",
"Late sent packets");
826 stats_mgr4_->addCustomCounter(
"shortwait",
"Short waits for packets");
827 stats_mgr4_->addCustomCounter(
"multircvd",
"Multiple packets receives");
828 stats_mgr4_->addCustomCounter(
"latercvd",
"Late received packets");
830 stats_mgr6_->addCustomCounter(
"latesend",
"Late sent packets");
831 stats_mgr6_->addCustomCounter(
"shortwait",
"Short waits for packets");
832 stats_mgr6_->addCustomCounter(
"multircvd",
"Multiple packets receives");
833 stats_mgr6_->addCustomCounter(
"latercvd",
"Late received packets");
846 uint8_t family = (options.
getIpVersion() == 6) ? AF_INET6 : AF_INET;
852 "Values for IP version: " <<
854 " and server address: " << servername <<
" are mismatched.");
858 if (family == AF_INET6) {
860 port = DHCP6_CLIENT_PORT;
863 port = DHCP6_SERVER_PORT;
872 if (!localname.empty()) {
885 }
else if (!servername.empty()) {
900 int broadcast_enable = 1;
901 int ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
902 &broadcast_enable,
sizeof(broadcast_enable));
905 "unable to set broadcast option on the socket");
912 int ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
913 &hops,
sizeof(hops));
923 int idx = iface->getIndex();
924 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
929 "unable to enable multicast on socket " << sock
930 <<
". errno = " << errno);
940 const uint64_t packets_num,
941 const bool preload ) {
943 for (uint64_t i = packets_num; i > 0; --i) {
970 stats_mgr4_->incrementCounter(
"latercvd", latercvd);
972 stats_mgr6_->incrementCounter(
"latercvd", latercvd);
981 const uint64_t msg_num) {
982 for (uint64_t i = 0; i < msg_num; ++i) {
992 const uint32_t msg_type,
993 const uint64_t msg_num) {
994 for (uint64_t i = 0; i < msg_num; ++i) {
1019 std::string hex_buf;
1025 std::map<uint8_t, dhcp::Pkt4Ptr>::const_iterator pkt_it =
1030 const char* out_buf_data =
1031 static_cast<const char*
>(out_buf.
getData());
1032 std::vector<uint8_t> buf(out_buf_data, out_buf_data + out_buf.
getLength());
1039 std::map<uint8_t, dhcp::Pkt6Ptr>::const_iterator pkt_it =
1044 const char* out_buf_data =
1045 static_cast<const char*
>(out_buf.
getData());
1046 std::vector<uint8_t> buf(out_buf_data, out_buf_data + out_buf.
getLength());
1051 std::cout <<
"random-offset=" <<
getRandomOffset(arg_idx) << std::endl;
1058 std::cout <<
"contents: " << std::endl;
1061 while (line_len == 32) {
1062 if (hex_buf.length() - i < 32) {
1063 line_len = hex_buf.length() - i;
1066 std::cout << setfill(
'0') << setw(4) << std::hex << i << std::dec
1067 <<
" " << hex_buf.substr(i, line_len) << std::endl;
1071 std::cout << std::endl;
1090 std::string exchange_name =
"4-way exchanges";
1096 exchange_name =
"DISCOVER-OFFER";
1099 stats_mgr4_->getTestPeriod().length().total_nanoseconds() / 1e9;
1100 rate =
stats_mgr4_->getRcvdPacketsNum(xchg_type) / duration;
1107 "Solicit-Advertise";
1110 stats_mgr6_->getTestPeriod().length().total_nanoseconds() / 1e9;
1111 rate =
stats_mgr6_->getRcvdPacketsNum(xchg_type) / duration;
1113 std::ostringstream s;
1114 s <<
"***Rate statistics***" << std::endl;
1115 s <<
"Rate: " << rate <<
" " << exchange_name <<
"/second";
1117 s <<
", expected rate: " << options.
getRate() << std::endl;
1120 std::cout << s.str() << std::endl;
1127 ptime now = microsec_clock::universal_time();
1129 if (time_since_report.length().total_seconds() >= delay) {
1146 "hasn't been initialized");
1155 "hasn't been initialized");
1166 const std::string& separator )
const {
1167 std::ostringstream stream;
1168 for (std::vector<uint8_t>::const_iterator it = vec.begin();
1171 if (it == vec.begin()) {
1174 stream << separator <<
byte2Hex(*it);
1177 return (stream.str());
1182 std::ifstream temp_file;
1183 temp_file.open(file_name.c_str(), ios::in | ios::binary | ios::ate);
1184 if (!temp_file.is_open()) {
1188 std::streampos temp_size = temp_file.tellg();
1189 if (temp_size == std::streampos(0)) {
1193 temp_file.seekg(0, ios::beg);
1194 std::vector<char> file_contents(temp_size);
1195 temp_file.read(&file_contents[0], temp_size);
1201 std::vector<char> hex_digits;
1202 for (
size_t i = 0; i < file_contents.size(); ++i) {
1203 if (isxdigit(file_contents[i])) {
1204 hex_digits.push_back(file_contents[i]);
1205 }
else if (!isxdigit(file_contents[i]) &&
1206 !isspace(file_contents[i])) {
1208 " hexadecimal digit");
1212 if (hex_digits.size() % 2 != 0) {
1214 }
else if (hex_digits.empty()) {
1217 std::vector<uint8_t> binary_stream;
1218 for (
size_t i = 0; i < hex_digits.size(); i += 2) {
1220 s <<
"0x" << hex_digits[i] << hex_digits[i+1];
1223 binary_stream.push_back(
static_cast<uint8_t
>(b));
1245 }
else if (pkt4->getType() ==
DHCPACK) {
1274 uint8_t packet_type = pkt6->getType();
1329 bool receiving =
true;
1330 uint64_t received = 0;
1337 std::cerr <<
"Failed to receive DHCPv4 packet: "
1338 << e.
what() << std::endl;
1358 std::cerr <<
"Failed to receive DHCPv6 packet: "
1359 << e.
what() << std::endl;
1381 static bool factories_registered =
false;
1382 if (!factories_registered) {
1396 factories_registered =
true;
1401 static bool factories_registered =
false;
1402 if (!factories_registered) {
1435 factories_registered =
true;
1450 "before DHCP option factories can be registered");
1486 "command options must be parsed before running a test");
1516 time_period duration(from_iso_string(
"20111231T235959"),
1517 microsec_clock::universal_time());
1518 srandom(duration.length().total_seconds()
1519 + duration.length().fractional_seconds());
1539 if ((packets_due == 0) &&
testDiags(
'i')) {
1566 uint64_t renew_packets_due =
1581 uint64_t release_packets_due =
1625 std::cout <<
"Interrupted" << std::endl;
1652 }
else if (pid == 0) {
1654 do_stop ?
"stop" :
"start",
1680 const bool preload ) {
1683 uint8_t randomized = 0;
1708 pkt4->setHWAddr(
HTYPE_ETHER, mac_address.size(), mac_address);
1721 "hasn't been initialized");
1730 const std::vector<uint8_t>& template_buf,
1731 const bool preload ) {
1735 const uint8_t arg_idx = 0;
1737 uint8_t randomized = 0;
1750 std::vector<uint8_t> in_buf(template_buf.begin(),
1751 template_buf.end());
1761 pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
1763 setDefaults4(socket, boost::static_pointer_cast<Pkt4>(pkt4));
1771 "hasn't been initialized");
1775 boost::static_pointer_cast<Pkt4>(pkt4));
1803 "hasn't been initialized");
1816 <<
" to be sent, expected DHCPV6_RENEW or DHCPV6_RELEASE");
1840 "hasn't been initialized");
1852 const uint32_t transid = discover_pkt4->getTransid();
1864 if (!opt_serverid) {
1866 <<
"in OFFER message");
1871 pkt4->addOption(opt_serverid);
1876 if (!yiaddr.
isV4()) {
1883 opt_requested_address->setUint32(yiaddr.
toUint32());
1884 pkt4->addOption(opt_requested_address);
1887 pkt4->addOption(opt_parameter_list);
1896 pkt4->setHWAddr(offer_pkt4->getHWAddr());
1900 uint32_t elapsed_time = getElapsedTime<Pkt4Ptr>(discover_pkt4, offer_pkt4);
1901 pkt4->setSecs(
static_cast<uint16_t
>(elapsed_time / 1000));
1907 "hasn't been initialized");
1915 const std::vector<uint8_t>& template_buf,
1920 const uint8_t arg_idx = 1;
1922 const uint32_t transid = discover_pkt4->getTransid();
1930 std::vector<uint8_t> in_buf(template_buf.begin(),
1931 template_buf.end());
1943 HWAddrPtr hwaddr = offer_pkt4->getHWAddr();
1945 uint8_t hw_len = hwaddr->hwaddr_.size();
1947 memcpy(&mac_address[0], &hwaddr->hwaddr_[0],
1950 pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
1954 uint32_t elapsed_time = getElapsedTime<Pkt4Ptr>(discover_pkt4, offer_pkt4);
1955 pkt4->writeValueAt<uint16_t>(elp_offset,
1956 static_cast<uint16_t
>(elapsed_time / 1000));
1964 boost::shared_ptr<LocalizedOption>
1969 pkt4->addOption(opt_serverid);
1975 if (!opt_serverid_offer) {
1977 <<
"in OFFER message");
1979 boost::shared_ptr<LocalizedOption>
1982 opt_serverid_offer->getData(),
1984 pkt4->addOption(opt_serverid);
1992 if (!yiaddr.
isV4()) {
2000 boost::shared_ptr<LocalizedOption>
2006 opt_requested_ip->setUint32(yiaddr.
toUint32());
2007 pkt4->addOption(opt_requested_ip);
2009 setDefaults4(socket, boost::static_pointer_cast<Pkt4>(pkt4));
2019 "hasn't been initialized");
2023 boost::static_pointer_cast<Pkt4>(pkt4));
2029 const Pkt6Ptr& advertise_pkt6) {
2035 pkt6->addOption(opt_elapsed_time);
2038 if (!opt_clientid) {
2041 pkt6->addOption(opt_clientid);
2051 if (!opt_serverid) {
2057 pkt6->addOption(opt_serverid);
2078 "hasn't been initialized");
2086 const std::vector<uint8_t>& template_buf,
2087 const Pkt6Ptr& advertise_pkt6) {
2090 const uint8_t arg_idx = 1;
2096 transid_offset, transid));
2099 boost::shared_ptr<LocalizedOption>
2102 pkt6->addOption(opt_elapsed_time);
2110 boost::shared_ptr<LocalizedOption>
2115 pkt6->addOption(opt_serverid);
2122 if (!opt_serverid_advertise) {
2124 <<
"in ADVERTISE message");
2126 boost::shared_ptr<LocalizedOption>
2129 opt_serverid_advertise->getData(),
2131 pkt6->addOption(opt_serverid);
2137 boost::shared_ptr<Option6IA> opt_ia_na_advertise =
2138 boost::static_pointer_cast<Option6IA>(advertise_pkt6->getOption(
D6O_IA_NA));
2139 if (!opt_ia_na_advertise) {
2144 boost::shared_ptr<LocalizedOption>
2146 if (!opt_ia_na->valid()) {
2149 pkt6->addOption(opt_ia_na);
2152 if (!opt_serverid_advertise) {
2157 boost::shared_ptr<LocalizedOption>
2159 opt_serverid_advertise->getData(),
2161 pkt6->addOption(opt_serverid);
2165 if (!opt_clientid_advertise) {
2168 rand_offset -= (opt_clientid_advertise->len() - 1);
2170 boost::shared_ptr<LocalizedOption>
2172 opt_clientid_advertise->getData(),
2174 pkt6->addOption(opt_clientid);
2187 "hasn't been initialized");
2205 const bool preload ) {
2208 uint8_t randomized = 0;
2247 "hasn't been initialized");
2257 const std::vector<uint8_t>& template_buf,
2258 const bool preload ) {
2260 const int arg_idx = 0;
2267 transid_offset, transid));
2275 uint8_t randomized = 0;
2277 if (rand_offset > template_buf.size()) {
2281 pkt6->writeAt(rand_offset - randomized + 1,
2282 duid.end() - randomized, duid.end());
2296 "hasn't been initialized");
2311 if (iface == NULL) {
2314 pkt->setIface(iface->getName());
2318 pkt->setLocalPort(DHCP4_CLIENT_PORT);
2320 pkt->setRemotePort(DHCP4_SERVER_PORT);
2337 if (iface == NULL) {
2340 pkt->setIface(iface->getName());
2344 pkt->setLocalPort(DHCP6_CLIENT_PORT);
2346 pkt->setRemotePort(DHCP6_SERVER_PORT);
2348 pkt->setLocalAddr(socket.
addr_);
2361 pkt->addRelayInfo(relay_info);
2370 for (
auto entry : extra_opts) {
2371 pkt->addOption(entry.second);
2380 for (
auto entry : extra_opts) {
2381 pkt->addOption(entry.second);
2388 if (diags.find(diag) != std::string::npos) {
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
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)
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV4() const
Convenience function to check for an IPv4 address.
bool isV6Multicast() const
checks whether and address is IPv6 and is multicast
short getFamily() const
Returns the address family.
int openSocketFromAddress(const isc::asiolink::IOAddress &addr, const uint16_t port)
Opens UDP/IP socket and binds to address specified.
int openSocketFromIface(const std::string &ifname, const uint16_t port, const uint8_t family)
Opens UDP/IP socket and binds it to interface specified.
Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec=0)
Receive IPv4 packets or data from external sockets.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
bool configureDHCPPacketQueue(const uint16_t family, data::ConstElementPtr queue_control)
Configures DHCP packet queue.
int openSocketFromRemoteAddress(const isc::asiolink::IOAddress &remote_addr, const uint16_t port)
Opens UDP/IP socket to be used to connect to remote address.
IfacePtr getIface(int ifindex)
Returns interface specified interface index.
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec=0)
Receive IPv4 packets or data from external sockets.
static void OptionFactoryRegister(Option::Universe u, uint16_t type, Option::Factory *factory)
Registers factory method that produces options of specific option types.
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.
int getAggressivity() const
Returns aggressivity value.
int getServerIdOffset() const
Returns template offset for server-ID.
std::string getWrapped() const
Returns wrapped command.
int getRenewRate() const
Returns a rate at which DHCPv6 Renew messages are sent.
uint8_t getIpVersion() const
Returns IP version.
std::vector< uint8_t > getDuidTemplate() const
Returns DUID template.
int getRate() const
Returns exchange rate.
bool isRapidCommit() const
Check if rapid commit option used.
std::string getLocalName() const
Returns local address or interface name.
const isc::dhcp::OptionCollection & getExtraOpts() const
Returns extra options to be inserted.
int getLocalPort() const
Returns local port number.
int getReportDelay() const
Returns delay between two performance reports.
std::vector< int > getRandomOffset() const
Returns template offsets for rnd.
std::vector< double > getMaxDropPercentage() const
Returns maximal percentage of drops.
ExchangeMode
2-way (cmd line param -i) or 4-way exchanges
const MacAddrsVector & getMacsFromFile() const
Returns reference to a vector of MAC addresses read from a file.
bool isBroadcast() const
Checks if broadcast address is to be used.
std::vector< std::string > getTemplateFiles() const
Returns template file names.
std::vector< int > getTransactionIdOffset() const
brief Returns template offsets for xid.
std::vector< std::vector< uint8_t > > MacAddrsVector
A vector holding MAC addresses.
int getElapsedTimeOffset() const
Returns template offset for elapsed time.
std::string getServerName() const
Returns server name.
std::vector< int > getNumRequests() const
Returns maximum number of exchanges.
bool isUseRelayedV6() const
Check if generated DHCPv6 messages should appear as relayed.
int getExitWaitTime() const
Returns the time in microseconds to delay the program by.
uint32_t getClientsNum() const
Returns number of simulated clients.
int getPreload() const
Returns number of preload exchanges.
bool isSeeded() const
Checks if seed provided.
static CommandOptions & instance()
CommandOptions is a singleton class.
std::vector< double > getDropTime() const
Returns drop time.
std::vector< int > getMaxDrop() const
Returns maximum drops number.
int getPeriod() const
Returns test period.
int getReleaseRate() const
Returns a rate at which DHCPv6 Release messages are sent.
uint32_t getSeed() const
Returns random seed.
ExchangeMode getExchangeMode() const
Returns packet exchange mode.
void printCommandLine() const
Print command line arguments.
bool isInterface() const
Checks if interface name was used.
std::vector< uint8_t > getMacTemplate() const
Returns MAC address template.
int getRequestedIpOffset() const
Returns template offset for requested IP.
DHCP option at specific offset.
Exception thrown when the required option is not found in a packet.
A message sending rate control class for perfdhcp.
void setAggressivity(const int aggressivity)
Sets the value of aggressivity.
void updateSendTime()
Sets the timestamp of the last sent message to current time.
boost::posix_time::ptime getDue() const
Returns current due time to send next message.
bool isLateSent() const
Returns the value of the late send flag.
void setRate(const int rate)
Sets the new rate.
uint64_t getOutboundMessageCount()
Returns number of messages to be sent "now".
ExchangeType
DHCP packet exchange types.
@ XCHG_SA
DHCPv6 SOLICIT-ADVERTISE.
@ XCHG_RNA
DHCPv4 REQUEST-ACK (renewal)
@ XCHG_RA
DHCPv4 REQUEST-ACK.
@ XCHG_RL
DHCPv6 RELEASE-REPLY.
@ XCHG_RR
DHCPv6 REQUEST-REPLY.
@ XCHG_RN
DHCPv6 RENEW-REPLY.
@ XCHG_DO
DHCPv4 DISCOVER-OFFER.
Sequential numbers generator class.
void sendDiscover4(const TestControlSocket &socket, const bool preload=false)
Send DHCPv4 DISCOVER message.
void saveFirstPacket(const dhcp::Pkt4Ptr &pkt)
Save the first DHCPv4 sent packet of the specified type.
TestControl()
Default constructor.
static const uint8_t HW_ETHER_LEN
Length of the Ethernet HW address (MAC) in bytes.
isc::util::random::UniformRandomIntegerGenerator number_generator_
Generate uniformly distributed integers in range of [min, max].
std::map< uint8_t, dhcp::Pkt4Ptr > template_packets_v4_
First packets send.
StatsMgr< dhcp::Pkt6 > StatsMgr6
Statistics Manager for DHCPv6.
void addExtraOpts(const dhcp::Pkt4Ptr &pkt4)
Inserts extra options specified by user.
bool waitToExit() const
Delay the exit by a fixed given time to catch up to all exchanges that were already started.
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.
void sendRequest4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &discover_pkt4, const dhcp::Pkt4Ptr &offer_pkt4)
Send DHCPv4 REQUEST message.
NumberGeneratorPtr macaddr_gen_
Numbers generator for MAC address.
uint64_t getRcvdPacketsNum(ExchangeType xchg_type) const
Get number of received packets.
int getRequestedIpOffset() const
Return requested ip offset in a packet.
void processReceivedPacket4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &pkt4)
Process received DHCPv4 packet.
boost::shared_ptr< StatsMgr4 > StatsMgr4Ptr
Pointer to Statistics Manager for DHCPv4;.
boost::shared_ptr< NumberGenerator > NumberGeneratorPtr
The default generator pointer.
int openSocket() const
Open socket to communicate with DHCP server.
void sendRequest6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &advertise_pkt6)
Send DHCPv6 REQUEST message.
static bool interrupted_
Is program interrupted.
std::string byte2Hex(const uint8_t b) const
Convert binary value to hex string.
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.
StatsMgr6Ptr stats_mgr6_
Statistics Manager 6.
void processReceivedPacket6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &pkt6)
Process received DHCPv6 packet.
static TestControl & instance()
TestControl is a singleton class.
void setMacAddrGenerator(const NumberGeneratorPtr &generator)
Set new MAC address generator.
boost::posix_time::ptime last_report_
Last intermediate report time.
bool haveAllPacketsBeenReceived() const
Checks if all expected packets were already received.
StatsMgr4Ptr stats_mgr4_
Statistics Manager 4.
void cleanCachedPackets()
Removes cached DHCPv6 Reply packets every second.
bool sendRequestFromAck(const TestControlSocket &socket)
Send DHCPv4 renew (DHCPREQUEST) using specified socket.
void sendPackets(const TestControlSocket &socket, const uint64_t packets_num, const bool preload=false)
Send number of packets to initiate new exchanges.
dhcp::Pkt4Ptr createRequestFromAck(const dhcp::Pkt4Ptr &ack)
Creates DHCPREQUEST from a DHCPACK message.
std::string vector2Hex(const std::vector< uint8_t > &vec, const std::string &separator="") const
Convert vector in hexadecimal string.
uint32_t getCurrentTimeout() const
Returns a timeout for packet reception.
RateControl release_rate_control_
A rate control class for Release messages.
static dhcp::OptionPtr factoryOptionRequestOption6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ORO option.
bool sendMessageFromReply(const uint16_t msg_type, const TestControlSocket &socket)
Send DHCPv6 Renew or Release message using specified socket.
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_
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_
A storage for reply messages.
void registerOptionFactories6() const
Register option factory functions for DHCPv6.
bool checkExitConditions() const
Check if test exit conditions fulfilled.
void registerOptionFactories() const
Register option factory functions for DHCPv4 or DHCPv6.
uint64_t receivePackets(const TestControlSocket &socket)
Receive DHCPv4 or DHCPv6 packets from the server.
std::vector< uint8_t > TemplateBuffer
Packet template buffer.
void runWrapped(bool do_stop=false) const
Run wrapped command.
uint32_t getElapsedTime(const T &pkt1, const T &pkt2)
Calculate elapsed time between two packets.
void reset()
Resets internal state of the object.
void setDefaults6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &pkt)
Set default DHCPv6 packet parameters.
int run()
brief\ Run performance test.
boost::shared_ptr< StatsMgr6 > StatsMgr6Ptr
Pointer to Statistics Manager for DHCPv6.
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.
uint64_t sendMultipleRequests(const TestControlSocket &socket, const uint64_t msg_num)
Send number of DHCPREQUEST (renew) messages to a server.
bool testDiags(const char diag) const
Find if diagnostic flag has been set.
void printTemplates() const
Print templates information.
void setDefaults4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &pkt)
Set default DHCPv4 packet parameters.
TemplateBufferCollection template_buffers_
Packet template buffers.
uint64_t sendMultipleMessages6(const TestControlSocket &socket, const uint32_t msg_type, const uint64_t msg_num)
Send number of DHCPv6 Renew or Release messages to the server.
void printStats() const
Print performance statistics.
PacketStorage< dhcp::Pkt4 > ack_storage_
A 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.
StatsMgr< dhcp::Pkt4 > StatsMgr4
Statistics Manager for DHCPv4.
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.
void sendSolicit6(const TestControlSocket &socket, const bool preload=false)
Send DHCPv6 SOLICIT message.
uint64_t getSentPacketsNum(ExchangeType xchg_type) const
Get number of sent packets.
void initializeStatsMgr()
Initializes Statistics Manager.
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.
RateControl renew_rate_control_
A rate control class for Renew messages.
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.
StatsMgr ::ExchangeType ExchangeType
Packet exchange type.
void checkLateMessages(RateControl &rate_control)
Increments counter of late sent messages if required.
bool hasLateExitCommenced() const
Check if the program is in that period where the program was bound to exit, but was delayed by lateEx...
dhcp::OptionPtr generateClientId(const dhcp::HWAddrPtr &hwaddr) const
Generate DHCPv4 client identifier from HW address.
RateControl basic_rate_control_
A rate control class for Discover and Solicit messages.
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.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
size_t getLength() const
Return the length of data written in the buffer.
const void * getData() const
Return a pointer to the head of the data stored in the buffer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A wrapper interface for the ASIO library.
boost::shared_ptr< Element > ElementPtr
@ 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
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
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
ptime late_exit_target_time_
boost::shared_ptr< PerfPkt6 > PerfPkt6Ptr
Defines the logger used by the top-level component of kea-dhcp-ddns.
structure that describes a single relay information
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
Holds information about socket.
isc::asiolink::IOAddress addr_
Socket wrapper structure.
bool valid_
Is socket valid.
~TestControlSocket()
Destructor of the socket wrapper class.
TestControlSocket(const int socket)
Constructor of socket wrapper class.
uint16_t ifindex_
Interface index.