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 */