You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2017/11/14 01:48:32 UTC
[18/25] nifi-minifi-cpp git commit: MINIFICPP-250: Initial
implementation fo CapturePacket Processor that uses lipcap.
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/IcmpLayer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/IcmpLayer.h b/thirdparty/pcap++/Packet++/header/IcmpLayer.h
new file mode 100644
index 0000000..c2d3400
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/IcmpLayer.h
@@ -0,0 +1,703 @@
+#ifndef PACKETPP_ICMP_LAYER
+#define PACKETPP_ICMP_LAYER
+
+#include <Layer.h>
+#include <IPv4Layer.h>
+#ifdef _MSC_VER
+#include <Winsock2.h>
+#else
+#include <sys/time.h>
+#endif
+#include <vector>
+
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+ /**
+ * @struct icmphdr
+ * Represents ICMP basic protocol header (common for all ICMP message types)
+ */
+#pragma pack(push, 1)
+ typedef struct
+ {
+ /** message type */
+ uint8_t type;
+ /** message code */
+ uint8_t code;
+ /** message checksum */
+ uint16_t checksum;
+ } icmphdr;
+#pragma pack(pop)
+
+ /**
+ * An enum of all supported ICMP message types
+ */
+ enum IcmpMessageType
+ {
+ /** ICMP echo (ping) reply message */
+ ICMP_ECHO_REPLY = 0,
+ /** ICMP destination unreachable message */
+ ICMP_DEST_UNREACHABLE = 3,
+ /** ICMP source quench message */
+ ICMP_SOURCE_QUENCH = 4,
+ /** ICMP redirect message */
+ ICMP_REDIRECT = 5,
+ /** ICMP echo (ping) request message */
+ ICMP_ECHO_REQUEST = 8,
+ /** ICMP router advertisement message */
+ ICMP_ROUTER_ADV = 9,
+ /** ICMP router soliciatation message */
+ ICMP_ROUTER_SOL = 10,
+ /** ICMP time-to-live excceded message */
+ ICMP_TIME_EXCEEDED = 11,
+ /** ICMP parameter problem message */
+ ICMP_PARAM_PROBLEM = 12,
+ /** ICMP timestamp request message */
+ ICMP_TIMESTAMP_REQUEST = 13,
+ /** ICMP timestamp reply message */
+ ICMP_TIMESTAMP_REPLY = 14,
+ /** ICMP information request message */
+ ICMP_INFO_REQUEST = 15,
+ /** ICMP information reply message */
+ ICMP_INFO_REPLY = 16,
+ /** ICMP address mask request message */
+ ICMP_ADDRESS_MASK_REQUEST = 17,
+ /** ICMP address mask reply message */
+ ICMP_ADDRESS_MASK_REPLY = 18,
+ /** ICMP message type unsupported by PcapPlusPlus */
+ ICMP_UNSUPPORTED = 255
+ };
+
+ /**
+ * An enum for all possible codes for a destination unreachable message type
+ * Documentation is taken from Wikipedia: https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
+ */
+ enum IcmpDestUnreachableCodes
+ {
+ /** Network unreachable error */
+ IcmpNetworkUnreachable = 0,
+ /** Host unreachable error */
+ IcmpHostUnreachable = 1,
+ /** Protocol unreachable error (the designated transport protocol is not supported) */
+ IcmpProtocolUnreachable = 2,
+ /** Port unreachable error (the designated protocol is unable to inform the host of the incoming message) */
+ IcmpPortUnreachable = 3,
+ /** The datagram is too big. Packet fragmentation is required but the 'don't fragment' (DF) flag is on */
+ IcmpDatagramTooBig = 4,
+ /** Source route failed error */
+ IcmpSourceRouteFailed = 5,
+ /** Destination network unknown error */
+ IcmpDestinationNetworkUnknown = 6,
+ /** Destination host unknown error */
+ IcmpDestinationHostUnknown = 7,
+ /** Source host isolated error */
+ IcmpSourceHostIsolated = 8,
+ /** The destination network is administratively prohibited */
+ IcmpDestinationNetworkProhibited = 9,
+ /** The destination host is administratively prohibited */
+ IcmpDestinationHostProhibited = 10,
+ /** The network is unreachable for Type Of Service */
+ IcmpNetworkUnreachableForTypeOfService = 11,
+ /** The host is unreachable for Type Of Service */
+ IcmpHostUnreachableForTypeOfService = 12,
+ /** Communication administratively prohibited (administrative filtering prevents
+ * packet from being forwarded)
+ */
+ IcmpCommunicationProhibited = 13,
+ /** Host precedence violation (indicates the requested precedence is not permitted for
+ * the combination of host or network and port)
+ */
+ IcmpHostPrecedenceViolation = 14,
+ /** Precedence cutoff in effect (precedence of datagram is below the level set by
+ * the network administrators)
+ */
+ IcmpPrecedenceCutoff = 15
+ };
+
+
+ /**
+ * @struct icmp_echo_hdr
+ * ICMP echo (ping) request/reply message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** the echo (ping) request identifier */
+ uint16_t id;
+ /** the echo (ping) request sequence number */
+ uint16_t sequence;
+ /** a timestamp of when the message was sent */
+ uint64_t timestamp;
+ } icmp_echo_hdr;
+#pragma pack(pop)
+
+
+ /**
+ * @struct icmp_echo_request
+ * ICMP echo (ping) request/reply message structure
+ */
+ typedef struct
+ {
+ /** a pointer to the header data */
+ icmp_echo_hdr* header;
+ /** most echo requests/replies contain some payload data. This is the data length */
+ size_t dataLength;
+ /** most echo requests/replies contain some payload data. This is a pointer to this data */
+ uint8_t* data;
+ } icmp_echo_request;
+
+
+ /**
+ * @typedef icmp_echo_reply
+ * ICMP echo (ping) reply message structure, same as icmp_echo_request
+ */
+ typedef icmp_echo_request icmp_echo_reply;
+
+
+ /**
+ * @struct icmp_timestamp_request
+ * ICMP timestamp request message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** the timestamp request identifier */
+ uint16_t id;
+ /** the timestamp request sequence number */
+ uint16_t sequence;
+ /** the time (in milliseconds since midnight) the sender last touched the packet */
+ uint32_t originateTimestamp;
+ /** relevant for timestamp reply only - the time the echoer first touched it on receipt */
+ uint32_t receiveTimestamp;
+ /** relevant for timestamp reply only - the time the echoer last touched the message on sending it */
+ uint32_t transmitTimestamp;
+ } icmp_timestamp_request;
+#pragma pack(pop)
+
+
+ /**
+ * @typedef icmp_timestamp_reply
+ * ICMP timestamp reply message structure, same as icmp_timestamp_request
+ */
+ typedef icmp_timestamp_request icmp_timestamp_reply;
+
+
+ /**
+ * @struct icmp_destination_unreachable
+ * ICMP destination unreachable message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** unused 2 bytes */
+ uint16_t unused;
+ /** contains the MTU of the next-hop network if a code 4 error occurs */
+ uint16_t nextHopMTU;
+ } icmp_destination_unreachable;
+#pragma pack(pop)
+
+
+ /**
+ * @struct icmp_time_exceeded
+ * ICMP time-to-live exceeded message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** unused 4 bytes */
+ uint32_t unused;
+ } icmp_time_exceeded;
+#pragma pack(pop)
+
+
+ /**
+ * @typedef icmp_source_quench
+ * ICMP source quence message structure, same as icmp_time_exceeded
+ */
+ typedef icmp_time_exceeded icmp_source_quench;
+
+
+ /**
+ * @struct icmp_param_problem
+ * ICMP parameter problem message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** in the case of an invalid IP header (Code 0), this field indicates the byte offset of the error in the header */
+ uint8_t pointer;
+ /** unused 1 byte */
+ uint8_t unused1;
+ /** unused 2 bytes */
+ uint16_t unused2;
+ } icmp_param_problem;
+#pragma pack(pop)
+
+
+ /**
+ * @typedef icmp_router_solicitation
+ * ICMP router solicitation message structure, same as icmphdr
+ */
+ typedef icmphdr icmp_router_solicitation;
+
+ /**
+ * @struct icmp_redirect
+ * ICMP redirect message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** an IPv4 address of the gateway to which the redirection should be sent */
+ uint32_t gatewayAddress;
+ } icmp_redirect;
+#pragma pack(pop)
+
+
+ /**
+ * @struct icmp_router_address_structure
+ * Router address structure, relevant for ICMP router advertisement message type (icmp_router_advertisement)
+ */
+#pragma pack(push, 1)
+ struct icmp_router_address_structure
+ {
+ /** the IPv4 address of the advertised router */
+ uint32_t routerAddress;
+ /** The preferability of the router address as a default router address, relative to other router addresses
+ * on the same subnet. This is a twos-complement value where higher values indicate that the route is
+ * more preferable */
+ uint32_t preferenceLevel;
+
+ /**
+ * Set router address structure from a given IPv4 address and preference level
+ * @param[in] addr IPv4 address to set
+ * @param[in] preference Preference level to set
+ */
+ void setRouterAddress(IPv4Address addr, uint32_t preference);
+
+ /**
+ * @return The IPv4 address extracted from icmp_router_address_structure#routerAddress field
+ */
+ IPv4Address getAddress();
+ };
+#pragma pack(pop)
+
+
+ /**
+ * @struct icmp_router_advertisement_hdr
+ * ICMP router advertisement message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** the number of router advertisements in this message. Each advertisement contains one router address/preference level pair */
+ uint8_t advertisementCount;
+ /** the number of 32-bit words of information for each router address entry in the list. The value is normally set to 2
+ * (router address + preference level) */
+ uint8_t addressEntrySize;
+ /** the maximum number of seconds that the router addresses in this list may be considered valid */
+ uint16_t lifetime;
+ } icmp_router_advertisement_hdr;
+#pragma pack(pop)
+
+
+ /**
+ * @struct icmp_router_advertisement
+ * ICMP router advertisement message structure
+ */
+ struct icmp_router_advertisement
+ {
+ /** a pointer to the header data on the packet */
+ icmp_router_advertisement_hdr* header;
+
+ /**
+ * Extract router advertisement at a given index
+ * @param[in] index The index of the router advertisement
+ * @return A pointer to the router advertisement on the packet or null if index is out of range (less than zero or
+ * greater than the number of router advertisement records on this message, determined by advertisementCount field)
+ */
+ icmp_router_address_structure* getRouterAddress(int index);
+ };
+
+
+ /**
+ * @struct icmp_address_mask_request
+ * ICMP address mask request message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** the address mask request identifier */
+ uint16_t id;
+ /** the address mask request sequence */
+ uint16_t sequence;
+ /** the subnet mask of the requesting host */
+ uint32_t addressMask;
+ } icmp_address_mask_request;
+#pragma pack(pop)
+
+
+ /**
+ * @typedef icmp_address_mask_reply
+ * ICMP address mask reply message structure, same as icmp_address_mask_request
+ */
+ typedef icmp_address_mask_request icmp_address_mask_reply;
+
+
+ /**
+ * @struct icmp_info_request
+ * ICMP information request message structure
+ */
+#pragma pack(push, 1)
+ typedef struct : icmphdr
+ {
+ /** the information request identifier */
+ uint16_t id;
+ /** the information request sequence */
+ uint16_t sequence;
+ } icmp_info_request;
+#pragma pack(pop)
+
+
+ /**
+ * @typedef icmp_info_reply
+ * ICMP information reply message structure, same as icmp_info_request
+ */
+ typedef icmp_info_request icmp_info_reply;
+
+
+ /**
+ * @class IcmpLayer
+ * Represents an ICMP protocol layer (for IPv4 only)
+ */
+ class IcmpLayer : public Layer
+ {
+ private:
+ icmp_echo_request m_EchoData;
+ icmp_router_advertisement m_RouterAdvData;
+
+ bool cleanIcmpLayer();
+
+ bool setEchoData(IcmpMessageType echoType, uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen);
+
+ bool setIpAndL4Layers(IPv4Layer* ipLayer, Layer* l4Layer);
+
+ public:
+ /**
+ * A constructor that creates the layer from an existing packet raw data
+ * @param[in] data A pointer to the raw data (will be casted to @ref arphdr)
+ * @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
+ */
+ IcmpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = ICMP; }
+
+ /**
+ * An empty constructor that creates a new layer with an empty ICMP header without setting the ICMP type or ICMP data.
+ * Call the set*Data() methods to set ICMP type and data
+ */
+ IcmpLayer();
+
+ virtual ~IcmpLayer() {}
+
+ /**
+ * Get a pointer to the basic ICMP header. Notice this points directly to the data, so every change will change the actual packet data
+ * @return A pointer to the @ref icmphdr
+ */
+ inline icmphdr* getIcmpHeader() { return (icmphdr*)m_Data; };
+
+ /**
+ * @return The ICMP message type
+ */
+ IcmpMessageType getMessageType();
+
+ /**
+ * @param[in] type Type to check
+ * @return True if the layer if of the given type, false otherwise
+ */
+ bool isMessageOfType(IcmpMessageType type);
+
+ /**
+ * @return ICMP echo (ping) request data. If the layer isn't of type ICMP echo request NULL is returned
+ */
+ icmp_echo_request* getEchoRequestData();
+
+ /**
+ * Set echo (ping) request message data
+ * @param[in] id Echo (ping) request identifier
+ * @param[in] sequence Echo (ping) request sequence
+ * @param[in] timestamp Echo (ping) request timestamp
+ * @param[in] data A pointer to echo (ping) request payload to set
+ * @param[in] dataLen The length of the echo (ping) request payload
+ * @return A pointer to the echo (ping) request data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_echo_request* setEchoRequestData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen);
+
+ /**
+ * @return ICMP echo reply data. If the layer isn't of type ICMP echo reply NULL is returned
+ */
+ icmp_echo_reply* getEchoReplyData();
+
+ /**
+ * Set echo (ping) reply message data
+ * @param[in] id Echo (ping) reply identifier
+ * @param[in] sequence Echo (ping) reply sequence
+ * @param[in] timestamp Echo (ping) reply timestamp
+ * @param[in] data A pointer to echo (ping) reply payload to set
+ * @param[in] dataLen The length of the echo (ping) reply payload
+ * @return A pointer to the echo (ping) reply data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_echo_reply* setEchoReplyData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen);
+
+ /**
+ * @return ICMP timestamp request data. If the layer isn't of type ICMP timestamp request NULL is returned
+ */
+ icmp_timestamp_request* getTimestampRequestData();
+
+ /**
+ * Set timestamp request message data
+ * @param[in] id Timestamp request identifier
+ * @param[in] sequence Timestamp request sequence
+ * @param[in] originateTimestamp Time (in milliseconds since midnight) the sender last touched the packet
+ * @return A pointer to the timestamp request data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_timestamp_request* setTimestampRequestData(uint16_t id, uint16_t sequence, timeval originateTimestamp);
+
+ /**
+ * @return ICMP timestamp reply data. If the layer isn't of type ICMP timestamp reply NULL is returned
+ */
+ icmp_timestamp_reply* getTimestampReplyData();
+
+ /**
+ * Set timestamp reply message data
+ * @param[in] id Timestamp reply identifier
+ * @param[in] sequence Timestamp reply sequence
+ * @param[in] originateTimestamp Time (in milliseconds since midnight) the sender last touched the packet
+ * @param[in] receiveTimestamp The time the echoer first touched it on receipt
+ * @param[in] transmitTimestamp The time the echoer last touched the message on sending it
+ * @return A pointer to the timestamp reply data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_timestamp_reply* setTimestampReplyData(uint16_t id, uint16_t sequence,
+ timeval originateTimestamp, timeval receiveTimestamp, timeval transmitTimestamp);
+
+ /**
+ * @return ICMP destination unreachable data. If the layer isn't of type ICMP destination unreachable NULL is returned.
+ * The IP and L4 (ICMP/TCP/UDP) headers of the destination unreachable data are parsed as separate layers and can be
+ * retrieved via this->getNextLayer()
+ */
+ icmp_destination_unreachable* getDestUnreachableData();
+
+ /**
+ * Set destination unreachable message data. This method only works if IcmpLayer is already part of a packet (not
+ * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate layers
+ * and need a packet to be added to
+ * @param[in] code Destination unreachable code
+ * @param[in] nextHopMTU The MTU of the next-hop network if a code 4 error occurs
+ * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the packet
+ * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet
+ * @return A pointer to the destination unreachable data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_destination_unreachable* setDestUnreachableData(IcmpDestUnreachableCodes code, uint16_t nextHopMTU, IPv4Layer* ipHeader, Layer* l4Header);
+
+ /**
+ * @return ICMP source quench data. If the layer isn't of type ICMP source quench NULL is returned.
+ * The IP and L4 (ICMP/TCP/UDP) headers of the source quench data are parsed as separate layers and can be
+ * retrieved via this->getNextLayer()
+ */
+ icmp_source_quench* getSourceQuenchdata();
+
+ /**
+ * Set source quench message data. This method only works if IcmpLayer is already part of a packet (not
+ * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate layers
+ * and need a packet to be added to
+ * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the packet
+ * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet
+ * @return A pointer to the source quench data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_source_quench* setSourceQuenchdata(IPv4Layer* ipHeader, Layer* l4Header);
+
+ /**
+ * @return ICMP redirect data. If the layer isn't of type ICMP redirect NULL is returned.
+ * The IP and L4 (ICMP/TCP/UDP) headers of the redirect data are parsed as separate layers and can be
+ * retrieved via this->getNextLayer()
+ */
+ icmp_redirect* getRedirectData();
+
+ /**
+ * Set redirect message data. This method only works if IcmpLayer is already part of a packet (not
+ * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate layers
+ * and need a packet to be added to
+ * @param[in] code The redirect message code. Only values between 0 and 3 are legal, the rest will cause the method to fail
+ * @param[in] gatewayAddress An IPv4 address of the gateway to which the redirection should be sent
+ * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the packet
+ * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet
+ * @return A pointer to the redirect data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_redirect* setRedirectData(uint8_t code, IPv4Address gatewayAddress, IPv4Layer* ipHeader, Layer* l4Header);
+
+ /**
+ * @return ICMP router advertisement data. If the layer isn't of type ICMP router advertisement NULL is returned
+ */
+ icmp_router_advertisement* getRouterAdvertisementData();
+
+ /**
+ * Set router advertisement message data
+ * @param[in] code The router advertisement message code. Only codes 0 or 16 are legal, the rest will fail the method
+ * @param[in] lifetimeInSeconds The maximum number of seconds that the router addresses in this list may be considered valid
+ * @param[in] routerAddresses A vector of router advertisements to set
+ * @return A pointer to the router advertisement data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_router_advertisement* setRouterAdvertisementData(uint8_t code, uint16_t lifetimeInSeconds, const std::vector<icmp_router_address_structure>& routerAddresses);
+
+ /**
+ * @return ICMP router solicitation data. If the layer isn't of type ICMP router solicitation NULL is returned
+ */
+ icmp_router_solicitation* getRouterSolicitationData();
+
+ /**
+ * Set router solicitation message data. This message accepts no parameters as there are no parameters to this
+ * type of message (code is always zero)
+ * @return A pointer to the router solicitation data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_router_solicitation* setRouterSolicitationData();
+
+ /**
+ * @return ICMP time-to-live exceeded data. If the layer isn't of type ICMP time-to-live exceeded NULL is returned.
+ * The IP and L4 (ICMP/TCP/UDP) headers of the time exceeded data are parsed as separate layers and can be
+ * retrieved via this->getNextLayer()
+ */
+ icmp_time_exceeded* getTimeExceededData();
+
+ /**
+ * Set time-to-live exceeded message data. This method only works if IcmpLayer is already part of a packet (not
+ * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate layers
+ * and need a packet to be added to
+ * @param[in] code Time-to-live exceeded message code. Only codes 0 or 1 are legal, the rest will fail the method
+ * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the packet
+ * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet
+ * @return A pointer to the time-to-live exceeded data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_time_exceeded* setTimeExceededData(uint8_t code, IPv4Layer* ipHeader, Layer* l4Header);
+
+ /**
+ * @return ICMP parameter problem data. If the layer isn't of type ICMP parameter problem NULL is returned
+ */
+ icmp_param_problem* getParamProblemData();
+
+ /**
+ * Set parameter problem message data. This method only works if IcmpLayer is already part of a packet (not
+ * a standalone layer). The reason is the Internet and L4 headers given as parameters are added as separate layers
+ * and need a packet to be added to
+ * @param[in] code Parameter problem message code. Only code between 0 and 2 are legal, the rest will fail the method
+ * @param[in] errorOctetPointer In the case of an invalid IP header (Code 0), indicate the byte offset of the error in the header
+ * @param[in] ipHeader The Internet header of the original data. This layer is added as a separate layer on the packet
+ * @param[in] l4Header The L4 header of the original data. This layer is added as a separate layer on the packet
+ * @return A pointer to the parameter problem data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_param_problem* setParamProblemData(uint8_t code, uint8_t errorOctetPointer, IPv4Layer* ipHeader, Layer* l4Header);
+
+ /**
+ * @return ICMP address mask request data. If the layer isn't of type ICMP address mask request NULL is returned
+ */
+ icmp_address_mask_request* getAddressMaskRequestData();
+
+ /**
+ * Set address mask request message data
+ * @param[in] id Address mask request identifier
+ * @param[in] sequence Address mask request sequence
+ * @param[in] mask The subnet mask of the requesting host
+ * @return A pointer to the address mask request data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_address_mask_request* setAddressMaskRequestData(uint16_t id, uint16_t sequence, IPv4Address mask);
+
+ /**
+ * @return ICMP address mask reply data. If the layer isn't of type ICMP address mask reply NULL is returned
+ */
+ icmp_address_mask_reply* getAddressMaskReplyData();
+
+ /**
+ * Set address mask reply message data
+ * @param[in] id Address mask reply identifier
+ * @param[in] sequence Address mask reply sequence
+ * @param[in] mask The subnet mask of the requesting host
+ * @return A pointer to the address mask reply data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_address_mask_reply* setAddressMaskReplyData(uint16_t id, uint16_t sequence, IPv4Address mask);
+
+ /**
+ * @return ICMP address information request data. If the layer isn't of type ICMP information request NULL is returned
+ */
+ icmp_info_request* getInfoRequestData();
+
+ /**
+ * Set information request message data
+ * @param[in] id Information request identifier
+ * @param[in] sequence Information request sequence
+ * @return A pointer to the information request data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_info_request* setInfoRequestData(uint16_t id, uint16_t sequence);
+
+ /**
+ * @return ICMP address information reply data. If the layer isn't of type ICMP information reply NULL is returned
+ */
+ icmp_info_reply* getInfoReplyData();
+
+ /**
+ * Set information reply message data
+ * @param[in] id Information reply identifier
+ * @param[in] sequence Information reply sequence
+ * @return A pointer to the information reply data that have been set or NULL if something went wrong
+ * (an appropriate error log is printed in such cases)
+ */
+ icmp_info_reply* setInfoReplyData(uint16_t id, uint16_t sequence);
+
+
+ // implement abstract methods
+
+ /**
+ * ICMP messages of types: ICMP_DEST_UNREACHABLE, ICMP_SOURCE_QUENCH, ICMP_TIME_EXCEEDED, ICMP_REDIRECT, ICMP_PARAM_PROBLEM
+ * have data that contains IPv4 header and some L4 header (TCP/UDP/ICMP). This method parses these headers as separate
+ * layers on top of the ICMP layer
+ */
+ void parseNextLayer();
+
+ /**
+ * @return The ICMP header length. This length varies according to the ICMP message type. This length doesn't include
+ * IPv4 and L4 headers in case ICMP message type are: ICMP_DEST_UNREACHABLE, ICMP_SOURCE_QUENCH, ICMP_TIME_EXCEEDED,
+ * ICMP_REDIRECT, ICMP_PARAM_PROBLEM
+ */
+ size_t getHeaderLen();
+
+ /**
+ * Calculate ICMP checksum field
+ */
+ void computeCalculateFields();
+
+ std::string toString();
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelNetworkLayer; }
+ };
+
+} // namespace pcpp
+
+#endif /* PACKETPP_ICMP_LAYER */
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/IgmpLayer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/IgmpLayer.h b/thirdparty/pcap++/Packet++/header/IgmpLayer.h
new file mode 100644
index 0000000..61cb97a
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/IgmpLayer.h
@@ -0,0 +1,509 @@
+#ifndef PACKETPP_IGMP_LAYER
+#define PACKETPP_IGMP_LAYER
+
+#include <Layer.h>
+#include <IpAddress.h>
+#include <vector>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+/**
+ * @struct igmp_header
+ * IGMPv1 and IGMPv2 basic protocol header
+ */
+struct igmp_header
+{
+ /** Indicates the message type. The enum for message type is pcpp::IgmpType */
+ uint8_t type;
+ /** Specifies the time limit for the corresponding report. The field has a resolution of 100 milliseconds */
+ uint8_t maxResponseTime;
+ /** This is the 16-bit one's complement of the one's complement sum of the entire IGMP message */
+ uint16_t checksum;
+ /** This is the multicast address being queried when sending a Group-Specific or Group-and-Source-Specific Query */
+ uint32_t groupAddress;
+};
+
+
+/**
+ * @struct igmpv3_query_header
+ * IGMPv3 membership query basic header
+ */
+struct igmpv3_query_header
+{
+ /** IGMP message type. Should always have value of membership query (::IgmpType_MembershipQuery) */
+ uint8_t type;
+ /** This field specifies the maximum time (in 1/10 second) allowed before sending a responding report */
+ uint8_t maxResponseTime;
+ /** This is the 16-bit one's complement of the one's complement sum of the entire IGMP message */
+ uint16_t checksum;
+ /** This is the multicast address being queried when sending a Group-Specific or Group-and-Source-Specific Query */
+ uint32_t groupAddress;
+ /** Suppress Router-side Processing Flag + Querier's Robustness Variable */
+ uint8_t s_qrv;
+ /** Querier's Query Interval Code */
+ uint8_t qqic;
+ /** This field specifies the number of source addresses present in the Query */
+ uint16_t numOfSources;
+};
+
+
+/**
+ * @struct igmpv3_report_header
+ * IGMPv3 membership report basic header
+ */
+struct igmpv3_report_header
+{
+ /** IGMP message type. Should always have value of IGMPv3 membership report (::IgmpType_MembershipReportV3) */
+ uint8_t type;
+ /** Unused byte */
+ uint8_t reserved1;
+ /** This is the 16-bit one's complement of the one's complement sum of the entire IGMP message */
+ uint16_t checksum;
+ /** Unused bytes */
+ uint16_t reserved2;
+ /** This field specifies the number of group records present in the Report */
+ uint16_t numOfGroupRecords;
+};
+
+
+/**
+ * @struct igmpv3_group_record
+ * A block of fields containing information pertaining to the sender's membership in a single multicast group on the interface
+ * from which the Report is sent. Relevant only for IGMPv3 membership report messages
+ */
+struct igmpv3_group_record
+{
+ /** Group record type */
+ uint8_t recordType;
+ /** Contains the length of the Auxiliary Data field in this Group Record. A value other than 0 isn't supported */
+ uint8_t auxDataLen;
+ /** Specifies how many source addresses are present in this Group Record */
+ uint16_t numOfSources;
+ /** Contains the IP multicast address to which this Group Record pertains */
+ uint32_t multicastAddress;
+ /** A vector of n IP unicast addresses, where n is the value in this record's Number of Sources field */
+ uint8_t sourceAddresses[];
+
+ /**
+ * @return The multicast address in igmpv3_group_record#multicastAddress as IPv4Address instance
+ */
+ IPv4Address getMulticastAddress();
+
+ /**
+ * @return The number of source addresses in this group record
+ */
+ uint16_t getSourceAdressCount();
+
+ /**
+ * Get the source address at a certain index
+ * @param[in] index The index of the source address in the group record
+ * @return The source address in the requested index. If index is negative or higher than the number of source addresses in this
+ * group record the value if IPv4Address#Zero is returned
+ */
+ IPv4Address getSoruceAddressAtIndex(int index);
+
+ /**
+ * @return The total size in bytes of the group record
+ */
+ size_t getRecordLen();
+};
+
+
+/**
+ * IGMP message types
+ */
+enum IgmpType
+{
+ /** Unknown message type */
+ IgmpType_Unknown = 0,
+ /** IGMP Membership Query */
+ IgmpType_MembershipQuery = 0x11,
+ /** IGMPv1 Membership Report */
+ IgmpType_MembershipReportV1 = 0x12,
+ /** DVMRP */
+ IgmpType_DVMRP = 0x13,
+ /** PIM version 1 */
+ IgmpType_P1Mv1 = 0x14,
+ /** Cisco Trace Messages */
+ IgmpType_CiscoTrace = 0x15,
+ /** IGMPv2 Membership Report */
+ IgmpType_MembershipReportV2 = 0x16,
+ /** IGMPv2 Leave Group */
+ IgmpType_LeaveGroup = 0x17,
+ /** Multicast Traceroute Response */
+ IgmpType_MulticastTracerouteResponse = 0x1e,
+ /** Multicast Traceroute */
+ IgmpType_MulticastTraceroute = 0x1f,
+ /** IGMPv3 Membership Report */
+ IgmpType_MembershipReportV3 = 0x22,
+ /** MRD, Multicast Router Advertisement */
+ IgmpType_MulticastRouterAdvertisement = 0x30,
+ /** MRD, Multicast Router Solicitation */
+ IgmpType_MulticastRouterSolicitation = 0x31,
+ /** MRD, Multicast Router Termination */
+ IgmpType_MulticastRouterTermination = 0x32,
+};
+
+
+/**
+ * @class IgmpLayer
+ * A base class for all IGMP (Internet Group Management Protocol) protocol classes. This is an abstract class and cannot be instantiated,
+ * only its child classes can be instantiated. The inherited classes represent the different versions of the protocol:
+ * IGMPv1, IGMPv2 and IGMPv3
+ */
+class IgmpLayer : public Layer
+{
+protected:
+
+ IgmpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, ProtocolType igmpVer) : Layer(data, dataLen, NULL, packet) { m_Protocol = igmpVer; }
+
+ IgmpLayer(IgmpType type, const IPv4Address& groupAddr, uint8_t maxResponseTime, ProtocolType igmpVer);
+
+ uint16_t calculateChecksum();
+
+ size_t getHeaderSizeByVerAndType(ProtocolType igmpVer, IgmpType igmpType);
+public:
+
+ virtual ~IgmpLayer() {}
+
+ /**
+ * Get a pointer to the raw IGMPv1/IGMPv2 header. Notice this points directly to the data, so every change will change the actual packet data
+ * @return A pointer to the @ref igmp_header
+ */
+ inline igmp_header* getIgmpHeader() { return (igmp_header*)m_Data; }
+
+ /**
+ * @return The IPv4 multicast address stored igmp_header#groupAddress
+ */
+ inline IPv4Address getGroupAddress() { return IPv4Address(getIgmpHeader()->groupAddress); }
+
+ /**
+ * Set the IPv4 multicast address
+ * @param[in] groupAddr The IPv4 address to set
+ */
+ void setGroupAddress(const IPv4Address& groupAddr);
+
+ /**
+ * @return IGMP type set in igmp_header#type as ::IgmpType enum. Notice that if igmp_header#type contains a value
+ * that doesn't appear in the ::IgmpType enum, ::IgmpType_Unknown will be returned
+ */
+ IgmpType getType();
+
+ /**
+ * Set IGMP type (will be written to igmp_header#type field)
+ * @param[in] type The type to set
+ */
+ void setType(IgmpType type);
+
+ /**
+ * A static method that gets raw IGMP data (byte stream) and returns the IGMP version of this IGMP message
+ * @param[in] data The IGMP raw data (byte stream)
+ * @param[in] dataLen Raw data length
+ * @param[out] isQuery Return true if IGMP message type is ::IgmpType_MembershipQuery and false otherwise
+ * @return One of the values ::IGMPv1, ::IGMPv2, ::IGMPv3 according to detected IGMP version or ::UnknownProtocol if couldn't detect
+ * IGMP version
+ */
+ static ProtocolType getIGMPVerFromData(uint8_t* data, size_t dataLen, bool& isQuery);
+
+
+ // implement abstract methods
+
+ /**
+ * Does nothing for this layer (IGMP layer is always last)
+ */
+ void parseNextLayer() {}
+
+ /**
+ * @return Size of IGMP header = 8B
+ */
+ inline size_t getHeaderLen() { return sizeof(igmp_header); }
+
+ std::string toString();
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelNetworkLayer; }
+};
+
+
+/**
+ * @class IgmpV1Layer
+ * Represents IGMPv1 (Internet Group Management Protocol ver 1) layer. This class represents all the different messages of IGMPv1
+ */
+class IgmpV1Layer : public IgmpLayer
+{
+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
+ */
+ IgmpV1Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
+
+ /**
+ * A constructor that allocates a new IGMPv1 header
+ * @param[in] type The message type to set
+ * @param[in] groupAddr The multicast address to set. This is an optional parameter and has a default value of IPv4Address#Zero
+ * if not provided
+ */
+ IgmpV1Layer(IgmpType type, const IPv4Address& groupAddr = IPv4Address::Zero);
+
+ /**
+ * A destructor for this layer (does nothing)
+ */
+ ~IgmpV1Layer() {}
+
+
+ // implement abstract methods
+
+ /**
+ * Calculate the IGMP checksum and set igmp_header#maxResponseTime to 0 (this field is unused in IGMPv1)
+ */
+ void computeCalculateFields();
+
+};
+
+
+/**
+ * @class IgmpV2Layer
+ * Represents IGMPv2 (Internet Group Management Protocol ver 2) layer. This class represents all the different messages of IGMPv2
+ */
+class IgmpV2Layer : public IgmpLayer
+{
+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
+ */
+ IgmpV2Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
+
+ /**
+ * A constructor that allocates a new IGMPv2 header
+ * @param[in] type The message type to set
+ * @param[in] groupAddr The multicast address to set. This is an optional parameter and has a default value of IPv4Address#Zero
+ * @param[in] maxResponseTime The max response time to set. This is an optional parameter and has a default value of 0 if not provided
+ */
+ IgmpV2Layer(IgmpType type, const IPv4Address& groupAddr = IPv4Address::Zero, uint8_t maxResponseTime = 0);
+
+ /**
+ * A destructor for this layer (does nothing)
+ */
+ ~IgmpV2Layer() {}
+
+
+ // implement abstract methods
+
+ /**
+ * Calculate the IGMP checksum
+ */
+ void computeCalculateFields();
+};
+
+
+/**
+ * @class IgmpV3QueryLayer
+ * Represents an IGMPv3 (Internet Group Management Protocol ver 3) membership query message
+ */
+class IgmpV3QueryLayer : public IgmpLayer
+{
+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
+ */
+ IgmpV3QueryLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
+
+ /**
+ * A constructor that allocates a new IGMPv3 membership query
+ * @param[in] multicastAddr The multicast address to set. This is an optional parameter and has a default value of IPv4Address#Zero
+ * if not provided
+ * @param[in] maxResponseTime The max response time to set. This is an optional parameter and has a default value of 0 if not provided
+ * @param[in] s_qrv A 1-byte value representing the value in Suppress Router-side Processing Flag + Querier's Robustness Variable
+ * (igmpv3_query_header#s_qrv field). This is an optional parameter and has a default value of 0 if not provided
+ */
+ IgmpV3QueryLayer(const IPv4Address& multicastAddr = IPv4Address::Zero, uint8_t maxResponseTime = 0, uint8_t s_qrv = 0);
+
+ /**
+ * Get a pointer to the raw IGMPv3 membership query header. Notice this points directly to the data, so every change will change the
+ * actual packet data
+ * @return A pointer to the @ref igmpv3_query_header
+ */
+ inline igmpv3_query_header* getIgmpV3QueryHeader() { return (igmpv3_query_header*)m_Data; }
+
+ /**
+ * @return The number of source addresses in this message (as extracted from the igmpv3_query_header#numOfSources field)
+ */
+ uint16_t getSourceAddressCount();
+
+ /**
+ * Get the IPV4 source address in a certain index
+ * @param[in] index The requested index of the source address
+ * @return The IPv4 source address, or IPv4Address#Zero if index is out of bounds (of the message or of the layer)
+ */
+ IPv4Address getSourceAddressAtIndex(int index);
+
+ /**
+ * Add a new source address at the end of the source address list. The igmpv3_query_header#numOfSources field will be incremented accordingly
+ * @param[in] addr The IPv4 source address to add
+ * @return True if source address was added successfully or false otherwise. If false is returned an appropriate error message
+ * will be printed to log
+ */
+ bool addSourceAddress(const IPv4Address& addr);
+
+ /**
+ * Add a new source address at a certain index of the source address list. The igmpv3_query_header#numOfSources field will be incremented accordingly
+ * @param[in] addr The IPv4 source address to add
+ * @param[in] index The index to add the new source address at
+ * @return True if source address was added successfully or false otherwise. If false is returned an appropriate error message
+ * will be printed to log
+ */
+ bool addSourceAddressAtIndex(const IPv4Address& addr, int index);
+
+ /**
+ * Remove a source address at a certain index. The igmpv3_query_header#numOfSources field will be decremented accordingly
+ * @param[in] index The index of the source address to be removed
+ * @return True if source address was removed successfully or false otherwise. If false is returned an appropriate error message
+ * will be printed to log
+ */
+ bool removeSourceAddressAtIndex(int index);
+
+ /**
+ * Remove all source addresses in the message. The igmpv3_query_header#numOfSources field will be set to 0
+ * @return True if all source addresses were cleared successfully or false otherwise. If false is returned an appropriate error message
+ * will be printed to log
+ */
+ bool removeAllSourceAddresses();
+
+ // implement abstract methods
+
+ /**
+ * Calculate the IGMP checksum
+ */
+ void computeCalculateFields();
+
+ /**
+ * @return The message size in bytes which include the size of the basic header + the size of the source address list
+ */
+ size_t getHeaderLen();
+};
+
+
+/**
+ * @class IgmpV3ReportLayer
+ * Represents an IGMPv3 (Internet Group Management Protocol ver 3) membership report message
+ */
+class IgmpV3ReportLayer : public IgmpLayer
+{
+private:
+ igmpv3_group_record* addGroupRecordAt(uint8_t recordType, const IPv4Address& multicastAddress, const std::vector<IPv4Address>& sourceAddresses, int offset);
+
+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
+ */
+ IgmpV3ReportLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
+
+ /**
+ * A constructor that allocates a new IGMPv3 membership report with 0 group addresses
+ */
+ IgmpV3ReportLayer();
+
+ /**
+ * Get a pointer to the raw IGMPv3 membership report header. Notice this points directly to the data, so every change will change the
+ * actual packet data
+ * @return A pointer to the @ref igmpv3_report_header
+ */
+ inline igmpv3_report_header* getReportHeader() { return (igmpv3_report_header*)m_Data; }
+
+ /**
+ * @return The number of group records in this message (as extracted from the igmpv3_report_header#numOfGroupRecords field)
+ */
+ uint16_t getGroupRecordCount();
+
+ /**
+ * @return A pointer to the first group record or NULL if no group records exist. Notice the return value is a pointer to the real data,
+ * so changes in the return value will affect the packet data
+ */
+ igmpv3_group_record* getFirstGroupRecord();
+
+ /**
+ * Get the group record that comes next to a given group record. If "groupRecord" is NULL then NULL will be returned.
+ * If "groupRecord" is the last group record or if it is out of layer bounds NULL will be returned also. Notice the return value is a
+ * pointer to the real data casted to igmpv3_group_record type (as opposed to a copy of the option data). So changes in the return
+ * value will affect the packet data
+ * @param[in] groupRecord The group record to start searching from
+ * @return The next group record or NULL if "groupRecord" is NULL, last or out of layer bounds
+ */
+ igmpv3_group_record* getNextGroupRecord(igmpv3_group_record* groupRecord);
+
+ /**
+ * Add a new group record at a the end of the group record list. The igmpv3_report_header#numOfGroupRecords field will be
+ * incremented accordingly
+ * @param[in] recordType The type of the new group record
+ * @param[in] multicastAddress The multicast address of the new group record
+ * @param[in] sourceAddresses A vector containing all the source addresses of the new group record
+ * @return The method constructs a new group record, adds it to the end of the group record list of IGMPv3 report message and
+ * returns a pointer to the new message. If something went wrong in creating or adding the new group record a NULL value is returned
+ * and an appropriate error message is printed to log
+ */
+ igmpv3_group_record* addGroupRecord(uint8_t recordType, const IPv4Address& multicastAddress, const std::vector<IPv4Address>& sourceAddresses);
+
+ /**
+ * Add a new group record at a certain index of the group record list. The igmpv3_report_header#numOfGroupRecords field will be
+ * incremented accordingly
+ * @param[in] recordType The type of the new group record
+ * @param[in] multicastAddress The multicast address of the new group record
+ * @param[in] sourceAddresses A vector containing all the source addresses of the new group record
+ * @param[in] index The index to add the new group address at
+ * @return The method constructs a new group record, adds it to the IGMPv3 report message and returns a pointer to the new message.
+ * If something went wrong in creating or adding the new group record a NULL value is returned and an appropriate error message is
+ * printed to log
+ */
+ igmpv3_group_record* addGroupRecordAtIndex(uint8_t recordType, const IPv4Address& multicastAddress, const std::vector<IPv4Address>& sourceAddresses, int index);
+
+ /**
+ * Remove a group record at a certain index. The igmpv3_report_header#numOfGroupRecords field will be decremented accordingly
+ * @param[in] index The index of the group record to be removed
+ * @return True if group record was removed successfully or false otherwise. If false is returned an appropriate error message
+ * will be printed to log
+ */
+ bool removeGroupRecordAtIndex(int index);
+
+ /**
+ * Remove all group records in the message. The igmpv3_report_header#numOfGroupRecords field will be set to 0
+ * @return True if all group records were cleared successfully or false otherwise. If false is returned an appropriate error message
+ * will be printed to log
+ */
+ bool removeAllGroupRecords();
+
+ // implement abstract methods
+
+ /**
+ * Calculate the IGMP checksum
+ */
+ void computeCalculateFields();
+
+ /**
+ * @return The message size in bytes which include the size of the basic header + the size of the group record list
+ */
+ size_t getHeaderLen();
+};
+
+}
+
+#endif // PACKETPP_IGMP_LAYER
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/Layer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/Layer.h b/thirdparty/pcap++/Packet++/header/Layer.h
new file mode 100644
index 0000000..92b1dd2
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/Layer.h
@@ -0,0 +1,167 @@
+#ifndef PACKETPP_LAYER
+#define PACKETPP_LAYER
+
+#include <stdint.h>
+#include <stdio.h>
+#include "ProtocolType.h"
+#include <string>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+ class Packet;
+
+ /**
+ * @class Layer
+ * Layer is the base class for all protocol layers. Each protocol supported in PcapPlusPlus has a class that inherits Layer.
+ * The protocol layer class expose all properties and methods relevant for viewing and editing protocol fields.
+ * For example: a pointer to a structured header (e.g tcphdr, iphdr, etc.), protocol header size, payload size, compute
+ * fields that can be automatically computed, print protocol data to string, etc.
+ * Each protocol instance is obviously part of a protocol stack (which construct a packet). This protocol stack is represented
+ * in PcapPlusPlus in a linked list, and each layer is an element in this list. That's why each layer has proprties to the next and previous
+ * layer in the protocol stack
+ * The Layer class, as a base class, is abstract and the user can't create an instance of it (it has a private constructor)
+ * Each layer holds a pointer to the relevant place in the packet. The layer sees all the data from this pointer forward until the
+ * end of the packet. Here is an example packet showing this concept:
+ *
+ @verbatim
+
+ ====================================================
+ |Eth |IPv4 |TCP |Packet |
+ |Header |Header |Header |Payload |
+ ====================================================
+
+ |--------------------------------------------------|
+ EthLayer data
+ |---------------------------------------|
+ IPv4Layer data
+ |---------------------------|
+ TcpLayer data
+ |----------------|
+ PayloadLayer data
+
+ @endverbatim
+ *
+ */
+ class Layer {
+ friend class Packet;
+ public:
+ /**
+ * A destructor for this class. Frees the data if it was allocated by the layer constructor (see isAllocatedToPacket() for more info)
+ */
+ virtual ~Layer();
+
+ /**
+ * @return A pointer to the next layer in the protocol stack or NULL if the layer is the last one
+ */
+ inline Layer* getNextLayer() { return m_NextLayer; }
+
+ /**
+ * @return A pointer to the previous layer in the protocol stack or NULL if the layer is the first one
+ */
+ inline Layer* getPrevLayer() { return m_PrevLayer; }
+
+ /**
+ * @return The protocol enum
+ */
+ inline ProtocolType getProtocol() { return m_Protocol; }
+
+ /**
+ * @return A pointer to the layer raw data. In most cases it'll be a pointer to the first byte of the header
+ */
+ inline uint8_t* getData() { return m_Data; }
+
+ /**
+ * @return The length in bytes of the data from the first byte of the header until the end of the packet
+ */
+ inline size_t getDataLen() { return m_DataLen; }
+
+ /**
+ * @return A pointer for the layer payload, meaning the first byte after the header
+ */
+ uint8_t* getLayerPayload() { return m_Data + getHeaderLen(); }
+
+ /**
+ * @return The size in bytes of the payload
+ */
+ size_t getLayerPayloadSize() { return m_DataLen - getHeaderLen(); }
+
+ /**
+ * Raw data in layers can come from one of sources:
+ * 1. from an existing packet - this is the case when parsing packets received from files or the network. In this case the data was
+ * already allocated by someone else, and layer only holds the pointer to the relevant place inside this data
+ * 2. when creating packets, data is allocated when layer is created. In this case the layer is responsible for freeing it as well
+ *
+ * @return Returns true if the data was allocated by an external source (a packet) or false if it was allocated by the layer itself
+ */
+ inline bool isAllocatedToPacket() { return m_Packet != NULL; }
+
+ /**
+ * Copy the raw data of this layer to another array
+ * @param[out] toArr The destination byte array
+ */
+ void copyData(uint8_t* toArr);
+
+
+ // abstract methods
+
+ /**
+ * Each layer is responsible for parsing the next layer
+ */
+ virtual void parseNextLayer() = 0;
+
+ /**
+ * @return The header length in bytes
+ */
+ virtual size_t getHeaderLen() = 0;
+
+ /**
+ * Each layer can compute field values automatically using this method. This is an abstract method
+ */
+ virtual void computeCalculateFields() = 0;
+
+ /**
+ * @return A string representation of the layer most important data (should look like the layer description in Wireshark)
+ */
+ virtual std::string toString() = 0;
+
+ /**
+ * @return The OSI Model layer this protocol belongs to
+ */
+ virtual OsiModelLayer getOsiModelLayer() = 0;
+
+ protected:
+ uint8_t* m_Data;
+ size_t m_DataLen;
+ Packet* m_Packet;
+ ProtocolType m_Protocol;
+ Layer* m_NextLayer;
+ Layer* m_PrevLayer;
+
+ Layer() : m_Data(NULL), m_DataLen(0), m_Packet(NULL), m_Protocol(UnknownProtocol), m_NextLayer(NULL), m_PrevLayer(NULL) { }
+
+ Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) :
+ m_Data(data), m_DataLen(dataLen),
+ m_Packet(packet), m_Protocol(UnknownProtocol),
+ m_NextLayer(NULL), m_PrevLayer(prevLayer) {}
+
+ // Copy c'tor
+ Layer(const Layer& other);
+ Layer& operator=(const Layer& other);
+
+ inline void setNextLayer(Layer* nextLayer) { m_NextLayer = nextLayer; }
+ inline void setPrevLayer(Layer* prevLayer) { m_PrevLayer = prevLayer; }
+
+ virtual bool extendLayer(int offsetInLayer, size_t numOfBytesToExtend);
+ virtual bool shortenLayer(int offsetInLayer, size_t numOfBytesToShorten);
+ };
+
+} // namespace pcpp
+
+#endif /* PACKETPP_LAYER */
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/MplsLayer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/MplsLayer.h b/thirdparty/pcap++/Packet++/header/MplsLayer.h
new file mode 100644
index 0000000..1bc92d1
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/MplsLayer.h
@@ -0,0 +1,126 @@
+#ifndef PACKETPP_MPLS_LAYER
+#define PACKETPP_MPLS_LAYER
+
+#include <Layer.h>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+ /**
+ * @class MplsLayer
+ * Represents a MPLS (Multi-Protocol Label Switching) layer
+ */
+ class MplsLayer : public Layer
+ {
+ private:
+
+ #pragma pack(push, 1)
+ struct mpls_header
+ {
+ uint16_t hiLabel;
+ uint8_t misc;
+ uint8_t ttl;
+ };
+ #pragma pack(pop)
+
+ inline mpls_header* getMplsHeader() { return (mpls_header*)m_Data; };
+
+ 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
+ */
+ MplsLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = MPLS; }
+
+ /**
+ * A constructor that allocates a new MPLS header
+ * @param[in] mplsLabel MPLS label
+ * @param[in] ttl Time-to-leave value
+ * @param[in] expermentalUseValue Experimental use value
+ * @param[in] bottomOfStack Bottom-of-stack value which indicate whether the next layer will also be a MPLS label or not
+ */
+ MplsLayer(uint32_t mplsLabel, uint8_t ttl, uint8_t expermentalUseValue, bool bottomOfStack);
+
+ virtual ~MplsLayer() {}
+
+ /**
+ * @return TTL value of the MPLS header
+ */
+ inline uint8_t getTTL() { return getMplsHeader()->ttl; }
+
+ /**
+ * Set the TTL value
+ * @param[in] ttl The TTL value to set
+ */
+ inline void setTTL(uint8_t ttl) { getMplsHeader()->ttl = ttl; }
+
+ /**
+ * Get an indication whether the next layer is also be a MPLS label or not
+ * @return True if it's the last MPLS layer, false otherwise
+ */
+ bool isBottomOfStack();
+
+ /**
+ * Set the bottom-of-stack bit in the MPLS label
+ * @param[in] val Set or unset the bit
+ */
+ void setBottomOfStack(bool val);
+
+ /**
+ * @return The exp value (3 bits) of the MPLS label
+ */
+ uint8_t getExperimentalUseValue();
+
+ /**
+ * Set the exp value (3 bits) of the MPLS label
+ * @param[in] val The exp value to set. val must be a valid number meaning between 0 and 7 (inclusive)
+ * @return True if exp value was set successfully or false if val has invalid value
+ */
+ bool setExperimentalUseValue(uint8_t val);
+
+ /**
+ * @return The MPLS label value (20 bits)
+ */
+ uint32_t getMplsLabel();
+
+ /**
+ * Set the MPLS label (20 bits)
+ * @param[in] label The label to set. label must be a valid number meaning between 0 and 0xFFFFF (inclusive)
+ * @return True if label was set successfully or false if label has invalid value
+ */
+ bool setMplsLabel(uint32_t label);
+
+ // implement abstract methods
+
+ /**
+ * Currently identifies the following next layers: IPv4Layer, IPv6Layer, MplsLayer. Otherwise sets PayloadLayer
+ */
+ void parseNextLayer();
+
+ /**
+ * @return Size of MPLS header (4 bytes)
+ */
+ inline size_t getHeaderLen() { return sizeof(mpls_header); }
+
+ /**
+ * Set/unset the bottom-of-stack bit according to next layer: if it's a MPLS layer then bottom-of-stack will be unset. If it's not a
+ * MPLS layer this bit will be set
+ */
+ void computeCalculateFields();
+
+ std::string toString();
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelNetworkLayer; }
+ };
+
+} // namespace pcpp
+
+#endif /* PACKETPP_MPLS_LAYER */
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/NullLoopbackLayer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/NullLoopbackLayer.h b/thirdparty/pcap++/Packet++/header/NullLoopbackLayer.h
new file mode 100644
index 0000000..05c2fe7
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/NullLoopbackLayer.h
@@ -0,0 +1,92 @@
+#ifndef PACKETPP_NULL_LOOPBACK_LAYER
+#define PACKETPP_NULL_LOOPBACK_LAYER
+
+/// @file
+
+#include <Layer.h>
+
+namespace pcpp
+{
+
+ /** IPv4 protocol **/
+ #define PCPP_BSD_AF_INET 2
+ /** XEROX NS protocols */
+ #define PCPP_BSD_AF_NS 6
+ /** ISO */
+ #define PCPP_BSD_AF_ISO 7
+ /** AppleTalk */
+ #define PCPP_BSD_AF_APPLETALK 16
+ /** IPX */
+ #define PCPP_BSD_AF_IPX 23
+ /** OpenBSD (and probably NetBSD), BSD/OS IPv6 */
+ #define PCPP_BSD_AF_INET6_BSD 24
+ /** FreeBSD IPv6 */
+ #define PCPP_BSD_AF_INET6_FREEBSD 28
+ /** Darwin IPv6 */
+ #define PCPP_BSD_AF_INET6_DARWIN 30
+
+ /**
+ * @class NullLoopbackLayer
+ * Represents a NULL/Loopback layer
+ */
+ class NullLoopbackLayer : 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] packet A pointer to the Packet instance where layer will be stored in
+ */
+ NullLoopbackLayer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, NULL, packet) { m_Protocol = NULL_LOOPBACK; }
+
+ /**
+ * A constructor that allocates a new Null/Loopback header
+ * @param[in] family The family protocol to set
+ */
+ NullLoopbackLayer(uint32_t family);
+
+ /**
+ * A destructor for this layer (does nothing)
+ */
+ ~NullLoopbackLayer() {}
+
+ /**
+ * @return The protocol family in this layer
+ */
+ uint32_t getFamily();
+
+ /**
+ * Set a protocol family
+ * @param[in] family The family protocol to set
+ */
+ void setFamily(uint32_t family);
+
+
+ // implement abstract methods
+
+ /**
+ * Identifies the next layers by family:
+ * - for ::PCPP_BSD_AF_INET the next layer is IPv4Layer
+ * - for ::PCPP_BSD_AF_INET6_BSD, ::PCPP_BSD_AF_INET6_FREEBSD, ::PCPP_BSD_AF_INET6_DARWIN the next layer is IPv6Layer
+ * - for other values the next layer in PayloadLayer (unknown protocol)
+ */
+ void parseNextLayer();
+
+ /**
+ * @return Size of Null/Loopback header = 4B
+ */
+ inline size_t getHeaderLen() { return sizeof(uint32_t); }
+
+ /**
+ * Does nothing for this layer
+ */
+ void computeCalculateFields() {}
+
+ std::string toString();
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelDataLinkLayer; }
+ };
+
+} // namespace pcpp
+
+#endif /* PACKETPP_NULL_LOOPBACK_LAYER */
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/PPPoELayer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/PPPoELayer.h b/thirdparty/pcap++/Packet++/header/PPPoELayer.h
new file mode 100644
index 0000000..3bf728b
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/PPPoELayer.h
@@ -0,0 +1,661 @@
+#ifndef PACKETPP_PPPOE_LAYER
+#define PACKETPP_PPPOE_LAYER
+
+#include <Layer.h>
+#include <vector>
+#include <string.h>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+ /**
+ * @struct pppoe_header
+ * Represents an PPPoE protocol header
+ */
+#pragma pack(push, 1)
+ struct pppoe_header {
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+ /** PPPoE version */
+ uint8_t version:4,
+ /** PPPoE type */
+ type:4;
+ /** PPPoE code */
+ uint8_t code;
+#else
+ /** PPPoE version */
+ uint16_t version:4,
+ /** PPPoE type */
+ type:4,
+ /** PPPoE code */
+ code:8;
+#endif
+ /** PPPoE session ID (relevant for PPPoE session packets only) */
+ uint16_t sessionId;
+ /** Length (in bytes) of payload, not including the PPPoE header */
+ uint16_t payloadLength;
+ };
+#pragma pack(pop)
+
+
+ /**
+ * @class PPPoELayer
+ * An abstract class that describes the PPPoE protocol. Contains common data and logic of the two types of PPPoE packets: PPPoE session
+ * and PPPoE discovery
+ */
+ class PPPoELayer : public Layer
+ {
+ public:
+ /**
+ * PPPoE possible codes
+ */
+ enum PPPoECode
+ {
+ /** PPPoE session code */
+ PPPOE_CODE_SESSION = 0x00,
+ /** PPPoE discovery PADO */
+ PPPOE_CODE_PADO = 0x07,
+ /** PPPoE discovery PADI */
+ PPPOE_CODE_PADI = 0x09,
+ /** PPPoE discovery PADG */
+ PPPOE_CODE_PADG = 0x0a,
+ /** PPPoE discovery PADC */
+ PPPOE_CODE_PADC = 0x0b,
+ /** PPPoE discovery PADQ */
+ PPPOE_CODE_PADQ = 0x0c,
+ /** PPPoE discovery PADR */
+ PPPOE_CODE_PADR = 0x19,
+ /** PPPoE discovery PADS */
+ PPPOE_CODE_PADS = 0x65,
+ /** PPPoE discovery PADT */
+ PPPOE_CODE_PADT = 0xa7,
+ /** PPPoE discovery PADM */
+ PPPOE_CODE_PADM = 0xd3,
+ /** PPPoE discovery PADN */
+ PPPOE_CODE_PADN = 0xd4
+ };
+
+ ~PPPoELayer() {}
+
+ /**
+ * Get a pointer to the PPPoE header. Notice this points directly to the data, so every change will change the actual packet data
+ * @return A pointer to the pppoe_header
+ */
+ inline pppoe_header* getPPPoEHeader() { return (pppoe_header*)m_Data; };
+
+ // abstract methods implementation
+
+ /**
+ * Calculate @ref pppoe_header#payloadLength field
+ */
+ virtual void computeCalculateFields();
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelDataLinkLayer; }
+
+ protected:
+
+ // protected c'tor as this class shouldn't be instantiated
+ PPPoELayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { }
+
+ // protected c'tor as this class shouldn't be instantiated
+ PPPoELayer(uint8_t version, uint8_t type, PPPoELayer::PPPoECode code, uint16_t sessionId, size_t additionalBytesToAllocate = 0);
+
+ };
+
+
+ /**
+ * @class PPPoESessionLayer
+ * Describes the PPPoE session protocol
+ */
+ class PPPoESessionLayer : public PPPoELayer
+ {
+ public:
+
+ /**
+ * A constructor that creates the layer from an existing packet raw data
+ * @param[in] data A pointer to the raw data (will be casted to @ref pppoe_header)
+ * @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
+ */
+ PPPoESessionLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : PPPoELayer(data, dataLen, prevLayer, packet) { m_Protocol = PPPoESession; }
+
+ /**
+ * A constructor that allocates a new PPPoE Session header with version, type and session ID
+ * @param[in] version PPPoE version
+ * @param[in] type PPPoE type
+ * @param[in] sessionId PPPoE session ID
+ * @param[in] pppNextProtocol The next protocol to come after the PPPoE session header. Should be one of the PPP_* macros listed below
+ */
+ PPPoESessionLayer(uint8_t version, uint8_t type, uint16_t sessionId, uint16_t pppNextProtocol) : PPPoELayer(version, type, PPPoELayer::PPPOE_CODE_SESSION, sessionId, sizeof(uint16_t)) { setPPPNextProtocol(pppNextProtocol); }
+
+ virtual ~PPPoESessionLayer() {}
+
+ /**
+ * @return The protocol after the PPPoE session header. The return value is one of the PPP_* macros listed below. This method is also
+ * used when parsing a packet (this way we know which layer comes after the PPPoE session)
+ */
+ uint16_t getPPPNextProtocol();
+
+ /**
+ * Set the field that describes which header comes after the PPPoE session header
+ * @param[in] nextProtocol The protocol value. Should be one of the PPP_* macros listed below
+ */
+ void setPPPNextProtocol(uint16_t nextProtocol);
+
+ // abstract methods implementation
+
+ /**
+ * Currently identifies the following next layers: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer
+ */
+ virtual void parseNextLayer();
+
+ /**
+ * @return Size of @ref pppoe_header
+ */
+ virtual size_t getHeaderLen() { return sizeof(pppoe_header) + sizeof(uint16_t); }
+
+ virtual std::string toString();
+ };
+
+
+
+ /**
+ * @class PPPoEDiscoveryLayer
+ * Describes the PPPoE discovery protocol
+ */
+ class PPPoEDiscoveryLayer : public PPPoELayer
+ {
+ public:
+ /**
+ * PPPoE tag types
+ */
+ enum PPPoETagTypes
+ {
+ /** End-Of-List tag type*/
+ PPPOE_TAG_EOL = 0x0000,
+ /** Service-Name tag type*/
+ PPPOE_TAG_SVC_NAME = 0x0101,
+ /** AC-Name tag type*/
+ PPPOE_TAG_AC_NAME = 0x0102,
+ /** Host-Uniq tag type*/
+ PPPOE_TAG_HOST_UNIQ = 0x0103,
+ /** AC-Cookie tag type*/
+ PPPOE_TAG_AC_COOKIE = 0x0104,
+ /** Vendor-Specific tag type*/
+ PPPOE_TAG_VENDOR = 0x0105,
+ /** Credits tag type*/
+ PPPOE_TAG_CREDITS = 0x0106,
+ /** Metrics tag type*/
+ PPPOE_TAG_METRICS = 0x0107,
+ /** Sequence Number tag type */
+ PPPOE_TAG_SEQ_NUM = 0x0108,
+ /** Credit Scale Factor tag type */
+ PPPOE_TAG_CRED_SCALE = 0x0109,
+ /** Relay-Session-Id tag type */
+ PPPOE_TAG_RELAY_ID = 0x0110,
+ /** HURL tag type */
+ PPPOE_TAG_HURL = 0x0111,
+ /** MOTM tag type */
+ PPPOE_TAG_MOTM = 0x0112,
+ /** PPP-Max-Payload tag type */
+ PPPOE_TAG_MAX_PAYLD = 0x0120,
+ /** IP_Route_Add tag type */
+ PPPOE_TAG_IP_RT_ADD = 0x0121,
+ /** Service-Name-Error tag type */
+ PPPOE_TAG_SVC_ERR = 0x0201,
+ /** AC-System-Error tag type */
+ PPPOE_TAG_AC_ERR = 0x0202,
+ /** Generic-Error tag type */
+ PPPOE_TAG_GENERIC_ERR= 0x0203
+ };
+
+ /**
+ * @struct PPPoETag
+ * Represents a PPPoE tag and its data
+ */
+ struct PPPoETag
+ {
+ public:
+
+ /** The type of the data, can be converted to PPPoEDiscoveryLayer#PPPoETagTypes enum (or use getType()) */
+ uint16_t tagType;
+ /** The length of the tag data */
+ uint16_t tagDataLength;
+ /** A pointer to the tag data. It's recommended to use getTagDataAs() to retrieve the tag data or setTagData() to set tag data */
+ uint8_t tagData[];
+
+ /**
+ * A templated method to retrieve the tag data as a certain type T. For example, if tag data is 4B (integer) then this method
+ * should be used as getTagDataAs<int>() and it will return the tag data as integer.<BR>
+ * Notice this return value is a copy of the data, not a pointer to the actual data
+ * @param[in] tagDataOffset An optional parameter that specifies where to start copy the tag data. For example: if tag data is 20 bytes
+ * and you need only the 4 last bytes as integer then use this method like this: getTagDataAs<int>(16). The default is 0 - start copy
+ * from the beginning of tag data
+ * @return The tag data as type T
+ */
+ template<typename T>
+ T getTagDataAs(int tagDataOffset = 0)
+ {
+ T result;
+ memcpy(&result, tagData+tagDataOffset, sizeof(T));
+ return result;
+ }
+
+ /**
+ * A templated method to copy data of type T into the tag data. For example: if tag data is 4[Bytes] long use this method like
+ * this to set an integer "num" into tag data: setTagData<int>(num)
+ * @param[in] value The value of type T to copy to tag data
+ * @param[in] tagDataOffset An optional parameter that specifies where to start set the tag data. For example: if tag data is 20 bytes
+ * and you only need to set the 4 last bytes as integer then use this method like this: setTagDataAs<int>(num, 16).
+ * The default is 0 - start copy to the beginning of tag data
+ */
+ template<typename T>
+ void setTagData(T value, int tagDataOffset = 0)
+ {
+ memcpy(tagData+tagDataOffset, &value, sizeof(T));
+ }
+
+ /**
+ * @return The total size in bytes of this tag which includes: 2[Bytes] (tag name) + 2[Bytes] (tag length) + X[Bytes] (tag data length)
+ */
+ size_t getTagTotalSize() const;
+
+ /**
+ * @return The tag type converted to PPPoEDiscoveryLayer#PPPoETagTypes enum
+ */
+ PPPoEDiscoveryLayer::PPPoETagTypes getType();
+ private:
+ // private c'tor which isn't implemented to make this struct impossible to construct
+ PPPoETag();
+ };
+
+ /**
+ * A constructor that creates the layer from an existing packet raw data
+ * @param[in] data A pointer to the raw data (will be casted to @ref pppoe_header)
+ * @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
+ */
+ PPPoEDiscoveryLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : PPPoELayer(data, dataLen, prevLayer, packet) { m_Protocol = PPPoEDiscovery; m_TagCount = -1; }
+
+ /**
+ * A constructor that allocates a new PPPoE Discovery header with version, type, PPPoE code and session ID
+ * @param[in] version PPPoE version
+ * @param[in] type PPPoE type
+ * @param[in] code PPPoE code enum
+ * @param[in] sessionId PPPoE session ID
+ */
+ PPPoEDiscoveryLayer(uint8_t version, uint8_t type, PPPoELayer::PPPoECode code, uint16_t sessionId) : PPPoELayer(version, type, code, sessionId) { m_Protocol = PPPoEDiscovery; m_TagCount = -1; }
+
+ /**
+ * A copy constructor that copies the entire header from the other PPPoEDiscoveryLayer
+ */
+ PPPoEDiscoveryLayer(const PPPoEDiscoveryLayer& other) : PPPoELayer(other) { m_TagCount = other.m_TagCount; }
+
+ /**
+ * Retrieve a PPPoE tag by tag type. If packet consists of multiple tags of the same type, the first tag will be returned. If packet contains
+ * no tags of the tag type NULL will be returned. Notice the return value is a pointer to the real data casted to PPPoETag type (as opposed
+ * to a copy of the tag data). So changes in the return value will affect the packet data
+ * @param[in] tagType The type of the tag to search
+ * @return A pointer to the tag data casted to PPPoETag*
+ */
+ PPPoETag* getTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType);
+
+ /**
+ * @return The first tag in the PPPoE discovery layer, or NULL if no tags exist. Notice the return value is a pointer to the real data casted to PPPoETag type (as opposed
+ * to a copy of the tag data). So changes in the return value will affect the packet data
+ */
+ PPPoETag* getFirstTag();
+
+ /**
+ * Get the tag which come next to "tag" parameter. If "tag" is NULL or then NULL will be returned. If "tag" is the last tag NULL will be
+ * returned. Notice the return value is a pointer to the real data casted to PPPoETag type (as opposed to a copy of the tag data).
+ * So changes in the return value will affect the packet data
+ * @param[in] tag The tag to start search
+ * @return The next tag or NULL if "tag" is NULL or "tag" is the last tag
+ */
+ PPPoETag* getNextTag(PPPoETag* tag);
+
+ /**
+ * @return The number of tags in this layer
+ */
+ int getTagCount();
+
+ /**
+ * Add a new tag at the end of the layer (after the last tag)
+ * @param[in] tagType The type of the added tag
+ * @param[in] tagLength The length of the tag data
+ * @param[in] tagData A pointer to the tag data. This data will be copied to added tag data. Notice the length of tagData must be tagLength
+ * @return A pointer to the new added tag. Notice this is a pointer to the real data casted to PPPoETag type (as opposed to a copy of
+ * the tag data). So changes in this return value will affect the packet data
+ */
+ PPPoETag* addTag(PPPoETagTypes tagType, uint16_t tagLength, const uint8_t* tagData);
+
+ /**
+ * Add a new tag after an existing tag
+ * @param[in] tagType The type of the added tag
+ * @param[in] tagLength The length of the tag data
+ * @param[in] tagData A pointer to the tag data. This data will be copied to added tag data. Notice the length of tagData must be tagLength
+ * @param[in] prevTag The tag which the new added tag will come after
+ * @return A pointer to the new added tag. Notice this is a pointer to the real data casted to PPPoETag type (as opposed to a copy of
+ * the tag data). So changes in this return value will affect the packet data
+ */
+ PPPoETag* addTagAfter(PPPoETagTypes tagType, uint16_t tagLength, const uint8_t* tagData, PPPoETag* prevTag);
+
+ /**
+ * Remove an existing tag. Tag will be found by the tag type
+ * @param[in] tagType The tag type to remove
+ * @return True if tag was removed or false if tag wasn't found or if tag removal failed (in each case a proper error will be written
+ * to log)
+ */
+ bool removeTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType);
+
+ /**
+ * Remove all tags in this layer
+ * @return True if all tags were successfully or false if removal failed for some reason (a proper error will be written to log)
+ */
+ bool removeAllTags();
+
+ // abstract methods implementation
+
+ /**
+ * Does nothing for this layer (PPPoE discovery is always the last layer)
+ */
+ virtual void parseNextLayer() {};
+
+ /**
+ * @return The header length which is size of strcut pppoe_header plus the total size of tags
+ */
+ virtual size_t getHeaderLen();
+
+ virtual std::string toString() { return "PPP-over-Ethernet Discovery (" + codeToString((PPPoELayer::PPPoECode)getPPPoEHeader()->code) + ")"; }
+
+ private:
+ int m_TagCount;
+
+ PPPoETag* addTagAt(PPPoETagTypes tagType, uint16_t tagLength, const uint8_t* tagData, int offset);
+
+ PPPoETag* castPtrToPPPoETag(uint8_t* ptr);
+
+ std::string codeToString(PPPoECode code);
+ };
+
+
+ // Copied from Wireshark: ppptypes.h
+
+ /** Padding Protocol */
+#define PCPP_PPP_PADDING 0x1
+ /** ROHC small-CID */
+#define PCPP_PPP_ROHC_SCID 0x3
+ /** ROHC large-CID */
+#define PCPP_PPP_ROHC_LCID 0x5
+ /** Internet Protocol version 4 */
+#define PCPP_PPP_IP 0x21
+ /** OSI Network Layer */
+#define PCPP_PPP_OSI 0x23
+ /** Xerox NS IDP */
+#define PCPP_PPP_XNSIDP 0x25
+ /** DECnet Phase IV */
+#define PCPP_PPP_DEC4 0x27
+ /** AppleTalk */
+#define PCPP_PPP_AT 0x29
+ /** Novell IPX */
+#define PCPP_PPP_IPX 0x2b
+ /** Van Jacobson Compressed TCP/IP */
+#define PCPP_PPP_VJC_COMP 0x2d
+ /** Van Jacobson Uncompressed TCP/IP */
+#define PCPP_PPP_VJC_UNCOMP 0x2f
+ /** Bridging PDU */
+#define PCPP_PPP_BCP 0x31
+ /** Stream Protocol (ST-II) */
+#define PCPP_PPP_ST 0x33
+ /** Banyan Vines */
+#define PCPP_PPP_VINES 0x35
+ /** AppleTalk EDDP */
+#define PCPP_PPP_AT_EDDP 0x39
+ /** AppleTalk SmartBuffered */
+#define PCPP_PPP_AT_SB 0x3b
+ /** Multi-Link */
+#define PCPP_PPP_MP 0x3d
+ /** NETBIOS Framing */
+#define PCPP_PPP_NB 0x3f
+ /** Cisco Systems */
+#define PCPP_PPP_CISCO 0x41
+ /** Ascom Timeplex */
+#define PCPP_PPP_ASCOM 0x43
+ /** Fujitsu Link Backup and Load Balancing */
+#define PCPP_PPP_LBLB 0x45
+ /** DCA Remote Lan */
+#define PCPP_PPP_RL 0x47
+ /** Serial Data Transport Protocol */
+#define PCPP_PPP_SDTP 0x49
+ /** SNA over 802.2 */
+#define PCPP_PPP_LLC 0x4b
+ /** SNA */
+#define PCPP_PPP_SNA 0x4d
+ /** IPv6 Header Compression */
+#define PCPP_PPP_IPV6HC 0x4f
+ /** KNX Bridging Data */
+#define PCPP_PPP_KNX 0x51
+ /** Encryption */
+#define PCPP_PPP_ENCRYPT 0x53
+ /** Individual Link Encryption */
+#define PCPP_PPP_ILE 0x55
+ /** Internet Protocol version 6 */
+#define PCPP_PPP_IPV6 0x57
+ /** PPP Muxing */
+#define PCPP_PPP_MUX 0x59
+ /** Vendor-Specific Network Protocol (VSNP) */
+#define PCPP_PPP_VSNP 0x5b
+ /** TRILL Network Protocol (TNP) */
+#define PCPP_PPP_TNP 0x5d
+ /** RTP IPHC Full Header */
+#define PCPP_PPP_RTP_FH 0x61
+ /** RTP IPHC Compressed TCP */
+#define PCPP_PPP_RTP_CTCP 0x63
+ /** RTP IPHC Compressed Non TCP */
+#define PCPP_PPP_RTP_CNTCP 0x65
+ /** RTP IPHC Compressed UDP 8 */
+#define PCPP_PPP_RTP_CUDP8 0x67
+ /** RTP IPHC Compressed RTP 8 */
+#define PCPP_PPP_RTP_CRTP8 0x69
+ /** Stampede Bridging */
+#define PCPP_PPP_STAMPEDE 0x6f
+ /** MP+ Protocol */
+#define PCPP_PPP_MPPLUS 0x73
+ /** NTCITS IPI */
+#define PCPP_PPP_NTCITS_IPI 0xc1
+ /** Single link compression in multilink */
+#define PCPP_PPP_ML_SLCOMP 0xfb
+ /** Compressed datagram */
+#define PCPP_PPP_COMP 0xfd
+ /** 802.1d Hello Packets */
+#define PCPP_PPP_STP_HELLO 0x0201
+ /** IBM Source Routing BPDU */
+#define PCPP_PPP_IBM_SR 0x0203
+ /** DEC LANBridge100 Spanning Tree */
+#define PCPP_PPP_DEC_LB 0x0205
+ /** Cisco Discovery Protocol */
+#define PCPP_PPP_CDP 0x0207
+ /** Netcs Twin Routing */
+#define PCPP_PPP_NETCS 0x0209
+ /** STP - Scheduled Transfer Protocol */
+#define PCPP_PPP_STP 0x020b
+ /** EDP - Extreme Discovery Protocol */
+#define PCPP_PPP_EDP 0x020d
+ /** Optical Supervisory Channel Protocol */
+#define PCPP_PPP_OSCP 0x0211
+ /** Optical Supervisory Channel Protocol */
+#define PCPP_PPP_OSCP2 0x0213
+ /** Luxcom */
+#define PCPP_PPP_LUXCOM 0x0231
+ /** Sigma Network Systems */
+#define PCPP_PPP_SIGMA 0x0233
+ /** Apple Client Server Protocol */
+#define PCPP_PPP_ACSP 0x0235
+ /** MPLS Unicast */
+#define PCPP_PPP_MPLS_UNI 0x0281
+ /** MPLS Multicast */
+#define PCPP_PPP_MPLS_MULTI 0x0283
+ /** IEEE p1284.4 standard - data packets */
+#define PCPP_PPP_P12844 0x0285
+ /** ETSI TETRA Network Procotol Type 1 */
+#define PCPP_PPP_TETRA 0x0287
+ /** Multichannel Flow Treatment Protocol */
+#define PCPP_PPP_MFTP 0x0289
+ /** RTP IPHC Compressed TCP No Delta */
+#define PCPP_PPP_RTP_CTCPND 0x2063
+ /** RTP IPHC Context State */
+#define PCPP_PPP_RTP_CS 0x2065
+ /** RTP IPHC Compressed UDP 16 */
+#define PCPP_PPP_RTP_CUDP16 0x2067
+ /** RTP IPHC Compressed RTP 16 */
+#define PCPP_PPP_RTP_CRDP16 0x2069
+ /** Cray Communications Control Protocol */
+#define PCPP_PPP_CCCP 0x4001
+ /** CDPD Mobile Network Registration Protocol */
+#define PCPP_PPP_CDPD_MNRP 0x4003
+ /** Expand accelerator protocol */
+#define PCPP_PPP_EXPANDAP 0x4005
+ /** ODSICP NCP */
+#define PCPP_PPP_ODSICP 0x4007
+ /** DOCSIS DLL */
+#define PCPP_PPP_DOCSIS 0x4009
+ /** Cetacean Network Detection Protocol */
+#define PCPP_PPP_CETACEANNDP 0x400b
+ /** Stacker LZS */
+#define PCPP_PPP_LZS 0x4021
+ /** RefTek Protocol */
+#define PCPP_PPP_REFTEK 0x4023
+ /** Fibre Channel */
+#define PCPP_PPP_FC 0x4025
+ /** EMIT Protocols */
+#define PCPP_PPP_EMIT 0x4027
+ /** Vendor-Specific Protocol (VSP) */
+#define PCPP_PPP_VSP 0x405b
+ /** TRILL Link State Protocol (TLSP) */
+#define PCPP_PPP_TLSP 0x405d
+ /** Internet Protocol Control Protocol */
+#define PCPP_PPP_IPCP 0x8021
+ /** OSI Network Layer Control Protocol */
+#define PCPP_PPP_OSINLCP 0x8023
+ /** Xerox NS IDP Control Protocol */
+#define PCPP_PPP_XNSIDPCP 0x8025
+ /** DECnet Phase IV Control Protocol */
+#define PCPP_PPP_DECNETCP 0x8027
+ /** AppleTalk Control Protocol */
+#define PCPP_PPP_ATCP 0x8029
+ /** Novell IPX Control Protocol */
+#define PCPP_PPP_IPXCP 0x802b
+ /** Bridging NCP */
+#define PCPP_PPP_BRIDGENCP 0x8031
+ /** Stream Protocol Control Protocol */
+#define PCPP_PPP_SPCP 0x8033
+ /** Banyan Vines Control Protocol */
+#define PCPP_PPP_BVCP 0x8035
+ /** Multi-Link Control Protocol */
+#define PCPP_PPP_MLCP 0x803d
+ /** NETBIOS Framing Control Protocol */
+#define PCPP_PPP_NBCP 0x803f
+ /** Cisco Systems Control Protocol */
+#define PCPP_PPP_CISCOCP 0x8041
+ /** Ascom Timeplex Control Protocol (?) */
+#define PCPP_PPP_ASCOMCP 0x8043
+ /** Fujitsu LBLB Control Protocol */
+#define PCPP_PPP_LBLBCP 0x8045
+ /** DCA Remote Lan Network Control Protocol */
+#define PCPP_PPP_RLNCP 0x8047
+ /** Serial Data Control Protocol */
+#define PCPP_PPP_SDCP 0x8049
+ /** SNA over 802.2 Control Protocol */
+#define PCPP_PPP_LLCCP 0x804b
+ /** SNA Control Protocol */
+#define PCPP_PPP_SNACP 0x804d
+ /** IP6 Header Compression Control Protocol */
+#define PCPP_PPP_IP6HCCP 0x804f
+ /** KNX Bridging Control Protocol */
+#define PCPP_PPP_KNXCP 0x8051
+ /** Encryption Control Protocol */
+#define PCPP_PPP_ECP 0x8053
+ /** Individual Link Encryption Control Protocol */
+#define PCPP_PPP_ILECP 0x8055
+ /** IPv6 Control Protocol */
+#define PCPP_PPP_IPV6CP 0x8057
+ /** PPP Muxing Control Protocol */
+#define PCPP_PPP_MUXCP 0x8059
+ /** Vendor-Specific Network Control Protocol (VSNCP) [RFC3772] */
+#define PCPP_PPP_VSNCP 0x805b
+ /** TRILL Network Control Protocol (TNCP) */
+#define PCPP_PPP_TNCP 0x805d
+ /** Stampede Bridging Control Protocol */
+#define PCPP_PPP_STAMPEDECP 0x806f
+ /** MP+ Contorol Protocol */
+#define PCPP_PPP_MPPCP 0x8073
+ /** NTCITS IPI Control Protocol */
+#define PCPP_PPP_IPICP 0x80c1
+ /** Single link compression in multilink control */
+#define PCPP_PPP_SLCC 0x80fb
+ /** Compression Control Protocol */
+#define PCPP_PPP_CCP 0x80fd
+ /** Cisco Discovery Protocol Control Protocol */
+#define PCPP_PPP_CDPCP 0x8207
+ /** Netcs Twin Routing */
+#define PCPP_PPP_NETCSCP 0x8209
+ /** STP - Control Protocol */
+#define PCPP_PPP_STPCP 0x820b
+ /** EDPCP - Extreme Discovery Protocol Control Protocol */
+#define PCPP_PPP_EDPCP 0x820d
+ /** Apple Client Server Protocol Control */
+#define PCPP_PPP_ACSPC 0x8235
+ /** MPLS Control Protocol */
+#define PCPP_PPP_MPLSCP 0x8281
+ /** IEEE p1284.4 standard - Protocol Control */
+#define PCPP_PPP_P12844CP 0x8285
+ /** ETSI TETRA TNP1 Control Protocol */
+#define PCPP_PPP_TETRACP 0x8287
+ /** Multichannel Flow Treatment Protocol */
+#define PCPP_PPP_MFTPCP 0x8289
+ /** Link Control Protocol */
+#define PCPP_PPP_LCP 0xc021
+ /** Password Authentication Protocol */
+#define PCPP_PPP_PAP 0xc023
+ /** Link Quality Report */
+#define PCPP_PPP_LQR 0xc025
+ /** Shiva Password Authentication Protocol */
+#define PCPP_PPP_SPAP 0xc027
+ /** CallBack Control Protocol (CBCP) */
+#define PCPP_PPP_CBCP 0xc029
+ /** BACP Bandwidth Allocation Control Protocol */
+#define PCPP_PPP_BACP 0xc02b
+ /** BAP Bandwidth Allocation Protocol */
+#define PCPP_PPP_BAP 0xc02d
+ /** Vendor-Specific Authentication Protocol (VSAP) */
+#define PCPP_PPP_VSAP 0xc05b
+ /** Container Control Protocol */
+#define PCPP_PPP_CONTCP 0xc081
+ /** Challenge Handshake Authentication Protocol */
+#define PCPP_PPP_CHAP 0xc223
+ /** RSA Authentication Protocol */
+#define PCPP_PPP_RSAAP 0xc225
+ /** Extensible Authentication Protocol */
+#define PCPP_PPP_EAP 0xc227
+ /** Mitsubishi Security Information Exchange Protocol (SIEP) */
+#define PCPP_PPP_SIEP 0xc229
+ /** Stampede Bridging Authorization Protocol */
+#define PCPP_PPP_SBAP 0xc26f
+ /** Proprietary Authentication Protocol */
+#define PCPP_PPP_PRPAP 0xc281
+ /** Proprietary Authentication Protocol */
+#define PCPP_PPP_PRPAP2 0xc283
+ /** Proprietary Node ID Authentication Protocol */
+#define PCPP_PPP_PRPNIAP 0xc481
+
+} // namespace pcpp
+
+#endif /* PACKETPP_PPPOE_LAYER */