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:31 UTC

[17/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/Packet.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/Packet.h b/thirdparty/pcap++/Packet++/header/Packet.h
new file mode 100644
index 0000000..29713a3
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/Packet.h
@@ -0,0 +1,257 @@
+#ifndef PACKETPP_PACKET
+#define PACKETPP_PACKET
+
+#include "RawPacket.h"
+#include "Layer.h"
+#include <vector>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+	/**
+	 * @class Packet
+	 * This class represents a parsed packet. It contains the raw data (RawPacket instance), and a linked list of layers, each layer is a parsed
+	 * protocol that this packet contains. The layers linked list is ordered where the first layer is the lowest in the packet (currently it's always
+	 * Ethernet protocol as PcapPlusPlus supports only Ethernet packets), the next layer will be L2.5 or L3 (e.g VLAN, IPv4, IPv6, etc.), and so on.
+	 * etc.), etc. The last layer in the linked list will be the highest in the packet.
+	 * For example: for a standard HTTP request packet the layer will look like this: EthLayer -> IPv4Layer -> TcpLayer -> HttpRequestLayer <BR>
+	 * Packet instance isn't read only. The user can add or remove layers, update current layer, etc.
+	 */
+	class Packet {
+		friend class Layer;
+	private:
+		RawPacket* m_RawPacket;
+		Layer* m_FirstLayer;
+		Layer* m_LastLayer;
+		uint64_t m_ProtocolTypes;
+		size_t m_MaxPacketLen;
+		std::vector<Layer*> m_LayersAllocatedInPacket;
+		bool m_FreeRawPacket;
+
+	public:
+
+		/**
+		 * A constructor for creating a new packet. Very useful when creating packets.
+		 * When using this constructor an empty raw buffer is allocated (with the size of maxPacketLen) and a new RawPacket is created
+		 * @param[in] maxPacketLen The expected packet length in bytes
+		 */
+		Packet(size_t maxPacketLen = 1);
+
+		/**
+		 * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that came from the network.
+		 * When using this constructor a pointer to the RawPacket is saved (data isn't copied) and the RawPacket is parsed, meaning all layers
+		 * are created and linked to each other in the right order. In this overload of the constructor the user can specify whether to free
+		 * the instance of raw packet when the Packet is free or not
+		 * @param[in] rawPacket A pointer to the raw packet
+		 * @param[in] freeRawPacket Optional parameter. A flag indicating if the destructor should also call the raw packet destructor or not. Default value is false
+		 * @param[in] parseUntil Optional parameter. Parse the packet until you reach a certain protocol (inclusive). Can be useful for cases when you need to parse only up to a
+		 * certain layer and want to avoid the performance impact and memory consumption of parsing the whole packet. Default value is ::UnknownProtocol which means don't take this
+		 * parameter into account
+		 * @param[in] parseUntilLayer Optional parameter. Parse the packet until you reach a certain layer in the OSI model (inclusive). Can be useful for cases when you need to
+		 * parse only up to a certain OSI layer (for example transport layer) and want to avoid the performance impact and memory consumption of parsing the whole packet.
+		 * Default value is ::OsiModelLayerUnknown which means don't take this parameter into account
+		 */
+		Packet(RawPacket* rawPacket, bool freeRawPacket = false, ProtocolType parseUntil = UnknownProtocol, OsiModelLayer parseUntilLayer = OsiModelLayerUnknown);
+
+		/**
+		 * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that came from the network.
+		 * When using this constructor a pointer to the RawPacket is saved (data isn't copied) and the RawPacket is parsed, meaning all layers
+		 * are created and linked to each other in the right order. In this overload of the constructor the user can specify whether to free
+		 * the instance of raw packet when the Packet is free or not. This constructor should be used to parse the packet up to a certain layer
+		 * @param[in] rawPacket A pointer to the raw packet
+		 * @param[in] parseUntil Optional parameter. Parse the packet until you reach a certain protocol (inclusive). Can be useful for cases when you need to parse only up to a
+		 * certain layer and want to avoid the performance impact and memory consumption of parsing the whole packet
+		 */
+		Packet(RawPacket* rawPacket, ProtocolType parseUntil);
+
+		/**
+		 * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that came from the network.
+		 * When using this constructor a pointer to the RawPacket is saved (data isn't copied) and the RawPacket is parsed, meaning all layers
+		 * are created and linked to each other in the right order. In this overload of the constructor the user can specify whether to free
+		 * the instance of raw packet when the Packet is free or not. . This constructor should be used to parse the packet up to a certain layer in the OSI model
+		 * @param[in] rawPacket A pointer to the raw packet
+		 * @param[in] parseUntilLayer Optional parameter. Parse the packet until you reach a certain layer in the OSI model (inclusive). Can be useful for cases when you need to
+		 * parse only up to a certain OSI layer (for example transport layer) and want to avoid the performance impact and memory consumption of parsing the whole packet
+		 */
+		Packet(RawPacket* rawPacket, OsiModelLayer parseUntilLayer);
+
+		/**
+		 * A destructor for this class. Frees all layers allocated by this instance (Notice: it doesn't free layers that weren't allocated by this
+		 * class, for example layers that were added by addLayer() or insertLayer() ). In addition it frees the raw packet if it was allocated by
+		 * this instance (meaning if it was allocated by this instance constructor)
+		 */
+		virtual ~Packet();
+
+		/**
+		 * A copy constructor for this class. This copy constructor copies all the raw data and re-create all layers. So when the original Packet
+		 * is being freed, no data will be lost in the copied instance
+		 * @param[in] other The instance to copy from
+		 */
+		Packet(const Packet& other);
+
+		/**
+		 * Assignment operator overloading. It first frees all layers allocated by this instance (Notice: it doesn't free layers that weren't allocated by this
+		 * class, for example layers that were added by addLayer() or insertLayer() ). In addition it frees the raw packet if it was allocated by
+		 * this instance (meaning if it was allocated by this instance constructor).
+		 * Afterwards it copies the data from the other packet in the same way used in the copy constructor.
+		 * @param[in] other The instance to copy from
+		 */
+		Packet& operator=(const Packet& other);
+
+		/**
+		 * Get a pointer to the Packet's RawPacket
+		 * @return A pointer to the Packet's RawPacket
+		 */
+		inline RawPacket* getRawPacket() { return m_RawPacket; }
+
+		/**
+		 * Set a RawPacket and re-construct all packet layers
+		 * @param[in] rawPacket Raw packet to set
+		 * @param[in] freeRawPacket A flag indicating if the destructor should also call the raw packet destructor or not
+		 * @param[in] parseUntil Parse the packet until it reaches this protocol. Can be useful for cases when you need to parse only up to a certain layer and want to avoid the
+		 * performance impact and memory consumption of parsing the whole packet. Default value is ::UnknownProtocol which means don't take this parameter into account
+		 * @param[in] parseUntilLayer Parse the packet until certain layer in OSI model. Can be useful for cases when you need to parse only up to a certain layer and want to avoid the
+		 * performance impact and memory consumption of parsing the whole packet. Default value is ::OsiModelLayerUnknown which means don't take this parameter into account
+		 */
+		void setRawPacket(RawPacket* rawPacket, bool freeRawPacket, ProtocolType parseUntil = UnknownProtocol, OsiModelLayer parseUntilLayer = OsiModelLayerUnknown);
+
+		/**
+		 * Get a pointer to the Packet's RawPacket in a read-only manner
+		 * @return A pointer to the Packet's RawPacket
+		 */
+		inline RawPacket* getRawPacketReadOnly() const { return m_RawPacket; }
+
+		/**
+		 * Get a pointer to the first (lowest) layer in the packet
+		 * @return A pointer to the first (lowest) layer in the packet
+		 */
+		inline Layer* getFirstLayer() { return m_FirstLayer; }
+
+		/**
+		 * Get a pointer to the last (highest) layer in the packet
+		 * @return A pointer to the last (highest) layer in the packet
+		 */
+		inline Layer* getLastLayer() { return m_LastLayer; }
+
+		/**
+		 * Add a new layer as the last layer in the packet. This method gets a pointer to the new layer as a parameter
+		 * and attaches it to the packet. Notice after calling this method the input layer is attached to the packet so
+		 * every change you make in it affect the packet; Also it cannot be attached to other packets
+		 * @param[in] newLayer A pointer to the new layer to be added to the packet
+		 * @return True if everything went well or false otherwise (an appropriate error log message will be printed in
+		 * such cases)
+		 */
+		bool addLayer(Layer* newLayer);
+
+		/**
+		 * Insert a new layer after an existing layer in the packet. This method gets a pointer to the new layer as a
+		 * parameter and attaches it to the packet. Notice after calling this method the input layer is attached to the
+		 * packet so every change you make in it affect the packet; Also it cannot be attached to other packets
+		 * @param[in] prevLayer A pointer to an existing layer in the packet which the new layer should followed by. If
+		 * this layer isn't attached to a packet and error will be printed to log and false will be returned
+		 * @param[in] newLayer A pointer to the new layer to be added to the packet
+		 * @return True if everything went well or false otherwise (an appropriate error log message will be printed in
+		 * such cases)
+		 */
+		bool insertLayer(Layer* prevLayer, Layer* newLayer);
+
+		/**
+		 * Remove an existing layer from the packet
+		 * @param[in] layer The layer to remove
+		 * @return True if everything went well or false otherwise (an appropriate error log message will be printed in
+		 * such cases)
+		 */
+		bool removeLayer(Layer* layer);
+
+		/**
+		 * A templated method to get a layer of a certain type (protocol). If no layer of such type is found, NULL is returned
+		 * @return A pointer to the layer of the requested type, NULL if not found
+		 */
+		template<class TLayer>
+		TLayer* getLayerOfType();
+
+		/**
+		 * A templated method to get the first layer of a certain type (protocol), start searching from a certain layer.
+		 * For example: if a packet looks like: EthLayer -> VlanLayer(1) -> VlanLayer(2) -> VlanLayer(3) -> IPv4Layer
+		 * and the user put VlanLayer(2) as a parameter and wishes to search for a VlanLayer, VlanLayer(3) will be returned
+		 * If no layer of such type is found, NULL is returned
+		 * @param[in] after A pointer to the layer to start search from
+		 * @return A pointer to the layer of the requested type, NULL if not found
+		 */
+		template<class TLayer>
+		TLayer* getNextLayerOfType(Layer* after);
+
+		/**
+		 * Check whether the packet contains a certain protocol
+		 * @param[in] protocolType The protocol type to search
+		 * @return True if the packet contains the protocol, false otherwise
+		 */
+		inline bool isPacketOfType(ProtocolType protocolType) { return m_ProtocolTypes & protocolType; }
+
+		/**
+		 * Each layer can have fields that can be calculate automatically from other fields using Layer#computeCalculateFields(). This method forces all layers to calculate these
+		 * fields values
+		 */
+		void computeCalculateFields();
+
+		/**
+		 * Each layer can print a string representation of the layer most important data using Layer#toString(). This method aggregates this string from all layers and
+		 * print it to a complete string containing all packet's relevant data
+		 * @param[in] timeAsLocalTime Print time as local time or GMT. Default (true value) is local time, for GMT set to false
+		 * @return A string containing most relevant data from all layers (looks like the packet description in Wireshark)
+		 */
+		std::string printToString(bool timeAsLocalTime = true);
+
+		/**
+		 * Similar to printToString(), but instead of one string it outputs a list of strings, one string for every layer
+		 * @param[out] result A string vector that will contain all strings
+		 * @param[in] timeAsLocalTime Print time as local time or GMT. Default (true value) is local time, for GMT set to false
+		 */
+		void printToStringList(std::vector<std::string>& result, bool timeAsLocalTime = true);
+
+	private:
+		void copyDataFrom(const Packet& other);
+
+		void destructPacketData();
+
+		bool extendLayer(Layer* layer, int offsetInLayer, size_t numOfBytesToExtend);
+		bool shortenLayer(Layer* layer, int offsetInLayer, size_t numOfBytesToShorten);
+
+		void reallocateRawData(size_t newSize);
+
+		std::string printPacketInfo(bool timeAsLocalTime);
+	};
+
+	template<class TLayer>
+	TLayer* Packet::getLayerOfType()
+	{
+		if (dynamic_cast<TLayer*>(m_FirstLayer) != NULL)
+			return (TLayer*)m_FirstLayer;
+
+		return getNextLayerOfType<TLayer>(m_FirstLayer);
+	}
+
+	template<class TLayer>
+	TLayer* Packet::getNextLayerOfType(Layer* after)
+	{
+		if (after == NULL)
+			return NULL;
+
+		Layer* curLayer = after->getNextLayer();
+		while ((curLayer != NULL) && (dynamic_cast<TLayer*>(curLayer) == NULL))
+		{
+			curLayer = curLayer->getNextLayer();
+		}
+
+		return (TLayer*)curLayer;
+	}
+
+} // namespace pcpp
+
+#endif /* PACKETPP_PACKET */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/PacketUtils.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/PacketUtils.h b/thirdparty/pcap++/Packet++/header/PacketUtils.h
new file mode 100644
index 0000000..d4cccf8
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/PacketUtils.h
@@ -0,0 +1,34 @@
+#ifndef PACKETPP_PACKET_UTILS
+#define PACKETPP_PACKET_UTILS
+
+#include "Packet.h"
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+	/**
+	 * A method that is given a packet and calculates a hash value by the packet's 5-tuple. Supports IPv4, IPv6,
+	 * TCP and UDP. For packets which doesn't have 5-tuple (for example: packets which aren't IPv4/6 or aren't
+	 * TCP/UDP) the value of 0 will be returned
+	 * @param[in] packet The packet to calculate hash for
+	 * @return The hash value calculated for this packet or 0 if the packet doesn't contain 5-tuple
+	 */
+	uint32_t hash5Tuple(Packet* packet);
+
+	/**
+	 * A method that is given a packet and calculates a hash value by the packet's 2-tuple (IP src + IP dst). Supports
+	 * IPv4 and IPv6. For packets which aren't IPv4/6 the value of 0 will be returned
+	 * @param[in] packet The packet to calculate hash for
+	 * @return The hash value calculated for this packet or 0 if the packet isn't IPv4/6
+	 */
+	uint32_t hash2Tuple(Packet* packet);
+
+} // namespace pcpp
+
+#endif /* PACKETPP_PACKET_UTILS */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/PayloadLayer.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/PayloadLayer.h b/thirdparty/pcap++/Packet++/header/PayloadLayer.h
new file mode 100644
index 0000000..f92de33
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/PayloadLayer.h
@@ -0,0 +1,78 @@
+#ifndef PACKETPP_PAYLOAD_LAYER
+#define PACKETPP_PAYLOAD_LAYER
+
+#include <Layer.h>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+	/**
+	 * @class PayloadLayer
+	 * Represents a generic or unknown layer or a packet payload
+	 */
+	class PayloadLayer : public Layer
+	{
+	public:
+		 /** A constructor that creates the layer from an existing packet raw data
+		 * @param[in] data A pointer to the raw data
+		 * @param[in] dataLen Size of the data in bytes
+		 * @param[in] prevLayer A pointer to the previous layer
+		 * @param[in] packet A pointer to the Packet instance where layer will be stored in
+		 */
+		PayloadLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = GenericPayolad; }
+
+		/**
+		 * A constructor that allocates a new payload
+		 * @param[in] data A raw buffer that will be used as a payload. This data will be copied to the layer
+		 * @param[in] dataLen The raw buffer length
+		 * @param[in] dummy A dummy parameter to separate the constructor signature from the other constructor. Its value isn't used anywhere
+		 * @todo dummy is probably not necessary anymore. Remove it
+		 */
+		PayloadLayer(const uint8_t* data, size_t dataLen, bool dummy);
+
+		~PayloadLayer() {}
+
+		/**
+		 * Get a pointer to the payload data
+		 * @return A pointer to the payload data
+		 */
+		inline uint8_t* getPayload() { return m_Data; }
+
+		/**
+		 * Get the payload data length
+		 * @return The payload data length in bytes
+		 */
+		inline size_t getPayloadLen() { return m_DataLen; }
+
+		// implement abstract methods
+
+		/**
+		 * Does nothing for this layer (PayloadLayer is always last)
+		 */
+		void parseNextLayer() {}
+
+		/**
+		 * @return Payload data length in bytes
+		 */
+		inline size_t getHeaderLen() { return m_DataLen; }
+
+		/**
+		 * Does nothing for this layer
+		 */
+		void computeCalculateFields() {}
+
+		std::string toString();
+
+		OsiModelLayer getOsiModelLayer() { return OsiModelApplicationLayer; }
+
+	};
+
+} // namespace pcpp
+
+#endif /* PACKETPP_PAYLOAD_LAYER */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/ProtocolType.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/ProtocolType.h b/thirdparty/pcap++/Packet++/header/ProtocolType.h
new file mode 100644
index 0000000..d90ebfa
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/ProtocolType.h
@@ -0,0 +1,225 @@
+#ifndef PCAPPP_PROTOCOL_TYPES
+#define PCAPPP_PROTOCOL_TYPES
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+	/**
+	 * An enum representing all protocols supported by PcapPlusPlus
+	 */
+	enum ProtocolType
+	{
+		/**
+		 * Unknown protocol (or unsupported by PcapPlusPlus)
+		 */
+		UnknownProtocol = 0x00,
+
+		/**
+		 * Ethernet protocol
+		 */
+		Ethernet = 0x01,
+
+		/**
+		 * IPv4 protocol
+		 */
+		IPv4 = 0x02,
+
+		/**
+		 * IPv6 protocol
+		 */
+		IPv6 = 0x04,
+
+		/**
+		 * IP protocol (aggregation bitmask of IPv4 and IPv6 protocols)
+		 */
+		IP = 0x06,
+
+		/**
+		 * TCP protocol
+		 */
+		TCP = 0x08,
+
+		/**
+		 * UDP protocol
+		 */
+		UDP = 0x10,
+
+		/**
+		 * HTTP request protocol
+		 */
+		HTTPRequest = 0x20,
+
+		/**
+		 * HTTP response protocol
+		 */
+		HTTPResponse = 0x40,
+
+		/**
+		 * HTTP protocol (aggregation bitmask of HTTP request and HTTP response protocols)
+		 */
+		HTTP = 0x20 | 0x40,
+
+		/**
+		 * ARP protocol
+		 */
+		ARP = 0x80,
+
+		/**
+		 * VLAN protocol
+		 */
+		VLAN = 0x100,
+
+		/**
+		 * ICMP protocol (currently not supported by PcapPlusPlus)
+		 */
+		ICMP = 0x200,
+
+		/**
+		 * PPPoE session protocol
+		 */
+		PPPoESession = 0x400,
+
+		/**
+		 * PPPoE discovery protocol
+		 */
+		PPPoEDiscovery = 0x800,
+
+		/**
+		 * PPPoE protocol (aggregation bitmask of PPPoESession and PPPoEDiscovery protocols)
+		 */
+		PPPoE = 0x400 | 0x800,
+
+		/**
+		 * DNS protocol
+		 */
+		DNS = 0x1000,
+
+		/**
+		 * MPLS protocol
+		 */
+		MPLS = 0x2000,
+
+		/**
+		 * GRE version 0 protocol
+		 */
+		GREv0 = 0x4000,
+
+		/**
+		 * GRE version 1 protocol
+		 */
+		GREv1 = 0x8000,
+
+		/**
+		 * GRE protocol (aggregation bitmask of GREv0 and GREv1 protocols)
+		 */
+		GRE = 0x4000 | 0x8000,
+
+		/**
+		 * PPP for PPTP protocol
+		 */
+		PPP_PPTP = 0x10000,
+
+		/**
+		 * SSL/TLS protocol
+		 */
+		SSL = 0x20000,
+
+		/**
+		 * SLL (Linux cooked capture) protocol
+		 */
+		SLL = 0x40000,
+
+		/**
+		 * DHCP/BOOTP protocol
+		 */
+		DHCP = 0x80000,
+
+		/**
+		 * Null/Loopback protocol
+		 */
+		NULL_LOOPBACK = 0x100000,
+
+		/**
+		 * IGMP protocol
+		 */
+		IGMP = 0xE00000,
+
+		/**
+		 * IGMPv1 protocol
+		 */
+		IGMPv1 = 0x200000,
+
+		/**
+		 * IGMPv2 protocol
+		 */
+		IGMPv2 = 0x400000,
+
+		/**
+		 * IGMPv3 protocol
+		 */
+		IGMPv3 = 0x800000,
+
+		/**
+		 * Generic payload (no specific protocol)
+		 */
+		GenericPayolad = 0x1000000,
+
+		/**
+		 * VXLAN protocol
+		 */
+		VXLAN = 0x2000000,
+
+		/**
+		 * SIP request protocol
+		 */
+		SIPRequest = 0x4000000,
+
+		/**
+		 * SIP response protocol
+		 */
+		SIPResponse = 0x8000000,
+
+		/**
+		 * SIP protocol (aggregation bitmask of SIPRequest and SIPResponse protocols)
+		 */
+		SIP = 0x4000000 | 0x8000000,
+
+		/**
+		 * SDP protocol
+		 */
+		SDP = 0x10000000
+	};
+
+
+	/**
+	 * An enum representing OSI model layers
+	 */
+	enum OsiModelLayer
+	{
+		/** Physical layer (layer 1) */
+		OsiModelPhysicalLayer = 1,
+		/** Data link layer (layer 2) */
+		OsiModelDataLinkLayer = 2,
+		/** Network layer (layer 3) */
+		OsiModelNetworkLayer = 3,
+		/** Transport layer (layer 4) */
+		OsiModelTransportLayer = 4,
+		/** Session layer (layer 5) */
+		OsiModelSesionLayer = 5,
+		/** Presentation layer (layer 6) */
+		OsiModelPresentationLayer = 6,
+		/** Application layer (layer 7) */
+		OsiModelApplicationLayer = 7,
+		/** Unknown / null layer */
+		OsiModelLayerUnknown = 8
+	};
+
+} //namespace pcpp
+
+#endif

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/RawPacket.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/RawPacket.h b/thirdparty/pcap++/Packet++/header/RawPacket.h
new file mode 100644
index 0000000..b69229b
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/RawPacket.h
@@ -0,0 +1,378 @@
+#ifndef PCAPPP_RAW_PACKET
+#define PCAPPP_RAW_PACKET
+
+#include <stdint.h>
+#ifdef _MSC_VER
+#include <WinSock2.h>
+#else
+#include <sys/time.h>
+#endif
+#include <stddef.h>
+
+/// @file
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+	/**
+	 * An enum describing all known link layer type. Taken from: http://www.tcpdump.org/linktypes.html .
+	 * Currently only Ethernet (1) and SLL (113) are supported
+	 */
+	enum LinkLayerType
+	{
+		/** BSD loopback encapsulation */
+		LINKTYPE_NULL = 0,
+		/** IEEE 802.3 Ethernet */
+		LINKTYPE_ETHERNET = 1,
+		/** AX.25 packet */
+		LINKTYPE_AX25 = 3,
+		/** IEEE 802.5 Token Ring */
+		LINKTYPE_IEEE802_5 = 6,
+		/** ARCNET Data Packets */
+		LINKTYPE_ARCNET_BSD = 7,
+		/** SLIP, encapsulated with a LINKTYPE_SLIP header */
+		LINKTYPE_SLIP = 8,
+		/** PPP, as per RFC 1661 and RFC 1662 */
+		LINKTYPE_PPP = 9,
+		/** FDDI, as specified by ANSI INCITS 239-1994 */
+		LINKTYPE_FDDI = 10,
+		/** Raw IP */
+		LINKTYPE_DLT_RAW1 = 12,
+		/** Raw IP (OpenBSD) */
+		LINKTYPE_DLT_RAW2 = 14,
+		/** PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547 */
+		LINKTYPE_PPP_HDLC = 50,
+		/** PPPoE */
+		LINKTYPE_PPP_ETHER = 51,
+		/** RFC 1483 LLC/SNAP-encapsulated ATM */
+		LINKTYPE_ATM_RFC1483 = 100,
+		/** Raw IP */
+		LINKTYPE_RAW = 101,
+		/** Cisco PPP with HDLC framing */
+		LINKTYPE_C_HDLC = 104,
+		/** IEEE 802.11 wireless LAN */
+		LINKTYPE_IEEE802_11 = 105,
+		/** Frame Relay */
+		LINKTYPE_FRELAY = 107,
+		/** OpenBSD loopback encapsulation */
+		LINKTYPE_LOOP = 108,
+		/** Linux "cooked" capture encapsulation */
+		LINKTYPE_LINUX_SLL = 113,
+		/** Apple LocalTalk */
+		LINKTYPE_LTALK = 114,
+		/** OpenBSD pflog */
+		LINKTYPE_PFLOG = 117,
+		/** Prism monitor mode information followed by an 802.11 header */
+		LINKTYPE_IEEE802_11_PRISM = 119,
+		/** RFC 2625 IP-over-Fibre Channel */
+		LINKTYPE_IP_OVER_FC = 122,
+		/** ATM traffic, encapsulated as per the scheme used by SunATM devices */
+		LINKTYPE_SUNATM = 123,
+		/** Radiotap link-layer information followed by an 802.11 header */
+		LINKTYPE_IEEE802_11_RADIOTAP = 127,
+		/** ARCNET Data Packets, as described by the ARCNET Trade Association standard ATA 878.1-1999 */
+		LINKTYPE_ARCNET_LINUX = 129,
+		/** Apple IP-over-IEEE 1394 cooked header */
+		LINKTYPE_APPLE_IP_OVER_IEEE1394 = 138,
+		/** Signaling System 7 Message Transfer Part Level 2 */
+		LINKTYPE_MTP2_WITH_PHDR = 139,
+		/** Signaling System 7 Message Transfer Part Level 2 */
+		LINKTYPE_MTP2 = 140,
+		/** Signaling System 7 Message Transfer Part Level 3 */
+		LINKTYPE_MTP3 = 141,
+		/** Signaling System 7 Signalling Connection Control Part */
+		LINKTYPE_SCCP = 142,
+		/** Signaling System 7 Signalling Connection Control Part */
+		LINKTYPE_DOCSIS = 143,
+		/** Linux-IrDA packets */
+		LINKTYPE_LINUX_IRDA = 144,
+		/** AVS monitor mode information followed by an 802.11 header */
+		LINKTYPE_IEEE802_11_AVS = 163,
+		/** BACnet MS/TP frames */
+		LINKTYPE_BACNET_MS_TP = 165,
+		/** PPP in HDLC-like encapsulation, like LINKTYPE_PPP_HDLC, but with the 0xff address byte replaced by a direction indication - 0x00 for incoming and 0x01 for outgoing */
+		LINKTYPE_PPP_PPPD = 166,
+		/** General Packet Radio Service Logical Link Control */
+		LINKTYPE_GPRS_LLC = 169,
+		/** Transparent-mapped generic framing procedure */
+		LINKTYPE_GPF_T = 170,
+		/** Frame-mapped generic framing procedure */
+		LINKTYPE_GPF_F = 171,
+		/** Link Access Procedures on the D Channel (LAPD) frames */
+		LINKTYPE_LINUX_LAPD = 177,
+		/** Bluetooth HCI UART transport layer */
+		LINKTYPE_BLUETOOTH_HCI_H4 = 187,
+		/** USB packets, beginning with a Linux USB header */
+		LINKTYPE_USB_LINUX = 189,
+		/** Per-Packet Information information */
+		LINKTYPE_PPI = 192,
+		/** IEEE 802.15.4 wireless Personal Area Network */
+		LINKTYPE_IEEE802_15_4 = 195,
+		/** Various link-layer types, with a pseudo-header, for SITA */
+		LINKTYPE_SITA = 196,
+		/** Various link-layer types, with a pseudo-header, for Endace DAG cards; encapsulates Endace ERF record */
+		LINKTYPE_ERF = 197,
+		/** Bluetooth HCI UART transport layer */
+		LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR = 201,
+		/** AX.25 packet, with a 1-byte KISS header containing a type indicator */
+		LINKTYPE_AX25_KISS = 202,
+		/** Link Access Procedures on the D Channel (LAPD) frames */
+		LINKTYPE_LAPD = 203,
+		/** PPP, as per RFC 1661 and RFC 1662, preceded with a one-byte pseudo-header with a zero value meaning "received by this host" and a non-zero value meaning  "sent by this host" */
+		LINKTYPE_PPP_WITH_DIR = 204,
+		/** Cisco PPP with HDLC framing */
+		LINKTYPE_C_HDLC_WITH_DIR = 205,
+		/** Frame Relay */
+		LINKTYPE_FRELAY_WITH_DIR = 206,
+		/** IPMB over an I2C circuit */
+		LINKTYPE_IPMB_LINUX = 209,
+		/** IEEE 802.15.4 wireless Personal Area Network */
+		LINKTYPE_IEEE802_15_4_NONASK_PHY = 215,
+		/** USB packets, beginning with a Linux USB header */
+		LINKTYPE_USB_LINUX_MMAPPED = 220,
+		/** Fibre Channel FC-2 frames, beginning with a Frame_Header */
+		LINKTYPE_FC_2 = 224,
+		/** Fibre Channel FC-2 frames */
+		LINKTYPE_FC_2_WITH_FRAME_DELIMS = 225,
+		/** Solaris ipnet pseudo-header */
+		LINKTYPE_IPNET = 226,
+		/** CAN (Controller Area Network) frames, with a pseudo-header as supplied by Linux SocketCAN */
+		LINKTYPE_CAN_SOCKETCAN = 227,
+		/** Raw IPv4; the packet begins with an IPv4 header */
+		LINKTYPE_IPV4 = 228,
+		/** Raw IPv6; the packet begins with an IPv6 header */
+		LINKTYPE_IPV6 = 229,
+		/** IEEE 802.15.4 wireless Personal Area Network, without the FCS at the end of the frame */
+		LINKTYPE_IEEE802_15_4_NOFCS = 230,
+		/** Raw D-Bus messages, starting with the endianness flag, followed by the message type, etc., but without the authentication handshake before the message sequence */
+		LINKTYPE_DBUS = 231,
+		/** DVB-CI (DVB Common Interface for communication between a PC Card module and a DVB receiver), with the message format specified by the PCAP format for DVB-CI specification */
+		LINKTYPE_DVB_CI = 235,
+		/** Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but not the same as, 27.010) */
+		LINKTYPE_MUX27010 = 236,
+		/** D_PDUs as described by NATO standard STANAG 5066, starting with the synchronization sequence, and including both header and data CRCs */
+		LINKTYPE_STANAG_5066_D_PDU = 237,
+		/** Linux netlink NETLINK NFLOG socket log messages */
+		LINKTYPE_NFLOG = 239,
+		/** Pseudo-header for Hilscher Gesellschaft für Systemautomation mbH netANALYZER devices, followed by an Ethernet frame, beginning with the MAC header and ending with the FCS */
+		LINKTYPE_NETANALYZER = 240,
+		/** Pseudo-header for Hilscher Gesellschaft für Systemautomation mbH netANALYZER devices, followed by an Ethernet frame, beginning with the preamble, SFD, and MAC header, and ending with the FCS */
+		LINKTYPE_NETANALYZER_TRANSPARENT = 241,
+		/** IP-over-InfiniBand, as specified by RFC 4391 section 6 */
+		LINKTYPE_IPOIB = 242,
+		/** MPEG-2 Transport Stream transport packets, as specified by ISO 13818-1/ITU-T Recommendation H.222.0 */
+		LINKTYPE_MPEG_2_TS = 243,
+		/** Pseudo-header for ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as used by their ng40 protocol tester */
+		LINKTYPE_NG40 = 244,
+		/** Pseudo-header for NFC LLCP packet captures, followed by frame data for the LLCP Protocol as specified by NFCForum-TS-LLCP_1.1 */
+		LINKTYPE_NFC_LLCP = 245,
+		/** Raw InfiniBand frames, starting with the Local Routing Header */
+		LINKTYPE_INFINIBAND = 247,
+		/** SCTP packets, as defined by RFC 4960, with no lower-level protocols such as IPv4 or IPv6 */
+		LINKTYPE_SCTP = 248,
+		/** USB packets, beginning with a USBPcap header */
+		LINKTYPE_USBPCAP = 249,
+		/** Serial-line packet header for the Schweitzer Engineering Laboratories "RTAC" product */
+		LINKTYPE_RTAC_SERIAL = 250,
+		/** Bluetooth Low Energy air interface Link Layer packets */
+		LINKTYPE_BLUETOOTH_LE_LL = 251,
+		/** Linux Netlink capture encapsulation */
+		LINKTYPE_NETLINK = 253,
+		/** Bluetooth Linux Monitor encapsulation of traffic for the BlueZ stack */
+		LINKTYPE_BLUETOOTH_LINUX_MONITOR = 254,
+		/** Bluetooth Basic Rate and Enhanced Data Rate baseband packets */
+		LINKTYPE_BLUETOOTH_BREDR_BB = 255,
+		/** Bluetooth Low Energy link-layer packets */
+		LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR = 256,
+		/** PROFIBUS data link layer packets, as specified by IEC standard 61158-6-3 */
+		LINKTYPE_PROFIBUS_DL = 257,
+		/** Apple PKTAP capture encapsulation */
+		LINKTYPE_PKTAP = 258,
+		/** Ethernet-over-passive-optical-network packets */
+		LINKTYPE_EPON = 259,
+		/** IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" in the PICMG HPM.2 specification */
+		LINKTYPE_IPMI_HPM_2 = 260,
+		/** Per Joshua Wright <jw...@hasborg.com>, formats for Z-Wave RF profiles R1 and R2 captures */
+		LINKTYPE_ZWAVE_R1_R2 = 261,
+		/** Per Joshua Wright <jw...@hasborg.com>, formats for Z-Wave RF profile R3 captures */
+		LINKTYPE_ZWAVE_R3 = 262,
+		/** Formats for WattStopper Digital Lighting Management (DLM) and Legrand Nitoo Open protocol common packet structure captures */
+		LINKTYPE_WATTSTOPPER_DLM = 263,
+		/** Messages between ISO 14443 contactless smartcards (Proximity Integrated Circuit Card, PICC) and card readers (Proximity Coupling Device, PCD), with the message format specified by the PCAP format for ISO14443 specification */
+		LINKTYPE_ISO_14443 = 264
+	};
+
+	/**
+	 * Max packet size supported
+	 */
+#define PCPP_MAX_PACKET_SIZE 65536
+
+	/**
+	 * @class RawPacket
+	 * This class holds the packet as raw (not parsed) data. The data is held as byte array. In addition to the data itself
+	 * every instance also holds a timestamp representing the time the packet was received by the NIC.
+	 * RawPacket instance isn't read only. The user can change the packet data, add or remove data, etc.
+	 */
+	class RawPacket
+	{
+	protected:
+		uint8_t* m_pRawData;
+		int m_RawDataLen;
+		int m_FrameLength;
+		timeval m_TimeStamp;
+		bool m_DeleteRawDataAtDestructor;
+		bool m_RawPacketSet;
+		LinkLayerType m_linkLayerType;
+		void Init();
+		void copyDataFrom(const RawPacket& other, bool allocateData = true);
+	public:
+		/**
+		 * A constructor that receives a pointer to the raw data (allocated elsewhere). This constructor is usually used when packet
+		 * is captured using a packet capturing engine (like libPcap. WinPcap, PF_RING, etc.). The capturing engine allocates the raw data
+		 * memory and give the user a pointer to it + a timestamp it has arrived to the device
+		 * @param[in] pRawData A pointer to the raw data
+		 * @param[in] rawDataLen The raw data length in bytes
+		 * @param[in] timestamp The timestamp packet was received by the NIC
+		 * @param[in] deleteRawDataAtDestructor An indicator whether raw data pointer should be freed when the instance is freed or not. If set
+		 * to 'true' than pRawData will be freed when instanced is being freed
+		 * @param[in] layerType The link layer type of this raw packet. The default is Ethernet
+		 */
+		RawPacket(const uint8_t* pRawData, int rawDataLen, timeval timestamp, bool deleteRawDataAtDestructor, LinkLayerType layerType = LINKTYPE_ETHERNET);
+
+		/**
+		 * A default constructor that initializes class'es attributes to default value:
+		 * - data pointer is set to NULL
+		 * - data length is set to 0
+		 * - deleteRawDataAtDestructor is set to 'true'
+		 * @todo timestamp isn't set here to a default value
+		 */
+		RawPacket();
+
+		/**
+		 * A destructor for this class. Frees the raw data if deleteRawDataAtDestructor was set to 'true'
+		 */
+		virtual ~RawPacket();
+
+		/**
+		 * A copy constructor that copies all data from another instance. Notice all raw data is copied (using memcpy), so when the original or
+		 * the other instance are freed, the other won't be affected
+		 * @param[in] other The instance to copy from
+		 */
+		RawPacket(const RawPacket& other);
+
+		/**
+		 * Assignment operator overload for this class. When using this operator on an already initialized RawPacket instance,
+		 * the original raw data is freed first. Then the other instance is copied to this instance, the same way the copy constructor works
+		 * @todo free raw data only if deleteRawDataAtDestructor was set to 'true'
+		 * @param[in] other The instance to copy from
+		 */
+		RawPacket& operator=(const RawPacket& other);
+
+		/**
+		 * Set a raw data. If data was already set and deleteRawDataAtDestructor was set to 'true' the old data will be freed first
+		 * @param[in] pRawData A pointer to the new raw data
+		 * @param[in] rawDataLen The new raw data length in bytes
+		 * @param[in] timestamp The timestamp packet was received by the NIC
+		 * @param[in] layerType The link layer type for this raw data
+		 * @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the actual packet length. This parameter represents the packet 
+		 * length. This parameter is optional, if not set or set to -1 it is assumed both lengths are equal
+		 * @return True if raw data was set successfully, false otherwise
+		 */
+		virtual bool setRawData(const uint8_t* pRawData, int rawDataLen, timeval timestamp, LinkLayerType layerType = LINKTYPE_ETHERNET, int frameLength = -1);
+
+		/**
+		 * Get raw data pointer
+		 * @return A pointer to the raw data
+		 */
+		const uint8_t* getRawData();
+
+		/**
+		 * Get read only raw data pointer
+		 * @return A read-only pointer to the raw data
+		 */
+		const uint8_t* getRawDataReadOnly() const;
+
+		/**
+		 * Get the link layer tpye
+		 * @return the type of the link layer
+		 */
+		LinkLayerType getLinkLayerType() const;
+
+		/**
+		 * Get raw data length in bytes
+		 * @return Raw data length in bytes
+		 */
+		int getRawDataLen() const;
+
+		/**
+		 * Get frame length in bytes
+		 * @return frame length in bytes
+		 */
+		int getFrameLength() const;
+		/**
+		 * Get raw data timestamp
+		 * @return Raw data timestamp
+		 */
+		timeval getPacketTimeStamp();
+
+		/**
+		 * Get an indication whether raw data was already set for this instance.
+		 * @return True if raw data was set for this instance. Raw data can be set using the non-default constructor, using setRawData(), using
+		 * the copy constructor or using the assignment operator. Returns false otherwise, for example: if the instance was created using the
+		 * default constructor or clear() was called
+		 */
+		inline bool isPacketSet() { return m_RawPacketSet; }
+
+		/**
+		 * Clears all members of this instance, meaning setting raw data to NULL, raw data length to 0, etc. Currently raw data is always freed,
+		 * even if deleteRawDataAtDestructor was set to 'false'
+		 * @todo deleteRawDataAtDestructor was set to 'true', don't free the raw data
+		 * @todo set timestamp to a default value as well
+		 */
+		virtual void clear();
+
+		/**
+		 * Append data to the end of current data. This method works without allocating more memory, it just uses memcpy() to copy dataToAppend at
+		 * the end of the current data. This means that the method assumes this memory was already allocated by the user. If it isn't the case then
+		 * this method will cause memory corruption
+		 * @param[in] dataToAppend A pointer to the data to append to current raw data
+		 * @param[in] dataToAppendLen Length in bytes of dataToAppend
+		 */
+		virtual void appendData(const uint8_t* dataToAppend, size_t dataToAppendLen);
+
+		/**
+		 * Insert new data at some index of the current data and shift the remaining old data to the end. This method works without allocating more memory,
+		 * it just copies dataToAppend at the relevant index and shifts the remaining data to the end. This means that the method assumes this memory was
+		 * already allocated by the user. If it isn't the case then this method will cause memory corruption
+		 * @param[in] atIndex The index to insert the new data to
+		 * @param[in] dataToInsert A pointer to the new data to insert
+		 * @param[in] dataToInsertLen Length in bytes of dataToInsert
+		 */
+		virtual void insertData(int atIndex, const uint8_t* dataToInsert, size_t dataToInsertLen);
+
+		/**
+		 * Remove certain number of bytes from current raw data buffer. All data after the removed bytes will be shifted back
+		 * @param[in] atIndex The index to start removing bytes from
+		 * @param[in] numOfBytesToRemove Number of bytes to remove
+		 * @return True if all bytes were removed successfully, or false if atIndex+numOfBytesToRemove is out-of-bounds of the raw data buffer
+		 */
+		virtual bool removeData(int atIndex, size_t numOfBytesToRemove);
+
+		/**
+		 * Re-allocate raw packet buffer meaning add size to it without losing the current packet data. This method allocates the required buffer size as instructed
+		 * by the use and then copies the raw data from the current allocated buffer to the new one. This method can become useful if the user wants to insert or
+		 * append data to the raw data, and the previous allocated buffer is too small, so the user wants to allocate a larger buffer and get RawPacket instance to
+		 * point to it
+		 * @param[in] newBufferLength The new buffer length as required by the user. The method is responsible to allocate the memory
+		 * @return True if data was reallocated successfully, false otherwise
+		 */
+		virtual bool reallocateData(size_t newBufferLength);
+	};
+
+} // namespace pcpp
+
+#endif

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/SSLCommon.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/SSLCommon.h b/thirdparty/pcap++/Packet++/header/SSLCommon.h
new file mode 100644
index 0000000..7688786
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/SSLCommon.h
@@ -0,0 +1,495 @@
+#ifndef PACKETPP_SSL_LAYER_COMMON
+#define PACKETPP_SSL_LAYER_COMMON
+
+
+/**
+ * @file
+ * See detailed explanation of the TLS/SSL protocol support in PcapPlusPlus in SSLLayer.h
+ */
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+	/**
+	 * @struct ssl_tls_record_layer
+	 * The common part of all SSL/TLS messages
+	 */
+#pragma pack(push, 1)
+	struct ssl_tls_record_layer
+	{
+		/** Message (record) type (one of ::SSLRecordType) */
+		uint8_t recordType;
+		/** Message (record) version (one of ::SSLVersion) */
+		uint16_t recordVersion;
+		/** Message (record) length in bytes */
+		uint16_t length;
+	};
+#pragma pack(pop)
+
+
+	/**
+	 * @struct ssl_tls_handshake_layer
+	 * The common part of all SSL/TLS handshake message types
+	 */
+#pragma pack(push, 1)
+	struct ssl_tls_handshake_layer
+	{
+		/** Type of the handshake message (one of ::SSLHandshakeType) */
+		uint8_t handshakeType;
+		/** Length of the message. Length is 3-Byte long, This is the MSB byte */
+		uint8_t length1;
+		/** Length of the message. Length is 3-Byte long, This is the 2 LSB bytes */
+		uint16_t length2;
+	};
+#pragma pack(pop)
+
+
+	/**
+	 * @struct ssl_tls_client_server_hello
+	 * The common header part of client-hello and server-hello handshake messages
+	 */
+#pragma pack(push, 1)
+	struct ssl_tls_client_server_hello : ssl_tls_handshake_layer
+	{
+		/** SSL/TLS handshake version (one of ::SSLVersion) */
+		uint16_t handshakeVersion;
+		/** 32-bytes random number */
+		uint8_t random[32];
+	};
+#pragma pack(pop)
+
+
+	/**
+	 * @struct ssl_tls_change_cipher_spec
+	 * SSL/TLS change-cipher-spec message structure
+	 */
+#pragma pack(push, 1)
+	struct ssl_tls_change_cipher_spec
+	{
+		/** Unused byte */
+		uint8_t changeCipherSpec;
+	};
+#pragma pack(pop)
+
+
+	/**
+	 * @struct ssl_tls_alert
+	 * SSL/TLS alert message structure
+	 */
+#pragma pack(push, 1)
+	struct ssl_tls_alert
+	{
+		/** Alert level (one of ::SSLAlertLevel) */
+		uint8_t alertLevel;
+		/** Alert description (one of ::SSLAlertDescription) */
+		uint8_t alertDescription;
+	};
+#pragma pack(pop)
+
+
+	/**
+	 * SSL/TLS message types
+	 */
+	enum SSLRecordType
+	{
+		/** Change-cipher-spec message */
+		SSL_CHANGE_CIPHER_SPEC = 20,
+		/** SSL alert message */
+		SSL_ALERT              = 21,
+		/** SSL handshake message */
+		SSL_HANDSHAKE          = 22,
+		/** SSL data message */
+		SSL_APPLICATION_DATA   = 23
+	};
+
+	/**
+	 * SSL/TLS versions. Only SSL3.0 and above are supported
+	 */
+	enum SSLVersion
+	{
+		/** SSLv2.0 */
+		SSL2   = 0x0200,
+		/** SSLv3.0 */
+		SSL3   = 0x0300,
+		/** TLSv1.0 */
+		TLS1_0 = 0x0301,
+		/** TLSv1.1 */
+		TLS1_1 = 0x0302,
+		/** TLSv1.2 */
+		TLS1_2 = 0x0303
+	};
+
+	/**
+	 * SSL/TLS handshake message types
+	 */
+	enum SSLHandshakeType
+	{
+		/** Hello-request message type */
+		SSL_HELLO_REQUEST       = 0,
+		/** Client-hello message type */
+		SSL_CLIENT_HELLO        = 1,
+		/** Server-hello message type */
+		SSL_SERVER_HELLO        = 2,
+		/** New-session-ticket message type */
+		SSL_NEW_SESSION_TICKET	= 4,
+		/** Certificate message type */
+		SSL_CERTIFICATE         = 11,
+		/** Server-key-exchange message type */
+		SSL_SERVER_KEY_EXCHANGE = 12,
+		/** Certificate-request message type */
+		SSL_CERTIFICATE_REQUEST = 13,
+		/** Server-hello-done message type */
+		SSL_SERVER_DONE         = 14,
+		/** Certificate-verify message type */
+		SSL_CERTIFICATE_VERIFY  = 15,
+		/** Client-key-exchange message type */
+		SSL_CLIENT_KEY_EXCHANGE = 16,
+		/** Finish message type */
+		SSL_FINISHED            = 20,
+		/** Unknown SSL handshake message */
+		SSL_HANDSHAKE_UNKNOWN   = 255
+	};
+
+	/**
+	 * SSL/TLS alert levels
+	 */
+	enum SSLAlertLevel
+	{
+		/** Warning level alert */
+		SSL_ALERT_LEVEL_WARNING       = 1,
+		/** Fatal level alert */
+		SSL_ALERT_LEVEL_FATAL         = 2,
+		/** For encrypted alerts the level is unknown so this type will be returned */
+		SSL_ALERT_LEVEL_ENCRYPTED     = 255
+	};
+
+	/**
+	 * SSL/TLS alert description types
+	 */
+	enum SSLAlertDescription
+	{
+		/** Close notify alert */
+		SSL_ALERT_CLOSE_NOTIFY            =  0,
+		/** Unexpected message alert */
+		SSL_ALERT_UNEXPECTED_MESSAGE      = 10,
+		/** Bad record MAC alert */
+		SSL_ALERT_BAD_RECORD_MAC          = 20,
+		/** Decryption failed alert */
+		SSL_ALERT_DECRYPTION_FAILED       = 21,
+		/**  */
+		SSL_ALERT_RECORD_OVERFLOW         = 22,
+		/** Decompression failure alert */
+		SSL_ALERT_DECOMPRESSION_FAILURE   = 30,
+		/** Handshake failure alert */
+		SSL_ALERT_HANDSHAKE_FAILURE       = 40,
+		/** No certificate alert */
+		SSL_ALERT_NO_CERTIFICATE          = 41,
+		/** Bad certificate alert */
+		SSL_ALERT_BAD_CERTIFICATE         = 42,
+		/** Unsupported certificate */
+		SSL_ALERT_UNSUPPORTED_CERTIFICATE = 43,
+		/** Certificate revoked alert */
+		SSL_ALERT_CERTIFICATE_REVOKED     = 44,
+		/** Certificate expired alert */
+		SSL_ALERT_CERTIFICATE_EXPIRED     = 45,
+		/** Certificate unknown alert */
+		SSL_ALERT_CERTIFICATE_UNKNOWN     = 46,
+		/** Illegal parameter alert */
+		SSL_ALERT_ILLEGAL_PARAMETER       = 47,
+		/** Unknown CA alert */
+		SSL_ALERT_UNKNOWN_CA              = 48,
+		/** Access denied alert */
+		SSL_ALERT_ACCESS_DENIED           = 49,
+		/** Decode error alert */
+		SSL_ALERT_DECODE_ERROR            = 50,
+		/** Decrypt error alert */
+		SSL_ALERT_DECRYPT_ERROR           = 51,
+		/** Export restriction alert */
+		SSL_ALERT_EXPORT_RESTRICTION      = 60,
+		/** Protocol version alert */
+		SSL_ALERT_PROTOCOL_VERSION        = 70,
+		/** Insufficient security alert */
+		SSL_ALERT_INSUFFICIENT_SECURITY   = 71,
+		/** Internal error alert */
+		SSL_ALERT_INTERNAL_ERROR          = 80,
+		/** User cancelled alert */
+		SSL_ALERT_USER_CANCELLED          = 90,
+		/** No negotiation alert */
+		SSL_ALERT_NO_RENEGOTIATION        = 100,
+		/** Unsupported extension alert */
+		SSL_ALERT_UNSUPPORTED_EXTENSION   = 110,
+		/** Encrtpyed alert (cannot determine its type) */
+		SSL_ALERT_ENCRYPRED				= 255
+	};
+
+	/**
+	 * SSL/TLS key exchange algorithms
+	 */
+	enum SSLKeyExchangeAlgorithm
+	{
+		/** NULL value */
+		SSL_KEYX_NULL,
+		/** RSA (Rivest-Shamir-Adleman) */
+		SSL_KEYX_RSA,
+		/** Diffie-Hellman */
+		SSL_KEYX_DH,
+		/** Diffie-Hellman ephemeral */
+		SSL_KEYX_DHE,
+		/** Elliptic curve Diffie�Hellman */
+		SSL_KEYX_ECDH,
+		/** Elliptic curve Diffie�Hellman ephemeral */
+		SSL_KEYX_ECDHE,
+		/** Fortezza Crypto Card */
+		SSL_KEYX_FORTEZZA,
+		/** Kerberos 5 */
+		SSL_KEYX_KRB5,
+		/**  Pre-Shared Key */
+		SSL_KEYX_PSK,
+		/** GOST */
+		SSL_KEYX_GOST,
+		/** Secure Remote Password */
+		SSL_KEYX_SRP,
+		/** PCT */
+		SSL_KEYX_PCT,
+		/** Unknown algorithm */
+		SSL_KEYX_Unknown
+	};
+
+	/**
+	 * SSL/TLS authentication algorithms
+	 */
+	enum SSLAuthenticationAlgorithm
+	{
+		/** NULL value */
+		SSL_AUTH_NULL,
+		/** RSA (Rivest-Shamir-Adleman) */
+		SSL_AUTH_RSA,
+		/** Digital Signature Standard */
+		SSL_AUTH_DSS,
+		/** Anonymous */
+		SSL_AUTH_anon,
+		/** Diffie-Hellman based key-exchange protocol */
+		SSL_AUTH_KEA,
+		/** Kerberos 5 */
+		SSL_AUTH_KRB5,
+		/** Pre-Shared Key */
+		SSL_AUTH_PSK,
+		/** Elliptic Curve Digital Signature Algorithm */
+		SSL_AUTH_ECDSA,
+		/** GOST */
+		SSL_AUTH_GOST,
+		/** SHA-1 (Secure Hash Algorithm) */
+		SSL_AUTH_SHA,
+		/** PCT */
+		SSL_AUTH_PCT,
+		/** Diffie-Hellman ephemeral */
+		SSL_AUTH_DHE,
+		/** Unknown algorithm */
+		SSL_AUTH_Unknown
+	};
+
+	/**
+	 * SSL/TLS symmetric encryption algorithms
+	 */
+	enum SSLSymetricEncryptionAlgorithm
+	{
+		/** NULL value */
+		SSL_SYM_NULL,
+		/** RC4_40 */
+		SSL_SYM_RC4_40,
+		/** RC4_128 */
+		SSL_SYM_RC4_128,
+		/** RC2_CBC_40 */
+		SSL_SYM_RC2_CBC_40,
+		/** IDEA_CBC */
+		SSL_SYM_IDEA_CBC,
+		/** DES40_CBC */
+		SSL_SYM_DES40_CBC,
+		/** DES_CBC */
+		SSL_SYM_DES_CBC,
+		/** 3DES_EDE_CBC */
+		SSL_SYM_3DES_EDE_CBC,
+		/** FORTEZZA_CBC */
+		SSL_SYM_FORTEZZA_CBC,
+		/** DES_CBC_40 */
+		SSL_SYM_DES_CBC_40,
+		/** AES_128_CBC */
+		SSL_SYM_AES_128_CBC,
+		/** AES_256_CBC */
+		SSL_SYM_AES_256_CBC,
+		/** CAMELLIA_128_CBC */
+		SSL_SYM_CAMELLIA_128_CBC,
+		/** CAMELLIA_128_GCM */
+		SSL_SYM_CAMELLIA_128_GCM,
+		/** CAMELLIA_256_GCM */
+		SSL_SYM_CAMELLIA_256_GCM,
+		/** RC4_56 */
+		SSL_SYM_RC4_56,
+		/** RC2_CBC_56 */
+		SSL_SYM_RC2_CBC_56,
+		/** GOST28147 */
+		SSL_SYM_GOST28147,
+		/** CAMELLIA_256_CBC */
+		SSL_SYM_CAMELLIA_256_CBC,
+		/** SEED_CBC */
+		SSL_SYM_SEED_CBC,
+		/** AES_128 */
+		SSL_SYM_AES_128,
+		/** AES_256 */
+		SSL_SYM_AES_256,
+		/** SSL_SYM_AES_128_GCM */
+		SSL_SYM_AES_128_GCM,
+		/** AES_256_GCM */
+		SSL_SYM_AES_256_GCM,
+		/** RC4_128_EXPORT40 */
+		SSL_SYM_RC4_128_EXPORT40,
+		/** RC2_CBC_128_CBC */
+		SSL_SYM_RC2_CBC_128_CBC,
+		/** IDEA_128_CBC */
+		SSL_SYM_IDEA_128_CBC,
+		/** DES_64_CBC */
+		SSL_SYM_DES_64_CBC,
+		/** DES_192_EDE3_CBC */
+		SSL_SYM_DES_192_EDE3_CBC,
+		/** RC4_64 */
+		SSL_SYM_RC4_64,
+		/** ARIA_128_CBC*/
+		SSL_SYM_ARIA_128_CBC,
+		/** ARIA_256_CBC */
+		SSL_SYM_ARIA_256_CBC,
+		/** ARIA_128_GCM */
+		SSL_SYM_ARIA_128_GCM,
+		/** ARIA_256_GCM */
+		SSL_SYM_ARIA_256_GCM,
+		/** CHACHA20_POLY1305 */
+		SSL_SYM_CHACHA20_POLY1305,
+		/** Unknown algorithm */
+		SSL_SYM_Unknown
+	};
+
+	/**
+	 * SSL/TLS hashing algortihms
+	 */
+	enum SSLHashingAlgorithm
+	{
+		/** NULL value */
+		SSL_HASH_NULL,
+		/** Message-Digest Algorithm */
+		SSL_HASH_MD5,
+		/** SHA-1 (Secure Hash Algorithm) */
+		SSL_HASH_SHA,
+		/** SHA-256 (Secure Hash Algorithm) */
+		SSL_HASH_SHA256,
+		/** GOST 28147 */
+		SSL_HASH_GOST28147,
+		/**  GOST R 34.11 */
+		SSL_HASH_GOSTR3411,
+		/** SHA-384 (Secure Hash Algorithm) */
+		SSL_HASH_SHA384,
+		/** CCM mode (Counter with CBC-MAC) */
+		SSL_HASH_CCM,
+		/** CCM mode (Counter with CBC-MAC) */
+		SSL_HASH_CCM_8,
+		/** Unknown algorithm */
+		SSL_HASH_Unknown
+	};
+
+	/**
+	 * SSL/TLS extension types
+	 */
+	enum SSLExtensionType
+	{
+		/** Server Name Indication extension */
+		SSL_EXT_SERVER_NAME = 0,
+		/** Maximum Fragment Length Negotiation extension */
+		SSL_EXT_MAX_FRAGMENT_LENGTH = 1,
+		/** Client Certificate URLs extension */
+		SSL_EXT_CLIENT_CERTIFICATE_URL = 2,
+		/** Trusted CA Indication extension */
+		SSL_EXT_TRUSTED_CA_KEYS = 3,
+		/** Truncated HMAC extension */
+		SSL_EXT_TRUNCATED_HMAC = 4,
+		/** Certificate Status Request extension */
+		SSL_EXT_STATUS_REQUEST = 5,
+		/** TLS User Mapping extension */
+		SSL_EXT_USER_MAPPING = 6,
+		/** Client Authorization  extension */
+		SSL_EXT_CLIENT_AUTHZ = 7,
+		/** Server Authorization extension */
+		SSL_EXT_SERVER_AUTHZ = 8,
+		/** Certificate Type extension */
+		SSL_EXT_CERT_TYPE = 9,
+		/** Supported Elliptic Curves extension */
+		SSL_EXT_ELLIPTIC_CURVES = 10,
+		/** Elliptic Curves Point Format extension */
+		SSL_EXT_EC_POINT_FORMATS = 11,
+		/** Secure Remote Password extension */
+		SSL_EXT_SRP = 12,
+		/** Signature Algorithms extension */
+		SSL_EXT_SIGNATURE_ALGORITHMS = 13,
+		/** Use Secure Real-time Transport Protocol extension */
+		SSL_EXT_USE_SRTP = 14,
+		/** TLS Heartbit extension */
+		SSL_EXT_HEARTBEAT = 15,
+		/** Application Layer Protocol Negotiation (ALPN) extension */
+		SSL_EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION = 16,
+		/** Status Request extension */
+		SSL_EXT_STATUS_REQUEST_V2 = 17,
+		/** Signed Certificate Timestamp extension */
+		SSL_EXT_SIGNED_CERTIFICATE_TIMESTAMP = 18,
+		/** Client Certificate Type extension */
+		SSL_EXT_CLIENT_CERTIFICATE_TYPE = 19,
+		/** Server Certificate Type extension */
+		SSL_EXT_SERVER_CERTIFICATE_TYPE = 20,
+		/** ClientHello Padding extension */
+		SSL_EXT_PADDING = 21,
+		/** Encrypt-then-MAC extension */
+		SSL_EXT_ENCRYPT_THEN_MAC = 22,
+		/** Extended Master Secret extension */
+		SSL_EXT_EXTENDED_MASTER_SECRET = 23,
+		/** Token Binding extension */
+		SSL_EXT_TOKEN_BINDING = 24,
+		/** SessionTicket TLS extension */
+		SSL_EXT_SESSIONTICKET_TLS = 35,
+		/** Renegotiation Indication extension */
+		SSL_EXT_RENEGOTIATION_INFO = 65281,
+		/** Unknown extension */
+		SSL_EXT_Unknown
+	};
+
+	/**
+	 * SSL/TLS client certificate types
+	 */
+	enum SSLClientCertificateType
+	{
+		/** RSA_SIGN */
+		SSL_CCT_RSA_SIGN = 1,
+		/** DSS_SIGN */
+		SSL_CCT_DSS_SIGN = 2,
+		/** RSA_FIXED_DH */
+		SSL_CCT_RSA_FIXED_DH = 3,
+		/** DSS_FIXED_DH */
+		SSL_CCT_DSS_FIXED_DH = 4,
+		/** RSA_EPHEMERAL_DH_RESERVED */
+		SSL_CCT_RSA_EPHEMERAL_DH_RESERVED = 5,
+		/** DSS_EPHEMERAL_DH_RESERVED */
+		SSL_CCT_DSS_EPHEMERAL_DH_RESERVED = 6,
+		/** FORTEZZA_DMS_RESERVED */
+		SSL_CCT_FORTEZZA_DMS_RESERVED = 20,
+		/** ECDSA_SIGN */
+		SSL_CCT_ECDSA_SIGN = 64,
+		/** FIXED_ECDH */
+		SSL_CCT_RSA_FIXED_ECDH = 65,
+		/** ECDSA_FIXED_ECDH */
+		SSL_CCT_ECDSA_FIXED_ECDH = 66,
+		/** Unknown client certificate type */
+		SSL_CCT_UNKNOWN
+	};
+
+} //namespace pcpp
+
+#endif // PACKETPP_SSL_LAYER_COMMON

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/header/SSLHandshake.h
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/header/SSLHandshake.h b/thirdparty/pcap++/Packet++/header/SSLHandshake.h
new file mode 100644
index 0000000..4d217a2
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/header/SSLHandshake.h
@@ -0,0 +1,946 @@
+#ifndef PACKETPP_SSL_HANDSHAKE_MESSAGE
+#define PACKETPP_SSL_HANDSHAKE_MESSAGE
+
+#include <SSLCommon.h>
+#include <PointerVector.h>
+
+/**
+ * @file
+ * See detailed explanation of the TLS/SSL protocol support in PcapPlusPlus in SSLLayer.h
+ */
+
+/**
+ * \namespace pcpp
+ * \brief The main namespace for the PcapPlusPlus lib
+ */
+namespace pcpp
+{
+
+
+/**
+ * @class SSLCipherSuite
+ * Represents a cipher-suite and enables access all information about it such as all algorithms it encapsulates,
+ * its ID (as appears in the client-hello or server-hello messages),
+ * its name (e.g "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA") etc. PcapPlusPlus contains static instances of this type
+ * for all known cipher-suites and enables access to them through name or ID (see getCipherSuiteByID() and
+ * getCipherSuiteByName() ). List of cipher-suite was taken from here:
+ * http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
+ */
+class SSLCipherSuite
+{
+public:
+	/**
+	 * A c'tor for this class, should never be used by a user
+	 * @param[in] id Cipher-suite ID
+	 * @param[in] keyExAlg Key-exchange algorithm used in this cipher-suite
+	 * @param[in] authAlg Authentication algorithm used in this cipher-suite
+	 * @param[in] symKeyAlg Symmetric key algorithm used in this cipher-suite
+	 * @param[in] MACAlg MAC algorithm used in this cipher-suite
+	 * @param[in] name String representation of this cipher-suite
+	 */
+	SSLCipherSuite(uint16_t id, SSLKeyExchangeAlgorithm keyExAlg,
+			SSLAuthenticationAlgorithm authAlg,
+			SSLSymetricEncryptionAlgorithm symKeyAlg,
+			SSLHashingAlgorithm MACAlg,
+			const char* name)
+	: m_Id(id), m_KeyExAlg(keyExAlg), m_AuthAlg(authAlg), m_SymKeyAlg(symKeyAlg), m_MACAlg(MACAlg), m_Name(name) {}
+
+	/**
+	 * @return Cipher-suite ID
+	 */
+	inline uint16_t getID() { return m_Id; }
+
+	/**
+	 * @return String representation of this cipher-suite
+	 */
+	inline std::string asString() { return m_Name; }
+
+	/**
+	 * @return Key-exchange algorithm used in this cipher-suite
+	 */
+	inline SSLKeyExchangeAlgorithm getKeyExchangeAlg() { return m_KeyExAlg; }
+
+	/**
+	 * @return Authentication algorithm used in this cipher-suite
+	 */
+	inline SSLAuthenticationAlgorithm getAuthAlg() { return m_AuthAlg; }
+
+	/**
+	 * @return Symmetric key algorithm used in this cipher-suite
+	 */
+	inline SSLSymetricEncryptionAlgorithm getSymKeyAlg() { return m_SymKeyAlg; }
+
+	/**
+	 * @return MAC algorithm used in this cipher-suite
+	 */
+	inline SSLHashingAlgorithm getMACAlg() { return m_MACAlg; }
+
+	/**
+	 * A static method that returns a cipher-suite instance by ID
+	 * @param[in] id Cipher-suite ID
+	 * @return A cipher-suite instance matching this ID or NULL if ID not found
+	 */
+	static SSLCipherSuite* getCipherSuiteByID(uint16_t id);
+
+	/**
+	 *  A static method that returns a cipher-suite instance by name
+	 *  @param[in] name Cipher-suite name (e.g "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA")
+	 *  @return A cipher-suite instance matching this name or NULL if name not found
+	 */
+	static SSLCipherSuite* getCipherSuiteByName(std::string name);
+
+private:
+	uint16_t m_Id;
+	SSLKeyExchangeAlgorithm m_KeyExAlg;
+	SSLAuthenticationAlgorithm m_AuthAlg;
+	SSLSymetricEncryptionAlgorithm m_SymKeyAlg;
+	SSLHashingAlgorithm m_MACAlg;
+	std::string m_Name;
+};
+
+
+/**
+ * @class SSLExtension
+ * Represents a SSL/TLS extension. This is a base class that can represent any type of extension. Inherited classes may
+ * contain parsing logic for specific extensions. This class provides capabilities such as getting the extension type,
+ * length and viewing the extension data as raw (byte array)
+ */
+class SSLExtension
+{
+public:
+	/**
+	 * C'tor for this class
+	 * @param[in] data The raw data for the extension
+	 */
+	SSLExtension(uint8_t* data);
+
+	virtual ~SSLExtension() { }
+
+	/**
+	 * @return The type of the extension as enum
+	 */
+	SSLExtensionType getType();
+
+	/**
+	 * @return The type of the extension as a numeric value
+	 */
+	uint16_t getTypeAsInt();
+
+	/**
+	 * @return The length of the extension data in bytes (not including the type and length fields)
+	 */
+	uint16_t getLength();
+
+	/**
+	 * @return The total length of the extension, including type and length fields and the extension data field
+	 */
+	uint16_t getTotalLength();
+
+	/**
+	 * @return A pointer to the raw data of the extension
+	 */
+	uint8_t* getData();
+
+protected:
+
+	/**
+	 * @struct SSLExtensionStruct
+	 * Represents the common fields of the extension
+	 */
+	struct SSLExtensionStruct
+	{
+		/** Extension type */
+		uint16_t extensionType;
+		/** Extension length */
+		uint16_t extensionDataLength;
+		/** Extension data as raw (byte array) */
+		uint8_t	 extensionData[];
+	};
+
+	uint8_t* m_RawData;
+
+	inline SSLExtensionStruct* getExtensionStruct() { return (SSLExtensionStruct*)m_RawData; }
+};
+
+
+/**
+ * @class SSLServerNameIndicationExtension
+ * Represents SSL/TLS Server Name Indication extension. Inherits from SSLExtension and add parsing of the hostname
+ * written in the extension data
+ */
+class SSLServerNameIndicationExtension : public SSLExtension
+{
+public:
+	/**
+	 * C'tor for this class
+	 * @param[in] data The raw data for the extension
+	 */
+	SSLServerNameIndicationExtension(uint8_t* data) : SSLExtension(data) {}
+
+	/**
+	 * @return The hostname written in the extension data
+	 */
+	std::string getHostName();
+};
+
+
+/**
+ * @class SSLx509Certificate
+ * Represents a x509v3 certificate. the SSLCertificateMessage class returns an instance of this class as the certificate.
+ * Currently this class doesn't do much as it doesn't parse the certificate. It only acts as container to the raw data
+ * and returns general info as data as raw, length, etc. In the future I may add full parsing of the certificate
+ */
+class SSLx509Certificate
+{
+public:
+
+	/**
+	 * C'tor for this class
+	 * @param[in] data The raw data of the certificate
+	 * @param[in] dataLen The length in bytes of the raw data
+	 * @param[in] allDataExists Certificate messages usually spread on more than 1 packet. So a certificate is likely
+	 * to split between 2 packets or more. This field indicates whether the raw data contains all ceritificate data
+	 * of just a part of it
+	 */
+	SSLx509Certificate(uint8_t* data, size_t dataLen, bool allDataExists)
+		: m_Data(data), m_DataLen(dataLen), m_AllDataExists(allDataExists) {}
+
+	/**
+	 * @return A pointer to the raw data
+	 */
+	uint8_t* getData() { return m_Data; }
+
+	/**
+	 * @return Raw data length
+	 */
+	size_t getDataLength() { return m_DataLen; }
+
+	/**
+	 * Certificate messages usually spread on more than 1 packet. So a certificate is likely to split between 2 packets
+	 * or more. This method provides an indication whether all certificate data exists or only part of it
+	 * @return True if this data contains all certificate data, false otherwise
+	 */
+	bool allDataExists() { return m_AllDataExists; }
+
+private:
+	uint8_t* m_Data;
+	size_t m_DataLen;
+	bool m_AllDataExists;
+};
+
+
+class SSLHandshakeLayer;
+
+
+/**
+ * @class SSLHandshakeMessage
+ * A base class for SSL/TLS handshake messages. This is an abstract class and cannot be instantiated. SSL/TLS handshake
+ * messages are contained in SSLHandshakeLayer, meaning a SSLHandshakeLayer instance can contain one or more SSLHandshakeMessage
+ * instances. For example: one SSLHandshakeLayer may contain a server-hello, certificate,
+ * server-key-exchange, and server-hello-done messages (although it's not such a common case, most handshake layers
+ * contain 1 handshake message only)
+ */
+class SSLHandshakeMessage
+{
+public:
+
+	virtual ~SSLHandshakeMessage() {}
+
+	/**
+	 * A factory method for creating instances of handshake messages from raw data
+	 * @param[in] data The raw data containing 1 handshake message
+	 * @param[in] dataLen Raw data length in bytes
+	 * @param[in] container A pointer to the SSLHandshakeLayer instance which will contain the created message.
+	 * This parameter is required because the handshake message includes a pointer to its container
+	 */
+	static SSLHandshakeMessage* createHandhakeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container);
+
+	/**
+	 * @return The handshake message type
+	 */
+	virtual SSLHandshakeType getHandshakeType();
+
+	/**
+	 * @return The handshake message length in bytes. Notice that sometimes the handshake message is divided between
+	 * several packets, in this case this method will return the length of part of the message in the current packet
+	 */
+	virtual size_t getMessageLength();
+
+	/**
+	 * @return True if current packet contains the entire message or false otherwise. This method is important
+	 * because sometimes handshake messages are divided in consequent packets (happens a lot in certificate messages
+	 * which usually contain several KB of data which is larger than standard packet size, so the message is divided between
+	 * several packets)
+	 */
+	virtual bool isMessageComplete();
+
+	/**
+	 * @return A pointer to the SSLHandshakeLayer instance containing this message
+	 */
+	inline SSLHandshakeLayer* getContainingLayer() { return m_Container; }
+
+	/**
+	 * @return A string representation of the message type (e.g "Client Hello message")
+	 */
+	virtual std::string toString() = 0;
+
+protected:
+
+	SSLHandshakeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container);
+
+	uint8_t* m_Data;
+	size_t m_DataLen;
+	SSLHandshakeLayer* m_Container;
+
+};
+
+
+/**
+ * @class SSLClientHelloMessage
+ * Represents a client-hello message (type 1). Inherits from SSLHandshakeMessage and adds parsing of all fields
+ * of this message including the message extensions, cipher-suite list, etc.
+ */
+class SSLClientHelloMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and shouldn't be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLClientHelloMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container);
+
+	virtual ~SSLClientHelloMessage() {}
+
+	/**
+	 * @return A struct containing common fields for client-hello and server-hello messages. Notice this points directly
+	 * to the data, so every change will change the actual packet data
+	 */
+	inline ssl_tls_client_server_hello* getClientHelloHeader() { return (ssl_tls_client_server_hello*)m_Data; }
+
+	/**
+	 * @return Handshake SSL/TLS version (notice it may be different than SSLLayer#getRecordVersion(). Each client-hello
+	 * or server-hello message has both record version and handshake version and they may differ from one another)
+	 */
+	SSLVersion getHandshakeVersion();
+
+	/**
+	 * @return Session ID length in bytes. If server-hello message doesn't include session ID 0 will be returned
+	 */
+	uint8_t getSessionIDLength();
+
+	/**
+	 * @return Session ID as byte array. If server-hello message doesn't include session ID NULL will be returned
+	 */
+	uint8_t* getSessionID();
+
+	/**
+	 * @return The number of cipher-suites included in this message
+	 */
+	int getCipherSuiteCount();
+
+	/**
+	 * Get a pointer to a cipher-suite by index. The cipher-suites are numbered according to their order of appearance
+	 * in the message. If index is out of bounds (less than 0 or larger than total amount of cipher suites) NULL will be
+	 * returned
+	 * @param[in] index The index of the cipher-suite to return
+	 * @return The pointer to the cipher-suite object or NULL if index is out of bounds
+	 */
+	SSLCipherSuite* getCipherSuite(int index);
+
+	/**
+	 * @return The value of the compression method byte
+	 */
+	uint8_t getCompressionMethodsValue();
+
+	/**
+	 * @return The number of extensions in this message
+	 */
+	int getExtensionCount();
+
+	/**
+	 * @return The size (in bytes) of all extensions data in this message. Extracted from the "extensions length" field
+	 */
+	uint16_t getExtensionsLenth();
+
+	/**
+	 * Get a pointer to an extension by index. The extensions are numbered according to their order of appearance
+	 * in the message. If index is out of bounds (less than 0 or larger than total amount of extensions) NULL will be
+	 * returned
+	 * @param[in] index The index of the extension to return
+	 * @return The pointer to the extension or NULL if index is out of bounds
+	 */
+	SSLExtension* getExtension(int index);
+
+	/**
+	 * Get a pointer to an extension by numeric type field. Every extension has a 2-byte numeric value representing
+	 * its type (for example: renegotiation info extension type is 0x1ff). This method gets the type and returns a
+	 * pointer to the extension object
+	 * @param[in] type The 2-byte numeric type of the extension
+	 * @return A pointer to the extension object of NULL if this type doesn't exist in this message
+	 */
+	SSLExtension* getExtensionOfType(uint16_t type);
+
+	/**
+	 * Get a pointer to an extension by its enum type
+	 * @param[in] type The type of extension to return
+	 * @return A pointer to the extension object or NULL if this type doesn't exist in this message
+	 */
+	SSLExtension* getExtensionOfType(SSLExtensionType type);
+
+	/**
+	 * Get a pointer to an extension by its class type. This is a templated method that is used with the type of the
+	 * requested extension and returns the first extension instance of this type
+	 * @return A pointer to the extension object or NULL if this extension type doesn't exist in this message
+	 *
+	 */
+	template<class TExtension>
+	TExtension* getExtensionOfType();
+
+	// implement abstract methods
+
+	std::string toString();
+
+private:
+	PointerVector<SSLExtension> m_ExtensionList;
+
+};
+
+
+/**
+ * @class SSLServerHelloMessage
+ * Represents SSL/TLS server-hello message (type 2). Inherits from SSLHandshakeMessage and adds parsing of all fields
+ * of this message including the message extensions, cipher-suite, etc.
+ */
+class SSLServerHelloMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and shouldn't be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLServerHelloMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container);
+
+	virtual ~SSLServerHelloMessage() {}
+
+	/**
+	 * @return A struct containing common fields for client-hello and server-hello messages. Notice this points directly
+	 * to the data, so every change will change the actual packet data
+	 */
+	inline ssl_tls_client_server_hello* getServerHelloHeader() { return (ssl_tls_client_server_hello*)m_Data; }
+
+	/**
+	 * @return Handshake SSL/TLS version (notice it may be different than SSLLayer#getRecordVersion(). Each client-hello
+	 * or server-hello message has both record version and handshake version and they may differ from one another)
+	 */
+	SSLVersion getHandshakeVersion();
+
+	/**
+	 * @return Session ID length in bytes. If server-hello message doesn't include session ID 0 will be returned
+	 */
+	uint8_t getSessionIDLength();
+
+	/**
+	 * @return Session ID as byte array. If server-hello message doesn't include session ID NULL will be returned
+	 */
+	uint8_t* getSessionID();
+
+	/**
+	 * @return A pointer to the cipher suite encapsulated in this message (server-hello message contains one
+	 * cipher-suite, the one that will be used to for encryption between client and server)
+	 */
+	SSLCipherSuite* getCipherSuite();
+
+	/**
+	 * @return The value of the compression method byte
+	 */
+	uint8_t getCompressionMethodsValue();
+
+	/**
+	 * @return The number of extensions in this message
+	 */
+	int getExtensionCount();
+
+	/**
+	 * @return The size (in bytes) of all extensions data in this message. Extracted from the "extensions length" field
+	 */
+	uint16_t getExtensionsLenth();
+
+	/**
+	 * Get a pointer to an extension by index. The extensions are numbered according to their order of appearance
+	 * in the message. If index is out of bounds (less than 0 or larger than total amount of extensions) NULL will be
+	 * returned
+	 * @param[in] index The index of the extension to return
+	 * @return The pointer to the extension or NULL if index is out of bounds
+	 */
+	SSLExtension* getExtension(int index);
+
+	/**
+	 * Get a pointer to an extension by numeric type field. Every extension has a 2-byte numeric value representing
+	 * its type (for example: renegotiation info extension type is 0x1ff). This method gets the type and returns a
+	 * pointer to the extension object
+	 * @param[in] type The 2-byte numeric type of the extension
+	 * @return A pointer to the extension object of NULL if this type doesn't exist in this message
+	 */
+	SSLExtension* getExtensionOfType(uint16_t type);
+
+	/**
+	 * Get a pointer to an extension by its enum type
+	 * @param[in] type The type of extension to return
+	 * @return A pointer to the extension object or NULL if this type doesn't exist in this message
+	 */
+	SSLExtension* getExtensionOfType(SSLExtensionType type);
+
+	/**
+	 * Get a pointer to an extension by its class type. This is a templated method that is used with the type of the
+	 * requested extension and returns the first extension instance of this type
+	 * @return A pointer to the extension object or NULL if this extension type doesn't exist in this message
+	 *
+	 */
+	template<class TExtension>
+	TExtension* getExtensionOfType();
+
+	// implement abstract methods
+
+	std::string toString();
+
+private:
+	PointerVector<SSLExtension> m_ExtensionList;
+};
+
+
+/**
+ * @class SSLCertificateMessage
+ * Represents SSL/TLS certificate message (type 11). Inherits from SSLHandshakeMessage and adds parsing functionality
+ * such as extracting the certificates data. Notice that in most cases this message is spread over more than 1 packet
+ * as its size is too big for a single packet. So SSLCertificateMessage instance will be created just for the first
+ * part of the message - the one encapsulated in the first packet. Other parts (encapsulated in the following packets)
+ * won't be recognized as SSLCertificateMessage messages
+ */
+class SSLCertificateMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLCertificateMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container);
+
+	virtual ~SSLCertificateMessage() {}
+
+	/**
+	 * @return The number of certificates encapsulated in this message (as written in the 'length' field of the
+	 * message). Notice that because the message may spread over several packets, not all certificates will necessarily
+	 * be in this packet. So, for example, there may be a case where this method return 3 (message contains 3
+	 * certificates) but this message actually contains only 1 certificate as the other 2 are spread over the other
+	 * packets
+	 */
+	int getNumOfCertificates();
+
+	/**
+	 * Get a certificate by index
+	 * @param[in] index The index of the certificate to retrieve
+	 * @return A pointer to the certificate object. Notice that if index < 0 or index > num of certificates encapsulated
+	 * in current packet a NULL value will be returned
+	 */
+	SSLx509Certificate* getCertificate(int index);
+
+	// implement abstract methods
+
+	std::string toString();
+
+private:
+	PointerVector<SSLx509Certificate> m_CertificateList;
+};
+
+
+/**
+ * @class SSLHelloRequestMessage
+ * Represents SSL/TLS hello-request message (type 0). This message has no additional payload except for the common payload
+ * described in SSLHandshakeMessage
+ */
+class SSLHelloRequestMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLHelloRequestMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {}
+
+	virtual ~SSLHelloRequestMessage() {}
+
+	// implement abstract methods
+
+	std::string toString();
+};
+
+
+/**
+ * @class SSLServerKeyExchangeMessage
+ * Represents SSL/TLS server-key-exchange message (type 12). Inherits from SSLHandshakeMessage and adds parsing
+ * functionality such as getting the server key exchange params as raw data (parsing of this may be added in the
+ * future)
+ */
+class SSLServerKeyExchangeMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLServerKeyExchangeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {}
+
+	~SSLServerKeyExchangeMessage() {}
+
+	/**
+	 * @return A pointer to the raw data of the server key exchange params. Currently this data can only returned as
+	 * raw, parsing may be added in the future. Notice that if the message is spread over more than 1 packet in a way
+	 * params doesn't exist in the first packet, NULL will be returned
+	 */
+	uint8_t* getServerKeyExchangeParams();
+
+	/**
+	 * @return The size of the params field. Notice that if the message is spread over more than 1 packet in a way the
+	 * ssl_tls_handshake_layer cannot be parsed from the packet, 0 will be returned. Also, if only part of the params
+	 * exist in current packet (and the rest are on consequent packets), the size that will be returned is the size
+	 * of the part that exists in the current packet (and not total size of params)
+	 */
+	size_t getServerKeyExchangeParamsLength();
+
+	// implement abstract methods
+
+	std::string toString();
+};
+
+
+/**
+ * @class SSLClientKeyExchangeMessage
+ * Represents SSL/TLS client-key-exchange message (type 16). Inherits from SSLHandshakeMessage and adds parsing
+ * functionality such as getting the server key exchange params as raw data (parsing of this may be added in the
+ * future)
+ */
+class SSLClientKeyExchangeMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLClientKeyExchangeMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {}
+
+	~SSLClientKeyExchangeMessage() {}
+
+	/**
+	 * @return A pointer to the raw data of the server key exchange params. Currently this data can only be returned
+	 * as raw, parsing may be added in the future. Notice that if the message is spread over more than 1 packet in
+	 * a way params doesn't exist in the first packet, NULL will be returned
+	 */
+	uint8_t* getClientKeyExchangeParams();
+
+	/**
+	 * @return The size of the params field. Notice that if the message is spread over more than 1 packet in a way the
+	 * ssl_tls_handshake_layer cannot be parsed from the packet, 0 will be returned. Also, if only part of the params
+	 * exist in current packet (and the rest are on consequent packets), the size that will be returned is the size
+	 * of the part that exists in the current packet (and not the total size of params)
+	 */
+	size_t getClientKeyExchangeParamsLength();
+
+	// implement abstract methods
+
+	std::string toString();
+};
+
+
+/**
+ * @class SSLCertificateRequestMessage
+ * Represents SSL/TLS certificate-request message (type 13). Inherits from SSLHandshakeMessage and adds parsing
+ * functionality such as retrieving client certificate types and authority data
+ */
+class SSLCertificateRequestMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLCertificateRequestMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container);
+
+	~SSLCertificateRequestMessage() {}
+
+	/**
+	 * @return A reference to a vector containing all client certificate types exist in this message
+	 */
+	std::vector<SSLClientCertificateType>& getCertificateTypes();
+
+	/**
+	 * @return A pointer to the certificate authority data as raw data (byte array). Parsing of this data may be added
+	 * in the future. Notice that if this message is spread over several packets in a way none of the certificate
+	 * authority data exists in this packet, NULL will be returned
+	 */
+	uint8_t* getCertificateAuthorityData();
+
+	/**
+	 * @return The length of certificate authority data returned by getCertificateAuthorityData(). Notice that if
+	 * this message is spread over several packets in a way none of certificate authority data exists in the current
+	 * packet, 0 will be returned. Also, if some of the data exists in the consequent packets, the length that will be
+	 * returned is the length of data exists in the current packet only (and not the total length)
+	 */
+	size_t getCertificateAuthorityLength();
+
+	// implement abstract methods
+
+	std::string toString();
+
+private:
+	std::vector<SSLClientCertificateType> m_ClientCertificateTypes;
+};
+
+
+/**
+ * @class SSLServerHelloDoneMessage
+ * Represents SSL/TLS server-hello-done message (type 14). This message has no additional payload except for the common
+ * payload described in SSLHandshakeMessage
+ */
+class SSLServerHelloDoneMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLServerHelloDoneMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {}
+
+	virtual ~SSLServerHelloDoneMessage() {}
+
+	// implement abstract methods
+
+	std::string toString();
+};
+
+
+/**
+ * @class SSLCertificateVerifyMessage
+ * Represents SSL/TLS certificate-verify message (type 15). Inherits from SSLHandshakeMessage and adds parsing
+ * functionality such as retrieving signed hash data as raw data (parsing may be added in the future)
+ * @todo This message type wasn't tested in unit-tests
+ */
+class SSLCertificateVerifyMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLCertificateVerifyMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {}
+
+	virtual ~SSLCertificateVerifyMessage() {}
+
+	/**
+	 * @return A pointer to the signed hash data as raw data (byte array). Parsing of this data may be added
+	 * in the future. Notice that if this message is spread over several packets in a way none of the signed hash data
+	 * exists in this packet, NULL will be returned
+	 */
+	uint8_t* getSignedHash();
+
+	/**
+	 * @return The length of signed hash data returned by getSignedHash(). Notice that if this message is spread over
+	 * several packets in a way none of this data exists in the current packet, 0 will be returned. Also, if some of
+	 * the data exists in the consequent packets, the length that will be returned will be the length of data exists in
+	 * the current packet only (and not the total length)
+	 */
+	size_t getSignedHashLength();
+
+	// implement abstract methods
+
+	std::string toString();
+};
+
+
+/**
+ * @class SSLFinishedMessage
+ * Represents SSL/TLS finished message (type 20). Inherits from SSLHandshakeMessage and adds parsing
+ * functionality such as retrieving signed hash data as raw data (parsing may be added in the future)
+ * @todo This message type wasn't tested in unit-tests
+ */
+class SSLFinishedMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLFinishedMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {}
+
+	virtual ~SSLFinishedMessage() {}
+
+	/**
+	 * @return A pointer to the signed hash data as raw data (byte array). Parsing of this data may be added
+	 * in the future. Notice that if this message is spread over several packets in a way none of the signed hash data
+	 * exists in this packet, NULL will be returned
+	 */
+	uint8_t* getSignedHash();
+
+	/**
+	 * @return The length of signed hash data returned by getSignedHash(). Notice that if the message is spread over
+	 * several packets in a way none of this data exists in the current packet, 0 will be returned. Also, if some of
+	 * the data exists in the consequent packets, the length that will be returned will be the length of data exists
+	 * in the current packet only (and not the total length)
+	 */
+	size_t getSignedHashLength();
+
+	// implement abstract methods
+
+	std::string toString();
+};
+
+
+/**
+ * @class SSLNewSessionTicketMessage
+ * Represents SSL/TLS new-session-ticket message (type 4). Inherits from SSLHandshakeMessage and adds parsing
+ * functionality such as retrieving session ticket data as raw data (parsing may be added in the future)
+ */
+class SSLNewSessionTicketMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLNewSessionTicketMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {}
+
+	virtual ~SSLNewSessionTicketMessage() {}
+
+	/**
+	 * @return A pointer to the session ticket data as raw data (byte array). Parsing of this data may be added
+	 * in the future. Notice that if this message is spread over several packets in a way none of the signed hash data
+	 * exists in current packet, NULL will be returned
+	 */
+	uint8_t* getSessionTicketData();
+
+	/**
+	 * @return The length of session ticket data returned by getSessionTicketData(). Notice that if this message is
+	 * spread over several packets in a way none of this data exists in the current packet, 0 will be returned. Also,
+	 * if some of the data exist in the consequent packets, the length that will be returned will be the length of the
+	 * data existing in the current packet only (and not the total length)
+	 */
+	size_t getSessionTicketDataLength();
+
+	// implement abstract methods
+
+	std::string toString();
+};
+
+
+/**
+ * @class SSLUnknownMessage
+ * Represents an unknown type of message or an encrypted message that PcapPlusPlus can't determine its type. In these
+ * cases length can't always be determined from the message itself (especially if the message is encrypted), so
+ * the length of this message will always be the size counted from message start until the end of the layer
+ */
+class SSLUnknownMessage : public SSLHandshakeMessage
+{
+public:
+
+	/**
+	 * C'tor for this class. Currently only in use in SSLHandshakeMessage::createHandhakeMessage() and should be used
+	 * by a user
+	 * @param[in] data The message as raw data
+	 * @param[in] dataLen Message raw data length in bytes
+	 * @param[in] container The SSL handshake layer which shall contain this message
+	 */
+	SSLUnknownMessage(uint8_t* data, size_t dataLen, SSLHandshakeLayer* container) : SSLHandshakeMessage(data, dataLen, container) {}
+
+	virtual ~SSLUnknownMessage() {}
+
+	// implement virtual and abstract methods
+
+	/**
+	 * @return Always ::SSL_HANDSHAKE_UNKNOWN (overridden from SSLHandshakeMessage)
+	 */
+	SSLHandshakeType getHandshakeType();
+
+	/**
+	 * @return The length of the data from message start until the end of the layer. Since it's an unknown type
+	 * or an encrypted message the length parsed from the message can't be guaranteed to be the correct length. That's
+	 * why the length returned is the size until the end of the layer
+	 */
+	size_t getMessageLength();
+
+	std::string toString();
+};
+
+template<class TExtension>
+TExtension* SSLClientHelloMessage::getExtensionOfType()
+{
+	size_t vecSize = m_ExtensionList.size();
+	for (size_t i = 0; i < vecSize; i++)
+	{
+		SSLExtension* curElem = m_ExtensionList.at(i);
+		 if (dynamic_cast<TExtension*>(curElem) != NULL)
+			 return (TExtension*)curElem;
+	}
+
+	return NULL;
+}
+
+template<class TExtension>
+TExtension* SSLServerHelloMessage::getExtensionOfType()
+{
+	size_t vecSize = m_ExtensionList.size();
+	for (size_t i = 0; i < vecSize; i++)
+	{
+		SSLExtension* curElem = m_ExtensionList.at(i);
+		 if (dynamic_cast<TExtension*>(curElem) != NULL)
+			 return (TExtension*)curElem;
+	}
+
+	return NULL;
+}
+
+} // namespace pcpp
+
+#endif /* PACKETPP_SSL_HANDSHAKE_MESSAGE */