35 Pkt6::RelayInfo::RelayInfo()
43 <<
"), hop-count=" <<
static_cast<int>(hop_count_) <<
"," << endl
44 <<
"link-address=" << linkaddr_.toText()
45 <<
", peer-address=" << peeraddr_.toText() <<
", "
46 <<
options_.size() <<
" option(s)" << endl;
48 tmp << option->second->toText() << endl;
76 Pkt6::prepareGetAnyRelayOption(
const RelaySearchOrder& order,
77 int& start,
int& end,
int& direction)
const {
118 prepareGetAnyRelayOption(order, start, end, direction);
126 for (
int i = start; i != end + direction; i += direction) {
151 prepareGetAnyRelayOption(order, start, end, direction);
159 for (
int i = start; i != end + direction; i += direction) {
173 const uint8_t relay_level)
const {
177 <<
" There is no info about "
178 << relay_level + 1 <<
" relay.");
181 OptionCollection::const_iterator x =
relay_info_[relay_level].options_.find(opt_type);
194 <<
" There is no info about "
195 << relay_level + 1 <<
" relay.");
198 OptionCollection::iterator x =
relay_info_[relay_level].options_.find(opt_type);
201 OptionPtr relay_option_copy = x->second->clone();
202 x->second = relay_option_copy;
214 <<
" There is no info about " << relay_level + 1 <<
" relay.");
224 <<
" There is no info about " << relay_level + 1 <<
" relay.");
234 for (OptionCollection::const_iterator opt = relay.
options_.begin();
235 opt != relay.
options_.end(); ++opt) {
236 len += (opt->second)->
len();
246 for (
int relay_index =
relay_info_.size(); relay_index > 0; --relay_index) {
257 for (OptionCollection::const_iterator it =
options_.begin();
260 length += (*it).second->len();
298 for (vector<RelayInfo>::iterator relay =
relay_info_.begin();
305 isc::asiolink::V6ADDRESS_LEN);
307 isc::asiolink::V6ADDRESS_LEN);
314 for (OptionCollection::const_iterator opt =
315 relay->options_.begin();
316 opt != relay->options_.end(); ++opt) {
350 " not implemented yet.");
367 if (
data_.size() < 4) {
369 <<
data_.size() <<
", DHCPv6 header alone has 4 bytes.");
397 OptionBuffer::const_iterator end) {
398 size_t size = std::distance(begin, end);
402 <<
data_.size() <<
", DHCPv6 header alone has 4 bytes.");
408 ((*begin++) << 8) + (*begin++);
446 size_t bufsize =
data_.size();
453 size_t relay_msg_offset = 0;
454 size_t relay_msg_len = 0;
460 offset += isc::asiolink::V6ADDRESS_LEN;
462 offset += isc::asiolink::V6ADDRESS_LEN;
471 &relay_msg_offset, &relay_msg_len);
478 if (relay_msg_offset == 0 || relay_msg_len == 0) {
487 if (relay_msg_len >= bufsize) {
491 uint8_t inner_type =
data_[offset + relay_msg_offset];
492 offset += relay_msg_offset;
493 bufsize = relay_msg_len;
508 if ( (offset ==
data_.size()) && (bufsize == 0) ) {
529 "not implemented yet.");
540 uint8_t hlen = opt_duid->getData().size();
544 vector<uint8_t> hw_addr(hlen, 0);
545 std::vector<unsigned char> duid_data = opt_duid->getData();
555 if (duid_data.size() >= 5) {
557 duid_data.size() - 2);
558 mac.reset(
new HWAddr(&duid_data[4], duid_data.size() - 4, hwtype));
566 if (duid_data.size() >= 9) {
568 duid_data.size() - 2);
569 mac.reset(
new HWAddr(&duid_data[8], duid_data.size() - 8, hwtype));
588 std::stringstream label;
592 label <<
", tid=0x" << std::hex << transid << std::dec;
594 return (label.str());
599 std::stringstream label;
602 label <<
"duid=[" << (duid ? duid->toText() :
"no info")
609 label <<
", [" << hwaddr->toText() <<
"]";
612 return (label.str());
631 <<
"), transid=0x" <<
635 for (isc::dhcp::OptionCollection::const_iterator opt=
options_.begin();
638 tmp << opt->second->toText() << std::endl;
646 tmp <<
"relay[" << cnt++ <<
"]: " << relay->toText();
649 tmp <<
"No relays traversed." << endl;
673 std::pair<OptionCollection::const_iterator,
674 OptionCollection::const_iterator> range =
options_.equal_range(opt_type);
682 std::pair<OptionCollection::iterator,
683 OptionCollection::iterator> range =
options_.equal_range(opt_type);
688 for (OptionCollection::iterator opt_it = range.first;
689 opt_it != range.second; ++opt_it) {
690 OptionPtr option_copy = opt_it->second->clone();
691 opt_it->second = option_copy;
700 static const char* ADVERTISE =
"ADVERTISE";
701 static const char* CONFIRM =
"CONFIRM";
702 static const char* DECLINE =
"DECLINE";
703 static const char* INFORMATION_REQUEST =
"INFORMATION_REQUEST";
704 static const char* LEASEQUERY =
"LEASEQUERY";
705 static const char* LEASEQUERY_REPLY =
"LEASEQUERY_REPLY";
706 static const char* REBIND =
"REBIND";
707 static const char* RECONFIGURE =
"RECONFIGURE";
708 static const char* RELAY_FORW =
"RELAY_FORWARD";
709 static const char* RELAY_REPL =
"RELAY_REPLY";
710 static const char* RELEASE =
"RELEASE";
711 static const char* RENEW =
"RENEW";
712 static const char* REPLY =
"REPLY";
713 static const char* REQUEST =
"REQUEST";
714 static const char* SOLICIT =
"SOLICIT";
715 static const char* DHCPV4_QUERY =
"DHCPV4_QUERY";
716 static const char* DHCPV4_RESPONSE =
"DHCPV4_RESPONSE";
717 static const char* UNKNOWN =
"UNKNOWN";
730 return (INFORMATION_REQUEST);
736 return (LEASEQUERY_REPLY);
742 return (RECONFIGURE);
766 return (DHCPV4_QUERY);
769 return (DHCPV4_RESPONSE);
785 for (
size_t i = 0; i < question->relay_info_.size(); ++i) {
788 info.
hop_count_ = question->relay_info_[i].hop_count_;
789 info.
linkaddr_ = question->relay_info_[i].linkaddr_;
790 info.
peeraddr_ = question->relay_info_[i].peeraddr_;
797 info.
options_.insert(make_pair(opt->getType(), opt));
803 info.
options_.insert(make_pair(opt->getType(), opt));
839 if (data.size() >= 3) {
842 mac.reset(
new HWAddr(&data[0] + 2, data.size() - 2,
865 if (!device_id->getData().empty()) {
892 if (cm_mac && !cm_mac->getData().empty()) {
914 if (data.size() >= 5) {
923 hwtype = iface->getHWType();
927 mac.reset(
new HWAddr(&data[0] + 4, data.size() - 4, hwtype));
OptionCollection getNonCopiedOptions(const uint16_t opt_type) const
Returns all option instances of specified type without copying.
#define DOCSIS3_V6_CMTS_CM_MAC
IfacePtr getIface(int ifindex)
Returns interface specified interface index.
boost::shared_ptr< DUID > DuidPtr
isc::asiolink::IOAddress local_addr_
Local IP (v4 or v6) address.
HWAddrPtr getMACFromIPv6(const isc::asiolink::IOAddress &addr)
Attempts to convert IPv6 address into MAC.
OptionBuffer data_
Unparsed data (in received packets).
A generic exception that is thrown when a function is not implemented.
std::string iface_
Name of the network interface the packet was received/to be sent over.
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...
virtual std::string toText() const
Returns text representation of the packet.
static void packOptions6(isc::util::OutputBuffer &buf, const isc::dhcp::OptionCollection &options)
Stores DHCPv6 options in a buffer.
const isc::asiolink::IOAddress & getRelay6PeerAddress(uint8_t relay_level) const
return the peer address field from a relay option
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
uint16_t getRelayOverhead(const RelayInfo &relay) const
Calculates overhead introduced in specified relay.
uint16_t directLen() const
Calculates size of the message as if it was not relayed at all.
isc::dhcp::OptionCollection options_
options received from a specified relay, except relay-msg option
OptionPtr getOption(uint16_t type) const
Returns shared_ptr to suboption of specific type.
link-layer + time, see RFC3315, section 11.2
void packUDP()
Builds on wire packet for UDP transmission.
uint32_t transid_
Transaction-id (32 bits for v4, 24 bits for v6)
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto=UDP)
Constructor, used in replying to a message.
const IOAddress DEFAULT_ADDRESS6("::")
Default address used in Pkt6 constructor.
Base class for classes representing DHCP messages.
void copyRelayInfo(const Pkt6Ptr &question)
copies relay information from client's packet to server's response
boost::shared_ptr< Option > OptionPtr
void unpackRelayMsg()
Unpacks relayed message (RELAY-FORW or RELAY-REPL).
virtual std::string getLabel() const
Returns text representation of the primary packet identifiers.
#define DOCSIS3_V6_DEVICE_ID
OptionPtr getRelayOption(uint16_t option_code, uint8_t nesting_level)
Returns option inserted by relay.
OptionPtr getNonCopiedOption(const uint16_t type) const
Returns the first option of specified type without copying.
OptionPtr getNonCopiedAnyRelayOption(const uint16_t option_code, const RelaySearchOrder &order) const
Returns pointer to an instance of specified option.
virtual HWAddrPtr getMACFromDocsisCMTS()
Attempts to extract MAC/Hardware address from DOCSIS options.
virtual HWAddrPtr getMACFromSrcLinkLocalAddr()
Attempts to generate MAC/Hardware address from IPv6 link-local address.
static const uint32_t HWADDR_SOURCE_REMOTE_ID
A relay can insert remote-id.
std::vector< RelayInfo > relay_info_
Relay information.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
The traffic captures we have from cable modems as well as this list by IANA: http://www.iana.org/assignments/ arp-parameters/arp-parameters.xhtml suggest that Ethernet (1) should be used in DOCSIS environment.
void unpackUDP()
Parses on-wire form of UDP DHCPv6 packet.
Holds DUID (DHCPv6 Unique Identifier)
static const uint32_t HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION
Get it from RFC6939 option.
const isc::asiolink::IOAddress & getRelay6LinkAddress(uint8_t relay_level) const
return the link address field from a relay option
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.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the 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...
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
structure that describes a single relay information
static const size_t DHCPV6_RELAY_HDR_LEN
specifies relay DHCPv6 packet header length (over UDP)
A generic exception that is thrown when an unexpected error condition occurs.
virtual void unpack()
Dispatch method that handles binary packet parsing.
virtual size_t len()
Returns length of the packet.
OptionPtr getNonCopiedRelayOption(const uint16_t opt_type, const uint8_t relay_level) const
Returns pointer to an option inserted by relay agent.
virtual HWAddrPtr getMACFromDocsisModem()
Attempts to extract MAC/Hardware address from DOCSIS options inserted by the modem itself...
uint8_t msg_type_
DHCPv6 message type.
void clear()
Clear buffer content.
DHCPv6Proto
DHCPv6 transport protocol.
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
std::string toText() const
Returns printable representation of the relay information.
static const size_t DHCPV6_PKT_HDR_LEN
specifies non-relayed DHCPv6 packet header length (over UDP)
virtual void pack()
Prepares on-wire format.
link-layer, see RFC3315, section 11.4
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
virtual HWAddrPtr getMACFromIPv6RelayOpt()
Extract MAC/Hardware address from client link-layer address.
bool copy_retrieved_options_
Indicates if a copy of the retrieved option should be returned when Pkt::getOption is called...
uint16_t remote_port_
remote TCP or UDP port
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...
void packTCP()
Builds on wire packet for TCP transmission.
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 std::string makeLabel(const DuidPtr duid, const uint32_t transid, const HWAddrPtr &hwaddr)
Returns text representation of the given packet identifiers.
void unpackMsg(OptionBuffer::const_iterator begin, OptionBuffer::const_iterator end)
Unpacks direct (non-relayed) message.
RelaySearchOrder
defines relay search pattern
uint16_t local_port_
local TDP or UDP port
uint8_t hop_count_
number of traversed relays (up to 32)
OptionPtr getAnyRelayOption(const uint16_t option_code, const RelaySearchOrder &order)
Return first instance of a specified option.
uint32_t getTransid() const
Returns value of transaction-id field.
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
isc::asiolink::IOAddress remote_addr_
Remote IP address.
#define DHCP6_OPTION_SPACE
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
const char * getName() const
Returns name of the DHCPv6 message.
A generic exception that is thrown if a function is called in a prohibited way.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Hardware type that represents information from DHCPv4 packet.
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order...
isc::dhcp::OptionCollection getOptions(const uint16_t type)
Returns all instances of specified type.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
virtual HWAddrPtr getMACFromDUID()
Extract MAC/Hardware address from client-id.
isc::asiolink::IOAddress linkaddr_
fixed field in relay-forw/relay-reply
DHCPv6Proto proto_
UDP (usually) or TCP (bulk leasequery or failover)
isc::asiolink::IOAddress peeraddr_
fixed field in relay-forw/relay-reply
void unpackTCP()
Parses on-wire form of TCP DHCPv6 packet.
isc::util::OutputBuffer buffer_out_
Output buffer (used during message transmission)
The IOAddress class represents an IP addresses (version agnostic)
uint16_t calculateRelaySizes()
Calculates overhead for all relays defined for this message.
boost::shared_ptr< OptionVendor > OptionVendorPtr
Pointer to a vendor option.
DuidPtr getClientId() const
Retrieves the DUID from the Client Identifier option.
virtual uint8_t getType() const
Returns message type (e.g.
#define VENDOR_ID_CABLE_LABS
void addRelayInfo(const RelayInfo &relay)
add information about one traversed relay
isc::dhcp::OptionCollection options_
Collection of options present in this message.
static const uint32_t HWADDR_SOURCE_DUID
Extracted from DUID-LL or DUID-LLT (not 100% reliable as the client can send fake DUID)...
This class represents vendor-specific information option.
virtual HWAddrPtr getMACFromRemoteIdRelayOption()
Attempts to obtain MAC address from remote-id relay option.
static const size_t OPTION6_HDR_LEN
length of any DHCPv6 option header
uint8_t msg_type_
message type (RELAY-FORW oro RELAY-REPL)