- add Pcap++ Windows build
This commit is contained in:
454
pcappp/include/pcapplusplus/DhcpV6Layer.h
Normal file
454
pcappp/include/pcapplusplus/DhcpV6Layer.h
Normal file
@@ -0,0 +1,454 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user