21 #include <boost/date_time/posix_time/posix_time.hpp> 22 #include <boost/foreach.hpp> 35 using namespace boost::posix_time;
43 bool TestControl::interrupted_ =
false;
48 TestControl::hasLateExitCommenced()
const {
53 TestControl::waitToExit()
const {
54 static ptime exit_time = ptime(not_a_date_time);
59 if (wait_time && !haveAllPacketsBeenReceived()) {
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);
76 TestControl::haveAllPacketsBeenReceived()
const {
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];
93 responses = stats_mgr4_->getRcvdPacketsNum(StatsMgr4::XCHG_DO) +
94 stats_mgr4_->getRcvdPacketsNum(StatsMgr4::XCHG_RA);
96 responses = stats_mgr6_->getRcvdPacketsNum(StatsMgr6::XCHG_SA) +
97 stats_mgr6_->getRcvdPacketsNum(StatsMgr6::XCHG_RR);
100 return (responses == requests);
103 TestControl::TestControlSocket::TestControlSocket(
const int socket) :
105 ifindex_(0), valid_(true) {
114 IfacePtr iface = IfaceMgr::instance().getIface(ifindex_);
116 iface->delSocket(sockfd_);
121 TestControl::TestControlSocket::initSocketData() {
122 BOOST_FOREACH(
IfacePtr iface, IfaceMgr::instance().getIfaces()) {
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()) {
877 sock = IfaceMgr::instance().openSocketFromIface(localname,
882 sock = IfaceMgr::instance().openSocketFromAddress(localaddr,
885 }
else if (!servername.empty()) {
888 sock = IfaceMgr::instance().openSocketFromRemoteAddress(remoteaddr,
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) {
1384 LibDHCP::OptionFactoryRegister(Option::V4,
1388 LibDHCP::OptionFactoryRegister(Option::V4,
1392 LibDHCP::OptionFactoryRegister(Option::V4,
1396 factories_registered =
true;
1401 static bool factories_registered =
false;
1402 if (!factories_registered) {
1404 LibDHCP::OptionFactoryRegister(Option::V6,
1408 LibDHCP::OptionFactoryRegister(Option::V6,
1412 LibDHCP::OptionFactoryRegister(Option::V6,
1416 LibDHCP::OptionFactoryRegister(Option::V6,
1420 LibDHCP::OptionFactoryRegister(Option::V6,
1424 LibDHCP::OptionFactoryRegister(Option::V6,
1429 LibDHCP::OptionFactoryRegister(Option::V6,
1435 factories_registered =
true;
1450 "before DHCP option factories can be registered");
1486 "command options must be parsed before running a test");
1489 IfaceMgr::instance().configureDHCPPacketQueue(AF_INET,
data::ElementPtr());
1493 IfaceMgr::instance().configureDHCPPacketQueue(AF_INET6,
data::ElementPtr());
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;
1700 pkt4->addOption(Option::factory(Option::V4,
1708 pkt4->setHWAddr(
HTYPE_ETHER, mac_address.size(), mac_address);
1717 IfaceMgr::instance().send(pkt4);
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));
1767 IfaceMgr::instance().send(boost::static_pointer_cast<Pkt4>(pkt4));
1771 "hasn't been initialized");
1775 boost::static_pointer_cast<Pkt4>(pkt4));
1800 IfaceMgr::instance().send(msg);
1803 "hasn't been initialized");
1816 <<
" to be sent, expected DHCPV6_RENEW or DHCPV6_RELEASE");
1837 IfaceMgr::instance().send(msg);
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));
1904 IfaceMgr::instance().send(pkt4);
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));
2016 IfaceMgr::instance().send(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);
2047 pkt6->addOption(Option::factory(Option::V6,
D6O_SERVERID,
2051 if (!opt_serverid) {
2057 pkt6->addOption(opt_serverid);
2075 IfaceMgr::instance().send(pkt6);
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);
2184 IfaceMgr::instance().send(pkt6);
2187 "hasn't been initialized");
2205 const bool preload ) {
2208 uint8_t randomized = 0;
2220 pkt6->addOption(Option::factory(Option::V6,
D6O_CLIENTID, duid));
2221 pkt6->addOption(Option::factory(Option::V6,
D6O_ORO));
2229 pkt6->addOption(Option::factory(Option::V6,
D6O_IA_NA));
2234 pkt6->addOption(Option::factory(Option::V6,
D6O_IA_PD));
2243 IfaceMgr::instance().send(pkt6);
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());
2292 IfaceMgr::instance().send(pkt6);
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) {
NumberGeneratorPtr transid_gen_
Transaction id generator.
static dhcp::OptionPtr factoryGeneric(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create generic option.
boost::shared_ptr< NumberGenerator > NumberGeneratorPtr
The default generator pointer.
int getExitWaitTime() const
Returns the time in microseconds to delay the program by.
static bool interrupted_
Is program interrupted.
uint32_t generateTransid()
generate transaction id.
bool sendRequestFromAck(const TestControlSocket &socket)
Send DHCPv4 renew (DHCPREQUEST) using specified socket.
void printTemplates() const
Print templates information.
void printStats() const
Print performance statistics.
boost::shared_ptr< PerfPkt6 > PerfPkt6Ptr
DHCP option at specific offset.
static dhcp::OptionPtr factoryIana6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create IA_NA option.
std::string getLocalName() const
Returns local address or interface name.
boost::shared_ptr< PerfPkt4 > PerfPkt4Ptr
int getAggressivity() const
Returns aggressivity value.
bool isUseRelayedV6() const
Check if generated DHCPv6 messages should appear as relayed.
int getPeriod() const
Returns test period.
Exception thrown when the required option is not found in a packet.
RateControl release_rate_control_
A rate control class for Release messages.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
PacketStorage< dhcp::Pkt4 > ack_storage_
A storage for DHCPACK messages.
void setDefaults4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &pkt)
Set default DHCPv4 packet parameters.
std::vector< uint8_t > generateDuid(uint8_t &randomized)
Generate DUID.
void registerOptionFactories4() const
Register option factory functions for DHCPv4.
static TestControl & instance()
TestControl is a singleton class.
std::vector< std::vector< uint8_t > > MacAddrsVector
A vector holding MAC addresses.
ExchangeType
DHCP packet exchange types.
boost::shared_ptr< Iface > IfacePtr
int run()
brief\ Run performance test.
uint32_t getCurrentTimeout() const
Returns a timeout for packet reception.
int getServerIdOffset() const
Returns template offset for server-ID.
bool checkExitConditions() const
Check if test exit conditions fulfilled.
void processReceivedPacket6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &pkt6)
Process received DHCPv6 packet.
boost::shared_ptr< Option > OptionPtr
void setTransidGenerator(const NumberGeneratorPtr &generator)
Set new transaction id generator.
boost::posix_time::ptime getDue() const
Returns current due time to send next message.
void checkLateMessages(RateControl &rate_control)
Increments counter of late sent messages if required.
StatsMgr4Ptr stats_mgr4_
Statistics Manager 4.
Universe
defines option universe DHCPv4 or DHCPv6
Represents a DHCPv6 packet.
boost::shared_ptr< Element > ElementPtr
static CommandOptions & instance()
CommandOptions is a singleton class.
void printIntermediateStats()
Print intermediate statistics.
std::vector< uint8_t > getMacTemplate() const
Returns MAC address template.
boost::shared_ptr< StatsMgr6 > StatsMgr6Ptr
Pointer to Statistics Manager for DHCPv6.
static dhcp::OptionPtr factoryRapidCommit6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 RAPID_COMMIT option instance.
TestControl()
Default constructor.
ptime late_exit_target_time_
std::vector< std::string > getTemplateFiles() const
Returns template file names.
StatsMgr< dhcp::Pkt4 > StatsMgr4
Statistics Manager for DHCPv4.
A message sending rate control class for perfdhcp.
uint8_t getIpVersion() const
Returns IP version.
void initPacketTemplates()
Reads packet templates from files.
dhcp::OptionPtr generateClientId(const dhcp::HWAddrPtr &hwaddr) const
Generate DHCPv4 client identifier from HW address.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
ExchangeMode getExchangeMode() const
Returns packet exchange mode.
RateControl renew_rate_control_
A rate control class for Renew messages.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
bool isSeeded() const
Checks if seed provided.
bool testDiags(const char diag) const
Find if diagnostic flag has been set.
uint64_t getOutboundMessageCount()
Returns number of messages to be sent "now".
static dhcp::OptionPtr factoryElapsedTime6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ELAPSED_TIME option.
TemplateBufferCollection template_buffers_
Packet template buffers.
StatsMgr6Ptr stats_mgr6_
Statistics Manager 6.
bool isBroadcast() const
Checks if broadcast address is to be used.
dhcp::Pkt4Ptr createRequestFromAck(const dhcp::Pkt4Ptr &ack)
Creates DHCPREQUEST from a DHCPACK message.
void printRate() const
Print rate statistics.
void updateSendTime()
Sets the timestamp of the last sent message to current time.
uint64_t sendMultipleRequests(const TestControlSocket &socket, const uint64_t msg_num)
Send number of DHCPREQUEST (renew) messages to a server.
StatsMgr ::ExchangeType ExchangeType
Packet exchange type.
std::vector< uint8_t > TemplateBuffer
Packet template buffer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
int openSocket() const
Open socket to communicate with DHCP server.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
uint64_t getSentPacketsNum(ExchangeType xchg_type) const
Get number of sent packets.
std::string getWrapped() const
Returns wrapped command.
bool hasLateExitCommenced() const
Check if the program is in that period where the program was bound to exit, but was delayed by lateEx...
std::vector< int > getTransactionIdOffset() const
brief Returns template offsets for xid.
structure that describes a single relay information
int getRandomOffset(const int arg_idx) const
Return randomization offset in a packet.
void printCommandLine() const
Print command line arguments.
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
bool isInterface() const
Checks if interface name was used.
void setRate(const int rate)
Sets the new rate.
std::vector< int > getRandomOffset() const
Returns template offsets for rnd.
int getReleaseRate() const
Returns a rate at which DHCPv6 Release messages are sent.
void runWrapped(bool do_stop=false) const
Run wrapped command.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
StatsMgr< dhcp::Pkt6 > StatsMgr6
Statistics Manager for DHCPv6.
A generic exception that is thrown when an unexpected error condition occurs.
void processReceivedPacket4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &pkt4)
Process received DHCPv4 packet.
boost::posix_time::ptime last_report_
Last intermediate report time.
std::map< uint8_t, dhcp::Pkt6Ptr > template_packets_v6_
std::vector< double > getDropTime() const
Returns drop time.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
isc::asiolink::IOAddress addr_
void sendRequest6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &advertise_pkt6)
Send DHCPv6 REQUEST message.
void sendPackets(const TestControlSocket &socket, const uint64_t packets_num, const bool preload=false)
Send number of packets to initiate new exchanges.
TemplateBuffer getTemplateBuffer(const size_t idx) const
Return template buffer.
int getTransactionIdOffset(const int arg_idx) const
Return transaction id offset in a packet.
std::string getServerName() const
Returns server name.
std::string vector2Hex(const std::vector< uint8_t > &vec, const std::string &separator="") const
Convert vector in hexadecimal string.
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
bool isV6Multicast() const
checks whether and address is IPv6 and is multicast
void sendDiscover4(const TestControlSocket &socket, const bool preload=false)
Send DHCPv4 DISCOVER message.
std::vector< uint8_t > getDuidTemplate() const
Returns DUID template.
uint64_t receivePackets(const TestControlSocket &socket)
Receive DHCPv4 or DHCPv6 packets from the server.
bool sendMessageFromReply(const uint16_t msg_type, const TestControlSocket &socket)
Send DHCPv6 Renew or Release message using specified socket.
bool isV4() const
Convenience function to check for an IPv4 address.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void initializeStatsMgr()
Initializes Statistics Manager.
int getLocalPort() const
Returns local port number.
bool valid_
Is socket valid.
void setAggressivity(const int aggressivity)
Sets the value of aggressivity.
std::vector< uint8_t > generateMacAddress(uint8_t &randomized)
Generate MAC address.
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
static dhcp::OptionPtr factoryRequestList4(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv4 Request List option.
int getReportDelay() const
Returns delay between two performance reports.
void copyIaOptions(const dhcp::Pkt6Ptr &pkt_from, dhcp::Pkt6Ptr &pkt_to)
Copies IA_NA or IA_PD option from one packet to another.
Represents DHCPv4 packet.
boost::shared_ptr< StatsMgr4 > StatsMgr4Ptr
Pointer to Statistics Manager for DHCPv4;.
static void handleChild(int sig)
Handle child signal.
void sendSolicit6(const TestControlSocket &socket, const bool preload=false)
Send DHCPv6 SOLICIT message.
int getElapsedTimeOffset() const
Returns template offset for elapsed time.
void cleanCachedPackets()
Removes cached DHCPv6 Reply packets every second.
uint8_t hop_count_
number of traversed relays (up to 32)
std::vector< int > getMaxDrop() const
Returns maximum drops number.
PacketStorage< dhcp::Pkt6 > reply_storage_
A storage for reply messages.
void saveFirstPacket(const dhcp::Pkt4Ptr &pkt)
Save the first DHCPv4 sent packet of the specified type.
void registerOptionFactories() const
Register option factory functions for DHCPv4 or DHCPv6.
A wrapper interface for the ASIO library.
void sendRequest4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &discover_pkt4, const dhcp::Pkt4Ptr &offer_pkt4)
Send DHCPv4 REQUEST message.
Socket wrapper structure.
void registerOptionFactories6() const
Register option factory functions for DHCPv6.
A generic exception that is thrown if a function is called in a prohibited way.
void printTemplate(const uint8_t packet_type) const
Print template information.
void readPacketTemplate(const std::string &file_name)
Read DHCP message template from file.
const isc::dhcp::OptionCollection & getExtraOpts() const
Returns extra options to be inserted.
std::vector< int > getNumRequests() const
Returns maximum number of exchanges.
int getRate() const
Returns exchange rate.
NumberGeneratorPtr macaddr_gen_
Numbers generator for MAC address.
isc::util::random::UniformRandomIntegerGenerator number_generator_
Generate uniformly distributed integers in range of [min, max].
static dhcp::OptionPtr factoryOptionRequestOption6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ORO option.
static const uint8_t HW_ETHER_LEN
Length of the Ethernet HW address (MAC) in bytes.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
isc::asiolink::IOAddress linkaddr_
fixed field in relay-forw/relay-reply
dhcp::OptionBuffer first_packet_serverid_
Buffer holding server id received in first packet.
std::vector< double > getMaxDropPercentage() const
Returns maximal percentage of drops.
static dhcp::OptionPtr factoryIapd6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create IA_PD option.
isc::asiolink::IOAddress peeraddr_
fixed field in relay-forw/relay-reply
dhcp::Pkt6Ptr createMessageFromReply(const uint16_t msg_type, const dhcp::Pkt6Ptr &reply)
Creates DHCPv6 message from the Reply packet.
void printDiagnostics() const
Print main diagnostics data.
The IOAddress class represents an IP addresses (version agnostic)
~TestControlSocket()
Destructor of the socket wrapper class.
uint16_t ifindex_
Interface index.
uint32_t getElapsedTime(const T &pkt1, const T &pkt2)
Calculate elapsed time between two packets.
ExchangeMode
2-way (cmd line param -i) or 4-way exchanges
void setDefaults6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &pkt)
Set default DHCPv6 packet parameters.
void setMacAddrGenerator(const NumberGeneratorPtr &generator)
Set new MAC address generator.
uint64_t getRcvdPacketsNum(ExchangeType xchg_type) const
Get number of received packets.
DHCPv6 SOLICIT-ADVERTISE.
std::string byte2Hex(const uint8_t b) const
Convert binary value to hex string.
const MacAddrsVector & getMacsFromFile() const
Returns reference to a vector of MAC addresses read from a file.
RateControl basic_rate_control_
A rate control class for Discover and Solicit messages.
std::map< uint8_t, dhcp::Pkt4Ptr > template_packets_v4_
First packets send.
int getRequestedIpOffset() const
Returns template offset for requested IP.
int getRequestedIpOffset() const
Return requested ip offset in a packet.
bool isLateSent() const
Returns the value of the late send flag.
int getElapsedTimeOffset() const
Return elapsed time offset in a packet.
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.
int getServerIdOffset() const
Return server id offset in a packet.
bool waitToExit() const
Delay the exit by a fixed given time to catch up to all exchanges that were already started.
uint32_t getSeed() const
Returns random seed.
bool isRapidCommit() const
Check if rapid commit option used.
void reset()
Resets internal state of the object.
Holds information about socket.
static void handleInterrupt(int sig)
Handle interrupt signal.
int getRenewRate() const
Returns a rate at which DHCPv6 Renew messages are sent.
uint32_t getClientsNum() const
Returns number of simulated clients.
Sequential numbers generator class.
short getFamily() const
Returns the address family.
void addExtraOpts(const dhcp::Pkt4Ptr &pkt4)
Inserts extra options specified by user.
uint8_t msg_type_
message type (RELAY-FORW oro RELAY-REPL)
int getPreload() const
Returns number of preload exchanges.
DHCPv4 REQUEST-ACK (renewal)