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:33 UTC
[19/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/GreLayer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/GreLayer.h b/thirdparty/pcap++/Packet++/header/GreLayer.h
new file mode 100644
index 0000000..63259cb
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/GreLayer.h
@@ -0,0 +1,425 @@
+#ifndef PACKETPP_GRE_LAYER
+#define PACKETPP_GRE_LAYER
+
+#include <Layer.h>
+
+/// @file
+
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+ /**
+ * @struct gre_basic_header
+ * Represents GRE basic protocol header (common for GREv0 and GREv1)
+ */
+#pragma pack(push, 1)
+ struct gre_basic_header
+ {
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+ /** Number of additional encapsulations which are permitted. 0 is the default value */
+ uint8_t recursionControl:3,
+ /** Strict source routing bit (GRE v0 only) */
+ strictSourceRouteBit:1,
+ /** Set if sequence number exists */
+ sequenceNumBit:1,
+ /** Set if key exists */
+ keyBit:1,
+ /** Set if routing exists (GRE v0 only) */
+ routingBit:1,
+ /** Set if checksum exists (GRE v0 only) */
+ checksumBit:1;
+#else
+ /** Set if checksum exists (GRE v0 only) */
+ uint8_t checksumBit:1,
+ /** Set if routing exists (GRE v0 only) */
+ routingBit:1,
+ /** Set if key exists */
+ keyBit:1,
+ /** Set if sequence number exists */
+ sequenceNumBit:1,
+ /** Strict source routing bit (GRE v0 only) */
+ strictSourceRouteBit:1,
+ /** Number of additional encapsulations which are permitted. 0 is the default value */
+ recursionControl:3;
+#endif
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+ /** GRE version - can be 0 or 1 */
+ uint8_t version:3,
+ /** Reserved */
+ flags:4,
+ /** Set if acknowledgment number is set (GRE v1 only) */
+ ackSequenceNumBit:1;
+#else
+ /** Set if acknowledgment number is set (GRE v1 only) */
+ uint8_t ackSequenceNumBit:1,
+ /** Reserved */
+ flags:4,
+ /** GRE version - can be 0 or 1 */
+ version:3;
+#endif
+
+ /** Protocol type of the next layer */
+ uint16_t protocol;
+ };
+#pragma pack(pop)
+
+
+ /**
+ * @struct gre1_header
+ * Represents GREv1 protocol header
+ */
+#pragma pack(push, 1)
+ struct gre1_header : gre_basic_header
+ {
+ /** Size of the payload not including the GRE header */
+ uint16_t payloadLength;
+ /** Contains the Peer's Call ID for the session to which this packet belongs */
+ uint16_t callID;
+ };
+#pragma pack(pop)
+
+
+ /**
+ * @struct ppp_pptp_header
+ * Represents PPP layer that comes after GREv1 as part of PPTP protocol
+ */
+#pragma pack(push, 1)
+ struct ppp_pptp_header
+ {
+ /** Broadcast address */
+ uint8_t address;
+ /** Control byte */
+ uint8_t control;
+ /** Protocol type of the next layer (see PPP_* macros at PPPoELayer.h) */
+ uint16_t protocol;
+ };
+#pragma pack(pop)
+
+
+ /**
+ * @class GreLayer
+ * Abstract base class for GRE layers (GREv0Layer and GREv1Layer). Cannot be instantiated and contains common logic for derived classes
+ */
+ class GreLayer : public Layer
+ {
+ public:
+
+ virtual ~GreLayer() {}
+
+ /**
+ * A static method that determines the GRE version of GRE layer raw data by looking at the gre_basic_header#version
+ * field
+ * @param[in] greData GRE layer raw data
+ * @param[in] greDataLen Size of raw data
+ * @return ::GREv0 or ::GREv1 values if raw data is GREv0 or GREv1 (accordingly) or ::UnknownProtocol otherwise
+ */
+ static ProtocolType getGREVersion(uint8_t* greData, size_t greDataLen);
+
+ /**
+ * Get sequence number value if field exists in layer
+ * @param[out] seqNumber The returned sequence number value if exists in layer. Else remain unchanged
+ * @return True if sequence number field exists in layer. In this case seqNumber will be filled with the value.
+ * Or false if sequence number field doesn't exist in layer
+ */
+ bool getSequenceNumber(uint32_t& seqNumber);
+
+ /**
+ * Set sequence number value. If field already exists (gre_basic_header#sequenceNumBit is set) then only the new
+ * value is set. If field doesn't exist it will be added to the layer, gre_basic_header#sequenceNumBit will be set
+ * and the new value will be set
+ * @param[in] seqNumber The sequence number value to set
+ * @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer)
+ */
+ bool setSequenceNumber(uint32_t seqNumber);
+
+ /**
+ * Unset sequence number and remove it from the layer
+ * @return True if managed to unset successfully or false (and error log) if sequence number wasn't set in the first
+ * place or if didn't manage to remove it from the layer
+ */
+ bool unsetSequenceNumber();
+
+
+ // implement abstract methods
+
+ /**
+ * Currently identifies the following next layers: IPv4Layer, IPv6Layer, VlanLayer, MplsLayer and PPP_PPTPLayer.
+ * Otherwise sets PayloadLayer
+ */
+ void parseNextLayer();
+
+ /**
+ * @return Size of GRE header (may change if optional fields are added or removed)
+ */
+ size_t getHeaderLen();
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelNetworkLayer; }
+
+ protected:
+ GreLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { }
+
+ GreLayer() {}
+
+ enum GreField
+ {
+ GreChecksumOrRouting = 0,
+ GreKey = 1,
+ GreSeq = 2,
+ GreAck = 3
+ };
+
+ uint8_t* getFieldValue(GreField field, bool returnOffsetEvenIfFieldMissing);
+
+ void computeCalculateFieldsInner();
+ };
+
+
+ /**
+ * @class GREv0Layer
+ * Represents a GRE version 0 protocol. Limitation: currently this layer doesn't support GRE routing information parsing
+ * and editing. So if a GREv0 packet includes routing information it won't be parse correctly. I didn't add it because
+ * of lack of time, but if you need it please tell me and I'll add it
+ */
+ class GREv0Layer : public GreLayer
+ {
+ 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
+ */
+ GREv0Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : GreLayer(data, dataLen, prevLayer, packet) { m_Protocol = GREv0; }
+
+ /**
+ * A constructor that creates a new GREv0 header and allocates the data
+ */
+ GREv0Layer();
+
+ virtual ~GREv0Layer() {}
+
+ /**
+ * Get a pointer to the basic GRE header containing only non-optional fields. Notice this points directly to the data,
+ * so every change will change the actual packet data. Also please notice that changing the set bits
+ * (gre_basic_header#strictSourceRouteBit, gre_basic_header#sequenceNumBit, gre_basic_header#keyBit, gre_basic_header#routingBit,
+ * gre_basic_header#checksumBit, gre_basic_header#ackSequenceNumBit) without using the proper set or unset methods (such
+ * as setChecksum(), unsetChecksum(), etc.) may result to wrong calculation of header length and really weird bugs.
+ * Please avoid doing so
+ * @return A pointer to the gre_basic_header
+ */
+ inline gre_basic_header* getGreHeader() { return (gre_basic_header*)m_Data; }
+
+ /**
+ * Get checksum value if field exists in layer
+ * @param[out] checksum The returned checksum value if exists in layer. Else remain unchanged
+ * @return True if checksum field exists in layer. In this case checksum parameter will be filled with the value.
+ * Or false if checksum field doesn't exist in layer
+ */
+ bool getChecksum(uint16_t& checksum);
+
+ /**
+ * Set checksum value. If checksum or offset fields already exist (gre_basic_header#checksumBit or gre_basic_header#routingBit are set)
+ * then only the new value is set. If both fields don't exist a new 4-byte value will be added to the layer,
+ * gre_basic_header#checksumBit will be set (gre_basic_header#routingBit will remain unset), the new checksum value
+ * will be set and offset value will be set to 0. The reason both fields are added is that GREv0 protocol states
+ * both of them or none of them should exist on packet (even if only one of the bits are set)
+ * @param[in] checksum The checksum value to set
+ * @return True if managed to set the value/s successfully, or false otherwise (if couldn't extend the layer)
+ */
+ bool setChecksum(uint16_t checksum);
+
+ /**
+ * Unset checksum and possibly remove it from the layer. It will be removed from the layer only if gre_basic_header#routingBit
+ * is not set as well. Otherwise checksum field will remain on packet with value of 0
+ * @return True if managed to unset successfully or false (and error log) if checksum wasn't set in the first
+ * place or if didn't manage to remove it from the layer
+ */
+ bool unsetChecksum();
+
+ /**
+ * Get offset value if field exists in layer. Notice there is no setOffset() method as GRE routing information isn't
+ * supported yet (see comment on class description)
+ * @param[out] offset The returned offset value if exists in layer. Else remain unchanged
+ * @return True if offset field exists in layer. In this case offset parameter will be filled with the value.
+ * Or false if offset field doesn't exist in layer
+ */
+ bool getOffset(uint16_t& offset);
+
+ /**
+ * Get key value if field exists in layer
+ * @param[out] key The returned key value if exists in layer. Else remain unchanged
+ * @return True if key field exists in layer. In this case key parameter will be filled with the value.
+ * Or false if key field doesn't exist in layer
+ */
+ bool getKey(uint32_t& key);
+
+ /**
+ * Set key value. If field already exists (gre_basic_header#keyBit is set) then only the new value is set.
+ * If field doesn't exist it will be added to the layer, gre_basic_header#keyBit will be set
+ * and the new value will be set
+ * @param[in] key The key value to set
+ * @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer)
+ */
+ bool setKey(uint32_t key);
+
+ /**
+ * Unset key and remove it from the layer
+ * @return True if managed to unset successfully or false (and error log) if key wasn't set in the first
+ * place or if didn't manage to remove it from the layer
+ */
+ bool unsetKey();
+
+
+ // implement abstract methods
+
+
+ /**
+ * Calculate the following fields:
+ * - gre_basic_header#protocol
+ * - GRE checksum field (if exists in packet)
+ */
+ void computeCalculateFields();
+
+ std::string toString();
+
+ };
+
+
+ /**
+ * @class GREv1Layer
+ * Represents a GRE version 1 protocol
+ */
+ class GREv1Layer : public GreLayer
+ {
+ 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
+ */
+ GREv1Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : GreLayer(data, dataLen, prevLayer, packet) { m_Protocol = GREv1; }
+
+ /**
+ * A constructor that creates a new GREv1 header and allocates the data
+ * @param[in] callID The call ID to set
+ */
+ GREv1Layer(uint16_t callID);
+
+ virtual ~GREv1Layer() {}
+
+ /**
+ * Get a pointer to the basic GREv1 header containing all non-optional fields. Notice this points directly to the data, so every change will change the actual
+ * packet data. Also please notice that changing the set bits (gre_basic_header#strictSourceRouteBit, gre_basic_header#sequenceNumBit, gre_basic_header#keyBit,
+ * gre_basic_header#routingBit, gre_basic_header#checksumBit, gre_basic_header#ackSequenceNumBit) without using the proper set or unset methods
+ * (such as setAcknowledgmentNum(), unsetSequenceNumber(), etc.) may result to wrong calculation of header length or illegal GREv1 packet and
+ * to some really weird bugs. Please avoid doing so
+ * @return A pointer to the gre1_header
+ */
+ inline gre1_header* getGreHeader() { return (gre1_header*)m_Data; }
+
+ /**
+ * Get acknowledgment (ack) number value if field exists in layer
+ * @param[out] ackNum The returned ack number value if exists in layer. Else remain unchanged
+ * @return True if ack number field exists in layer. In this case ackNum will be filled with the value.
+ * Or false if ack number field doesn't exist in layer
+ */
+ bool getAcknowledgmentNum(uint32_t& ackNum);
+
+ /**
+ * Set acknowledgment (ack) number value. If field already exists (gre_basic_header#ackSequenceNumBit is set)
+ * then only the new value is set. If field doesn't exist it will be added to the layer,
+ * gre_basic_header#ackSequenceNumBit will be set and the new value will be set
+ * @param[in] ackNum The ack number value to set
+ * @return True if managed to set the value successfully, or false otherwise (if couldn't extend the layer)
+ */
+ bool setAcknowledgmentNum(uint32_t ackNum);
+
+ /**
+ * Unset acknowledgment (ack) number and remove it from the layer
+ * @return True if managed to unset successfully or false (and error log) if ack number wasn't set in the first
+ * place or if didn't manage to remove it from the layer
+ */
+ bool unsetAcknowledgmentNum();
+
+
+ // implement abstract methods
+
+ /**
+ * Calculate the following fields:
+ * - gre1_header#payloadLength
+ * - gre_basic_header#protocol
+ */
+ void computeCalculateFields();
+
+ std::string toString();
+
+ };
+
+
+ /**
+ * @class PPP_PPTPLayer
+ * Represent a PPP (point-to-point) protocol header that comes after GREv1 header, as part of PPTP - Point-to-Point Tunneling Protocol
+ */
+ class PPP_PPTPLayer : public Layer
+ {
+ 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 ppp_pptp_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
+ */
+ PPP_PPTPLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = PPP_PPTP; }
+
+ /**
+ * A constructor that allocates a new PPP-PPTP header
+ * @param[in] address Address field
+ * @param[in] control Control field
+ */
+ PPP_PPTPLayer(uint8_t address, uint8_t control);
+
+ ~PPP_PPTPLayer() {}
+
+ /**
+ * Get a pointer to the PPP-PPTP header. Notice this points directly to the data, so every change will change the actual packet data
+ * @return A pointer to the @ref ppp_pptp_header
+ */
+ inline ppp_pptp_header* getPPP_PPTPHeader() { return (ppp_pptp_header*)m_Data; };
+
+
+ // implement abstract methods
+
+ /**
+ * Currently identifies the following next layers: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer
+ */
+ void parseNextLayer();
+
+ /**
+ * @return The size of @ref ppp_pptp_header
+ */
+ inline size_t getHeaderLen() { return sizeof(ppp_pptp_header); }
+
+ /**
+ * Calculate the following fields:
+ * - ppp_pptp_header#protocol
+ */
+ void computeCalculateFields();
+
+ std::string toString() { return "PPP for PPTP Layer"; }
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelSesionLayer; }
+
+ };
+
+} // namespace pcpp
+
+#endif /* PACKETPP_GRE_LAYER */
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/HttpLayer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/HttpLayer.h b/thirdparty/pcap++/Packet++/header/HttpLayer.h
new file mode 100644
index 0000000..d6b09e9
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/HttpLayer.h
@@ -0,0 +1,700 @@
+#ifndef PACKETPP_HTTP_LAYER
+#define PACKETPP_HTTP_LAYER
+
+#include "TextBasedProtocol.h"
+#include <string>
+#include <exception>
+#include <map>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+ /**
+ * An enum for HTTP version
+ */
+ enum HttpVersion
+ {
+ /** HTTP/0.9 */
+ ZeroDotNine,
+ /** HTTP/1.0 */
+ OneDotZero,
+ /** HTTP/1.1 */
+ OneDotOne,
+ /** Unknown HTTP version */
+ HttpVersionUnknown
+ };
+
+ // some popular HTTP fields
+
+ /** Host field */
+#define PCPP_HTTP_HOST_FIELD "Host"
+ /** Connection field */
+#define PCPP_HTTP_CONNECTION_FIELD "Connection"
+ /** User-Agent field */
+#define PCPP_HTTP_USER_AGENT_FIELD "User-Agent"
+ /** Referer field */
+#define PCPP_HTTP_REFERER_FIELD "Referer"
+ /** Accept field */
+#define PCPP_HTTP_ACCEPT_FIELD "Accept"
+ /** Accept-Encoding field */
+#define PCPP_HTTP_ACCEPT_ENCODING_FIELD "Accept-Encoding"
+ /** Accept-Language field */
+#define PCPP_HTTP_ACCEPT_LANGUAGE_FIELD "Accept-Language"
+ /** Cookie field */
+#define PCPP_HTTP_COOKIE_FIELD "Cookie"
+ /** Content-Length field */
+#define PCPP_HTTP_CONTENT_LENGTH_FIELD "Content-Length"
+ /** Content-Encoding field */
+#define PCPP_HTTP_CONTENT_ENCODING_FIELD "Content-Encoding"
+ /** Content-Type field */
+#define PCPP_HTTP_CONTENT_TYPE_FIELD "Content-Type"
+ /** Transfer-Encoding field */
+#define PCPP_HTTP_TRANSFER_ENCODING_FIELD "Transfer-Encoding"
+ /** Server field */
+#define PCPP_HTTP_SERVER_FIELD "Server"
+
+
+
+ // -------- Class HttpMessage -----------------
+
+
+ /**
+ * @class HttpMessage
+ * Represents a general HTTP message. It's an abstract class and cannot be instantiated. It's inherited by HttpRequestLayer and HttpResponseLayer
+ */
+ class HttpMessage : public TextBasedProtocolMessage
+ {
+ public:
+
+ virtual ~HttpMessage() {}
+
+ /**
+ * @return A pointer to a map containing all TCP ports recognize as HTTP
+ */
+ static const std::map<uint16_t, bool>* getHTTPPortMap();
+
+ // overriden methods
+
+ virtual HeaderField* addField(const std::string& fieldName, const std::string& fieldValue);
+ virtual HeaderField* addField(const HeaderField& newField);
+ virtual HeaderField* insertField(HeaderField* prevField, const std::string& fieldName, const std::string& fieldValue);
+ virtual HeaderField* insertField(HeaderField* prevField, const HeaderField& newField);
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelApplicationLayer; }
+
+ protected:
+ HttpMessage(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : TextBasedProtocolMessage(data, dataLen, prevLayer, packet) {}
+ HttpMessage() : TextBasedProtocolMessage() {}
+ HttpMessage(const HttpMessage& other) : TextBasedProtocolMessage(other) {}
+ HttpMessage& operator=(const HttpMessage& other) { TextBasedProtocolMessage::operator=(other); return *this; }
+
+ // implementation of abstract methods
+ char getHeaderFieldNameValueSeparator() { return ':'; }
+ bool spacesAllowedBetweenHeaderFieldNameAndValue() { return true; }
+ };
+
+
+
+
+ class HttpRequestFirstLine;
+
+
+
+
+ // -------- Class HttpRequestLayer -----------------
+
+ /**
+ * @class HttpRequestLayer
+ * Represents an HTTP request header and inherits all basic functionality of HttpMessage and TextBasedProtocolMessage.
+ * The functionality that is added for this class is the HTTP first line concept. An HTTP request has the following first line:
+ * <i>GET /bla/blabla.asp HTTP/1.1</i>
+ * Since it's not an "ordinary" HTTP field, it requires a special treatment and gets a class of it's own: HttpRequestFirstLine.
+ * Unlike most L2-4 protocols, an HTTP request header can spread over more than 1 packet. PcapPlusPlus currently doesn't support a header
+ * that is spread over more than 1 packet so in such cases: 1) only the first packet will be parsed as HttpRequestLayer (the other packets
+ * won't be recognized as HttpRequestLayer) and 2) the HTTP header for the first packet won't be complete (as it continues in the following
+ * packets), this why PcapPlusPlus can indicate that HTTP request header is complete or not(doesn't end with "\r\n\r\n" or "\n\n") using
+ * HttpMessage#isHeaderComplete()
+ */
+ class HttpRequestLayer : public HttpMessage
+ {
+ friend class HttpRequestFirstLine;
+ public:
+ /**
+ * HTTP request methods
+ */
+ enum HttpMethod
+ {
+ /** GET */
+ HttpGET,
+ /** HEAD */
+ HttpHEAD,
+ /** POST */
+ HttpPOST,
+ /** PUT */
+ HttpPUT,
+ /** DELETE */
+ HttpDELETE,
+ /** TRACE */
+ HttpTRACE,
+ /** OPTIONS */
+ HttpOPTIONS,
+ /** CONNECT */
+ HttpCONNECT,
+ /** PATCH */
+ HttpPATCH,
+ /** Unknown HTTP method */
+ HttpMethodUnknown
+ };
+
+ /** 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
+ */
+ HttpRequestLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
+
+ /**
+ * A constructor that allocates a new HTTP request header with only the first line filled. Object will be created without further fields.
+ * The user can then add fields using addField() methods
+ * @param[in] method The HTTP method used in this HTTP request
+ * @param[in] uri The URI of the first line
+ * @param[in] version HTTP version to be used in this request
+ */
+ HttpRequestLayer(HttpMethod method, std::string uri, HttpVersion version);
+
+ virtual ~HttpRequestLayer();
+
+ /**
+ * A copy constructor for this layer. This copy constructor inherits base copy constructor HttpMessage#HttpMessage() and add the functionality
+ * of copying the first line as well
+ * @param[in] other The instance to copy from
+ */
+ HttpRequestLayer(const HttpRequestLayer& other);
+
+ /**
+ * An assignment operator overload for this layer. This method inherits base assignment operator HttpMessage#operator=() and add the functionality
+ * of copying the first line as well
+ * @param[in] other The instance to copy from
+ */
+ HttpRequestLayer& operator=(const HttpRequestLayer& other);
+
+ /**
+ * @return A pointer to the first line instance for this message
+ */
+ inline HttpRequestFirstLine* getFirstLine() { return m_FirstLine; }
+
+ /**
+ * The URL is hostname+uri. So given the following URL, for example: "www.cnn.com/main.html", the hostname is "www.cnn.com" and the URI
+ * is "/.main.html". URI and hostname are split to 2 different places inside the HTTP request packet: URI is in the first line and hostname
+ * is in "HOST" field.
+ * This methods concatenates the hostname and URI to the full URL
+ * @return The URL of the HTTP request message
+ */
+ std::string getUrl();
+
+ // implement Layer's abstract methods
+ std::string toString();
+
+ private:
+ HttpRequestFirstLine* m_FirstLine;
+ };
+
+
+
+
+
+ // -------- Class HttpResponseLayer -----------------
+
+ class HttpResponseFirstLine;
+
+
+ /**
+ * @class HttpResponseLayer
+ * Represents an HTTP response header and inherits all basic functionality of HttpMessage and TextBasedProtocolMessage.
+ * The functionality that is added for this class is the HTTP first line concept. An HTTP response has the following first line:
+ * <i>200 OK HTTP/1.1</i>
+ * Since it's not an "ordinary" HTTP field, it requires a special treatment and gets a class of it's own: HttpResponseFirstLine.
+ * Unlike most L2-4 protocols, an HTTP response header can spread over more than 1 packet. PcapPlusPlus currently doesn't support a header
+ * that is spread over more than 1 packet so in such cases: 1) only the first packet will be parsed as HttpResponseLayer (the other packets
+ * won't be recognized as HttpResponseLayer) and 2) the HTTP header for the first packet won't be complete (as it continues in the following
+ * packets), this why PcapPlusPlus can indicate that HTTP response header is complete or not (doesn't end with "\r\n\r\n" or "\n\n") using
+ * HttpMessage#isHeaderComplete()
+ */
+ class HttpResponseLayer : public HttpMessage
+ {
+ friend class HttpResponseFirstLine;
+ public:
+ /**
+ * Enum for HTTP response status codes
+ */
+ enum HttpResponseStatusCode
+ {
+ /** 100 Continue*/
+ Http100Continue,
+ /** 101 Switching Protocols*/
+ Http101SwitchingProtocols,
+ /** 102 Processing */
+ Http102Processing,
+ /** 200 OK */
+ Http200OK,
+ /** 201 Created */
+ Http201Created,
+ /** 202 Accepted */
+ Http202Accepted,
+ /** 203 Non-Authoritative Information */
+ Http203NonAuthoritativeInformation,
+ /** 204 No Content*/
+ Http204NoContent,
+ /** 205 Reset Content*/
+ http205ResetContent,
+ /** 206 Partial Content */
+ Http206PartialContent,
+ /** 207 Multi-Status */
+ Http207MultiStatus,
+ /** 208 Already Reported */
+ Http208AlreadyReported,
+ /** 226 IM Used */
+ Http226IMUsed,
+ /** 300 Multiple Choices */
+ Http300MultipleChoices,
+ /** 301 Moved Permanently */
+ Http301MovedPermanently,
+ /** 302 (various messages) */
+ Http302,
+ /** 303 See Other */
+ Http303SeeOther,
+ /** 304 Not Modified */
+ Http304NotModified,
+ /** 305 Use Proxy */
+ Http305UseProxy,
+ /** 306 Switch Proxy */
+ Http306SwitchProxy,
+ /** 307 Temporary Redirect */
+ Http307TemporaryRedirect,
+ /** 308 Permanent Redirect, */
+ Http308PermanentRedirect,
+ /** 400 Bad Request */
+ Http400BadRequest,
+ /** 401 Unauthorized */
+ Http401Unauthorized,
+ /** 402 Payment Required */
+ Http402PaymentRequired,
+ /** 403 Forbidden */
+ Http403Forbidden,
+ /** 404 Not Found */
+ Http404NotFound,
+ /** 405 Method Not Allowed */
+ Http405MethodNotAllowed,
+ /** 406 Not Acceptable */
+ Http406NotAcceptable,
+ /** 407 Proxy Authentication Required */
+ Http407ProxyAuthenticationRequired,
+ /** 408 Request Timeout */
+ Http408RequestTimeout,
+ /** 409 Conflict */
+ Http409Conflict,
+ /** 410 Gone */
+ Http410Gone,
+ /** 411 Length Required */
+ Http411LengthRequired,
+ /** 412 Precondition Failed */
+ Http412PreconditionFailed,
+ /** 413 RequestEntity Too Large */
+ Http413RequestEntityTooLarge,
+ /** 414 Request-URI Too Long */
+ Http414RequestURITooLong,
+ /** 415 Unsupported Media Type */
+ Http415UnsupportedMediaType,
+ /** 416 Requested Range Not Satisfiable */
+ Http416RequestedRangeNotSatisfiable,
+ /** 417 Expectation Failed */
+ Http417ExpectationFailed,
+ /** 418 I'm a teapot */
+ Http418Imateapot,
+ /** 419 Authentication Timeout */
+ Http419AuthenticationTimeout,
+ /** 420 (various messages) */
+ Http420,
+ /** 422 Unprocessable Entity */
+ Http422UnprocessableEntity,
+ /** 423 Locked */
+ Http423Locked,
+ /** 424 Failed Dependency */
+ Http424FailedDependency,
+ /** 426 Upgrade Required */
+ Http426UpgradeRequired,
+ /** 428 Precondition Required */
+ Http428PreconditionRequired,
+ /** 429 Too Many Requests */
+ Http429TooManyRequests,
+ /** 431 Request Header Fields Too Large */
+ Http431RequestHeaderFieldsTooLarge,
+ /** 440 Login Timeout */
+ Http440LoginTimeout,
+ /** 444 No Response */
+ Http444NoResponse,
+ /** 449 Retry With */
+ Http449RetryWith,
+ /** 450 Blocked by Windows Parental Controls */
+ Http450BlockedByWindowsParentalControls,
+ /** 451 (various messages) */
+ Http451,
+ /** 494 Request Header Too Large */
+ Http494RequestHeaderTooLarge,
+ /** 495 Cert Error */
+ Http495CertError,
+ /** 496 No Cert */
+ Http496NoCert,
+ /** 497 HTTP to HTTPS */
+ Http497HTTPtoHTTPS,
+ /** 498 Token expired/invalid */
+ Http498TokenExpiredInvalid,
+ /** 499 (various messages) */
+ Http499,
+ /** 500 Internal Server Error */
+ Http500InternalServerError,
+ /** 501 Not Implemented */
+ Http501NotImplemented,
+ /** 502 Bad Gateway */
+ Http502BadGateway,
+ /** 503 Service Unavailable */
+ Http503ServiceUnavailable,
+ /** 504 Gateway Timeout */
+ Http504GatewayTimeout,
+ /** 505 HTTP Version Not Supported */
+ Http505HTTPVersionNotSupported,
+ /** 506 Variant Also Negotiates */
+ Http506VariantAlsoNegotiates,
+ /** 507 Insufficient Storage */
+ Http507InsufficientStorage,
+ /** 508 Loop Detected */
+ Http508LoopDetected,
+ /** 509 Bandwidth Limit Exceeded */
+ Http509BandwidthLimitExceeded,
+ /** 510 Not Extended */
+ Http510NotExtended,
+ /** 511 Network Authentication Required */
+ Http511NetworkAuthenticationRequired,
+ /** 520 Origin Error */
+ Http520OriginError,
+ /** 521 Web server is down */
+ Http521WebServerIsDown,
+ /** 522 Connection timed out */
+ Http522ConnectionTimedOut,
+ /** 523 Proxy Declined Request */
+ Http523ProxyDeclinedRequest,
+ /** 524 A timeout occurred */
+ Http524aTimeoutOccurred,
+ /** 598 Network read timeout error */
+ Http598NetworkReadTimeoutError,
+ /** 599 Network connect timeout error */
+ Http599NetworkConnectTimeoutError,
+ /** Unknown status code */
+ HttpStatusCodeUnknown
+ };
+
+
+ /** 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
+ */
+ HttpResponseLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
+
+ /**
+ * A constructor that allocates a new HTTP response header with only the first line filled. Object will be created without further fields.
+ * The user can then add fields using addField() methods
+ * @param[in] version HTTP version to be used
+ * @param[in] statusCode Status code to be used
+ * @param[in] statusCodeString Most status codes have their default string, e.g 200 is usually "OK", 404 is usually "Not Found", etc.
+ * But the user can set a non-default status code string and it will be written in the header first line. Empty string ("") means using the
+ * default status code string
+ */
+ HttpResponseLayer(HttpVersion version, HttpResponseLayer::HttpResponseStatusCode statusCode, std::string statusCodeString = "");
+
+ virtual ~HttpResponseLayer();
+
+ /**
+ * A copy constructor for this layer. This copy constructor inherits base copy constructor HttpMessage#HttpMessage() and adds the functionality
+ * of copying the first line as well
+ * @param[in] other The instance to copy from
+ */
+ HttpResponseLayer(const HttpResponseLayer& other);
+
+ /**
+ * An assignment operator overload for this layer. This method inherits base assignment operator HttpMessage#operator=() and adds the functionality
+ * of copying the first line as well
+ * @param[in] other The instance to copy from
+ */
+ HttpResponseLayer& operator=(const HttpResponseLayer& other);
+
+ /**
+ * @return A pointer to the first line instance for this message
+ */
+ inline HttpResponseFirstLine* getFirstLine() { return m_FirstLine; }
+
+ /**
+ * The length of the body of many HTTP response messages is determined by a HTTP header field called "Content-Length". This method sets
+ * The content-length field value. The method supports several cases:
+ * - If the "Content-Length" field exists - the method will only replace the existing value with the new value
+ * - If the "Content-Length" field doesn't exist - the method will create this field and put the value in it. Here are also 2 cases:
+ * - If prevFieldName is specified - the new "Content-Length" field will be created after it
+ * - If prevFieldName isn't specified or doesn't exist - the new "Content-Length" field will be created as the last field before
+ * end-of-header field
+ * @param[in] contentLength The content length value to set
+ * @param[in] prevFieldName Optional field, if specified and "Content-Length" field doesn't exist, it will be created after it
+ * @return A pointer to the "Content-Length" field, or NULL if creation failed for some reason
+ */
+ HeaderField* setContentLength(int contentLength, const std::string prevFieldName = "");
+
+ /**
+ * The length of the body of many HTTP response messages is determined by a HTTP header field called "Content-Length". This method
+ * parses this field, extracts its value and return it. If this field doesn't exist the method will return 0
+ * @return HTTP response body length determined by "Content-Length" field
+ */
+ int getContentLength();
+
+ // implement Layer's abstract methods
+
+ std::string toString();
+
+ private:
+ HttpResponseFirstLine* m_FirstLine;
+
+ };
+
+
+
+
+
+ // -------- Class HttpRequestFirstLine -----------------
+
+ /**
+ * @class HttpRequestFirstLine
+ * Represents an HTTP request header first line. The first line includes 3 parameters: HTTP method (e.g GET, POST, etc.),
+ * URI (e.g /main/index.html) and HTTP version (e.g HTTP/1.1). All these parameters are included in this class, and the user
+ * can retrieve or set them.
+ * This class cannot be instantiated by users, it's created inside HttpRequestLayer and user can get a pointer to an instance of it. All "get"
+ * methods of this class will retrieve the actual data of the HTTP request and the "set" methods will change the packet data.
+ * Since HTTP is a textual protocol, most fields aren't of fixed size and this also applies to the first line parameters. So most "set" methods
+ * of this class need in most cases to shorten or extend the data in HttpRequestLayer. These methods will return a false value if this
+ * action failed
+ */
+ class HttpRequestFirstLine
+ {
+ friend class HttpRequestLayer;
+ public:
+ /**
+ * @return The HTTP method
+ */
+ inline HttpRequestLayer::HttpMethod getMethod() { return m_Method; }
+
+ /**
+ * Set the HTTP method
+ * @param[in] newMethod The method to set
+ * @return False if newMethod is HttpRequestLayer#HttpMethodUnknown or if shortening/extending the HttpRequestLayer data failed. True otherwise
+ */
+ bool setMethod(HttpRequestLayer::HttpMethod newMethod);
+
+ /**
+ * @return A copied version of the URI (notice changing the return value won't change the actual data of the packet)
+ */
+ std::string getUri();
+
+ /**
+ * Set the URI
+ * @param[in] newUri The URI to set
+ * @return False if shortening/extending the HttpRequestLayer data failed. True otherwise
+ */
+ bool setUri(std::string newUri);
+
+ /**
+ * @return The HTTP version
+ */
+ inline HttpVersion getVersion() { return m_Version; }
+
+ /**
+ * Set the HTTP version. This method doesn't return a value since all supported HTTP versions are of the same size
+ * (HTTP/0.9, HTTP/1.0, HTTP/1.1)
+ * @param[in] newVersion The HTTP version to set
+ */
+ void setVersion(HttpVersion newVersion);
+
+ /**
+ * A static method for parsing the HTTP method out of raw data
+ * @param[in] data The raw data
+ * @param[in] dataLen The raw data length
+ * @return The parsed HTTP method
+ */
+ static HttpRequestLayer::HttpMethod parseMethod(char* data, size_t dataLen);
+
+ /**
+ * @return The size in bytes of the HTTP first line
+ */
+ inline int getSize() { return m_FirstLineEndOffset; }
+
+ /**
+ * As explained in HttpRequestLayer, an HTTP header can spread over more than 1 packet, so when looking at a single packet
+ * the header can be partial. Same goes for the first line - it can spread over more than 1 packet. This method returns an indication
+ * whether the first line is partial
+ * @return False if the first line is partial, true if it's complete
+ */
+ inline bool isComplete() { return m_IsComplete; }
+
+ /**
+ * @class HttpRequestFirstLineException
+ * This exception can be thrown while constructing HttpRequestFirstLine (the constructor is private, so the construction happens
+ * only in HttpRequestLayer). This kind of exception will be thrown if trying to construct with HTTP method of
+ * HttpRequestLayer#HttpMethodUnknown or with undefined HTTP version ::HttpVersionUnknown
+ */
+ class HttpRequestFirstLineException : public std::exception
+ {
+ public:
+ ~HttpRequestFirstLineException() throw() {}
+ void setMessage(std::string message) { m_Message = message; }
+ virtual const char* what() const throw()
+ {
+ return m_Message.c_str();
+ }
+ private:
+ std::string m_Message;
+ };
+ private:
+ HttpRequestFirstLine(HttpRequestLayer* httpRequest);
+ HttpRequestFirstLine(HttpRequestLayer* httpRequest, HttpRequestLayer::HttpMethod method, HttpVersion version, std::string uri = "/")
+ throw(HttpRequestFirstLineException);
+
+ void parseVersion();
+
+ HttpRequestLayer* m_HttpRequest;
+ HttpRequestLayer::HttpMethod m_Method;
+ HttpVersion m_Version;
+ int m_VersionOffset;
+ int m_UriOffset;
+ int m_FirstLineEndOffset;
+ bool m_IsComplete;
+ HttpRequestFirstLineException m_Exception;
+ };
+
+
+
+
+
+ // -------- Class HttpResponseFirstLine -----------------
+
+ /**
+ * @class HttpResponseFirstLine
+ * Represents an HTTP response header first line. The first line includes 2 parameters: status code (e.g 200 OK, 404 Not Found, etc.),
+ * and HTTP version (e.g HTTP/1.1). These 2 parameters are included in this class, and the user can retrieve or set them.
+ * This class cannot be instantiated by users, it's created inside HttpResponseLayer and user can get a pointer to an instance of it. The "get"
+ * methods of this class will retrieve the actual data of the HTTP response and the "set" methods will change the packet data.
+ * Since HTTP is a textual protocol, most fields aren't of fixed size and this also applies to the first line parameters. So most "set" methods
+ * of this class need in most cases to shorten or extend the data in HttpResponseLayer. These methods will return a false value if this
+ * action failed
+ */
+ class HttpResponseFirstLine
+ {
+ friend class HttpResponseLayer;
+ public:
+ /**
+ * @return The status code as HttpResponseLayer::HttpResponseStatusCode enum
+ */
+ inline HttpResponseLayer::HttpResponseStatusCode getStatusCode() { return m_StatusCode; }
+
+ /**
+ * @return The status code number as integer (e.g 200, 404, etc.)
+ */
+ int getStatusCodeAsInt();
+
+ /**
+ * @return The status code message (e.g "OK", "Not Found", etc.)
+ */
+ std::string getStatusCodeString();
+
+ /**
+ * Set the status code
+ * @param[in] newStatusCode The new status code to set
+ * @param[in] statusCodeString An optional parameter: set a non-default status code message (e.g "Bla Bla" instead of "Not Found"). If
+ * this parameter isn't supplied or supplied as empty string (""), the default message for the status code will be set
+ */
+ bool setStatusCode(HttpResponseLayer::HttpResponseStatusCode newStatusCode, std::string statusCodeString = "");
+
+ /**
+ * @return The HTTP version
+ */
+ inline HttpVersion getVersion() { return m_Version; }
+
+ /**
+ * Set the HTTP version. This method doesn't return a value since all supported HTTP versions are of the same size
+ * (HTTP/0.9, HTTP/1.0, HTTP/1.1)
+ * @param[in] newVersion The HTTP version to set
+ */
+ void setVersion(HttpVersion newVersion);
+
+ /**
+ * A static method for parsing the HTTP status code out of raw data
+ * @param[in] data The raw data
+ * @param[in] dataLen The raw data length
+ * @return The parsed HTTP status code as enum
+ */
+ static HttpResponseLayer::HttpResponseStatusCode parseStatusCode(char* data, size_t dataLen);
+
+ /**
+ * @return The size in bytes of the HTTP first line
+ */
+ inline int getSize() { return m_FirstLineEndOffset; }
+
+ /**
+ * As explained in HttpResponseLayer, an HTTP header can spread over more than 1 packet, so when looking at a single packet
+ * the header can be partial. Same goes for the first line - it can spread over more than 1 packet. This method returns an indication
+ * whether the first line is partial
+ * @return False if the first line is partial, true if it's complete
+ */
+ inline bool isComplete() { return m_IsComplete; }
+
+ /**
+ * @class HttpResponseFirstLineException
+ * This exception can be thrown while constructing HttpResponseFirstLine (the constructor is private, so the construction happens
+ * only in HttpResponseLayer). This kind of exception will be thrown if trying to construct with HTTP status code of
+ * HttpResponseLayer#HttpStatusCodeUnknown or with undefined HTTP version ::HttpVersionUnknown
+ */
+ class HttpResponseFirstLineException : public std::exception
+ {
+ public:
+ ~HttpResponseFirstLineException() throw() {}
+ void setMessage(std::string message) { m_Message = message; }
+ virtual const char* what() const throw()
+ {
+ return m_Message.c_str();
+ }
+ private:
+ std::string m_Message;
+ };
+
+ private:
+ HttpResponseFirstLine(HttpResponseLayer* httpResponse);
+ HttpResponseFirstLine(HttpResponseLayer* httpResponse, HttpVersion version, HttpResponseLayer::HttpResponseStatusCode statusCode, std::string statusCodeString = "");
+
+ static HttpVersion parseVersion(char* data, size_t dataLen);
+ static HttpResponseLayer::HttpResponseStatusCode validateStatusCode(char* data, size_t dataLen, HttpResponseLayer::HttpResponseStatusCode potentialCode);
+
+
+ HttpResponseLayer* m_HttpResponse;
+ HttpVersion m_Version;
+ HttpResponseLayer::HttpResponseStatusCode m_StatusCode;
+ int m_FirstLineEndOffset;
+ bool m_IsComplete;
+ HttpResponseFirstLineException m_Exception;
+ };
+
+} // namespace pcpp
+
+#endif /* PACKETPP_HTTP_LAYER */
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/IPv4Layer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/IPv4Layer.h b/thirdparty/pcap++/Packet++/header/IPv4Layer.h
new file mode 100644
index 0000000..4be1c55
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/IPv4Layer.h
@@ -0,0 +1,603 @@
+#ifndef PACKETPP_IPV4_LAYER
+#define PACKETPP_IPV4_LAYER
+
+#include "Layer.h"
+#include "IpAddress.h"
+#include <string.h>
+#include <vector>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+ /**
+ * @struct iphdr
+ * Represents an IPv4 protocol header
+ */
+#pragma pack(push, 1)
+ struct iphdr {
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+ /** IP header length, has the value of 5 for IPv4 */
+ uint8_t internetHeaderLength:4,
+ /** IP version number, has the value of 4 for IPv4 */
+ ipVersion:4;
+#else
+ /** IP version number, has the value of 4 for IPv4 */
+ uint8_t ipVersion:4,
+ /** IP header length, has the value of 5 for IPv4 */
+ internetHeaderLength:4;
+#endif
+ /** type of service, same as Differentiated Services Code Point (DSCP)*/
+ uint8_t typeOfService;
+ /** Entire packet (fragment) size, including header and data, in bytes */
+ uint16_t totalLength;
+ /** Identification field. Primarily used for uniquely identifying the group of fragments of a single IP datagram*/
+ uint16_t ipId;
+ /** Fragment offset field, measured in units of eight-byte blocks (64 bits) */
+ uint16_t fragmentOffset;
+ /** An eight-bit time to live field helps prevent datagrams from persisting (e.g. going in circles) on an internet. In practice, the field has become a hop count */
+ uint8_t timeToLive;
+ /** Defines the protocol used in the data portion of the IP datagram. Must be one of ::IPProtocolTypes */
+ uint8_t protocol;
+ /** Error-checking of the header */
+ uint16_t headerChecksum;
+ /** IPv4 address of the sender of the packet */
+ uint32_t ipSrc;
+ /** IPv4 address of the receiver of the packet */
+ uint32_t ipDst;
+ /*The options start here. */
+ };
+#pragma pack(pop)
+
+ /**
+ * An enum for all possible IPv4 and IPv6 protocol types
+ */
+ enum IPProtocolTypes
+ {
+ /** Dummy protocol for TCP */
+ PACKETPP_IPPROTO_IP = 0,
+ /** IPv6 Hop-by-Hop options */
+ PACKETPP_IPPROTO_HOPOPTS = 0,
+ /** Internet Control Message Protocol */
+ PACKETPP_IPPROTO_ICMP = 1,
+ /** Internet Gateway Management Protocol */
+ PACKETPP_IPPROTO_IGMP = 2,
+ /** IPIP tunnels (older KA9Q tunnels use 94) */
+ PACKETPP_IPPROTO_IPIP = 4,
+ /** Transmission Control Protocol */
+ PACKETPP_IPPROTO_TCP = 6,
+ /** Exterior Gateway Protocol */
+ PACKETPP_IPPROTO_EGP = 8,
+ /** PUP protocol */
+ PACKETPP_IPPROTO_PUP = 12,
+ /** User Datagram Protocol */
+ PACKETPP_IPPROTO_UDP = 17,
+ /** XNS IDP protocol */
+ PACKETPP_IPPROTO_IDP = 22,
+ /** IPv6 header */
+ PACKETPP_IPPROTO_IPV6 = 41,
+ /** IPv6 Routing header */
+ PACKETPP_IPPROTO_ROUTING = 43,
+ /** IPv6 fragmentation header */
+ PACKETPP_IPPROTO_FRAGMENT = 44,
+ /** GRE protocol */
+ PACKETPP_IPPROTO_GRE = 47,
+ /** encapsulating security payload */
+ PACKETPP_IPPROTO_ESP = 50,
+ /** authentication header */
+ PACKETPP_IPPROTO_AH = 51,
+ /** ICMPv6 */
+ PACKETPP_IPPROTO_ICMPV6 = 58,
+ /** IPv6 no next header */
+ PACKETPP_IPPROTO_NONE = 59,
+ /** IPv6 Destination options */
+ PACKETPP_IPPROTO_DSTOPTS = 60,
+ /** Raw IP packets */
+ PACKETPP_IPPROTO_RAW = 255,
+ /** Maximum value */
+ PACKETPP_IPPROTO_MAX
+ };
+
+
+ /**
+ * An enum for supported IPv4 option types
+ */
+ enum IPv4OptionTypes
+ {
+ /** End of Options List */
+ IPV4OPT_EndOfOtionsList = 0,
+ /** No Operation */
+ IPV4OPT_NOP = 1,
+ /** Record Route */
+ IPV4OPT_RecordRoute = 7,
+ /** MTU Probe */
+ IPV4OPT_MTUProbe = 11,
+ /** MTU Reply */
+ IPV4OPT_MTUReply = 12,
+ /** Quick-Start */
+ IPV4OPT_QuickStart = 25,
+ /** Timestamp */
+ IPV4OPT_Timestamp = 68,
+ /** Traceroute */
+ IPV4OPT_Traceroute = 82,
+ /** Security */
+ IPV4OPT_Security = 130,
+ /** Loose Source Route */
+ IPV4OPT_LooseSourceRoute = 131,
+ /** Extended Security */
+ IPV4OPT_ExtendedSecurity = 133,
+ /** Commercial Security */
+ IPV4OPT_CommercialSecurity = 134,
+ /** Stream ID */
+ IPV4OPT_StreamID = 136,
+ /** Strict Source Route */
+ IPV4OPT_StrictSourceRoute = 137,
+ /** Extended Internet Protocol */
+ IPV4OPT_ExtendedInternetProtocol = 145,
+ /** Address Extension */
+ IPV4OPT_AddressExtension = 147,
+ /** Router Alert */
+ IPV4OPT_RouterAlert = 148,
+ /** Selective Directed Broadcast */
+ IPV4OPT_SelectiveDirectedBroadcast = 149,
+ /** Dynamic Packet State */
+ IPV4OPT_DynamicPacketState = 151,
+ /** Upstream Multicast Pkt. */
+ IPV4OPT_UpstreamMulticastPkt = 152,
+ /** Unknown IPv4 option */
+ IPV4OPT_Unknown
+ };
+
+#define PCPP_IP_DONT_FRAGMENT 0x40
+#define PCPP_IP_MORE_FRAGMENTS 0x20
+
+ /**
+ * @struct IPv4TimestampOptionValue
+ * A struct representing a parsed value of the IPv4 timestamp option. This struct is used returned in IPv4OptionData#getTimestampOptionValue() method
+ */
+ struct IPv4TimestampOptionValue
+ {
+ public:
+
+ /**
+ * An enum for IPv4 timestamp option types
+ */
+ enum TimestampType
+ {
+ /** Value containing only timestamps */
+ TimestampOnly = 0,
+ /** Value containing both timestamps and IPv4 addresses */
+ TimestampAndIP = 1,
+ /** The IPv4 addresses are prespecified */
+ TimestampsForPrespecifiedIPs = 2,
+ /** Invalid or unknown value type */
+ Unknown = 3
+ };
+
+ /** The timestamp value type */
+ TimestampType type;
+
+ /** A list of timestamps parsed from the IPv4 timestamp option value */
+ std::vector<uint32_t> timestamps;
+
+ /** A list of IPv4 addresses parsed from the IPv4 timestamp option value */
+ std::vector<IPv4Address> ipAddresses;
+
+ /**
+ * Clear the structure. Clean the timestamps and IP addresses vectors and set the type as IPv4TimestampOptionValue#Unknown
+ */
+ void clear()
+ {
+ type = IPv4TimestampOptionValue::Unknown;
+ timestamps.clear();
+ ipAddresses.clear();
+ }
+ };
+
+
+ /**
+ * @struct IPv4OptionData
+ * Representing a IPv4 option in a TLV (type-length-value) structure
+ */
+ struct IPv4OptionData
+ {
+ public:
+ /** IPv4 option code, should be of type pcpp::IPv4OptionTypes */
+ uint8_t opCode;
+ /** IPv4 option length */
+ uint8_t len;
+ /** IPv4 option value */
+ uint8_t value[];
+
+ /**
+ * A templated method to retrieve the IPv4 option data as a certain type T. For example, if IPv4 option data is 4B
+ * (integer) then this method should be used as getValueAs<int>() and it will return the IPv4 option data as an integer.<BR>
+ * Notice this return value is a copy of the data, not a pointer to the actual data
+ * @param[in] valueOffset An optional parameter that specifies where to start copy the IPv4 option data. For example:
+ * if option data is 20 bytes and you need only the 4 last bytes as integer then use this method like this:
+ * getValueAs<int>(16). The default is 0 - start copying from the beginning of option data
+ * @return The IPv4 option data as type T
+ */
+ template<typename T>
+ T getValueAs(int valueOffset = 0)
+ {
+ if (getTotalSize() <= 2*sizeof(uint8_t) + valueOffset)
+ return 0;
+ if (getTotalSize() - 2*sizeof(uint8_t) - valueOffset < sizeof(T))
+ return 0;
+
+ T result;
+ memcpy(&result, value+valueOffset, sizeof(T));
+ return result;
+ }
+
+ /**
+ * A method for parsing the IPv4 option value as an IP list. This method is relevant only for certain types of IPv4 options which their value is a list of IPv4 addresses
+ * such as ::IPV4OPT_RecordRoute, ::IPV4OPT_StrictSourceRoute, ::IPV4OPT_LooseSourceRoute, etc. This method returns a vector of the IPv4 addresses. Blank IP addresses
+ * (meaning zeroed addresses - 0.0.0.0) will not be added to the returned list. If some error occurs during the parsing or the value is invalid an empty vector is returned
+ * @return A vector of IPv4 addresses parsed from the IPv4 option value
+ */
+ std::vector<IPv4Address> getValueAsIpList()
+ {
+ std::vector<IPv4Address> res;
+
+ size_t dataSize = getDataSize();
+ if (dataSize < 2)
+ return res;
+
+ uint8_t valueOffset = (uint8_t)(1);
+
+ while (valueOffset < dataSize)
+ {
+ uint32_t curValue;
+ memcpy(&curValue, value+valueOffset, sizeof(uint32_t));
+ if (curValue == 0)
+ break;
+
+ res.push_back(IPv4Address(curValue));
+
+ valueOffset += (uint8_t)(4);
+ }
+
+ return res;
+ }
+
+ /**
+ * A method for parsing the IPv4 timestamp option value. This method is relevant only for IPv4 timestamp option. For other option types an empty result will be returned.
+ * The returned structure contains the timestamp value type (timestamp only, timestamp + IP addresses, etc.) as well as 2 vectors containing the list of timestamps and the list
+ * of IP addresses (if applicable for the timestamp value type). Blank timestamps or IP addresses (meaning zeroed values - timestamp=0 or IP address=0.0.0.0) will not be added to
+ * the lists. If some error occurs during the parsing or the value is invalid an empty result is returned
+ * @return A structured containing the IPv4 timestamp value
+ */
+ IPv4TimestampOptionValue getTimestampOptionValue()
+ {
+ IPv4TimestampOptionValue res;
+ res.clear();
+
+ if (getType() != IPV4OPT_Timestamp)
+ return res;
+
+ size_t dataSize = getDataSize();
+ if (dataSize < 2)
+ return res;
+
+ res.type = (IPv4TimestampOptionValue::TimestampType)value[1];
+
+ uint8_t valueOffset = (uint8_t)(2);
+ bool readIPAddr = (res.type == IPv4TimestampOptionValue::TimestampAndIP);
+
+ while (valueOffset < dataSize)
+ {
+ uint32_t curValue;
+ memcpy(&curValue, value+valueOffset, sizeof(uint32_t));
+ if (curValue == 0)
+ break;
+
+ if (readIPAddr)
+ res.ipAddresses.push_back(IPv4Address(curValue));
+ else
+ res.timestamps.push_back(curValue);
+
+ if (res.type == IPv4TimestampOptionValue::TimestampAndIP)
+ readIPAddr = !readIPAddr;
+
+ valueOffset += (uint8_t)(4);
+ }
+
+ return res;
+ }
+
+ /**
+ * @return The total size in bytes of this IPv4 option which includes: 1[Byte] (option type) + 1[Byte]
+ * (option length) + X[Bytes] (option data length). For ::IPV4OPT_EndOfOtionsList and ::IPV4OPT_NOP the value 1 is returned
+ */
+ size_t getTotalSize() const
+ {
+ if (opCode == (uint8_t)IPV4OPT_EndOfOtionsList || opCode == (uint8_t)IPV4OPT_NOP)
+ return sizeof(uint8_t);
+
+ return (size_t)len;
+ }
+
+ /**
+ * @return The size of the option data (not containing the size of the option type and option length fields)
+ */
+ size_t getDataSize()
+ {
+ if (opCode == (uint8_t)IPV4OPT_EndOfOtionsList || opCode == (uint8_t)IPV4OPT_NOP)
+ return (size_t)0;
+
+ return (size_t)len - (2*sizeof(uint8_t));
+ }
+
+ /**
+ * @return IPv4 option type casted as pcpp::IPv4OptionTypes enum
+ */
+ inline IPv4OptionTypes getType() { return (IPv4OptionTypes)opCode; }
+
+ private:
+
+ // private c'tor which isn't implemented to make this struct impossible to construct
+ IPv4OptionData();
+ };
+
+
+
+ /**
+ * @class IPv4Layer
+ * Represents an IPv4 protocol layer
+ */
+ class IPv4Layer : public Layer
+ {
+ 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 iphdr)
+ * @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
+ */
+ IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = IPv4; m_OptionCount = -1; m_NumOfTrailingBytes = 0; m_TempHeaderExtension = 0; }
+
+ /**
+ * A constructor that allocates a new IPv4 header with empty fields
+ */
+ IPv4Layer();
+
+ /**
+ * A constructor that allocates a new IPv4 header with source and destination IPv4 addresses
+ * @param[in] srcIP Source IPv4 address
+ * @param[in] dstIP Destination IPv4 address
+ */
+ IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP);
+
+ /**
+ * A copy constructor that copy the entire header from the other IPv4Layer (including IPv4 options)
+ */
+ IPv4Layer(const IPv4Layer& other);
+
+ /**
+ * An assignment operator that first delete all data from current layer and then copy the entire header from the other IPv4Layer (including IPv4 options)
+ */
+ IPv4Layer& operator=(const IPv4Layer& other);
+
+ /**
+ * Get a pointer to the IPv4 header. Notice this points directly to the data, so every change will change the actual packet data
+ * @return A pointer to the @ref iphdr
+ */
+ inline iphdr* getIPv4Header() { return (iphdr*)m_Data; };
+
+ /**
+ * Get the source IP address in the form of IPv4Address
+ * @return An IPv4Address containing the source address
+ */
+ inline IPv4Address getSrcIpAddress() { return IPv4Address(getIPv4Header()->ipSrc); }
+
+ /**
+ * Set the source IP address
+ * @param[in] ipAddr The IP address to set
+ */
+ inline void setSrcIpAddress(const IPv4Address& ipAddr) { getIPv4Header()->ipSrc = ipAddr.toInt(); }
+
+ /**
+ * Get the destination IP address in the form of IPv4Address
+ * @return An IPv4Address containing the destination address
+ */
+ inline IPv4Address getDstIpAddress() { return IPv4Address(getIPv4Header()->ipDst); }
+
+ /**
+ * Set the dest IP address
+ * @param[in] ipAddr The IP address to set
+ */
+ inline void setDstIpAddress(const IPv4Address& ipAddr) { getIPv4Header()->ipDst = ipAddr.toInt(); }
+
+ /**
+ * @return True if this packet is a fragment (in sense of IP fragmentation), false otherwise
+ */
+ bool isFragment();
+
+ /**
+ * @return True if this packet is a fragment (in sense of IP fragmentation) and is the first fragment
+ * (which usually contains the L4 header). Return false otherwise (not a fragment or not the first fragment)
+ */
+ bool isFirstFragment();
+
+ /**
+ * @return True if this packet is a fragment (in sense of IP fragmentation) and is the last fragment.
+ * Return false otherwise (not a fragment or not the last fragment)
+ */
+ bool isLastFragment();
+
+ /**
+ * @return A bitmask containing the fragmentation flags (e.g IP_DONT_FRAGMENT or IP_MORE_FRAGMENTS)
+ */
+ uint8_t getFragmentFlags();
+
+ /**
+ * @return The fragment offset in case this packet is a fragment, 0 otherwise
+ */
+ uint16_t getFragmentOffset();
+
+ /**
+ * Get a pointer to an IPv4 option. Notice this points directly to the data, so every change will change the actual packet data
+ * @param[in] option The IPv4 option to get
+ * @return A pointer to the IPv4 option location in the packet
+ */
+ IPv4OptionData* getOptionData(IPv4OptionTypes option);
+
+ /**
+ * @return The first IPv4 option, or NULL if no IPv4 options exist. Notice the return value is a pointer to the real data casted to
+ * IPv4OptionData type (as opposed to a copy of the option data). So changes in the return value will affect the packet data
+ */
+ IPv4OptionData* getFirstOptionData();
+
+ /**
+ * Get the IPv4 option which comes next to "option" parameter. If "option" is NULL then NULL will be returned.
+ * If "option" is the last IPv4 option NULL will be returned. Notice the return value is a pointer to the real data casted to
+ * IPv4OptionData type (as opposed to a copy of the option data). So changes in the return value will affect the packet data
+ * @param[in] option The IPv4 option to start searching from
+ * @return The next IPv4 option or NULL if "option" is NULL or "option" is the last IPv4 option
+ */
+ IPv4OptionData* getNextOptionData(IPv4OptionData* option);
+
+ /**
+ * @return The number of IPv4 options in this layer
+ */
+ size_t getOptionsCount();
+
+ /**
+ * Add an IPv4 option
+ * @param[in] optionType The IPv4 option type to add
+ * @param[in] optionDataLength The length of the option data [in bytes]. For ::IPV4OPT_NOP and ::IPV4OPT_EndOfOtionsList this parameter must be 0 otherwise the method will fail
+ * @param[in] optionData A byte array containing the IPv4 option data (should be in size indicated in optionDataLength).
+ * For ::IPV4OPT_NOP and ::IPV4OPT_EndOfOtionsList this parameter is ignored (expected to be NULL)
+ * @return If option was added successfully a pointer to the new option will be returned. If adding failed NULL will be returned. Failure can happen if layer couldn't be extended for some reason
+ * or if added option exceeds maximum options length (in IPv4 total options length must not exceed 40 bytes). In any case of failure an appropriate error message will be printed to log
+ */
+ IPv4OptionData* addOption(IPv4OptionTypes optionType, uint8_t optionDataLength, const uint8_t* optionData);
+
+ /**
+ * Add an IPv4 option with value of IP address list. This method is relevant only for option types which value is IP address list such as ::IPV4OPT_StrictSourceRoute, ::IPV4OPT_RecordRoute
+ * and ::IPV4OPT_LooseSourceRoute. Please note this method calculates and sets the pointer field in the option value automatically
+ * @param[in] optionType The IPv4 option type to add (should be option type which value is IP address list)
+ * @param[in] ipList The list of IP addresses to set. Please note this method doesn't automatically adds zero IP addresses (with value of 0.0.0.0), so if you want the option value to
+ * include zero values please add them to the list
+ * @return If option was added successfully a pointer to the new option will be returned. If adding failed NULL will be returned. Failure can happen if layer couldn't be extended for some reason
+ * or if added option exceeds maximum options length (in IPv4 total options length must not exceed 40 bytes). In any case of failure an appropriate error message will be printed to log
+ */
+ IPv4OptionData* addOption(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList);
+
+ /**
+ * Add an IPv4 timestamp option. Please note that timestamp type of IPv4TimestampOptionValue#TimestampsForPrespecifiedIPs is currently not supported. Please also note this method calculates
+ * and sets the pointer field in the timestamp option value automatically
+ * @param[in] timestampValue Timestamp option value to set, including timestamp type (timestamp only or timestamp and IP) and a list of timestamps and/or IP addresses
+ * @return If option was added successfully a pointer to the new option will be returned. If adding failed NULL will be returned. Failure can happen if layer couldn't be extended for some
+ * reason, if added option exceeds maximum options length (in IPv4 total options length must not exceed 40 bytes), or if the timestamp value is wrong (for example:
+ * type is IPv4TimestampOptionValue#TimestampsForPrespecifiedIPs or IPv4TimestampOptionValue#Unknown, type is IPv4TimestampOptionValue#TimestampAndIP and number of timestamps is
+ * not equal to the number of IP addresses, etc.). In any case of failure an appropriate error message will be printed to log
+ */
+ IPv4OptionData* addTimestampOption(const IPv4TimestampOptionValue& timestampValue);
+
+ /**
+ * Add an IPv4 option after an existing option
+ * @param[in] optionType The IPv4 option type to add
+ * @param[in] optionDataLength The length of the option data [in bytes]. For ::IPV4OPT_NOP and ::IPV4OPT_EndOfOtionsList this parameter must be 0 otherwise the method will fail
+ * @param[in] optionData A byte array containing the IPv4 option data (should be in size indicated in optionDataLength).
+ * For ::IPV4OPT_NOP and ::IPV4OPT_EndOfOtionsList this parameter is ignored (expected to be NULL)
+ * @param[in] prevOption The option type which the new option should be added after. It's an optional parameter, if it's not set or set to an option that doesn't exist the new
+ * option will be added as the first option in the layer
+ * @return If option was added successfully a pointer to the new option will be returned. If adding failed NULL will be returned. Failure can happen if layer couldn't be extended for some reason
+ * or if added option exceeds maximum options length (in IPv4 total options length must not exceed 40 bytes). In any case of failure an appropriate error message will be printed to log
+ */
+ IPv4OptionData* addOptionAfter(IPv4OptionTypes optionType, uint8_t optionDataLength, const uint8_t* optionData, IPv4OptionTypes prevOption = IPV4OPT_Unknown);
+
+ /**
+ * Add an IPv4 option with value of IP address list after an existing option. This method is relevant only for option types which value is IP address list such as
+ * ::IPV4OPT_StrictSourceRoute, ::IPV4OPT_RecordRoute and ::IPV4OPT_LooseSourceRoute. Please note this method calculates and sets the pointer field in the option value automatically
+ * @param[in] optionType The IPv4 option type to add (should be option type which value is IP address list)
+ * @param[in] ipList The list of IP addresses to set. Please note this method doesn't automatically adds zero IP addresses (with value of 0.0.0.0), so if you want the option value to
+ * include zero values please add them to the list
+ * @param[in] prevOption The option type which the new option should be added after. It's an optional parameter, if it's not set or set to an option that doesn't exist the new
+ * option will be added as the first option in the layer
+ * @return If option was added successfully a pointer to the new option will be returned. If adding failed NULL will be returned. Failure can happen if layer couldn't be extended for some reason
+ * or if added option exceeds maximum options length (in IPv4 total options length must not exceed 40 bytes). In any case of failure an appropriate error message will be printed to log
+ */
+ IPv4OptionData* addOptionAfter(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList, IPv4OptionTypes prevOption = IPV4OPT_Unknown);
+
+ /**
+ * Add an IPv4 timestamp option after some existing option. Please note that timestamp type of IPv4TimestampOptionValue#TimestampsForPrespecifiedIPs is currently not supported.
+ * Please also note this method calculates and sets the pointer field in the timestamp option value automatically
+ * @param[in] timestampValue Timestamp option value to set, including timestamp type (timestamp only or timestamp and IP) and a list of timestamps and/or IP addresses
+ * @param[in] prevOption The option type which the new option should be added after. It's an optional parameter, if it's not set or set to an option that doesn't exist the new
+ * option will be added as the first option in the layer
+ * @return If option was added successfully a pointer to the new option will be returned. If adding failed NULL will be returned. Failure can happen if layer couldn't be extended for some
+ * reason, if added option exceeds maximum options length (in IPv4 total options length must not exceed 40 bytes), or if the timestamp value is wrong (for example:
+ * type is IPv4TimestampOptionValue#TimestampsForPrespecifiedIPs or IPv4TimestampOptionValue#Unknown, type is IPv4TimestampOptionValue#TimestampAndIP and number of timestamps is
+ * not equal to the number of IP addresses, etc.). In any case of failure an appropriate error message will be printed to log
+ */
+ IPv4OptionData* addTimestampOptionAfter(const IPv4TimestampOptionValue& timestampValue, IPv4OptionTypes prevOption = IPV4OPT_Unknown);
+
+ /**
+ * Remove an IPv4 option
+ * @param[in] option The option type to remove
+ * @return True if option was removed successfully or false if option type wasn't found or failed to shorten the layer. If an option appears twice in the layer, its first instance
+ * will be removed
+ */
+ bool removeOption(IPv4OptionTypes option);
+
+ /**
+ * Remove all IPv4 options from the layer
+ * @return True if options removed successfully or false if some error occurred (an appropriate error message will be printed to log)
+ */
+ bool removeAllOptions();
+
+
+ // implement abstract methods
+
+ /**
+ * Currently identifies the following next layers: UdpLayer, TcpLayer. Otherwise sets PayloadLayer
+ */
+ void parseNextLayer();
+
+ /**
+ * @return Size of IPv4 header (including IPv4 options if exist)
+ */
+ inline size_t getHeaderLen() { return (size_t)(getIPv4Header()->internetHeaderLength*4) + m_TempHeaderExtension; }
+
+ /**
+ * Calculate the following fields:
+ * - iphdr#ipVersion = 4;
+ * - iphdr#totalLength = total packet length
+ * - iphdr#headerChecksum = calculated
+ * - iphdr#protocol = calculated if next layer is known: ::PACKETPP_IPPROTO_TCP for TCP, ::PACKETPP_IPPROTO_UDP for UDP, ::PACKETPP_IPPROTO_ICMP for ICMP
+ */
+ void computeCalculateFields();
+
+ std::string toString();
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelNetworkLayer; }
+
+ private:
+ size_t m_OptionCount;
+ int m_NumOfTrailingBytes;
+ int m_TempHeaderExtension;
+
+ void copyLayerData(const IPv4Layer& other);
+ IPv4OptionData* castPtrToOptionData(uint8_t* ptr);
+ IPv4OptionData* addOptionAt(IPv4OptionTypes optionType, uint8_t optionDataLength, const uint8_t* optionData, int offset);
+ void adjustOptionsTrailer(size_t totalOptSize);
+ void buildIPListOptionData(const std::vector<IPv4Address>& ipList, uint8_t** optionData, int& optionDataLength);
+ void buildTimestampOptionData(const IPv4TimestampOptionValue& timestampVal, uint8_t** optionData, int& optionDataLength);
+ void incOptionCount(int val);
+ void setOptionCount(int val);
+ void initLayer();
+ };
+
+} // namespace pcpp
+
+#endif /* PACKETPP_IPV4_LAYER */
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/IPv6Layer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/IPv6Layer.h b/thirdparty/pcap++/Packet++/header/IPv6Layer.h
new file mode 100644
index 0000000..4d882e2
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/IPv6Layer.h
@@ -0,0 +1,125 @@
+#ifndef PACKETPP_IPV6_LAYER
+#define PACKETPP_IPV6_LAYER
+
+#include "Layer.h"
+#include "IpAddress.h"
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+ /**
+ * @struct ip6_hdr
+ * Represents an IPv6 protocol header
+ */
+#pragma pack(push, 1)
+ struct ip6_hdr {
+ #if (BYTE_ORDER == LITTLE_ENDIAN)
+ /** Traffic class */
+ uint8_t trafficClass:4,
+ /** IP version number, has the value of 6 for IPv6 */
+ ipVersion:4;
+ #else
+ /** IP version number, has the value of 6 for IPv6 */
+ uint8_t ipVersion:4,
+ /** Traffic class */
+ trafficClass:4;
+ #endif
+ /** Flow label */
+ uint8_t flowLabel[3];
+ /** The size of the payload in octets, including any extension headers */
+ uint16_t payloadLength;
+ /** Specifies the type of the next header (protocol). Must be one of ::IPProtocolTypes */
+ uint8_t nextHeader;
+ /** Replaces the time to live field of IPv4 */
+ uint8_t hopLimit;
+ /** Source address */
+ uint8_t ipSrc[16];
+ /** Destination address */
+ uint8_t ipDst[16];
+ };
+#pragma pack(pop)
+
+
+ /**
+ * @class IPv6Layer
+ * Represents an IPv6 protocol layer
+ */
+ class IPv6Layer : public Layer
+ {
+ 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 ip6_hdr)
+ * @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
+ */
+ IPv6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = IPv6; }
+
+ /**
+ * A constructor that allocates a new IPv6 header with empty fields
+ */
+ IPv6Layer();
+
+ /**
+ * A constructor that allocates a new IPv6 header with source and destination IPv6 addresses
+ * @param[in] srcIP Source IPv6 address
+ * @param[in] dstIP Destination IPv6 address
+ */
+ IPv6Layer(const IPv6Address& srcIP, const IPv6Address& dstIP);
+
+ /**
+ * Get a pointer to the IPv6 header. Notice this points directly to the data, so every change will change the actual packet data
+ * @return A pointer to the @ref ip6_hdr
+ */
+ inline ip6_hdr* getIPv6Header() { return (ip6_hdr*)m_Data; };
+
+ /**
+ * Get the source IP address in the form of IPv6Address
+ * @return An IPv6Address containing the source address
+ */
+ inline IPv6Address getSrcIpAddress() { return IPv6Address(getIPv6Header()->ipSrc); }
+
+ /**
+ * Get the destination IP address in the form of IPv6Address
+ * @return An IPv6Address containing the destination address
+ */
+ inline IPv6Address getDstIpAddress() { return IPv6Address(getIPv6Header()->ipDst); }
+
+ // implement abstract methods
+
+ /**
+ * Currently identifies the following next layers: UdpLayer, TcpLayer. Otherwise sets PayloadLayer
+ */
+ void parseNextLayer();
+
+ /**
+ * @return Size of @ref ip6_hdr
+ */
+ inline size_t getHeaderLen() { return sizeof(ip6_hdr); }
+
+ /**
+ * Calculate the following fields:
+ * - ip6_hdr#payloadLength = size of payload (all data minus header size)
+ * - ip6_hdr#ipVersion = 6
+ * - ip6_hdr#nextHeader = calculated if next layer is known: ::PACKETPP_IPPROTO_TCP for TCP, ::PACKETPP_IPPROTO_UDP for UDP, ::PACKETPP_IPPROTO_ICMP for ICMP
+ */
+ void computeCalculateFields();
+
+ std::string toString();
+
+ OsiModelLayer getOsiModelLayer() { return OsiModelNetworkLayer; }
+
+ private:
+ void initLayer();
+ };
+
+} // namespace pcpp
+
+#endif /* PACKETPP_IPV6_LAYER */