21#include <boost/foreach.hpp> 
   43        << 
"), hop-count=" << 
static_cast<int>(
hop_count_)  << 
"," << endl
 
   45        << 
", peer-address=" << 
peeraddr_.toText() << 
", " 
   46        << 
options_.size() << 
" option(s)" << endl;
 
   47    for (
auto const& option : 
options_) {
 
   48        tmp << option.second->toText() << endl;
 
 
   76Pkt6::prepareGetAnyRelayOption(
const RelaySearchOrder& order,
 
   77                               int& start, 
int& end, 
int& direction)
 const {
 
  117    prepareGetAnyRelayOption(order, start, end, direction);
 
  125    for (
int i = start; i != end + direction; i += direction) {
 
 
  150    prepareGetAnyRelayOption(order, start, end, direction);
 
  158    for (
int i = start; i != end + direction; i += direction) {
 
 
  182    prepareGetAnyRelayOption(order, start, end, direction);
 
  191    for (
int i = start; i != end + direction; i += direction) {
 
  192        std::pair<OptionCollection::const_iterator,
 
  193                  OptionCollection::const_iterator> range =
 
  195        opts.insert(range.first, range.second);
 
 
  213    prepareGetAnyRelayOption(order, start, end, direction);
 
  222    for (
int i = start; i != end + direction; i += direction) {
 
  223        std::pair<OptionCollection::iterator,
 
  224                  OptionCollection::iterator> range =
 
  230            BOOST_FOREACH(
auto& opt_it, range) {
 
  231                OptionPtr option_copy = opt_it.second->clone();
 
  232                opt_it.second = option_copy;
 
  235        opts.insert(range.first, range.second);
 
 
  242                              const uint8_t relay_level)
 const {
 
  246                  << 
" There is no info about " 
  247                  << relay_level + 1 << 
" relay.");
 
  250    OptionCollection::const_iterator x = 
relay_info_[relay_level].options_.find(opt_type);
 
 
  263                  << 
" There is no info about " 
  264                  << relay_level + 1 << 
" relay.");
 
  267    OptionCollection::iterator x = 
relay_info_[relay_level].options_.find(opt_type);
 
  270            OptionPtr relay_option_copy = x->second->clone();
 
  271            x->second = relay_option_copy;
 
 
  281                               const uint8_t relay_level)
 const {
 
  285                  << 
" There is no info about " 
  286                  << relay_level + 1 << 
" relay.");
 
  289    std::pair<OptionCollection::const_iterator,
 
  290              OptionCollection::const_iterator> range =
 
  291        relay_info_[relay_level].options_.equal_range(opt_type);
 
 
  297                      const uint8_t relay_level) {
 
  301                  << 
" There is no info about " 
  302                  << relay_level + 1 << 
" relay.");
 
  307    std::pair<OptionCollection::iterator,
 
  308              OptionCollection::iterator> range =
 
  309        relay_info_[relay_level].options_.equal_range(opt_type);
 
  314        BOOST_FOREACH(
auto& opt_it, range) {
 
  315            OptionPtr option_copy = opt_it.second->clone();
 
  316            opt_it.second = option_copy;
 
 
  327                  << 
" There is no info about " << relay_level + 1 << 
" relay.");
 
 
  337                  << 
" There is no info about " << relay_level + 1 << 
" relay.");
 
 
  347    for (
auto const& opt : relay.
options_) {
 
  348        len += (opt.second)->
len();
 
 
  358    for (
int relay_index = 
relay_info_.size(); relay_index > 0; --relay_index) {
 
 
  370        length += it.second->len();
 
 
  412                buffer_out_.writeData(&(relay.linkaddr_.toBytes()[0]),
 
  413                                     isc::asiolink::V6ADDRESS_LEN);
 
  414                buffer_out_.writeData(&relay.peeraddr_.toBytes()[0],
 
  415                                     isc::asiolink::V6ADDRESS_LEN);
 
  422                for (
auto const& opt : relay.options_) {
 
 
  456              " not implemented yet.");
 
 
  473    if (
data_.size() < 4) {
 
  475                  << 
data_.size() << 
", DHCPv6 header alone has 4 bytes.");
 
 
  505                OptionBuffer::const_iterator end) {
 
  506    size_t size = std::distance(begin, end);
 
  510                  << 
data_.size() << 
", DHCPv6 header alone has 4 bytes.");
 
  516        ((*begin++) << 8) + (*begin++);
 
 
  554    size_t bufsize = 
data_.size();
 
  561        size_t relay_msg_offset = 0;
 
  562        size_t relay_msg_len = 0;
 
  568        offset += isc::asiolink::V6ADDRESS_LEN;
 
  570        offset += isc::asiolink::V6ADDRESS_LEN;
 
  579                                &relay_msg_offset, &relay_msg_len);
 
  586        if (relay_msg_offset == 0 || relay_msg_len == 0) {
 
  595        if (relay_msg_len >= bufsize) {
 
  599        uint8_t inner_type = 
data_[offset + relay_msg_offset];
 
  600        offset += relay_msg_offset; 
 
  601        bufsize = relay_msg_len;    
 
  616    if ( (offset == 
data_.size()) && (bufsize == 0) ) {
 
 
  637              "not implemented yet.");
 
 
  648    uint8_t hlen = opt_duid->getData().size();
 
  652    vector<uint8_t> hw_addr(hlen, 0);
 
  653    std::vector<unsigned char> duid_data = opt_duid->getData();
 
  663        if (duid_data.size() >= 5) {
 
  665                                               duid_data.size() - 2);
 
  666            mac.reset(
new HWAddr(&duid_data[4], duid_data.size() - 4, hwtype));
 
  674        if (duid_data.size() >= 9) {
 
  676                                               duid_data.size() - 2);
 
  677            mac.reset(
new HWAddr(&duid_data[8], duid_data.size() - 8, hwtype));
 
 
  696    std::stringstream label;
 
  700    label << 
", tid=0x" << std::hex << transid << std::dec;
 
  702    return (label.str());
 
 
  707    std::stringstream label;
 
  713    label << 
"duid=[" << (duid ? duid->toText() : 
"no info")
 
  714          << 
"], [" << (hwaddr ? hwaddr->toText() : 
"no hwaddr info") << 
"]";
 
  716    return (label.str());
 
 
  736    tmp << 
", trans_id=0x" << hex << 
transid_ << dec;
 
  739        tmp << 
"," << endl << 
"options:";
 
  742                tmp << endl << opt.second->toText(2);
 
  744                tmp << 
"(unknown)" << endl;
 
  749        tmp << 
"," << endl << 
"message contains no options";
 
  754        tmp << endl << 
relay_info_.size() << 
" relay(s):" << endl;
 
  757            tmp << 
"relay[" << cnt++ << 
"]: " << relay.toText();
 
  760        tmp << endl << 
"No relays traversed." << endl;
 
 
  785    static const char* ADVERTISE = 
"ADVERTISE";
 
  786    static const char* CONFIRM = 
"CONFIRM";
 
  787    static const char* DECLINE = 
"DECLINE";
 
  788    static const char* INFORMATION_REQUEST = 
"INFORMATION_REQUEST";
 
  789    static const char* LEASEQUERY = 
"LEASEQUERY";
 
  790    static const char* LEASEQUERY_DATA = 
"LEASEQUERY_DATA";
 
  791    static const char* LEASEQUERY_DONE = 
"LEASEQUERY_DONE";
 
  792    static const char* LEASEQUERY_REPLY = 
"LEASEQUERY_REPLY";
 
  793    static const char* REBIND = 
"REBIND";
 
  794    static const char* RECONFIGURE = 
"RECONFIGURE";
 
  795    static const char* RELAY_FORW = 
"RELAY_FORWARD";
 
  796    static const char* RELAY_REPL = 
"RELAY_REPLY";
 
  797    static const char* 
RELEASE = 
"RELEASE";
 
  798    static const char* RENEW = 
"RENEW";
 
  799    static const char* REPLY = 
"REPLY";
 
  800    static const char* REQUEST = 
"REQUEST";
 
  801    static const char* SOLICIT = 
"SOLICIT";
 
  802    static const char* DHCPV4_QUERY = 
"DHCPV4_QUERY";
 
  803    static const char* DHCPV4_RESPONSE = 
"DHCPV4_RESPONSE";
 
  804    static const char* ADDR_REG_INFORM = 
"ADDR_REG_INFORM";
 
  805    static const char* ADDR_REG_REPLY = 
"ADDR_REG_REPLY";
 
  806    static const char* UNKNOWN = 
"UNKNOWN";
 
  819        return (INFORMATION_REQUEST);
 
  825        return (LEASEQUERY_DATA);
 
  828        return (LEASEQUERY_DONE);
 
  831        return (LEASEQUERY_REPLY);
 
  837        return (RECONFIGURE);
 
  861        return (DHCPV4_QUERY);
 
  864        return (DHCPV4_RESPONSE);
 
  867        return (ADDR_REG_INFORM);
 
  870        return (ADDR_REG_REPLY);
 
 
  886    for (
size_t i = 0; i < question->relay_info_.size(); ++i) {
 
  889        info.hop_count_ = question->relay_info_[i].hop_count_;
 
  890        info.linkaddr_ = question->relay_info_[i].linkaddr_;
 
  891        info.peeraddr_ = question->relay_info_[i].peeraddr_;
 
  898            info.options_.insert(make_pair(opt->getType(), opt));
 
  904            info.options_.insert(make_pair(opt->getType(), opt));
 
 
  940            if (
data.size() >= 3) {
 
 
  962        vendor = boost::dynamic_pointer_cast< OptionVendor>(opt.second);
 
  971            if (!device_id->getData().empty()) {
 
 
  997        vendor = boost::dynamic_pointer_cast< OptionVendor>(opt.second);
 
 1006        if (cm_mac && !cm_mac->getData().empty()) {
 
 
 1028            if (
data.size() >= 5) {
 
 1032                uint16_t hwtype = 0; 
 
 1037                    hwtype = iface->getHWType();
 
 
boost::shared_ptr< Option > OptionPtr
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 when a function is not implemented.
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)
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
Holds DUID (DHCPv6 Unique Identifier)
@ DUID_LL
link-layer, see RFC3315, section 11.4
@ DUID_LLT
link-layer + time, see RFC3315, section 11.2
IfacePtr getIface(const unsigned int ifindex)
Returns interface specified interface index.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
static size_t unpackOptions6(const OptionBuffer &buf, const std::string &option_space, isc::dhcp::OptionCollection &options, size_t *relay_msg_offset=0, size_t *relay_msg_len=0)
Parses provided buffer as DHCPv6 options and creates Option objects.
static void packOptions6(isc::util::OutputBuffer &buf, const isc::dhcp::OptionCollection &options)
Stores DHCPv6 options in a buffer.
static const size_t OPTION6_HDR_LEN
length of any DHCPv6 option header
virtual std::string toText() const
Returns text representation of the packet.
uint16_t calculateRelaySizes()
Calculates overhead for all relays defined for this message.
virtual HWAddrPtr getMACFromIPv6RelayOpt()
Extract MAC/Hardware address from client link-layer address.
DHCPv6Proto
DHCPv6 transport protocol.
virtual std::string getLabel() const
Returns text representation of the primary packet identifiers.
OptionCollection getRelayOptions(uint16_t option_code, uint8_t nesting_level)
Returns options inserted by relay.
static const size_t DHCPV6_PKT_HDR_LEN
specifies non-relayed DHCPv6 packet header length (over UDP)
virtual size_t len()
Returns length of the packet.
virtual void pack()
Prepares on-wire format.
OptionPtr getRelayOption(uint16_t option_code, uint8_t nesting_level)
Returns option inserted by relay.
virtual HWAddrPtr getMACFromRemoteIdRelayOption()
Attempts to obtain MAC address from remote-id relay option.
void unpackTCP()
Parses on-wire form of TCP DHCPv6 packet.
const char * getName() const
Returns name of the DHCPv6 message.
virtual HWAddrPtr getMACFromSrcLinkLocalAddr()
Attempts to generate MAC/Hardware address from IPv6 link-local address.
OptionPtr getNonCopiedRelayOption(const uint16_t opt_type, const uint8_t relay_level) const
Returns pointer to an option inserted by relay agent.
void unpackRelayMsg()
Unpacks relayed message (RELAY-FORW or RELAY-REPL).
RelaySearchOrder
defines relay search pattern
@ RELAY_SEARCH_FROM_CLIENT
@ RELAY_SEARCH_FROM_SERVER
static std::string makeLabel(const DuidPtr duid, const uint32_t transid, const HWAddrPtr &hwaddr)
Returns text representation of the given packet identifiers.
OptionPtr getAnyRelayOption(const uint16_t option_code, const RelaySearchOrder &order)
Return first instance of a specified option.
DuidPtr getClientId() const
Retrieves the DUID from the Client Identifier option.
void packTCP()
Builds on wire packet for TCP transmission.
OptionPtr getNonCopiedAnyRelayOption(const uint16_t option_code, const RelaySearchOrder &order) const
Returns pointer to an instance of specified option.
void copyRelayInfo(const Pkt6Ptr &question)
copies relay information from client's packet to server's response
DHCPv6Proto proto_
UDP (usually) or TCP (bulk leasequery or failover)
const isc::asiolink::IOAddress & getRelay6PeerAddress(uint8_t relay_level) const
return the peer address field from a relay option
virtual void unpack()
Dispatch method that handles binary packet parsing.
OptionCollection getAllRelayOptions(const uint16_t option_code, const RelaySearchOrder &order)
Return first instances of a specified option.
virtual HWAddrPtr getMACFromDUID()
Extract MAC/Hardware address from client-id.
virtual HWAddrPtr getMACFromDocsisCMTS()
Attempts to extract MAC/Hardware address from DOCSIS options.
const isc::asiolink::IOAddress & getRelay6LinkAddress(uint8_t relay_level) const
return the link address field from a relay option
OptionCollection getNonCopiedAllRelayOptions(const uint16_t option_code, const RelaySearchOrder &order) const
Returns pointers to instances of specified option.
std::vector< RelayInfo > relay_info_
Relay information.
uint8_t msg_type_
DHCPv6 message type.
Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto=UDP)
Constructor, used in replying to a message.
void addRelayInfo(const RelayInfo &relay)
add information about one traversed relay
virtual HWAddrPtr getMACFromDocsisModem()
Attempts to extract MAC/Hardware address from DOCSIS options inserted by the modem itself.
OptionCollection getNonCopiedRelayOptions(const uint16_t opt_type, const uint8_t relay_level) const
Returns all option instances inserted by relay agent.
void packUDP()
Builds on wire packet for UDP transmission.
void unpackUDP()
Parses on-wire form of UDP DHCPv6 packet.
void unpackMsg(OptionBuffer::const_iterator begin, OptionBuffer::const_iterator end)
Unpacks direct (non-relayed) message.
uint16_t directLen() const
Calculates size of the message as if it was not relayed at all.
uint16_t getRelayOverhead(const RelayInfo &relay) const
Calculates overhead introduced in specified relay.
virtual uint8_t getType() const
Returns message type (e.g.
static const size_t DHCPV6_RELAY_HDR_LEN
specifies relay DHCPv6 packet header length (over UDP)
isc::asiolink::IOAddress remote_addr_
Remote IP address.
uint16_t local_port_
local TDP or UDP port
uint32_t transid_
Transaction-id (32 bits for v4, 24 bits for v6)
isc::asiolink::IOAddress local_addr_
Local IP (v4 or v6) address.
OptionBuffer data_
Unparsed data (in received packets).
uint16_t remote_port_
remote TCP or UDP port
uint32_t getTransid() const
Returns value of transaction-id field.
isc::dhcp::OptionCollection options_
Collection of options present in this message.
isc::util::OutputBuffer buffer_out_
Output buffer (used during message transmission)
OptionCollection getNonCopiedOptions(const uint16_t opt_type) const
Returns all option instances of specified type without copying.
Pkt(uint32_t transid, const isc::asiolink::IOAddress &local_addr, const isc::asiolink::IOAddress &remote_addr, uint16_t local_port, uint16_t remote_port)
Constructor.
bool copy_retrieved_options_
Indicates if a copy of the retrieved option should be returned when Pkt::getOption is called.
std::string iface_
Name of the network interface the packet was received/to be sent over.
OptionPtr getNonCopiedOption(const uint16_t type) const
Returns the first option of specified type without copying.
HWAddrPtr getMACFromIPv6(const isc::asiolink::IOAddress &addr)
Attempts to convert IPv6 address into MAC.
@ D6O_CLIENT_LINKLAYER_ADDR
@ DHCPV6_INFORMATION_REQUEST
@ DHCPV6_LEASEQUERY_REPLY
#define VENDOR_ID_CABLE_LABS
#define DOCSIS3_V6_CMTS_CM_MAC
#define DOCSIS3_V6_DEVICE_ID
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
static const uint32_t HWADDR_SOURCE_REMOTE_ID
A relay can insert remote-id.
static const uint32_t HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION
Get it from RFC6939 option.
static const uint32_t HWADDR_SOURCE_DOCSIS_MODEM
A cable modem (acting as DHCP client) that supports DOCSIS standard can insert DOCSIS options that co...
static const uint32_t HWADDR_SOURCE_DUID
Extracted from DUID-LL or DUID-LLT (not 100% reliable as the client can send fake DUID).
static const uint32_t HWADDR_SOURCE_DOCSIS_CMTS
A CMTS (acting as DHCP relay agent) that supports DOCSIS standard can insert DOCSIS options that cont...
boost::shared_ptr< OptionVendor > OptionVendorPtr
Pointer to a vendor option.
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
boost::shared_ptr< DUID > DuidPtr
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_DOCSIS
The traffic captures we have from cable modems as well as this list by IANA: http://www....
boost::shared_ptr< Option > OptionPtr
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
Defines the logger used by the top-level component of kea-lfc.
const IOAddress DEFAULT_ADDRESS6("::")
Default address used in Pkt6 constructor.
#define DHCP6_OPTION_SPACE
Hardware type that represents information from DHCPv4 packet.
static const size_t MAX_HWADDR_LEN
Maximum size of a hardware address.
structure that describes a single relay information
RelayInfo()
default constructor
uint16_t relay_msg_len_
length of the relay_msg_len Used when calculating length during pack/unpack
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)
std::string toText() const
Returns printable representation of the relay information.
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