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;
 
  660    auto flags(std::cout.flags());
 
  661    while (line_len == 32) {
 
  662        if (hex_buf.length() - i < 32) {
 
  663            line_len = hex_buf.length() - i;
 
  666            std::cout << setfill(
'0') << setw(4) << std::hex << i << std::dec
 
  667                      << 
"   " << hex_buf.substr(i, line_len) << std::endl;
 
  672    std::cout.flags(flags);
 
  673    std::cout << std::endl;
 
 
  681    } 
else if (
options_.getIpVersion() == 6) {
 
 
  690    std::string exchange_name = 
"4-way exchanges";
 
  697            exchange_name = 
"DISCOVER-OFFER";
 
  699    } 
else if (
options_.getIpVersion() == 6) {
 
  704            exchange_name = 
options_.isRapidCommit() ? 
"Solicit-Reply" :
 
  709        stats_mgr_.getTestPeriod().length().total_nanoseconds() / 1e9;
 
  710    rate = 
stats_mgr_.getRcvdPacketsNum(xchg_type) / duration;
 
  711    std::ostringstream s;
 
  712    s << 
"***Rate statistics***" << std::endl;
 
  713    s << 
"Rate: " << rate << 
" " << exchange_name << 
"/second";
 
  715        s << 
", expected rate: " << 
options_.getRate() << std::endl;
 
  718    std::cout << s.str() << std::endl;
 
  720    std::cout <<
"***Malformed Packets***" << std::endl
 
 
  727    int delay = 
options_.getReportDelay();
 
  728    ptime now = microsec_clock::universal_time();
 
  730    if (time_since_report.length().total_seconds() >= delay) {
 
  732                                          options_.getCleanReportSeparator());
 
 
  748                        const std::string& separator ) {
 
  749    std::ostringstream stream;
 
  751    for (
auto const& it : vec) {
 
  756            stream << separator << 
byte2Hex(it);
 
  759    return (stream.str());
 
 
  764    std::ifstream temp_file;
 
  765    temp_file.open(file_name.c_str(), ios::in | ios::binary | ios::ate);
 
  766    if (!temp_file.is_open()) {
 
  770    std::streampos temp_size = temp_file.tellg();
 
  771    if (temp_size == std::streampos(0)) {
 
  775    temp_file.seekg(0, ios::beg);
 
  776    std::vector<char> file_contents(temp_size);
 
  777    temp_file.read(&file_contents[0], temp_size);
 
  783    std::vector<char> hex_digits;
 
  784    for (
size_t i = 0; i < file_contents.size(); ++i) {
 
  785        if (isxdigit(file_contents[i])) {
 
  786            hex_digits.push_back(file_contents[i]);
 
  787        } 
else if (!isxdigit(file_contents[i]) &&
 
  788                   !isspace(file_contents[i])) {
 
  790                      " hexadecimal digit");
 
  794    if (hex_digits.size() % 2 != 0) {
 
  796    } 
else if (hex_digits.empty()) {
 
  799    std::vector<uint8_t> binary_stream;
 
  800    for (
size_t i = 0; i < hex_digits.size(); i += 2) {
 
  802        s << 
"0x" << hex_digits[i] << hex_digits[i+1];
 
  805        binary_stream.push_back(
static_cast<uint8_t
>(b));
 
 
  815        Pkt4Ptr discover_pkt4(boost::dynamic_pointer_cast<Pkt4>(pkt));
 
  826    } 
else if (pkt4->getType() == 
DHCPACK) {
 
 
  858        std::set<std::string> current;
 
  861        for (
auto const& opt : pkt6->options_) {
 
  862            switch (opt.second->getType()) {
 
  866                auto ret = current.emplace(boost::dynamic_pointer_cast<
 
  876                auto ret = current.emplace(boost::dynamic_pointer_cast<
 
 
  898        std::set<std::string> current;
 
  899        current.insert(pkt4->getYiaddr().toText());
 
 
  916        iapref = boost::dynamic_pointer_cast<
 
  920        iaaddr = boost::dynamic_pointer_cast<
 
  924    bool address_and_prefix = 
options_.getLeaseType().includes(
 
  926    bool prefix_only = 
options_.getLeaseType().includes(
 
  928    bool address_only = 
options_.getLeaseType().includes(
 
  930    if ((address_and_prefix && iapref && iaaddr) ||
 
  931        (prefix_only && iapref && !address_and_prefix) ||
 
  932        (address_only && iaaddr && !address_and_prefix)) {
 
 
  941    uint8_t packet_type = pkt6->getType();
 
  944        Pkt6Ptr solicit_pkt6(boost::dynamic_pointer_cast<Pkt6>(pkt));
 
 
 1005    unsigned int pkt_count = 0;
 
 1009        if (
options_.getIpVersion() == 4) {
 
 1010            Pkt4Ptr pkt4 = boost::dynamic_pointer_cast<Pkt4>(pkt);
 
 1013            Pkt6Ptr pkt6 = boost::dynamic_pointer_cast<Pkt6>(pkt);
 
 
 1021    static bool factories_registered = 
false;
 
 1022    if (!factories_registered) {
 
 1036    factories_registered = 
true;
 
 
 1041    static bool factories_registered = 
false;
 
 1042    if (!factories_registered) {
 
 1075    factories_registered = 
true;
 
 
 1089                  "before DHCP option factories can be registered");
 
 
 1108    receiver_(socket, options.isSingleThreaded(), options.getIpVersion()),
 
 1119    if (
options_.getIpVersion() == 0) {
 
 1121                  "command options must be parsed before running a test");
 
 1122    } 
else if (
options_.getIpVersion() == 4) {
 
 1132    uint32_t clients_num = 
options_.getClientsNum() == 0 ?
 
 1147        time_period duration(from_iso_string(
"20111231T235959"),
 
 1148                             microsec_clock::universal_time());
 
 1149        srandom(duration.length().total_seconds()
 
 1150                + duration.length().fractional_seconds());
 
 
 1158    if (!
options_.getWrapped().empty()) {
 
 1164        } 
else if (pid == 0) {
 
 1165            execlp(
options_.getWrapped().c_str(), do_stop ? 
"stop" : 
"start", (
void*)0);
 
 
 1191    uint8_t randomized = 0;
 
 1217    pkt4->setHWAddr(
HTYPE_ETHER, mac_address.size(), mac_address);
 
 1224    if (
options_.getIncreaseElapsedTime() &&
 
 1225        stats_mgr_.getTestPeriod().length().total_seconds() >= 
options_.getWaitForElapsedTime() &&
 
 1226        stats_mgr_.getTestPeriod().length().total_seconds() < 
options_.getWaitForElapsedTime() +
 
 1227                                     options_.getIncreaseElapsedTime()) {
 
 1230        uint32_t val = 
stats_mgr_.getTestPeriod().length().total_seconds() - 
options_.getWaitForElapsedTime() + 1;
 
 1234        pkt4->setSecs(
static_cast<uint16_t
>(val));
 
 
 1251                           const bool preload ) {
 
 1254    const uint8_t arg_idx = 0;
 
 1256    uint8_t randomized = 0;
 
 1269    std::vector<uint8_t> in_buf(template_buf.begin(),
 
 1270                                template_buf.end());
 
 1280    pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
 
 1286    socket_.send(boost::static_pointer_cast<Pkt4>(pkt4));
 
 1290                                    boost::static_pointer_cast<Pkt4>(pkt4));
 
 
 1301                  "invalid message type " 
 1303                      << 
" to be sent, expected DHCPREQUEST or DHCPRELEASE");
 
 1317    msg->setGiaddr(ack->getGiaddr());
 
 
 1340                  << 
" to be sent, expected DHCPV6_RENEW or DHCPV6_RELEASE");
 
 
 1370    const uint32_t transid = discover_pkt4->getTransid();
 
 1382        if (!opt_serverid) {
 
 1384                      << 
"in OFFER message");
 
 1389        pkt4->addOption(opt_serverid);
 
 1394    if (!yiaddr.
isV4()) {
 
 1401    opt_requested_address->setUint32(yiaddr.
toUint32());
 
 1402    pkt4->addOption(opt_requested_address);
 
 1405    pkt4->addOption(opt_parameter_list);
 
 1409    pkt4->setGiaddr(offer_pkt4->getGiaddr());
 
 1414    pkt4->setHWAddr(offer_pkt4->getHWAddr());
 
 1419    pkt4->setSecs(
static_cast<uint16_t
>(elapsed_time / 1000));
 
 
 1433    const uint8_t arg_idx = 1;
 
 1435    const uint32_t transid = discover_pkt4->getTransid();
 
 1443    std::vector<uint8_t> in_buf(template_buf.begin(),
 
 1444                                template_buf.end());
 
 1456    HWAddrPtr hwaddr = offer_pkt4->getHWAddr();
 
 1458    uint8_t hw_len = hwaddr->hwaddr_.size();
 
 1460        memcpy(&mac_address[0], &hwaddr->hwaddr_[0],
 
 1463    pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
 
 1468    pkt4->writeValueAt<uint16_t>(elp_offset,
 
 1469                                 static_cast<uint16_t
>(elapsed_time / 1000));
 
 1477        boost::shared_ptr<LocalizedOption>
 
 1482        pkt4->addOption(opt_serverid);
 
 1488        if (!opt_serverid_offer) {
 
 1490                      << 
"in OFFER message");
 
 1492        boost::shared_ptr<LocalizedOption>
 
 1495                                             opt_serverid_offer->getData(),
 
 1497        pkt4->addOption(opt_serverid);
 
 1505    if (!yiaddr.
isV4()) {
 
 1513    boost::shared_ptr<LocalizedOption>
 
 1519    opt_requested_ip->setUint32(yiaddr.
toUint32());
 
 1520    pkt4->addOption(opt_requested_ip);
 
 1529    socket_.send(boost::static_pointer_cast<Pkt4>(pkt4));
 
 1532                               boost::static_pointer_cast<Pkt4>(pkt4));
 
 
 1543    pkt6->addOption(opt_elapsed_time);
 
 1546    if (!opt_clientid) {
 
 1549    pkt6->addOption(opt_clientid);
 
 1559        if (!opt_serverid) {
 
 1565        pkt6->addOption(opt_serverid);
 
 
 1590                          const Pkt6Ptr& advertise_pkt6) {
 
 1593    const uint8_t arg_idx = 1;
 
 1599                                  transid_offset, transid));
 
 1602    boost::shared_ptr<LocalizedOption>
 
 1605    pkt6->addOption(opt_elapsed_time);
 
 1613        boost::shared_ptr<LocalizedOption>
 
 1618        pkt6->addOption(opt_serverid);
 
 1625        if (!opt_serverid_advertise) {
 
 1627                      << 
"in ADVERTISE message");
 
 1629        boost::shared_ptr<LocalizedOption>
 
 1632                                             opt_serverid_advertise->getData(),
 
 1634        pkt6->addOption(opt_serverid);
 
 1641    if (!opt_ia_na_advertise) {
 
 1646    boost::shared_ptr<LocalizedOption>
 
 1648    if (!opt_ia_na->valid()) {
 
 1651    pkt6->addOption(opt_ia_na);
 
 1654    if (!opt_serverid_advertise) {
 
 1659    boost::shared_ptr<LocalizedOption>
 
 1661                                         opt_serverid_advertise->getData(),
 
 1663    pkt6->addOption(opt_serverid);
 
 1667    if (!opt_clientid_advertise) {
 
 1670    rand_offset -= (opt_clientid_advertise->len() - 1);
 
 1672    boost::shared_ptr<LocalizedOption>
 
 1674                                         opt_clientid_advertise->getData(),
 
 1676    pkt6->addOption(opt_clientid);
 
 
 1704    uint8_t randomized = 0;
 
 1715    if (
options_.getIncreaseElapsedTime() &&
 
 1716        stats_mgr_.getTestPeriod().length().total_seconds() >= 
options_.getWaitForElapsedTime() &&
 
 1717        stats_mgr_.getTestPeriod().length().total_seconds() < 
options_.getWaitForElapsedTime() +
 
 1718                                     options_.getIncreaseElapsedTime()) {
 
 1722        uint32_t val = (
stats_mgr_.getTestPeriod().length().total_seconds() - 
options_.getWaitForElapsedTime() + 1)*100;
 
 1727        pkt6->addOption(elapsed);
 
 
 1767                          const bool preload ) {
 
 1768    const int arg_idx = 0;
 
 1775                                  transid_offset, transid));
 
 1783    uint8_t randomized = 0;
 
 1785    if (rand_offset > template_buf.size()) {
 
 1789    pkt6->writeAt(rand_offset - randomized + 1,
 
 1790                  duid.end() - randomized, duid.end());
 
 
 1813    if (iface == NULL) {
 
 1816    pkt->setIface(iface->getName());
 
 1818    pkt->setIndex(
socket_.ifindex_);
 
 1820    pkt->setLocalPort(DHCP4_CLIENT_PORT);
 
 1823        pkt->setRemotePort(
options_.getRemotePort());
 
 1825        pkt->setRemotePort(DHCP4_SERVER_PORT);
 
 1830    pkt->setLocalAddr(
socket_.addr_);
 
 1833    if (!
options_.checkMultiSubnet()) {
 
 1834        pkt->setGiaddr(
socket_.addr_);
 
 
 1846    if (iface == NULL) {
 
 1849    pkt->setIface(iface->getName());
 
 1851    pkt->setIndex(
socket_.ifindex_);
 
 1853    pkt->setLocalPort(DHCP6_CLIENT_PORT);
 
 1856        pkt->setRemotePort(
options_.getRemotePort());
 
 1858        pkt->setRemotePort(DHCP6_SERVER_PORT);
 
 1861    pkt->setLocalAddr(
socket_.addr_);
 
 1879      pkt->addRelayInfo(relay_info);
 
 
 1888    result.insert(result.end(), a.begin(), a.end());
 
 1889    result.insert(result.end(), b.begin(), b.end());
 
 1893static void mergeOptionIntoPacket(
Pkt4Ptr const& packet,
 
 1895    uint16_t 
const code(extra_option->getType());
 
 1897    OptionPtr const& option(packet->getOption(code));
 
 1902            packet->delOption(code);
 
 1903            packet->addOption(boost::make_shared<Option>(
 
 1905                concatenateBuffers(option->getData(),
 
 1906                                   extra_option->getData())));
 
 1914    packet->addOption(extra_option);
 
 1923    for (
auto const& entry : extra_opts) {
 
 1924        mergeOptionIntoPacket(pkt, entry.second);
 
 
 1932    for (
auto const& entry : extra_opts) {
 
 1933        pkt->addOption(entry.second);
 
 
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an object can not be found.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
std::string toText() const
Convert the address to a string.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV4() const
Convenience function to check for an IPv4 address.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
bool configureDHCPPacketQueue(const uint16_t family, data::ConstElementPtr queue_control)
Configures DHCP packet queue.
static void OptionFactoryRegister(Option::Universe u, uint16_t type, Option::Factory *factory)
Registers factory method that produces options of specific option types.
isc::asiolink::IOAddress getAddress() const
Returns address contained within this option.
Class that represents IAPREFIX option in DHCPv6.
Forward declaration to OptionInt.
static OptionPtr factory(Option::Universe u, uint16_t type, const OptionBuffer &buf)
Factory function to create instance of option.
Universe
defines option universe DHCPv4 or DHCPv6
Represents DHCPv4 packet.
Represents a DHCPv6 packet.
Socket wrapper structure.
ExchangeMode
2-way (cmd line param -i) or 4-way exchanges
std::vector< std::vector< uint8_t > > MacAddrsVector
A vector holding MAC addresses.
static int malformed_pkts_
DHCP option at specific offset.
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