libraries/pcappp/include/pcapplusplus/DhcpV6Layer.h

455 lines
16 KiB
C++

#ifndef PACKETPP_DHCPV6_LAYER
#define PACKETPP_DHCPV6_LAYER
#include "Layer.h"
#include "TLVData.h"
/// @file
/**
* \namespace pcpp
* \brief The main namespace for the PcapPlusPlus lib
*/
namespace pcpp
{
/**
* DHCPv6 message types
*/
enum DhcpV6MessageType
{
/** Unknown message type */
DHCPV6_UNKNOWN_MSG_TYPE = 0,
/** Solicit message type (Client to Server) */
DHCPV6_SOLICIT = 1,
/** Advertise message type (Server to Client) */
DHCPV6_ADVERTISE = 2,
/** Request message type (Client to Server) */
DHCPV6_REQUEST = 3,
/** Confirm message type (Client to Server) */
DHCPV6_CONFIRM = 4,
/** Renew message type (Client to Server) */
DHCPV6_RENEW = 5,
/** Rebind message type (Client to Server) */
DHCPV6_REBIND = 6,
/** Reply message type (Server to Client) */
DHCPV6_REPLY = 7,
/** Release message type (Client to Server) */
DHCPV6_RELEASE = 8,
/** Decline message type (Client to Server) */
DHCPV6_DECLINE = 9,
/** Reconfigure message type (Server to Client) */
DHCPV6_RECONFIGURE = 10,
/** Information-Request message type (Client to Server) */
DHCPV6_INFORMATION_REQUEST = 11,
/** Relay-Forward message type (Relay agent to Server) */
DHCPV6_RELAY_FORWARD = 12,
/** Relay-Reply message type (Server to Relay agent) */
DHCPV6_RELAY_REPLY = 13
};
/**
* DHCPv6 option types.
* Resources for more information:
* - https://onlinelibrary.wiley.com/doi/pdf/10.1002/9781118073810.app2
* - https://datatracker.ietf.org/doc/html/rfc5970
* - https://datatracker.ietf.org/doc/html/rfc6607
* - https://datatracker.ietf.org/doc/html/rfc8520
*/
enum DhcpV6OptionType
{
/** Unknown option type */
DHCPV6_OPT_UNKNOWN = 0,
/** Client Identifier (DUID of client) */
DHCPV6_OPT_CLIENTID = 1,
/** Server Identifier (DUID of server) */
DHCPV6_OPT_SERVERID = 2,
/** Identity Association for Non-temporary addresses */
DHCPV6_OPT_IA_NA = 3,
/** Identity Association for Temporary addresses */
DHCPV6_OPT_IA_TA = 4,
/** IA Address option */
DHCPV6_OPT_IAADDR = 5,
/** Option Request Option */
DHCPV6_OPT_ORO = 6,
/** Preference setting */
DHCPV6_OPT_PREFERENCE = 7,
/** The amount of time since the client began the current DHCP transaction */
DHCPV6_OPT_ELAPSED_TIME = 8,
/** The DHCP message being relayed by a relay agent */
DHCPV6_OPT_RELAY_MSG = 9,
/** Authentication information */
DHCPV6_OPT_AUTH = 11,
/** Server unicast */
DHCPV6_OPT_UNICAST = 12,
/** Status code */
DHCPV6_OPT_STATUS_CODE = 13,
/** Rapid commit */
DHCPV6_OPT_RAPID_COMMIT = 14,
/** User class */
DHCPV6_OPT_USER_CLASS = 15,
/** Vendor class */
DHCPV6_OPT_VENDOR_CLASS = 16,
/** Vendor specific information */
DHCPV6_OPT_VENDOR_OPTS = 17,
/** Interface ID */
DHCPV6_OPT_INTERFACE_ID = 18,
/** Reconfigure Message */
DHCPV6_OPT_RECONF_MSG = 19,
/** Reconfigure Accept */
DHCPV6_OPT_RECONF_ACCEPT = 20,
/** SIP Servers Domain Name */
DHCPV6_OPT_SIP_SERVERS_D = 21,
/** SIP Servers IPv6 Address List */
DHCPV6_OPT_SIP_SERVERS_A = 22,
/** DNS Recursive Name Server */
DHCPV6_OPT_DNS_SERVERS = 23,
/** Domain Search List */
DHCPV6_OPT_DOMAIN_LIST = 24,
/** Identity Association for Prefix Delegation */
DHCPV6_OPT_IA_PD = 25,
/** IA_PD Prefix */
DHCPV6_OPT_IAPREFIX = 26,
/** Network Information Service (NIS) Servers */
DHCPV6_OPT_NIS_SERVERS = 27,
/** Network Information Service v2 (NIS+) Servers */
DHCPV6_OPT_NISP_SERVERS = 28,
/** Network Information Service (NIS) domain name */
DHCPV6_OPT_NIS_DOMAIN_NAME = 29,
/** Network Information Service v2 (NIS+) domain name */
DHCPV6_OPT_NISP_DOMAIN_NAME = 30,
/** Simple Network Time Protocol (SNTP) servers */
DHCPV6_OPT_SNTP_SERVERS = 31,
/** Information Refresh */
DHCPV6_OPT_INFORMATION_REFRESH_TIME = 32,
/** Broadcast and Multicast Service (BCMCS) Domain Name List */
DHCPV6_OPT_BCMCS_SERVER_D = 33,
/** Broadcast and Multicast Service (BCMCS) IPv6 Address List */
DHCPV6_OPT_BCMCS_SERVER_A = 34,
/** Geographical location in civic (e.g., postal) format */
DHCPV6_OPT_GEOCONF_CIVIC = 36,
/** Relay Agent Remote ID */
DHCPV6_OPT_REMOTE_ID = 37,
/** Relay Agent Subscriber ID */
DHCPV6_OPT_SUBSCRIBER_ID = 38,
/** FQDN */
DHCPV6_OPT_CLIENT_FQDN = 39,
/** One or more IPv6 addresses associated with PANA (Protocol for carrying Authentication for Network Access) Authentication Agents */
DHCPV6_OPT_PANA_AGENT = 40,
/** Time zone to be used by the client in IEEE 1003.1 format */
DHCPV6_OPT_NEW_POSIX_TIMEZONE = 41,
/** Time zone (TZ) database entry referred to by entry name */
DHCPV6_OPT_NEW_TZDB_TIMEZONE = 42,
/** Relay Agent Echo Request */
DHCPV6_OPT_ERO = 43,
/** Query option */
DHCPV6_OPT_LQ_QUERY = 44,
/** Client Data */
DHCPV6_OPT_CLIENT_DATA = 45,
/** Client Last Transaction Time */
DHCPV6_OPT_CLT_TIME = 46,
/** Relay data */
DHCPV6_OPT_LQ_RELAY_DATA = 47,
/** Client link */
DHCPV6_OPT_LQ_CLIENT_LINK = 48,
/** Mobile IPv6 Home Network Information */
DHCPV6_OPT_MIP6_HNINF = 49,
/** Mobile IPv6 Relay Agent */
DHCPV6_OPT_MIP6_RELAY = 50,
/** Location to Service Translation (LoST) server domain name */
DHCPV6_OPT_V6_LOST = 51,
/** Access Points (CAPWAP) Access Controller IPv6 addresses */
DHCPV6_OPT_CAPWAP_AC_V6 = 52,
/** DHCPv6 Bulk LeaseQuery */
DHCPV6_OPT_RELAY_ID = 53,
/** List of IPv6 addresses for servers providing particular types of IEEE 802.21 Mobility Service (MoS) */
DHCPV6_OPT_IPH6_ADDRESS_MOS = 54,
/** List of FQDNs for servers providing particular types of IEEE 802.21 Mobility Service (MoS) */
DHCPV6_OPT_IPV6_FQDN_MOS = 55,
/** Network Time Protocol (NTP) or Simple NTP (SNTP) Server Location */
DHCPV6_OPT_NTP_SERVER = 56,
/** Boot File Uniform Resource Locator (URL) */
DHCPV6_OPT_BOOTFILE_URL = 59,
/** Boot File Parameters */
DHCPV6_OPT_BOOTFILE_PARAM = 60,
/** Client System Architecture Type */
DHCPV6_OPT_CLIENT_ARCH_TYPE = 61,
/** Client Network Interface Identifier */
DHCPV6_OPT_NII = 62,
/** ERP Local Domain Name */
DHCPV6_OPT_ERP_LOCAL_DOMAIN_NAME = 65,
/** Relay supplied options */
DHCPV6_OPT_RELAY_SUPPLIED_OPTIONS = 66,
/** Virtual Subnet Selection */
DHCPV6_OPT_VSS = 68,
/** Client link layer */
DHCPV6_OPT_CLIENT_LINKLAYER_ADDR = 79,
/** Manufacturer Usage Description */
DHCPV6_OPT_MUD_URL = 112
};
/**
* @class DhcpV6Option
* A wrapper class for DHCPv6 options. This class does not create or modify DHCP option records, but rather
* serves as a wrapper and provides useful methods for setting and retrieving data to/from them
*/
class DhcpV6Option : public TLVRecord<uint16_t, uint16_t>
{
public:
/**
* A c'tor for this class that gets a pointer to the option raw data (byte array)
* @param[in] optionRawData A pointer to the option raw data
*/
DhcpV6Option(uint8_t* optionRawData) : TLVRecord(optionRawData) { }
/**
* A d'tor for this class, currently does nothing
*/
virtual ~DhcpV6Option() { }
/**
* @return The option type converted to ::DhcpV6OptionType enum
*/
DhcpV6OptionType getType() const;
/**
* @return The raw option value (byte array) as a hex string
*/
std::string getValueAsHexString() const;
// implement abstract methods
size_t getTotalSize() const;
size_t getDataSize() const;
};
/**
* @class DhcpV6OptionBuilder
* A class for building DHCPv6 options. This builder receives the option parameters in its c'tor,
* builds the DHCPv6 option raw buffer and provides a build() method to get a DhcpV6Option object out of it
*/
class DhcpV6OptionBuilder : public TLVRecordBuilder
{
public:
/**
* A c'tor for building DHCPv6 options from a string representing the hex stream of the raw byte value.
* The DhcpV6Option object can later be retrieved by calling build()
* @param[in] optionType DHCPv6 option type
* @param[in] optionValueAsHexStream The value as a hex stream string
*/
DhcpV6OptionBuilder(DhcpV6OptionType optionType, const std::string& optionValueAsHexStream) :
TLVRecordBuilder(static_cast<uint16_t>(optionType), optionValueAsHexStream, true) { }
/**
* A c'tor for building DHCPv6 options from a byte array representing their value. The DhcpV6Option object can be later
* retrieved by calling build()
* @param[in] optionType DHCPv6 option type
* @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in any way.
* @param[in] optionValueLen Option value length in bytes
*/
DhcpV6OptionBuilder(DhcpV6OptionType optionType, const uint8_t* optionValue, uint8_t optionValueLen) :
TLVRecordBuilder(static_cast<uint16_t>(optionType), optionValue, optionValueLen) {}
/**
* Build the DhcpV6Option object out of the parameters defined in the c'tor
* @return The DhcpV6Option object
*/
DhcpV6Option build() const;
};
/**
* @struct dhcpv6_header
* Represents the basic DHCPv6 protocol header
*/
struct dhcpv6_header
{
/** DHCPv6 message type */
uint8_t messageType;
/** DHCPv6 transaction ID (first byte) */
uint8_t transactionId1;
/** DHCPv6 transaction ID (second byte) */
uint8_t transactionId2;
/** DHCPv6 transaction ID (last byte) */
uint8_t transactionId3;
};
/**
* @class DhcpV6Layer
* Represents a DHCPv6 (Dynamic Host Configuration Protocol version 6) protocol layer
*/
class DhcpV6Layer : public Layer
{
public:
/**
* A constructor that creates the layer from an existing packet raw data
* @param[in] data A pointer to the raw data
* @param[in] dataLen Size of the data in bytes
* @param[in] prevLayer A pointer to the previous layer
* @param[in] packet A pointer to the Packet instance where layer will be stored in
*/
DhcpV6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
/**
* A constructor that creates the layer from scratch
* @param[in] messageType A DHCPv6 message type to be set
* @param[in] transactionId The transaction ID to be set. Notice the transaction ID is 3-byte long so the value shouldn't exceed 0xFFFFFF
*/
DhcpV6Layer(DhcpV6MessageType messageType, uint32_t transactionId);
/**
* @return The message type of this DHCPv6 message
*/
DhcpV6MessageType getMessageType() const;
/**
* @return The string value of the message type of this DHCPv6 message
*/
std::string getMessageTypeAsString() const;
/**
* Set the message type for this layer
* @param[in] messageType The message type to set
* @return No return value
*/
void setMessageType(DhcpV6MessageType messageType);
/**
* @return The transaction ID of this DHCPv6 message
*/
uint32_t getTransactionID() const;
/**
* Set the transaction ID for this DHCPv6 message
* @param[in] transactionId The transaction ID value to set
* @return No return value
*/
void setTransactionID(uint32_t transactionId) const;
/**
* @return The first DHCPv6 option in the packet. If there are no DHCPv6 options the returned value will contain
* a logical NULL (DhcpV6Option#isNull() == true)
*/
DhcpV6Option getFirstOptionData() const;
/**
* Get the DHCPv6 option that comes after a given option. If the given option was the last one, the
* returned value will contain a logical NULL (DhcpV6Option#isNull() == true)
* @param[in] dhcpv6Option A given DHCPv6 option
* @return A DhcpV6Option object containing the option data that comes next, or logical NULL if the given DHCPv6
* option: (1) was the last one; (2) contains a logical NULL or (3) doesn't belong to this packet
*/
DhcpV6Option getNextOptionData(DhcpV6Option dhcpv6Option) const;
/**
* Get a DHCPv6 option by type
* @param[in] option DHCPv6 option type
* @return A DhcpV6OptionType object containing the first DHCP option data that matches this type, or logical NULL
* (DhcpV6Option#isNull() == true) if no such option found
*/
DhcpV6Option getOptionData(DhcpV6OptionType option) const;
/**
* @return The number of DHCPv6 options in this layer
*/
size_t getOptionCount() const;
/**
* Add a new DHCPv6 option at the end of the layer
* @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add
* @return A DhcpV6Option object containing the newly added DHCP option data or logical NULL
* (DhcpV6Option#isNull() == true) if addition failed
*/
DhcpV6Option addOption(const DhcpV6OptionBuilder& optionBuilder);
/**
* Add a new DHCPv6 option after an existing one
* @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add
* @param[in] optionType The DHCPv6 option type which the newly added option will come after
* @return A DhcpV6Option object containing the newly added DHCPv6 option data or logical NULL
* (DhcpV6Option#isNull() == true) if addition failed
*/
DhcpV6Option addOptionAfter(const DhcpV6OptionBuilder& optionBuilder, DhcpV6OptionType optionType);
/**
* Add a new DHCPv6 option before an existing one
* @param[in] optionBuilder A DhcpV6OptionBuilder object that contains the requested DHCPv6 option data to add
* @param[in] optionType The DHCPv6 option type which the newly added option will come before
* @return A DhcpV6Option object containing the newly added DHCPv6 option data or logical NULL
* (DhcpV6Option#isNull() == true) if addition failed
*/
DhcpV6Option addOptionBefore(const DhcpV6OptionBuilder& optionBuilder, DhcpV6OptionType optionType);
/**
* Remove an existing DHCPv6 option from the layer
* @param[in] optionType The DHCPv6 option type to remove
* @return True if DHCPv6 option was successfully removed or false if type wasn't found or if removal failed
*/
bool removeOption(DhcpV6OptionType optionType);
/**
* Remove all DHCPv6 options in this layer
* @return True if all DHCPv6 options were successfully removed or false if removal failed for some reason
*/
bool removeAllOptions();
/**
* A static method that checks whether a port is considered as a DHCPv6 port
* @param[in] port The port number to check
* @return True if this is a DHCPv6 port number, false otherwise
*/
static inline bool isDhcpV6Port(uint16_t port);
/**
* A static method that validates the input data
* @param[in] data The pointer to the beginning of a byte stream of an DHCPv6 layer
* @param[in] dataLen The length of the byte stream
* @return True if the data is valid and can represent an DHCPv6 layer
*/
static inline bool isDataValid(const uint8_t* data, size_t dataLen);
// implement abstract methods
/**
* Does nothing for this layer (DhcpV6Layer is always last)
*/
void parseNextLayer() {}
/**
* @return The size of @ref dhcpv6_header + size of options
*/
size_t getHeaderLen() const { return m_DataLen; }
/**
* Does nothing for this layer
*/
void computeCalculateFields() {}
std::string toString() const;
OsiModelLayer getOsiModelLayer() const { return OsiModelApplicationLayer; }
private:
uint8_t* getOptionsBasePtr() const { return m_Data + sizeof(dhcpv6_header); }
dhcpv6_header* getDhcpHeader() const { return (dhcpv6_header*)m_Data; }
DhcpV6Option addOptionAt(const DhcpV6OptionBuilder& optionBuilder, int offset);
TLVRecordReader<DhcpV6Option> m_OptionReader;
};
// implementation of inline methods
bool DhcpV6Layer::isDhcpV6Port(uint16_t port)
{
return (port == 546) || (port == 547);
}
bool DhcpV6Layer::isDataValid(const uint8_t* data, size_t dataLen)
{
return dataLen >= sizeof(dhcpv6_header);
}
}
# endif // PACKETPP_DHCPV6_LAYER