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:27 UTC
[13/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++/src/IcmpLayer.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/IcmpLayer.cpp b/thirdparty/pcap++/Packet++/src/IcmpLayer.cpp
new file mode 100644
index 0000000..12bde7b
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/IcmpLayer.cpp
@@ -0,0 +1,721 @@
+#define LOG_MODULE PacketLogModuleIcmpLayer
+
+#include <IcmpLayer.h>
+#include <PayloadLayer.h>
+#include <Packet.h>
+#include <IpUtils.h>
+#include <Logger.h>
+#include <sstream>
+#include <string.h>
+#if defined(WIN32) || defined(WINx64) //for using ntohl, ntohs, etc.
+#include <winsock2.h>
+#elif LINUX
+#include <in.h> //for using ntohl, ntohs, etc.
+#elif MAC_OS_X
+#include <arpa/inet.h> //for using ntohl, ntohs, etc.
+#endif
+
+namespace pcpp
+{
+
+icmp_router_address_structure* icmp_router_advertisement::getRouterAddress(int index)
+{
+ if (index < 0 || index >= header->advertisementCount)
+ return NULL;
+
+ uint8_t* headerAsByteArr = (uint8_t*)header;
+ return (icmp_router_address_structure*)(headerAsByteArr + sizeof(icmp_router_advertisement_hdr) + index*sizeof(icmp_router_address_structure));
+}
+
+void icmp_router_address_structure::setRouterAddress(IPv4Address addr, uint32_t preference)
+{
+ routerAddress = addr.toInt();
+ preferenceLevel = htonl(preference);
+}
+
+IPv4Address icmp_router_address_structure::getAddress()
+{
+ return IPv4Address(routerAddress);
+}
+
+IcmpLayer::IcmpLayer() : Layer()
+{
+ m_DataLen = sizeof(icmphdr);
+ m_Data = new uint8_t[m_DataLen];
+ memset(m_Data, 0, m_DataLen);
+ m_Protocol = ICMP;
+}
+
+IcmpMessageType IcmpLayer::getMessageType()
+{
+ uint8_t type = getIcmpHeader()->type;
+ if (type > 18)
+ return ICMP_UNSUPPORTED;
+
+ return (IcmpMessageType)type;
+}
+
+bool IcmpLayer::isMessageOfType(IcmpMessageType type)
+{
+ return (getMessageType() == type);
+}
+
+bool IcmpLayer::cleanIcmpLayer()
+{
+ // remove all layers after
+
+ if (m_Packet != NULL)
+ {
+ Layer* layerToRemove = this->getNextLayer();
+ while (layerToRemove != NULL)
+ {
+ Layer* temp = layerToRemove->getNextLayer();
+ if (!m_Packet->removeLayer(layerToRemove))
+ return false;
+ layerToRemove = temp;
+ }
+ }
+
+
+ // shorten layer to size of icmphdr
+
+ size_t headerLen = this->getHeaderLen();
+ if (headerLen > sizeof(icmphdr))
+ {
+ if (!this->shortenLayer(sizeof(icmphdr), headerLen - sizeof(icmphdr)))
+ return false;
+ }
+
+ return true;
+}
+
+bool IcmpLayer::setEchoData(IcmpMessageType echoType, uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen)
+{
+ if (!cleanIcmpLayer())
+ return false;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_echo_hdr) - sizeof(icmphdr) + dataLen))
+ return false;
+
+ getIcmpHeader()->type = (uint8_t)echoType;
+
+ icmp_echo_request* header = NULL;
+ if (echoType == ICMP_ECHO_REQUEST)
+ header = getEchoRequestData();
+ else if (echoType == ICMP_ECHO_REPLY)
+ header = (icmp_echo_request*)getEchoReplyData();
+ else
+ return false;
+
+ header->header->code = 0;
+ header->header->checksum = 0;
+ header->header->id = htons(id);
+ header->header->sequence = htons(sequence);
+ header->header->timestamp = timestamp;
+ if (data != NULL && dataLen > 0)
+ memcpy(header->data, data, dataLen);
+
+ return true;
+}
+
+bool IcmpLayer::setIpAndL4Layers(IPv4Layer* ipLayer, Layer* l4Layer)
+{
+ if (m_Packet == NULL)
+ {
+ LOG_ERROR("Cannot set ICMP data that involves IP and L4 layers on a layer not attached to a packet. "
+ "Please add the ICMP layer to a packet and try again");
+ return false;
+ }
+
+ if (ipLayer != NULL && !m_Packet->addLayer(ipLayer))
+ {
+ LOG_ERROR("Couldn't add IP layer to ICMP packet");
+ return false;
+ }
+
+ if (l4Layer != NULL && !m_Packet->addLayer(l4Layer))
+ {
+ LOG_ERROR("Couldn't add L4 layer to ICMP packet");
+ return false;
+ }
+
+ return true;
+}
+
+icmp_echo_request* IcmpLayer::getEchoRequestData()
+{
+ if (!isMessageOfType(ICMP_ECHO_REQUEST))
+ return NULL;
+
+ m_EchoData.header = (icmp_echo_hdr*)m_Data;
+ m_EchoData.data = (uint8_t*)(m_Data + sizeof(icmp_echo_hdr));
+ m_EchoData.dataLength = m_DataLen - sizeof(icmp_echo_hdr);
+
+ return &m_EchoData;
+}
+
+icmp_echo_request* IcmpLayer::setEchoRequestData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen)
+{
+ if (setEchoData(ICMP_ECHO_REQUEST, id, sequence, timestamp, data, dataLen))
+ return getEchoRequestData();
+ else
+ return NULL;
+}
+
+icmp_echo_reply* IcmpLayer::getEchoReplyData()
+{
+ if (!isMessageOfType(ICMP_ECHO_REPLY))
+ return NULL;
+
+ m_EchoData.header = (icmp_echo_hdr*)m_Data;
+ m_EchoData.data = (uint8_t*)(m_Data + sizeof(icmp_echo_hdr));
+ m_EchoData.dataLength = m_DataLen - sizeof(icmp_echo_hdr);
+
+ return &m_EchoData;
+}
+
+icmp_echo_reply* IcmpLayer::setEchoReplyData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen)
+{
+ if (setEchoData(ICMP_ECHO_REPLY, id, sequence, timestamp, data, dataLen))
+ return getEchoReplyData();
+ else
+ return NULL;
+}
+
+
+icmp_timestamp_request* IcmpLayer::getTimestampRequestData()
+{
+ if (!isMessageOfType(ICMP_TIMESTAMP_REQUEST))
+ return NULL;
+
+ return (icmp_timestamp_request*)m_Data;
+}
+
+icmp_timestamp_request* IcmpLayer::setTimestampRequestData(uint16_t id, uint16_t sequence, timeval originateTimestamp)
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_timestamp_request) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_TIMESTAMP_REQUEST;
+
+ icmp_timestamp_request* header = getTimestampRequestData();
+ header->code = 0;
+ header->id = htons(id);
+ header->sequence = htons(sequence);
+ header->originateTimestamp = htonl(originateTimestamp.tv_sec*1000 + originateTimestamp.tv_usec/1000);
+ header->receiveTimestamp = 0;
+ header->transmitTimestamp = 0;
+
+ return header;
+}
+
+icmp_timestamp_reply* IcmpLayer::getTimestampReplyData()
+{
+ if (!isMessageOfType(ICMP_TIMESTAMP_REPLY))
+ return NULL;
+
+ return (icmp_timestamp_reply*)m_Data;
+}
+
+icmp_timestamp_reply* IcmpLayer::setTimestampReplyData(uint16_t id, uint16_t sequence,
+ timeval originateTimestamp, timeval receiveTimestamp, timeval transmitTimestamp)
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_timestamp_reply) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_TIMESTAMP_REPLY;
+
+ icmp_timestamp_reply* header = getTimestampReplyData();
+ header->code = 0;
+ header->id = htons(id);
+ header->sequence = htons(sequence);
+ header->originateTimestamp = htonl(originateTimestamp.tv_sec*1000 + originateTimestamp.tv_usec/1000);
+ header->receiveTimestamp = htonl(receiveTimestamp.tv_sec*1000 + receiveTimestamp.tv_usec/1000);
+ header->transmitTimestamp = htonl(transmitTimestamp.tv_sec*1000 + transmitTimestamp.tv_usec/1000);
+
+ return header;
+}
+
+icmp_destination_unreachable* IcmpLayer::getDestUnreachableData()
+{
+ if (!isMessageOfType(ICMP_DEST_UNREACHABLE))
+ return NULL;
+
+ return (icmp_destination_unreachable*)m_Data;
+}
+
+icmp_destination_unreachable* IcmpLayer::setDestUnreachableData(IcmpDestUnreachableCodes code, uint16_t nextHopMTU, IPv4Layer* ipHeader, Layer* l4Header)
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_destination_unreachable) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_DEST_UNREACHABLE;
+
+ icmp_destination_unreachable* header = getDestUnreachableData();
+ header->code = code;
+ header->nextHopMTU = htons(nextHopMTU);
+ header->unused = 0;
+
+ if (!setIpAndL4Layers(ipHeader, l4Header))
+ return NULL;
+
+ return header;
+}
+
+icmp_source_quench* IcmpLayer::getSourceQuenchdata()
+{
+ if (!isMessageOfType(ICMP_SOURCE_QUENCH))
+ return NULL;
+
+ return (icmp_source_quench*)m_Data;
+
+}
+
+icmp_source_quench* IcmpLayer::setSourceQuenchdata(IPv4Layer* ipHeader, Layer* l4Header)
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_source_quench) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_SOURCE_QUENCH;
+
+ icmp_source_quench* header = getSourceQuenchdata();
+ header->unused = 0;
+
+ if (!setIpAndL4Layers(ipHeader, l4Header))
+ return NULL;
+
+ return header;
+}
+
+icmp_redirect* IcmpLayer::getRedirectData()
+{
+ if (!isMessageOfType(ICMP_REDIRECT))
+ return NULL;
+
+ return (icmp_redirect*)m_Data;
+}
+
+icmp_redirect* IcmpLayer::setRedirectData(uint8_t code, IPv4Address gatewayAddress, IPv4Layer* ipHeader, Layer* l4Header)
+{
+ if (code > 3)
+ {
+ LOG_ERROR("Unknown code %d for ICMP redirect data", (int)code);
+ return NULL;
+ }
+
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_redirect) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_REDIRECT;
+
+ icmp_redirect* header = getRedirectData();
+ header->code = code;
+ header->gatewayAddress = gatewayAddress.toInt();
+
+ if (!setIpAndL4Layers(ipHeader, l4Header))
+ return NULL;
+
+ return header;
+}
+
+icmp_router_advertisement* IcmpLayer::getRouterAdvertisementData()
+{
+ if (!isMessageOfType(ICMP_ROUTER_ADV))
+ return NULL;
+
+ m_RouterAdvData.header = (icmp_router_advertisement_hdr*)m_Data;
+
+ return &m_RouterAdvData;
+}
+
+icmp_router_advertisement* IcmpLayer::setRouterAdvertisementData(uint8_t code, uint16_t lifetimeInSeconds, const std::vector<icmp_router_address_structure>& routerAddresses)
+{
+ if (code != 0 && code != 16)
+ {
+ LOG_ERROR("Unknown code %d for ICMP router advertisement data (only codes 0 and 16 are legal)", (int)code);
+ return NULL;
+ }
+
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_router_advertisement_hdr) + (routerAddresses.size()*sizeof(icmp_router_address_structure)) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_ROUTER_ADV;
+
+ icmp_router_advertisement* header = getRouterAdvertisementData();
+ header->header->code = code;
+ header->header->lifetime = htons(lifetimeInSeconds);
+ header->header->advertisementCount = (uint8_t)routerAddresses.size();
+ header->header->addressEntrySize = 2;
+
+ icmp_router_address_structure* curPos = (icmp_router_address_structure*)((uint8_t*)header->header + sizeof(icmp_router_advertisement_hdr));
+ for (std::vector<icmp_router_address_structure>::const_iterator iter = routerAddresses.begin(); iter != routerAddresses.end(); iter++)
+ {
+ curPos->routerAddress = iter->routerAddress;
+ curPos->preferenceLevel = iter->preferenceLevel;
+ curPos += 1;
+ }
+
+ return header;
+}
+
+icmp_router_solicitation* IcmpLayer::getRouterSolicitationData()
+{
+ if (!isMessageOfType(ICMP_ROUTER_SOL))
+ return NULL;
+
+ return (icmp_router_solicitation*)m_Data;
+}
+
+icmp_router_solicitation* IcmpLayer::setRouterSolicitationData()
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_ROUTER_SOL;
+
+ icmp_router_solicitation* header = getRouterSolicitationData();
+ header->code = 0;
+
+ return header;
+}
+
+icmp_time_exceeded* IcmpLayer::getTimeExceededData()
+{
+ if (!isMessageOfType(ICMP_TIME_EXCEEDED))
+ return NULL;
+
+ return (icmp_time_exceeded*)m_Data;
+}
+
+icmp_time_exceeded* IcmpLayer::setTimeExceededData(uint8_t code, IPv4Layer* ipHeader, Layer* l4Header)
+{
+ if (code > 1)
+ {
+ LOG_ERROR("Unknown code %d for ICMP time exceeded data", (int)code);
+ return NULL;
+ }
+
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_time_exceeded) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_TIME_EXCEEDED;
+
+ icmp_time_exceeded* header = getTimeExceededData();
+ header->code = code;
+ header->unused = 0;
+
+ if (!setIpAndL4Layers(ipHeader, l4Header))
+ return NULL;
+
+ return header;
+}
+
+icmp_param_problem* IcmpLayer::getParamProblemData()
+{
+ if (!isMessageOfType(ICMP_PARAM_PROBLEM))
+ return NULL;
+
+ return (icmp_param_problem*)m_Data;
+}
+
+icmp_param_problem* IcmpLayer::setParamProblemData(uint8_t code, uint8_t errorOctetPointer, IPv4Layer* ipHeader, Layer* l4Header)
+{
+ if (code > 2)
+ {
+ LOG_ERROR("Unknown code %d for ICMP parameter problem data", (int)code);
+ return NULL;
+ }
+
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_param_problem) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_PARAM_PROBLEM;
+
+ icmp_param_problem* header = getParamProblemData();
+ header->code = code;
+ header->unused1 = 0;
+ header->unused2 = 0;
+ header->pointer = errorOctetPointer;
+
+ if (!setIpAndL4Layers(ipHeader, l4Header))
+ return NULL;
+
+ return header;
+}
+
+icmp_address_mask_request* IcmpLayer::getAddressMaskRequestData()
+{
+ if (!isMessageOfType(ICMP_ADDRESS_MASK_REQUEST))
+ return NULL;
+
+ return (icmp_address_mask_request*)m_Data;
+}
+
+icmp_address_mask_request* IcmpLayer::setAddressMaskRequestData(uint16_t id, uint16_t sequence, IPv4Address mask)
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_address_mask_request) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_ADDRESS_MASK_REQUEST;
+
+ icmp_address_mask_request* header = getAddressMaskRequestData();
+ header->code = 0;
+ header->id = htons(id);
+ header->sequence = htons(sequence);
+ header->addressMask = mask.toInt();
+
+ return header;
+}
+
+icmp_address_mask_reply* IcmpLayer::getAddressMaskReplyData()
+{
+ if (!isMessageOfType(ICMP_ADDRESS_MASK_REPLY))
+ return NULL;
+
+ return (icmp_address_mask_reply*)m_Data;
+}
+
+icmp_address_mask_reply* IcmpLayer::setAddressMaskReplyData(uint16_t id, uint16_t sequence, IPv4Address mask)
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_address_mask_reply) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_ADDRESS_MASK_REPLY;
+
+ icmp_address_mask_reply* header = getAddressMaskReplyData();
+ header->code = 0;
+ header->id = htons(id);
+ header->sequence = htons(sequence);
+ header->addressMask = htonl(mask.toInt());
+
+ return header;
+}
+
+icmp_info_request* IcmpLayer::getInfoRequestData()
+{
+ if (!isMessageOfType(ICMP_INFO_REQUEST))
+ return NULL;
+
+ return (icmp_info_request*)m_Data;
+}
+
+icmp_info_request* IcmpLayer::setInfoRequestData(uint16_t id, uint16_t sequence)
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_info_request) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_INFO_REQUEST;
+
+ icmp_info_request* header = getInfoRequestData();
+ header->code = 0;
+ header->id = htons(id);
+ header->sequence = htons(sequence);
+
+ return header;
+}
+
+icmp_info_reply* IcmpLayer::getInfoReplyData()
+{
+ if (!isMessageOfType(ICMP_INFO_REPLY))
+ return NULL;
+
+ return (icmp_info_reply*)m_Data;
+}
+
+icmp_info_reply* IcmpLayer::setInfoReplyData(uint16_t id, uint16_t sequence)
+{
+ if (!cleanIcmpLayer())
+ return NULL;
+
+ if (!this->extendLayer(m_DataLen, sizeof(icmp_info_reply) - sizeof(icmphdr)))
+ return NULL;
+
+ getIcmpHeader()->type = (uint8_t)ICMP_INFO_REPLY;
+
+ icmp_info_reply* header = getInfoReplyData();
+ header->code = 0;
+ header->id = htons(id);
+ header->sequence = htons(sequence);
+
+ return header;
+}
+
+
+void IcmpLayer::parseNextLayer()
+{
+ IcmpMessageType type = getMessageType();
+ size_t headerLen = 0;
+
+ switch (type)
+ {
+ case ICMP_DEST_UNREACHABLE:
+ case ICMP_SOURCE_QUENCH:
+ case ICMP_TIME_EXCEEDED:
+ case ICMP_REDIRECT:
+ case ICMP_PARAM_PROBLEM:
+ headerLen = getHeaderLen();
+ if (m_DataLen - headerLen >= sizeof(iphdr))
+ m_NextLayer = new IPv4Layer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet);
+ return;
+ default:
+ headerLen = getHeaderLen();
+ if (m_DataLen > headerLen)
+ m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet);
+ return;
+ }
+}
+
+size_t IcmpLayer::getHeaderLen()
+{
+ IcmpMessageType type = getMessageType();
+ size_t routerAdvSize = 0;
+ switch (type)
+ {
+ case ICMP_ECHO_REQUEST:
+ case ICMP_ECHO_REPLY:
+ return m_DataLen;
+ case ICMP_TIMESTAMP_REQUEST:
+ case ICMP_TIMESTAMP_REPLY:
+ return sizeof(icmp_timestamp_request);
+ case ICMP_ROUTER_SOL:
+ case ICMP_INFO_REQUEST:
+ case ICMP_INFO_REPLY:
+ case ICMP_UNSUPPORTED:
+ return sizeof(icmphdr);
+ case ICMP_ADDRESS_MASK_REPLY:
+ case ICMP_ADDRESS_MASK_REQUEST:
+ return sizeof(icmp_address_mask_request);
+ case ICMP_DEST_UNREACHABLE:
+ return sizeof(icmp_destination_unreachable);
+ case ICMP_REDIRECT:
+ return sizeof(icmp_redirect);
+ case ICMP_TIME_EXCEEDED:
+ case ICMP_SOURCE_QUENCH:
+ return sizeof(icmp_time_exceeded);
+ case ICMP_PARAM_PROBLEM:
+ return sizeof(icmp_param_problem);
+ case ICMP_ROUTER_ADV:
+ routerAdvSize = sizeof(icmp_router_advertisement_hdr) + (getRouterAdvertisementData()->header->advertisementCount*sizeof(icmp_router_address_structure));
+ return routerAdvSize;
+ default:
+ return sizeof(icmphdr);
+ }
+}
+
+void IcmpLayer::computeCalculateFields()
+{
+ // calculate checksum
+ getIcmpHeader()->checksum = 0;
+
+ size_t icmpLen = 0;
+ Layer* curLayer = this;
+ while (curLayer != NULL)
+ {
+ icmpLen += curLayer->getHeaderLen();
+ curLayer = curLayer->getNextLayer();
+ }
+
+ ScalarBuffer<uint16_t> buffer;
+ buffer.buffer = (uint16_t*)getIcmpHeader();
+ buffer.len = icmpLen;
+ size_t checksum = compute_checksum(&buffer, 1);
+
+ getIcmpHeader()->checksum = htons(checksum);
+}
+
+std::string IcmpLayer::toString()
+{
+ std::string messageTypeAsString;
+ IcmpMessageType type = getMessageType();
+ switch (type)
+ {
+ case ICMP_ECHO_REPLY:
+ messageTypeAsString = "Echo (ping) reply";
+ break;
+ case ICMP_DEST_UNREACHABLE:
+ messageTypeAsString = "Destination unreachable";
+ break;
+ case ICMP_SOURCE_QUENCH:
+ messageTypeAsString = "Source quench (flow control)";
+ break;
+ case ICMP_REDIRECT:
+ messageTypeAsString = "Redirect";
+ break;
+ case ICMP_ECHO_REQUEST:
+ messageTypeAsString = "Echo (ping) request";
+ break;
+ case ICMP_ROUTER_ADV:
+ messageTypeAsString = "Router advertisement";
+ break;
+ case ICMP_ROUTER_SOL:
+ messageTypeAsString = "Router solicitation";
+ break;
+ case ICMP_TIME_EXCEEDED:
+ messageTypeAsString = "Time-to-live exceeded";
+ break;
+ case ICMP_PARAM_PROBLEM:
+ messageTypeAsString = "Parameter problem: bad IP header";
+ break;
+ case ICMP_TIMESTAMP_REQUEST:
+ messageTypeAsString = "Timestamp request";
+ break;
+ case ICMP_TIMESTAMP_REPLY:
+ messageTypeAsString = "Timestamp reply";
+ break;
+ case ICMP_INFO_REQUEST:
+ messageTypeAsString = "Information request";
+ break;
+ case ICMP_INFO_REPLY:
+ messageTypeAsString = "Information reply";
+ break;
+ case ICMP_ADDRESS_MASK_REQUEST:
+ messageTypeAsString = "Address mask request";
+ break;
+ case ICMP_ADDRESS_MASK_REPLY:
+ messageTypeAsString = "Address mask reply";
+ break;
+ default:
+ messageTypeAsString = "Unknown";
+ break;
+ }
+
+ std::ostringstream typeStream;
+ typeStream << (int)getIcmpHeader()->type;
+
+ return "ICMP Layer, " + messageTypeAsString + " (type: " + typeStream.str() + ")";
+}
+
+} // namespace pcpp
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/IgmpLayer.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/IgmpLayer.cpp b/thirdparty/pcap++/Packet++/src/IgmpLayer.cpp
new file mode 100644
index 0000000..c4dab29
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/IgmpLayer.cpp
@@ -0,0 +1,600 @@
+#define LOG_MODULE PacketLogModuleIgmpLayer
+
+#include <IgmpLayer.h>
+#include <IpUtils.h>
+#include <Logger.h>
+#include <string.h>
+#ifdef WIN32 //for using ntohl, ntohs, etc.
+#include <winsock2.h>
+#elif LINUX
+#include <in.h> //for using ntohl, ntohs, etc.
+#elif MAC_OS_X
+#include <arpa/inet.h> //for using ntohl, ntohs, etc.
+#endif
+
+namespace pcpp
+{
+
+/*************
+ * IgmpLayer
+ *************/
+
+IgmpLayer::IgmpLayer(IgmpType type, const IPv4Address& groupAddr, uint8_t maxResponseTime, ProtocolType igmpVer)
+{
+ m_DataLen = getHeaderSizeByVerAndType(igmpVer, type);
+ m_Data = new uint8_t[m_DataLen];
+ memset(m_Data, 0, m_DataLen);
+ m_Protocol = igmpVer;
+
+ setType(type);
+ if (groupAddr != IPv4Address::Zero)
+ setGroupAddress(groupAddr);
+
+ getIgmpHeader()->maxResponseTime = maxResponseTime;
+}
+
+void IgmpLayer::setGroupAddress(const IPv4Address& groupAddr)
+{
+ igmp_header* hdr = getIgmpHeader();
+ hdr->groupAddress = groupAddr.toInt();
+}
+
+IgmpType IgmpLayer::getType()
+{
+ uint8_t type = getIgmpHeader()->type;
+ if (type < (uint8_t)IgmpType_MembershipQuery ||
+ (type > (uint8_t)IgmpType_LeaveGroup && type < (uint8_t)IgmpType_MulticastTracerouteResponse) ||
+ (type > (uint8_t)IgmpType_MulticastTraceroute && type < (uint8_t)IgmpType_MembershipReportV3) ||
+ (type > (uint8_t)IgmpType_MembershipReportV3 && type < (uint8_t)IgmpType_MulticastRouterAdvertisement) ||
+ type > IgmpType_MulticastRouterTermination)
+ return IgmpType_Unknown;
+
+ return (IgmpType)type;
+}
+
+void IgmpLayer::setType(IgmpType type)
+{
+ if (type == IgmpType_Unknown)
+ return;
+
+ igmp_header* hdr = getIgmpHeader();
+ hdr->type = type;
+}
+
+ProtocolType IgmpLayer::getIGMPVerFromData(uint8_t* data, size_t dataLen, bool& isQuery)
+{
+ isQuery = false;
+
+ if (dataLen < 8 || data == NULL)
+ return UnknownProtocol;
+
+ switch ((int)data[0])
+ {
+ case IgmpType_MembershipReportV2:
+ case IgmpType_LeaveGroup:
+ return IGMPv2;
+ case IgmpType_MembershipReportV1:
+ return IGMPv1;
+ case IgmpType_MembershipReportV3:
+ return IGMPv3;
+ case IgmpType_MembershipQuery:
+ {
+ isQuery = true;
+
+ if (dataLen >= sizeof(igmpv3_query_header))
+ return IGMPv3;
+
+ if (data[1] == 0)
+ return IGMPv1;
+ else
+ return IGMPv2;
+ }
+ default:
+ return UnknownProtocol;
+ }
+}
+
+uint16_t IgmpLayer::calculateChecksum()
+{
+ ScalarBuffer<uint16_t> buffer;
+ buffer.buffer = (uint16_t*)getIgmpHeader();
+ buffer.len = getHeaderLen();
+ return compute_checksum(&buffer, 1);
+}
+
+size_t IgmpLayer::getHeaderSizeByVerAndType(ProtocolType igmpVer, IgmpType igmpType)
+{
+ if (igmpVer == IGMPv1 || igmpVer == IGMPv2)
+ return sizeof(igmp_header);
+
+ if (igmpVer == IGMPv3)
+ {
+ if (igmpType == IgmpType_MembershipQuery)
+ return sizeof(igmpv3_query_header);
+ else if (igmpType == IgmpType_MembershipReportV3)
+ return sizeof(igmpv3_report_header);
+ }
+
+ return 0;
+}
+
+std::string IgmpLayer::toString()
+{
+ std::string igmpVer = "";
+ switch (getProtocol())
+ {
+ case IGMPv1:
+ igmpVer = "1";
+ break;
+ case IGMPv2:
+ igmpVer = "2";
+ break;
+ default:
+ igmpVer = "3";
+ }
+
+ std::string msgType;
+
+ switch (getType())
+ {
+ case IgmpType_MembershipQuery:
+ msgType = "Membership Query";
+ break;
+ case IgmpType_MembershipReportV1:
+ msgType = "Membership Report";
+ break;
+ case IgmpType_DVMRP:
+ msgType = "DVMRP";
+ break;
+ case IgmpType_P1Mv1:
+ msgType = "PIMv1";
+ break;
+ case IgmpType_CiscoTrace:
+ msgType = "Cisco Trace";
+ break;
+ case IgmpType_MembershipReportV2:
+ msgType = "Membership Report";
+ break;
+ case IgmpType_LeaveGroup:
+ msgType = "Leave Group";
+ break;
+ case IgmpType_MulticastTracerouteResponse:
+ msgType = "Multicast Traceroute Response";
+ break;
+ case IgmpType_MulticastTraceroute:
+ msgType = "Multicast Traceroute";
+ break;
+ case IgmpType_MembershipReportV3:
+ msgType = "Membership Report";
+ break;
+ case IgmpType_MulticastRouterAdvertisement:
+ msgType = "Multicast Router Advertisement";
+ break;
+ case IgmpType_MulticastRouterSolicitation:
+ msgType = "Multicast Router Solicitation";
+ break;
+ case IgmpType_MulticastRouterTermination:
+ msgType = "Multicast Router Termination";
+ break;
+ default:
+ msgType = "Unknown";
+ break;
+ }
+
+ std::string result = "IGMPv" + igmpVer + " Layer, " + msgType + " message";
+ return result;
+}
+
+
+
+
+/*************
+ * IgmpV1Layer
+ *************/
+
+IgmpV1Layer::IgmpV1Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) :
+ IgmpLayer(data, dataLen, prevLayer, packet, IGMPv1)
+{
+}
+
+IgmpV1Layer::IgmpV1Layer(IgmpType type, const IPv4Address& groupAddr) :
+ IgmpLayer(type, groupAddr, 0, IGMPv1)
+{
+}
+
+void IgmpV1Layer::computeCalculateFields()
+{
+ igmp_header* hdr = getIgmpHeader();
+ hdr->checksum = 0;
+ hdr->checksum = htons(calculateChecksum());
+ hdr->maxResponseTime = 0;
+}
+
+
+
+
+
+/*************
+ * IgmpV2Layer
+ *************/
+
+IgmpV2Layer::IgmpV2Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) :
+ IgmpLayer(data, dataLen, prevLayer, packet, IGMPv2)
+{
+}
+
+IgmpV2Layer::IgmpV2Layer(IgmpType type, const IPv4Address& groupAddr, uint8_t maxResponseTime) :
+ IgmpLayer(type, groupAddr, maxResponseTime, IGMPv2)
+{
+}
+
+void IgmpV2Layer::computeCalculateFields()
+{
+ igmp_header* hdr = getIgmpHeader();
+ hdr->checksum = 0;
+ hdr->checksum = htons(calculateChecksum());
+}
+
+
+
+
+
+/******************
+ * IgmpV3QueryLayer
+ ******************/
+
+
+IgmpV3QueryLayer::IgmpV3QueryLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) :
+ IgmpLayer(data, dataLen, prevLayer, packet, IGMPv3)
+{
+}
+
+IgmpV3QueryLayer::IgmpV3QueryLayer(const IPv4Address& multicastAddr, uint8_t maxResponseTime, uint8_t s_qrv) :
+ IgmpLayer(IgmpType_MembershipQuery, multicastAddr, maxResponseTime, IGMPv3)
+{
+ getIgmpV3QueryHeader()->s_qrv = s_qrv;
+}
+
+uint16_t IgmpV3QueryLayer::getSourceAddressCount()
+{
+ return ntohs(getIgmpV3QueryHeader()->numOfSources);
+}
+
+IPv4Address IgmpV3QueryLayer::getSourceAddressAtIndex(int index)
+{
+ uint16_t numOfSources = getSourceAddressCount();
+ if (index < 0 || index >= numOfSources)
+ return IPv4Address::Zero;
+
+ // verify numOfRecords is a reasonable number that points to data within the packet
+ int ptrOffset = index * sizeof(uint32_t) + sizeof(igmpv3_query_header);
+ if (ptrOffset + sizeof(uint32_t) > getDataLen())
+ return IPv4Address::Zero;
+
+ uint8_t* ptr = m_Data + ptrOffset;
+ return IPv4Address(*(uint32_t*)ptr);
+}
+
+size_t IgmpV3QueryLayer::getHeaderLen()
+{
+ uint16_t numOfSources = getSourceAddressCount();
+
+ int headerLen = numOfSources * sizeof(uint32_t) + sizeof(igmpv3_query_header);
+
+ // verify numOfRecords is a reasonable number that points to data within the packet
+ if ((size_t)headerLen > getDataLen())
+ return getDataLen();
+
+ return (size_t)headerLen;
+}
+
+void IgmpV3QueryLayer::computeCalculateFields()
+{
+ igmpv3_query_header* hdr = getIgmpV3QueryHeader();
+ hdr->checksum = 0;
+ hdr->checksum = htons(calculateChecksum());
+}
+
+bool IgmpV3QueryLayer::addSourceAddress(const IPv4Address& addr)
+{
+ return addSourceAddressAtIndex(addr, getSourceAddressCount());
+}
+
+bool IgmpV3QueryLayer::addSourceAddressAtIndex(const IPv4Address& addr, int index)
+{
+ uint16_t sourceAddrCount = getSourceAddressCount();
+
+ if (index < 0 || index > (int)sourceAddrCount)
+ {
+ LOG_ERROR("Cannot add source address at index %d, index is out of bounds", index);
+ return false;
+ }
+
+ size_t offset = sizeof(igmpv3_query_header) + index * sizeof(uint32_t);
+ if (offset > getHeaderLen())
+ {
+ LOG_ERROR("Cannot add source address at index %d, index is out of packet bounds", index);
+ return false;
+ }
+
+ if (!extendLayer(offset, sizeof(uint32_t)))
+ {
+ LOG_ERROR("Cannot add source address at index %d, didn't manage to extend layer", index);
+ return false;
+ }
+
+ uint32_t addrAsInt = addr.toInt();
+ memcpy(m_Data + offset, &addrAsInt, sizeof(uint32_t));
+
+ getIgmpV3QueryHeader()->numOfSources = htons(sourceAddrCount+1);
+
+ return true;
+}
+
+bool IgmpV3QueryLayer::removeSourceAddressAtIndex(int index)
+{
+ uint16_t sourceAddrCount = getSourceAddressCount();
+
+ if (index < 0 || index > (int)sourceAddrCount-1)
+ {
+ LOG_ERROR("Cannot remove source address at index %d, index is out of bounds", index);
+ return false;
+ }
+
+ size_t offset = sizeof(igmpv3_query_header) + index * sizeof(uint32_t);
+ if (offset >= getHeaderLen())
+ {
+ LOG_ERROR("Cannot remove source address at index %d, index is out of packet bounds", index);
+ return false;
+ }
+
+ if (!shortenLayer(offset, sizeof(uint32_t)))
+ {
+ LOG_ERROR("Cannot remove source address at index %d, didn't manage to shorten layer", index);
+ return false;
+ }
+
+ getIgmpV3QueryHeader()->numOfSources = htons(sourceAddrCount-1);
+
+ return true;
+}
+
+bool IgmpV3QueryLayer::removeAllSourceAddresses()
+{
+ size_t offset = sizeof(igmpv3_query_header);
+ size_t numOfBytesToShorted = getHeaderLen() - offset;
+
+ if (!shortenLayer(offset, numOfBytesToShorted))
+ {
+ LOG_ERROR("Cannot remove all source addresses, didn't manage to shorten layer");
+ return false;
+ }
+
+ getIgmpV3QueryHeader()->numOfSources = 0;
+
+ return true;
+}
+
+
+
+
+
+/*******************
+ * IgmpV3ReportLayer
+ *******************/
+
+IgmpV3ReportLayer::IgmpV3ReportLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) :
+ IgmpLayer(data, dataLen, prevLayer, packet, IGMPv3)
+{
+}
+
+IgmpV3ReportLayer::IgmpV3ReportLayer() :
+ IgmpLayer(IgmpType_MembershipReportV3, IPv4Address::Zero, 0, IGMPv3)
+{
+}
+
+uint16_t IgmpV3ReportLayer::getGroupRecordCount()
+{
+ return ntohs(getReportHeader()->numOfGroupRecords);
+
+}
+
+igmpv3_group_record* IgmpV3ReportLayer::getFirstGroupRecord()
+{
+ // check if there are group records at all
+ if (getHeaderLen() <= sizeof(igmpv3_report_header))
+ return NULL;
+
+ uint8_t* curGroupPtr = m_Data + sizeof(igmpv3_report_header);
+ return (igmpv3_group_record*)curGroupPtr;
+}
+
+igmpv3_group_record* IgmpV3ReportLayer::getNextGroupRecord(igmpv3_group_record* groupRecord)
+{
+ if (groupRecord == NULL)
+ return NULL;
+
+ // prev group was the last group
+ if ((uint8_t*)groupRecord + groupRecord->getRecordLen() - m_Data >= (int)getHeaderLen())
+ return NULL;
+
+ igmpv3_group_record* nextGroup = (igmpv3_group_record*)((uint8_t*)groupRecord + groupRecord->getRecordLen());
+
+ return nextGroup;
+}
+
+size_t IgmpV3ReportLayer::getHeaderLen()
+{
+ return m_DataLen;
+}
+
+void IgmpV3ReportLayer::computeCalculateFields()
+{
+ igmpv3_report_header* hdr = getReportHeader();
+ hdr->checksum = 0;
+ hdr->checksum = htons(calculateChecksum());
+}
+
+igmpv3_group_record* IgmpV3ReportLayer::addGroupRecordAt(uint8_t recordType, const IPv4Address& multicastAddress, const std::vector<IPv4Address>& sourceAddresses, int offset)
+{
+ if (offset > (int)getHeaderLen())
+ {
+ LOG_ERROR("Cannot add group record, offset is out of layer bounds");
+ return NULL;
+ }
+
+ size_t groupRecordSize = sizeof(igmpv3_group_record) + sizeof(uint32_t)*sourceAddresses.size();
+
+ if (!extendLayer(offset, groupRecordSize))
+ {
+ LOG_ERROR("Cannot add group record, cannot extend layer");
+ return NULL;
+ }
+
+ uint8_t* groupRecordBuffer = new uint8_t[groupRecordSize];
+ memset(groupRecordBuffer, 0, groupRecordSize);
+ igmpv3_group_record* newGroupRecord = (igmpv3_group_record*)groupRecordBuffer;
+ newGroupRecord->multicastAddress = multicastAddress.toInt();
+ newGroupRecord->recordType = recordType;
+ newGroupRecord->auxDataLen = 0;
+ newGroupRecord->numOfSources = htons(sourceAddresses.size());
+
+ int srcAddrOffset = 0;
+ for (std::vector<IPv4Address>::const_iterator iter = sourceAddresses.begin(); iter != sourceAddresses.end(); iter++)
+ {
+ uint32_t addrAsInt = iter->toInt();
+ memcpy(newGroupRecord->sourceAddresses + srcAddrOffset, &addrAsInt, sizeof(uint32_t));
+ srcAddrOffset += sizeof(uint32_t);
+ }
+
+ memcpy(m_Data + offset, groupRecordBuffer, groupRecordSize);
+
+ delete[] groupRecordBuffer;
+
+ getReportHeader()->numOfGroupRecords = htons(getGroupRecordCount() + 1);
+
+ return (igmpv3_group_record*)(m_Data + offset);
+}
+
+igmpv3_group_record* IgmpV3ReportLayer::addGroupRecord(uint8_t recordType, const IPv4Address& multicastAddress, const std::vector<IPv4Address>& sourceAddresses)
+{
+ return addGroupRecordAt(recordType, multicastAddress, sourceAddresses, (int)getHeaderLen());
+}
+
+igmpv3_group_record* IgmpV3ReportLayer::addGroupRecordAtIndex(uint8_t recordType, const IPv4Address& multicastAddress, const std::vector<IPv4Address>& sourceAddresses, int index)
+{
+ int groupCnt = (int)getGroupRecordCount();
+
+ if (index < 0 || index > groupCnt)
+ {
+ LOG_ERROR("Cannot add group record, index %d out of bounds", index);
+ return NULL;
+ }
+
+ size_t offset = sizeof(igmpv3_report_header);
+
+ igmpv3_group_record* curRecord = getFirstGroupRecord();
+ for (int i = 0; i < index; i++)
+ {
+ if (curRecord == NULL)
+ {
+ LOG_ERROR("Cannot add group record, cannot find group record at index %d", i);
+ return NULL;
+ }
+
+ offset += curRecord->getRecordLen();
+ curRecord = getNextGroupRecord(curRecord);
+ }
+
+ return addGroupRecordAt(recordType, multicastAddress, sourceAddresses, (int)offset);
+}
+
+bool IgmpV3ReportLayer::removeGroupRecordAtIndex(int index)
+{
+ int groupCnt = (int)getGroupRecordCount();
+
+ if (index < 0 || index >= groupCnt)
+ {
+ LOG_ERROR("Cannot remove group record, index %d is out of bounds", index);
+ return false;
+ }
+
+ size_t offset = sizeof(igmpv3_report_header);
+
+ igmpv3_group_record* curRecord = getFirstGroupRecord();
+ for (int i = 0; i < index; i++)
+ {
+ if (curRecord == NULL)
+ {
+ LOG_ERROR("Cannot remove group record at index %d, cannot find group record at index %d", index, i);
+ return false;
+ }
+
+ offset += curRecord->getRecordLen();
+ curRecord = getNextGroupRecord(curRecord);
+ }
+
+ if (!shortenLayer((int)offset, curRecord->getRecordLen()))
+ {
+ LOG_ERROR("Cannot remove group record at index %d, cannot shorted layer", index);
+ return false;
+ }
+
+ getReportHeader()->numOfGroupRecords = htons(groupCnt-1);
+
+ return true;
+}
+
+bool IgmpV3ReportLayer::removeAllGroupRecords()
+{
+ int offset = (int)sizeof(igmpv3_report_header);
+
+ if (!shortenLayer(offset, getHeaderLen()-offset))
+ {
+ LOG_ERROR("Cannot remove all group records, cannot shorted layer");
+ return false;
+ }
+
+ getReportHeader()->numOfGroupRecords = 0;
+ return true;
+}
+
+
+
+
+
+
+/*********************
+ * igmpv3_group_record
+ *********************/
+
+IPv4Address igmpv3_group_record::getMulticastAddress()
+{
+ return IPv4Address(multicastAddress);
+}
+
+uint16_t igmpv3_group_record::getSourceAdressCount()
+{
+ return ntohs(numOfSources);
+}
+
+IPv4Address igmpv3_group_record::getSoruceAddressAtIndex(int index)
+{
+ uint16_t numOfRecords = getSourceAdressCount();
+ if (index < 0 || index >= numOfRecords)
+ return IPv4Address::Zero;
+
+ int offset = index * sizeof(uint32_t);
+ uint8_t* ptr = sourceAddresses + offset;
+ return IPv4Address(*(uint32_t*)ptr);
+}
+
+size_t igmpv3_group_record::getRecordLen()
+{
+ uint16_t numOfRecords = getSourceAdressCount();
+
+ int headerLen = numOfRecords * sizeof(uint32_t) + sizeof(igmpv3_group_record);
+ return (size_t)headerLen;
+}
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/Layer.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/Layer.cpp b/thirdparty/pcap++/Packet++/src/Layer.cpp
new file mode 100644
index 0000000..f6ca822
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/Layer.cpp
@@ -0,0 +1,103 @@
+#define LOG_MODULE PacketLogModuleLayer
+
+#include <Layer.h>
+#include <string.h>
+#include "Logger.h"
+#include "Packet.h"
+
+namespace pcpp
+{
+
+Layer::~Layer()
+{
+ if (!isAllocatedToPacket())
+ delete [] m_Data;
+}
+
+Layer::Layer(const Layer& other) : m_DataLen(other.m_DataLen), m_Packet(NULL), m_Protocol(other.m_Protocol), m_NextLayer(NULL), m_PrevLayer(NULL)
+{
+ m_Data = new uint8_t[other.m_DataLen];
+ memcpy(m_Data, other.m_Data, other.m_DataLen);
+}
+
+Layer& Layer::operator=(const Layer& other)
+{
+ if (this == &other)
+ return *this;
+
+ if (m_Data != NULL)
+ delete [] m_Data;
+
+ m_DataLen = other.m_DataLen;
+ m_Packet = NULL;
+ m_Protocol = other.m_Protocol;
+ m_NextLayer = NULL;
+ m_PrevLayer = NULL;
+ m_Data = new uint8_t[other.m_DataLen];
+ memcpy(m_Data, other.m_Data, other.m_DataLen);
+
+ return *this;
+}
+
+void Layer::copyData(uint8_t* toArr)
+{
+ memcpy(toArr, m_Data, m_DataLen);
+}
+
+bool Layer::extendLayer(int offsetInLayer, size_t numOfBytesToExtend)
+{
+ if (m_Data == NULL)
+ {
+ LOG_ERROR("Layer's data is NULL");
+ return false;
+ }
+
+ if (m_Packet == NULL)
+ {
+ if ((size_t)offsetInLayer > m_DataLen)
+ {
+ LOG_ERROR("Requested offset is larger than data length");
+ return false;
+ }
+
+ uint8_t* newData = new uint8_t[m_DataLen + numOfBytesToExtend];
+ memcpy(newData, m_Data, offsetInLayer);
+ memcpy(newData + offsetInLayer + numOfBytesToExtend, m_Data + offsetInLayer, m_DataLen - offsetInLayer);
+ delete [] m_Data;
+ m_Data = newData;
+ m_DataLen += numOfBytesToExtend;
+ return true;
+ }
+
+ return m_Packet->extendLayer(this, offsetInLayer, numOfBytesToExtend);
+}
+
+bool Layer::shortenLayer(int offsetInLayer, size_t numOfBytesToShorten)
+{
+ if (m_Data == NULL)
+ {
+ LOG_ERROR("Layer's data is NULL");
+ return false;
+ }
+
+ if (m_Packet == NULL)
+ {
+ if ((size_t)offsetInLayer >= m_DataLen)
+ {
+ LOG_ERROR("Requested offset is larget than data length");
+ return false;
+ }
+
+ uint8_t* newData = new uint8_t[m_DataLen - numOfBytesToShorten];
+ memcpy(newData, m_Data, offsetInLayer);
+ memcpy(newData + offsetInLayer, m_Data + offsetInLayer + numOfBytesToShorten, m_DataLen - offsetInLayer - numOfBytesToShorten);
+ delete [] m_Data;
+ m_Data = newData;
+ m_DataLen -= numOfBytesToShorten;
+ return true;
+ }
+
+ return m_Packet->shortenLayer(this, offsetInLayer, numOfBytesToShorten);
+}
+
+} // namespace pcpp
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/MplsLayer.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/MplsLayer.cpp b/thirdparty/pcap++/Packet++/src/MplsLayer.cpp
new file mode 100644
index 0000000..eb0c5ac
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/MplsLayer.cpp
@@ -0,0 +1,151 @@
+#define LOG_MODULE PacketLogModuleMplsLayer
+
+#include <MplsLayer.h>
+#include <IPv4Layer.h>
+#include <IPv6Layer.h>
+#include <PayloadLayer.h>
+#include <Logger.h>
+#include <string.h>
+#include <sstream>
+#if defined(WIN32) || defined(WINx64)
+#include <winsock2.h>
+#elif LINUX
+#include <in.h>
+#endif
+
+namespace pcpp
+{
+
+MplsLayer::MplsLayer(uint32_t mplsLabel, uint8_t ttl, uint8_t expermentalUseValue, bool bottomOfStack)
+{
+ m_DataLen = sizeof(mpls_header);
+ m_Data = new uint8_t[m_DataLen];
+ memset(m_Data, 0, m_DataLen);
+ m_Protocol = MPLS;
+
+ setMplsLabel(mplsLabel);
+ setTTL(ttl);
+ setExperimentalUseValue(expermentalUseValue);
+ setBottomOfStack(bottomOfStack);
+}
+
+bool MplsLayer::isBottomOfStack()
+{
+ return (getMplsHeader()->misc & 0x01);
+}
+
+void MplsLayer::setBottomOfStack(bool val)
+{
+ if (!val)
+ getMplsHeader()->misc &= 0xFE;
+ else
+ getMplsHeader()->misc |= 0xFF;
+}
+
+uint8_t MplsLayer::getExperimentalUseValue()
+{
+ return ((getMplsHeader()->misc & 0x0E) >> 1);
+}
+
+bool MplsLayer::setExperimentalUseValue(uint8_t val)
+{
+ // exp value is only 3 bits
+ if (val > 7)
+ {
+ LOG_ERROR("Set ExperimentalUse value got an illegal value: %d. Value must be lower than 8", val);
+ return false;
+ }
+
+ mpls_header* hdr = getMplsHeader();
+
+ // clear the 3 exp bits
+ hdr->misc &= 0xF1;
+
+ // move the 3 bits to their place
+ val = val << 1;
+
+ hdr->misc |= val;
+
+ return true;
+}
+
+uint32_t MplsLayer::getMplsLabel()
+{
+ return (htons(getMplsHeader()->hiLabel) << 4) | ((getMplsHeader()->misc & 0xF0) >> 4);
+}
+
+bool MplsLayer::setMplsLabel(uint32_t label)
+{
+ if (label > 0xFFFFF)
+ {
+ LOG_ERROR("MPLS label mustn't exceed 20 bits which is the value %d. Got a parameter with the value %d", 0xFFFFF, label);
+ return false;
+ }
+
+ mpls_header* hdr = getMplsHeader();
+
+ // clear the 4 label bits in misc field
+ hdr->misc &= 0x0F;
+
+ // take the last nibble of the label value and move this nibble to its place in misc
+ uint8_t miscVal = (label & 0x0F) << 4;
+
+ // update misc field
+ hdr->misc |= miscVal;
+
+ // get rid of the nibble that went to misc
+ label = label >> 4;
+
+ // set the high 2 bytes of the label
+ hdr->hiLabel = (uint16_t)htons(label);
+
+ return true;
+}
+
+
+void MplsLayer::parseNextLayer()
+{
+ size_t headerLen = getHeaderLen();
+ if (m_DataLen < headerLen + 1)
+ return;
+
+ if (!isBottomOfStack())
+ {
+ m_NextLayer = new MplsLayer(m_Data + sizeof(mpls_header), m_DataLen - sizeof(mpls_header), this, m_Packet);
+ return;
+ }
+
+ uint8_t nextNibble = (*((uint8_t*)(m_Data + headerLen)) & 0xF0) >> 4;
+
+ if (nextNibble == 4)
+ m_NextLayer = new IPv4Layer(m_Data + sizeof(mpls_header), m_DataLen - sizeof(mpls_header), this, m_Packet);
+ else if (nextNibble == 6)
+ m_NextLayer = new IPv6Layer(m_Data + sizeof(mpls_header), m_DataLen - sizeof(mpls_header), this, m_Packet);
+ else
+ m_NextLayer = new PayloadLayer(m_Data + sizeof(mpls_header), m_DataLen - sizeof(mpls_header), this, m_Packet);
+}
+
+void MplsLayer::computeCalculateFields()
+{
+ Layer* nextLayer = getNextLayer();
+ if (nextLayer != NULL)
+ {
+ setBottomOfStack((nextLayer->getProtocol() == MPLS));
+ }
+}
+
+std::string MplsLayer::toString()
+{
+ std::ostringstream labelStream;
+ labelStream << getMplsLabel();
+ std::ostringstream expStream;
+ expStream << (int)getExperimentalUseValue();
+ std::ostringstream ttlStream;
+ ttlStream << (int)getTTL();
+ std::string bottomOfStack = isBottomOfStack() ? "true" : "false";
+
+ return "MPLS Layer, Label: " + labelStream.str() + ", Exp: " + expStream.str() + ", TTL: " + ttlStream.str() +
+ ", Bottom of stack: " + bottomOfStack;
+}
+
+} // namespace pcpp
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/NullLoopbackLayer.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/NullLoopbackLayer.cpp b/thirdparty/pcap++/Packet++/src/NullLoopbackLayer.cpp
new file mode 100644
index 0000000..cab1578
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/NullLoopbackLayer.cpp
@@ -0,0 +1,79 @@
+#include <NullLoopbackLayer.h>
+#include <IPv4Layer.h>
+#include <IPv6Layer.h>
+#include <PayloadLayer.h>
+#include <string.h>
+
+namespace pcpp
+{
+
+#define BSWAP16(x) (((x) >> 8) | ((x) << 8))
+#define BSWAP32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) \
+ | (((x) & 0x0000FF00) << 8) | ((x) << 24))
+
+
+NullLoopbackLayer::NullLoopbackLayer(uint32_t family)
+{
+ m_DataLen = sizeof(uint32_t);
+ m_Data = new uint8_t[m_DataLen];
+ memset(m_Data, 0, m_DataLen);
+ m_Protocol = NULL_LOOPBACK;
+
+ setFamily(family);
+}
+
+uint32_t NullLoopbackLayer::getFamily()
+{
+ uint32_t family = *(uint32_t*)m_Data;
+ if ((family & 0xFFFF0000) != 0)
+ {
+ if ((family & 0xFF000000) == 0 && (family & 0x00FF0000) < 0x00060000)
+ {
+ family >>= 16;
+ }
+ else
+ {
+ family = BSWAP32(family);
+ }
+ }
+ else
+ {
+ if ((family & 0x000000FF) == 0 && (family & 0x0000FF00) < 0x00000600)
+ {
+ family = BSWAP16(family & 0xFFFF);
+ }
+ }
+
+ return family;
+}
+
+void NullLoopbackLayer::setFamily(uint32_t family)
+{
+ *m_Data = family;
+}
+
+void NullLoopbackLayer::parseNextLayer()
+{
+ uint32_t family = getFamily();
+ switch (family)
+ {
+ case PCPP_BSD_AF_INET:
+ m_NextLayer = new IPv4Layer(m_Data + sizeof(uint32_t), m_DataLen - sizeof(uint32_t), this, m_Packet);
+ break;
+ case PCPP_BSD_AF_INET6_BSD:
+ case PCPP_BSD_AF_INET6_FREEBSD:
+ case PCPP_BSD_AF_INET6_DARWIN:
+ m_NextLayer = new IPv6Layer(m_Data + sizeof(uint32_t), m_DataLen - sizeof(uint32_t), this, m_Packet);
+ break;
+ default:
+ m_NextLayer = new PayloadLayer(m_Data + sizeof(uint32_t), m_DataLen - sizeof(uint32_t), this, m_Packet);
+ }
+}
+
+
+std::string NullLoopbackLayer::toString()
+{
+ return "Null/Loopback";
+}
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/PPPoELayer.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/PPPoELayer.cpp b/thirdparty/pcap++/Packet++/src/PPPoELayer.cpp
new file mode 100644
index 0000000..aca584f
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/PPPoELayer.cpp
@@ -0,0 +1,414 @@
+#define LOG_MODULE PacketLogModulePPPoELayer
+
+#include <PPPoELayer.h>
+#include <IPv4Layer.h>
+#include <IPv6Layer.h>
+#include <PayloadLayer.h>
+#include <Logger.h>
+#include <map>
+#include <sstream>
+#if defined(WIN32) || defined(WINx64)
+#include <winsock2.h>
+#elif LINUX
+#include <in.h>
+#endif
+
+namespace pcpp
+{
+
+/// PPPoELayer
+/// ~~~~~~~~~~
+
+PPPoELayer::PPPoELayer(uint8_t version, uint8_t type, PPPoELayer::PPPoECode code, uint16_t sessionId, size_t additionalBytesToAllocate)
+{
+ m_DataLen = sizeof(pppoe_header) + additionalBytesToAllocate;
+ m_Data = new uint8_t[m_DataLen + additionalBytesToAllocate];
+ memset(m_Data, 0, m_DataLen + additionalBytesToAllocate);
+
+ pppoe_header* pppoeHdr = getPPPoEHeader();
+ pppoeHdr->version = (version & 0xf);
+ pppoeHdr->type = (type & 0x0f);
+ pppoeHdr->code = code;
+ pppoeHdr->sessionId = htons(sessionId);
+ pppoeHdr->payloadLength = 0;
+}
+
+void PPPoELayer::computeCalculateFields()
+{
+ pppoe_header* pppoeHdr = (pppoe_header*)m_Data;
+ pppoeHdr->payloadLength = htons(m_DataLen - sizeof(pppoe_header));
+}
+
+
+
+/// PPPoESessionLayer
+/// ~~~~~~~~~~~~~~~~~
+
+
+void PPPoESessionLayer::parseNextLayer()
+{
+ size_t headerLen = getHeaderLen();
+ if (m_DataLen <= headerLen)
+ return;
+
+ switch (getPPPNextProtocol())
+ {
+ case PCPP_PPP_IP:
+ m_NextLayer = new IPv4Layer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet);
+ break;
+ case PCPP_PPP_IPV6:
+ m_NextLayer = new IPv6Layer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet);
+ break;
+ default:
+ m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet);
+ break;
+ }
+
+}
+
+uint16_t PPPoESessionLayer::getPPPNextProtocol()
+{
+ if (m_DataLen < getHeaderLen())
+ {
+ LOG_ERROR("ERROR: size of layer is smaller then PPPoE session header");
+ return 0;
+ }
+
+ uint16_t pppNextProto = *(uint16_t*)(m_Data + sizeof(pppoe_header));
+ return ntohs(pppNextProto);
+}
+
+void PPPoESessionLayer::setPPPNextProtocol(uint16_t nextProtocol)
+{
+ if (m_DataLen < getHeaderLen())
+ {
+ LOG_ERROR("ERROR: size of layer is smaller then PPPoE session header");
+ return;
+ }
+
+ uint16_t* pppProto = (uint16_t*)(m_Data + sizeof(pppoe_header));
+ *pppProto = htons(nextProtocol);
+}
+
+std::map<uint16_t, std::string> createPPPNextProtoToStringMap()
+{
+ std::map<uint16_t, std::string> tempMap;
+ tempMap[PCPP_PPP_PADDING] = "Padding Protocol";
+ tempMap[PCPP_PPP_ROHC_SCID] = "ROHC small-CID";
+ tempMap[PCPP_PPP_ROHC_LCID] = "ROHC large-CID";
+ tempMap[PCPP_PPP_IP] = "Internet Protocol version 4";
+ tempMap[PCPP_PPP_OSI] = "OSI Network Layer";
+ tempMap[PCPP_PPP_XNSIDP] = "Xerox NS IDP";
+ tempMap[PCPP_PPP_DEC4] = "DECnet Phase IV";
+ tempMap[PCPP_PPP_AT] = "Appletalk";
+ tempMap[PCPP_PPP_IPX] = "Novell IPX";
+ tempMap[PCPP_PPP_VJC_COMP] = "Van Jacobson Compressed TCP/IP";
+ tempMap[PCPP_PPP_VJC_UNCOMP] = "Van Jacobson Uncompressed TCP/IP";
+ tempMap[PCPP_PPP_BCP] = "Bridging PDU";
+ tempMap[PCPP_PPP_ST] = "Stream Protocol (ST-II)";
+ tempMap[PCPP_PPP_VINES] = "Banyan Vines";
+ tempMap[PCPP_PPP_AT_EDDP] = "AppleTalk EDDP";
+ tempMap[PCPP_PPP_AT_SB] = "AppleTalk SmartBuffered";
+ tempMap[PCPP_PPP_MP] = "Multi-Link";
+ tempMap[PCPP_PPP_NB] = "NETBIOS Framing";
+ tempMap[PCPP_PPP_CISCO] = "Cisco Systems";
+ tempMap[PCPP_PPP_ASCOM] = "Ascom Timeplex";
+ tempMap[PCPP_PPP_LBLB] = "Fujitsu Link Backup and Load Balancing (LBLB)";
+ tempMap[PCPP_PPP_RL] = "DCA Remote Lan";
+ tempMap[PCPP_PPP_SDTP] = "Serial Data Transport Protocol (PPP-SDTP)";
+ tempMap[PCPP_PPP_LLC] = "SNA over 802.2";
+ tempMap[PCPP_PPP_SNA] = "SNA";
+ tempMap[PCPP_PPP_IPV6HC] = "IPv6 Header Compression ";
+ tempMap[PCPP_PPP_KNX] = "KNX Bridging Data";
+ tempMap[PCPP_PPP_ENCRYPT] = "Encryption";
+ tempMap[PCPP_PPP_ILE] = "Individual Link Encryption";
+ tempMap[PCPP_PPP_IPV6] = "Internet Protocol version 6";
+ tempMap[PCPP_PPP_MUX] = "PPP Muxing";
+ tempMap[PCPP_PPP_VSNP] = "Vendor-Specific Network Protocol (VSNP)";
+ tempMap[PCPP_PPP_TNP] = "TRILL Network Protocol (TNP)";
+ tempMap[PCPP_PPP_RTP_FH] = "RTP IPHC Full Header";
+ tempMap[PCPP_PPP_RTP_CTCP] = "RTP IPHC Compressed TCP";
+ tempMap[PCPP_PPP_RTP_CNTCP] = "RTP IPHC Compressed Non TCP";
+ tempMap[PCPP_PPP_RTP_CUDP8] = "RTP IPHC Compressed UDP 8";
+ tempMap[PCPP_PPP_RTP_CRTP8] = "RTP IPHC Compressed RTP 8";
+ tempMap[PCPP_PPP_STAMPEDE] = "Stampede Bridging";
+ tempMap[PCPP_PPP_MPPLUS] = "MP+ Protocol";
+ tempMap[PCPP_PPP_NTCITS_IPI] = "NTCITS IPI";
+ tempMap[PCPP_PPP_ML_SLCOMP] = "Single link compression in multilink";
+ tempMap[PCPP_PPP_COMP] = "Compressed datagram";
+ tempMap[PCPP_PPP_STP_HELLO] = "802.1d Hello Packets";
+ tempMap[PCPP_PPP_IBM_SR] = "IBM Source Routing BPDU";
+ tempMap[PCPP_PPP_DEC_LB] = "DEC LANBridge100 Spanning Tree";
+ tempMap[PCPP_PPP_CDP] = "Cisco Discovery Protocol";
+ tempMap[PCPP_PPP_NETCS] = "Netcs Twin Routing";
+ tempMap[PCPP_PPP_STP] = "STP - Scheduled Transfer Protocol";
+ tempMap[PCPP_PPP_EDP] = "EDP - Extreme Discovery Protocol";
+ tempMap[PCPP_PPP_OSCP] = "Optical Supervisory Channel Protocol (OSCP)";
+ tempMap[PCPP_PPP_OSCP2] = "Optical Supervisory Channel Protocol (OSCP)";
+ tempMap[PCPP_PPP_LUXCOM] = "Luxcom";
+ tempMap[PCPP_PPP_SIGMA] = "Sigma Network Systems";
+ tempMap[PCPP_PPP_ACSP] = "Apple Client Server Protocol";
+ tempMap[PCPP_PPP_MPLS_UNI] = "MPLS Unicast";
+ tempMap[PCPP_PPP_MPLS_MULTI] = "MPLS Multicast";
+ tempMap[PCPP_PPP_P12844] = "IEEE p1284.4 standard - data packets";
+ tempMap[PCPP_PPP_TETRA] = "ETSI TETRA Network Protocol Type 1";
+ tempMap[PCPP_PPP_MFTP] = "Multichannel Flow Treatment Protocol";
+ tempMap[PCPP_PPP_RTP_CTCPND] = "RTP IPHC Compressed TCP No Delta";
+ tempMap[PCPP_PPP_RTP_CS] = "RTP IPHC Context State";
+ tempMap[PCPP_PPP_RTP_CUDP16] = "RTP IPHC Compressed UDP 16";
+ tempMap[PCPP_PPP_RTP_CRDP16] = "RTP IPHC Compressed RTP 16";
+ tempMap[PCPP_PPP_CCCP] = "Cray Communications Control Protocol";
+ tempMap[PCPP_PPP_CDPD_MNRP] = "CDPD Mobile Network Registration Protocol";
+ tempMap[PCPP_PPP_EXPANDAP] = "Expand accelerator protocol";
+ tempMap[PCPP_PPP_ODSICP] = "ODSICP NCP";
+ tempMap[PCPP_PPP_DOCSIS] = "DOCSIS DLL";
+ tempMap[PCPP_PPP_CETACEANNDP] = "Cetacean Network Detection Protocol";
+ tempMap[PCPP_PPP_LZS] = "Stacker LZS";
+ tempMap[PCPP_PPP_REFTEK] = "RefTek Protocol";
+ tempMap[PCPP_PPP_FC] = "Fibre Channel";
+ tempMap[PCPP_PPP_EMIT] = "EMIT Protocols";
+ tempMap[PCPP_PPP_VSP] = "Vendor-Specific Protocol (VSP)";
+ tempMap[PCPP_PPP_TLSP] = "TRILL Link State Protocol (TLSP)";
+ tempMap[PCPP_PPP_IPCP] = "Internet Protocol Control Protocol";
+ tempMap[PCPP_PPP_OSINLCP] = "OSI Network Layer Control Protocol";
+ tempMap[PCPP_PPP_XNSIDPCP] = "Xerox NS IDP Control Protocol";
+ tempMap[PCPP_PPP_DECNETCP] = "DECnet Phase IV Control Protocol";
+ tempMap[PCPP_PPP_ATCP] = "AppleTalk Control Protocol";
+ tempMap[PCPP_PPP_IPXCP] = "Novell IPX Control Protocol";
+ tempMap[PCPP_PPP_BRIDGENCP] = "Bridging NCP";
+ tempMap[PCPP_PPP_SPCP] = "Stream Protocol Control Protocol";
+ tempMap[PCPP_PPP_BVCP] = "Banyan Vines Control Protocol";
+ tempMap[PCPP_PPP_MLCP] = "Multi-Link Control Protocol";
+ tempMap[PCPP_PPP_NBCP] = "NETBIOS Framing Control Protocol";
+ tempMap[PCPP_PPP_CISCOCP] = "Cisco Systems Control Protocol";
+ tempMap[PCPP_PPP_ASCOMCP] = "Ascom Timeplex";
+ tempMap[PCPP_PPP_LBLBCP] = "Fujitsu LBLB Control Protocol";
+ tempMap[PCPP_PPP_RLNCP] = "DCA Remote Lan Network Control Protocol (RLNCP)";
+ tempMap[PCPP_PPP_SDCP] = "Serial Data Control Protocol (PPP-SDCP)";
+ tempMap[PCPP_PPP_LLCCP] = "SNA over 802.2 Control Protocol";
+ tempMap[PCPP_PPP_SNACP] = "SNA Control Protocol";
+ tempMap[PCPP_PPP_IP6HCCP] = "IP6 Header Compression Control Protocol";
+ tempMap[PCPP_PPP_KNXCP] = "KNX Bridging Control Protocol";
+ tempMap[PCPP_PPP_ECP] = "Encryption Control Protocol";
+ tempMap[PCPP_PPP_ILECP] = "Individual Link Encryption Control Protocol";
+ tempMap[PCPP_PPP_IPV6CP] = "IPv6 Control Protocol";
+ tempMap[PCPP_PPP_MUXCP] = "PPP Muxing Control Protocol";
+ tempMap[PCPP_PPP_VSNCP] = "Vendor-Specific Network Control Protocol (VSNCP)";
+ tempMap[PCPP_PPP_TNCP] = "TRILL Network Control Protocol";
+ tempMap[PCPP_PPP_STAMPEDECP] = "Stampede Bridging Control Protocol";
+ tempMap[PCPP_PPP_MPPCP] = "MP+ Control Protocol";
+ tempMap[PCPP_PPP_IPICP] = "NTCITS IPI Control Protocol";
+ tempMap[PCPP_PPP_SLCC] = "Single link compression in multilink control";
+ tempMap[PCPP_PPP_CCP] = "Compression Control Protocol";
+ tempMap[PCPP_PPP_CDPCP] = "Cisco Discovery Protocol Control Protocol";
+ tempMap[PCPP_PPP_NETCSCP] = "Netcs Twin Routing";
+ tempMap[PCPP_PPP_STPCP] = "STP - Control Protocol";
+ tempMap[PCPP_PPP_EDPCP] = "EDPCP - Extreme Discovery Protocol Control Protocol";
+ tempMap[PCPP_PPP_ACSPC] = "Apple Client Server Protocol Control";
+ tempMap[PCPP_PPP_MPLSCP] = "MPLS Control Protocol";
+ tempMap[PCPP_PPP_P12844CP] = "IEEE p1284.4 standard - Protocol Control";
+ tempMap[PCPP_PPP_TETRACP] = "ETSI TETRA TNP1 Control Protocol";
+ tempMap[PCPP_PPP_MFTPCP] = "Multichannel Flow Treatment Protocol";
+ tempMap[PCPP_PPP_LCP] = "Link Control Protocol";
+ tempMap[PCPP_PPP_PAP] = "Password Authentication Protocol";
+ tempMap[PCPP_PPP_LQR] = "Link Quality Report";
+ tempMap[PCPP_PPP_SPAP] = "Shiva Password Authentication Protocol";
+ tempMap[PCPP_PPP_CBCP] = "Callback Control Protocol (CBCP)";
+ tempMap[PCPP_PPP_BACP] = "BACP Bandwidth Allocation Control Protocol";
+ tempMap[PCPP_PPP_BAP] = "BAP Bandwidth Allocation Protocol";
+ tempMap[PCPP_PPP_VSAP] = "Vendor-Specific Authentication Protocol (VSAP)";
+ tempMap[PCPP_PPP_CONTCP] = "Container Control Protocol";
+ tempMap[PCPP_PPP_CHAP] = "Challenge Handshake Authentication Protocol";
+ tempMap[PCPP_PPP_RSAAP] = "RSA Authentication Protocol";
+ tempMap[PCPP_PPP_EAP] = "Extensible Authentication Protocol";
+ tempMap[PCPP_PPP_SIEP] = "Mitsubishi Security Information Exchange Protocol (SIEP)";
+ tempMap[PCPP_PPP_SBAP] = "Stampede Bridging Authorization Protocol";
+ tempMap[PCPP_PPP_PRPAP] = "Proprietary Authentication Protocol";
+ tempMap[PCPP_PPP_PRPAP2] = "Proprietary Authentication Protocol";
+ tempMap[PCPP_PPP_PRPNIAP] = "Proprietary Node ID Authentication Protocol";
+ return tempMap;
+}
+
+const std::map<uint16_t, std::string> PPPNextProtoToString = createPPPNextProtoToStringMap();
+
+std::string PPPoESessionLayer::toString()
+{
+ std::map<uint16_t, std::string>::const_iterator iter = PPPNextProtoToString.find(getPPPNextProtocol());
+ std::string nextProtocol;
+ if (iter != PPPNextProtoToString.end())
+ nextProtocol = iter->second;
+ else
+ {
+ std::ostringstream stream;
+ stream << "Unknown (0x" << std::hex << getPPPNextProtocol() << ")";
+ nextProtocol = stream.str();
+ }
+
+ return "PPP-over-Ethernet Session (followed by '" + nextProtocol + "')";
+}
+
+
+
+/// PPPoEDiscoveryLayer
+/// ~~~~~~~~~~~~~~~~~~~
+
+
+PPPoEDiscoveryLayer::PPPoETagTypes PPPoEDiscoveryLayer::PPPoETag::getType()
+{
+ return (PPPoEDiscoveryLayer::PPPoETagTypes)ntohs(tagType);
+}
+
+size_t PPPoEDiscoveryLayer::PPPoETag::getTagTotalSize() const
+{
+ return 2*sizeof(uint16_t) + ntohs(tagDataLength);
+}
+
+PPPoEDiscoveryLayer::PPPoETag* PPPoEDiscoveryLayer::getTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType)
+{
+ // check if there are tags at all
+ if (m_DataLen <= sizeof(pppoe_header))
+ return NULL;
+
+ uint8_t* curTagPtr = m_Data + sizeof(pppoe_header);
+ while ((curTagPtr - m_Data) < (int)m_DataLen)
+ {
+ PPPoEDiscoveryLayer::PPPoETag* curTag = castPtrToPPPoETag(curTagPtr);
+ if (curTag->tagType == htons(tagType))
+ return curTag;
+
+ curTagPtr += curTag->getTagTotalSize();
+ }
+
+ return NULL;
+}
+
+PPPoEDiscoveryLayer::PPPoETag* PPPoEDiscoveryLayer::getFirstTag()
+{
+ // check if there are tags at all
+ if (m_DataLen <= sizeof(pppoe_header))
+ return NULL;
+
+ uint8_t* curTagPtr = m_Data + sizeof(pppoe_header);
+ return castPtrToPPPoETag(curTagPtr);
+}
+
+PPPoEDiscoveryLayer::PPPoETag* PPPoEDiscoveryLayer::getNextTag(PPPoEDiscoveryLayer::PPPoETag* tag)
+{
+ if (tag == NULL)
+ return NULL;
+
+ // prev tag was the last tag
+ if ((uint8_t*)tag + tag->getTagTotalSize() - m_Data >= (int)m_DataLen)
+ return NULL;
+
+ return castPtrToPPPoETag((uint8_t*)tag + tag->getTagTotalSize());
+}
+
+int PPPoEDiscoveryLayer::getTagCount()
+{
+ if (m_TagCount != -1)
+ return m_TagCount;
+
+ m_TagCount = 0;
+ PPPoEDiscoveryLayer::PPPoETag* curTag = getFirstTag();
+ while (curTag != NULL)
+ {
+ m_TagCount++;
+ curTag = getNextTag(curTag);
+ }
+
+ return m_TagCount;
+}
+
+PPPoEDiscoveryLayer::PPPoETag* PPPoEDiscoveryLayer::addTagAt(PPPoETagTypes tagType, uint16_t tagLength, const uint8_t* tagData, int offset)
+{
+ size_t tagTotalLength = 2*sizeof(uint16_t) + tagLength;
+ if (!extendLayer(offset, tagTotalLength))
+ {
+ LOG_ERROR("Could not extend PPPoEDiscoveryLayer in [%d] bytes", (int)tagTotalLength);
+ return NULL;
+ }
+
+ uint16_t tagTypeVal = htons((uint16_t)tagType);
+ tagLength = htons(tagLength);
+ memcpy(m_Data + offset, &tagTypeVal, sizeof(uint16_t));
+ memcpy(m_Data + offset + sizeof(uint16_t), &tagLength, sizeof(uint16_t));
+ if (tagLength > 0 && tagData != NULL)
+ memcpy(m_Data + offset + 2*sizeof(uint16_t), tagData, ntohs(tagLength));
+
+ uint8_t* newTagPtr = m_Data + offset;
+
+ getPPPoEHeader()->payloadLength += htons(tagTotalLength);
+ m_TagCount++;
+
+ return castPtrToPPPoETag(newTagPtr);
+}
+
+PPPoEDiscoveryLayer::PPPoETag* PPPoEDiscoveryLayer::addTagAfter(PPPoETagTypes tagType, uint16_t tagLength, const uint8_t* tagData, PPPoEDiscoveryLayer::PPPoETag* prevTag)
+{
+ if (prevTag == NULL)
+ {
+ LOG_ERROR("prevTag is NULL");
+ return NULL;
+ }
+
+ int offset = (uint8_t*)prevTag + prevTag->getTagTotalSize() - m_Data;
+
+ return addTagAt(tagType, tagLength, tagData, offset);
+}
+
+PPPoEDiscoveryLayer::PPPoETag* PPPoEDiscoveryLayer::addTag(PPPoETagTypes tagType, uint16_t tagLength, const uint8_t* tagData)
+{
+ return addTagAt(tagType, tagLength, tagData, getHeaderLen());
+}
+
+size_t PPPoEDiscoveryLayer::getHeaderLen()
+{
+ return sizeof(pppoe_header) + ntohs(getPPPoEHeader()->payloadLength);
+}
+
+PPPoEDiscoveryLayer::PPPoETag* PPPoEDiscoveryLayer::castPtrToPPPoETag(uint8_t* ptr)
+{
+ return (PPPoEDiscoveryLayer::PPPoETag*)ptr;
+}
+
+bool PPPoEDiscoveryLayer::removeTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType)
+{
+ PPPoEDiscoveryLayer::PPPoETag* tag = getTag(tagType);
+ if (tag == NULL)
+ {
+ LOG_ERROR("Couldn't find tag");
+ return false;
+ }
+
+ int offset = (uint8_t*)tag - m_Data;
+
+ return shortenLayer(offset, tag->getTagTotalSize());
+}
+
+bool PPPoEDiscoveryLayer::removeAllTags()
+{
+ int offset = sizeof(pppoe_header);
+ return shortenLayer(offset, m_DataLen-offset);
+}
+
+std::string PPPoEDiscoveryLayer::codeToString(PPPoECode code)
+{
+ switch (code)
+ {
+ case PPPoELayer::PPPOE_CODE_SESSION:return std::string("PPPoE Session");
+ case PPPoELayer::PPPOE_CODE_PADO: return std::string("PADO");
+ case PPPoELayer::PPPOE_CODE_PADI: return std::string("PADI");
+ case PPPoELayer::PPPOE_CODE_PADG: return std::string("PADG");
+ case PPPoELayer::PPPOE_CODE_PADC: return std::string("PADC");
+ case PPPoELayer::PPPOE_CODE_PADQ: return std::string("PADQ");
+ case PPPoELayer::PPPOE_CODE_PADR: return std::string("PADR");
+ case PPPoELayer::PPPOE_CODE_PADS: return std::string("PADS");
+ case PPPoELayer::PPPOE_CODE_PADT: return std::string("PADT");
+ case PPPoELayer::PPPOE_CODE_PADM: return std::string("PADM");
+ case PPPoELayer::PPPOE_CODE_PADN: return std::string("PADN");
+ default: return std::string("Unknown PPPoE code");
+ }
+}
+
+} // namespace pcpp
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/Packet.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/Packet.cpp b/thirdparty/pcap++/Packet++/src/Packet.cpp
new file mode 100644
index 0000000..81ad805
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/Packet.cpp
@@ -0,0 +1,504 @@
+#define LOG_MODULE PacketLogModulePacket
+
+#include <Packet.h>
+#include <EthLayer.h>
+#include <SllLayer.h>
+#include <NullLoopbackLayer.h>
+#include <IPv4Layer.h>
+#include <IPv6Layer.h>
+#include <PayloadLayer.h>
+#include <Logger.h>
+#include <string.h>
+#include <typeinfo>
+#include <sstream>
+#ifdef _MSC_VER
+#include <time.h>
+#include <SystemUtils.h>
+#endif
+
+
+namespace pcpp
+{
+
+Packet::Packet(size_t maxPacketLen) :
+ m_RawPacket(NULL),
+ m_FirstLayer(NULL),
+ m_LastLayer(NULL),
+ m_ProtocolTypes(UnknownProtocol),
+ m_MaxPacketLen(maxPacketLen),
+ m_FreeRawPacket(true)
+{
+ timeval time;
+ gettimeofday(&time, NULL);
+ uint8_t* data = new uint8_t[m_MaxPacketLen];
+ memset(data, 0, m_MaxPacketLen);
+ m_RawPacket = new RawPacket((const uint8_t*)data, 0, time, true, LINKTYPE_ETHERNET);
+}
+
+void Packet::setRawPacket(RawPacket* rawPacket, bool freeRawPacket, ProtocolType parseUntil, OsiModelLayer parseUntilLayer)
+{
+ destructPacketData();
+
+ m_FirstLayer = NULL;
+ m_LastLayer = NULL;
+ m_ProtocolTypes = UnknownProtocol;
+ m_MaxPacketLen = rawPacket->getRawDataLen();
+ m_FreeRawPacket = freeRawPacket;
+ m_RawPacket = rawPacket;
+ if (m_RawPacket && m_RawPacket->getLinkLayerType() == LINKTYPE_LINUX_SLL)
+ {
+ m_FirstLayer = new SllLayer((uint8_t*)m_RawPacket->getRawData(), m_RawPacket->getRawDataLen(), this);
+ }
+ else if (m_RawPacket && m_RawPacket->getLinkLayerType() == LINKTYPE_NULL)
+ {
+ m_FirstLayer = new NullLoopbackLayer((uint8_t*)m_RawPacket->getRawData(), m_RawPacket->getRawDataLen(), this);
+ }
+ else if (m_RawPacket && (m_RawPacket->getLinkLayerType() == LINKTYPE_RAW || m_RawPacket->getLinkLayerType() == LINKTYPE_DLT_RAW1 || m_RawPacket->getLinkLayerType() == LINKTYPE_DLT_RAW2))
+ {
+ uint8_t ipVer = m_RawPacket->getRawData()[0] & 0xf0;
+ if (ipVer == 0x40)
+ m_FirstLayer = new IPv4Layer((uint8_t*)m_RawPacket->getRawData(), m_RawPacket->getRawDataLen(), NULL, this);
+ else if (ipVer == 0x60)
+ m_FirstLayer = new IPv6Layer((uint8_t*)m_RawPacket->getRawData(), m_RawPacket->getRawDataLen(), NULL, this);
+ else
+ m_FirstLayer = new PayloadLayer((uint8_t*)m_RawPacket->getRawData(), m_RawPacket->getRawDataLen(), NULL, this);
+ }
+ else
+ {
+ m_FirstLayer = new EthLayer((uint8_t*)m_RawPacket->getRawData(), m_RawPacket->getRawDataLen(), this);
+ }
+
+ m_LastLayer = m_FirstLayer;
+ Layer* curLayer = m_FirstLayer;
+ while (curLayer != NULL && (curLayer->getProtocol() & parseUntil) == 0 && curLayer->getOsiModelLayer() <= parseUntilLayer)
+ {
+ m_ProtocolTypes |= curLayer->getProtocol();
+ curLayer->parseNextLayer();
+ m_LayersAllocatedInPacket.push_back(curLayer);
+ curLayer = curLayer->getNextLayer();
+ if (curLayer != NULL)
+ m_LastLayer = curLayer;
+ }
+
+ if (curLayer != NULL && (curLayer->getProtocol() & parseUntil) != 0)
+ {
+ m_ProtocolTypes |= curLayer->getProtocol();
+ m_LayersAllocatedInPacket.push_back(curLayer);
+ }
+
+ if (curLayer != NULL && curLayer->getOsiModelLayer() > parseUntilLayer)
+ {
+ m_LastLayer = curLayer->getPrevLayer();
+ delete curLayer;
+ m_LastLayer->m_NextLayer = NULL;
+ }
+}
+
+Packet::Packet(RawPacket* rawPacket, bool freeRawPacket, ProtocolType parseUntil, OsiModelLayer parseUntilLayer)
+{
+ m_FreeRawPacket = false;
+ m_RawPacket = NULL;
+ setRawPacket(rawPacket, freeRawPacket, parseUntil, parseUntilLayer);
+}
+
+Packet::Packet(RawPacket* rawPacket, ProtocolType parseUntil)
+{
+ m_FreeRawPacket = false;
+ m_RawPacket = NULL;
+ setRawPacket(rawPacket, false, parseUntil, OsiModelLayerUnknown);
+}
+
+Packet::Packet(RawPacket* rawPacket, OsiModelLayer parseUntilLayer)
+{
+ m_FreeRawPacket = false;
+ m_RawPacket = NULL;
+ setRawPacket(rawPacket, false, UnknownProtocol, parseUntilLayer);
+}
+
+Packet::Packet(const Packet& other)
+{
+ copyDataFrom(other);
+}
+
+void Packet::destructPacketData()
+{
+ std::vector<Layer*>::iterator iter = m_LayersAllocatedInPacket.begin();
+ while (iter != m_LayersAllocatedInPacket.end())
+ {
+ delete (*iter);
+ iter = m_LayersAllocatedInPacket.erase(iter);
+ }
+
+ if (m_RawPacket != NULL && m_FreeRawPacket)
+ {
+ delete m_RawPacket;
+ }
+}
+
+Packet& Packet::operator=(const Packet& other)
+{
+ destructPacketData();
+
+ copyDataFrom(other);
+
+ return *this;
+}
+
+void Packet::copyDataFrom(const Packet& other)
+{
+ m_RawPacket = new RawPacket(*(other.m_RawPacket));
+ m_FreeRawPacket = true;
+ m_MaxPacketLen = other.m_MaxPacketLen;
+ m_ProtocolTypes = other.m_ProtocolTypes;
+ m_FirstLayer = new EthLayer((uint8_t*)m_RawPacket->getRawData(), m_RawPacket->getRawDataLen(), this);
+ m_LastLayer = m_FirstLayer;
+ Layer* curLayer = m_FirstLayer;
+ while (curLayer != NULL)
+ {
+ curLayer->parseNextLayer();
+ m_LayersAllocatedInPacket.push_back(curLayer);
+ curLayer = curLayer->getNextLayer();
+ if (curLayer != NULL)
+ m_LastLayer = curLayer;
+ }
+}
+
+void Packet::reallocateRawData(size_t newSize)
+{
+ LOG_DEBUG("Allocating packet to new size: %d", (int)newSize);
+
+ // allocate a new array with size newSize
+ m_MaxPacketLen = newSize;
+
+ // set the new array to RawPacket
+ if (!m_RawPacket->reallocateData(m_MaxPacketLen))
+ {
+ LOG_ERROR("Couldn't reallocate data of raw packet to %d bytes", (int)m_MaxPacketLen);
+ return;
+ }
+
+ // set all data pointers in layers to the new array address
+ const uint8_t* dataPtr = m_RawPacket->getRawData();
+
+ Layer* curLayer = m_FirstLayer;
+ while (curLayer != NULL)
+ {
+ LOG_DEBUG("Setting new data pointer to layer '%s'", typeid(curLayer).name());
+ curLayer->m_Data = (uint8_t*)dataPtr;
+ dataPtr += curLayer->getHeaderLen();
+ curLayer = curLayer->getNextLayer();
+ }
+}
+
+bool Packet::addLayer(Layer* newLayer)
+{
+ return insertLayer(m_LastLayer, newLayer);
+}
+
+bool Packet::insertLayer(Layer* prevLayer, Layer* newLayer)
+{
+ if (newLayer == NULL)
+ {
+ LOG_ERROR("Layer to add is NULL");
+ return false;
+ }
+
+ if (newLayer->isAllocatedToPacket())
+ {
+ LOG_ERROR("Layer is already allocated to another packet. Cannot use layer in more than one packet");
+ return false;
+ }
+
+ if (m_RawPacket->getRawDataLen() + newLayer->getHeaderLen() > m_MaxPacketLen)
+ {
+ // reallocate to maximum value of: twice the max size of the packet or max size + new required length
+ if (m_RawPacket->getRawDataLen() + newLayer->getHeaderLen() > m_MaxPacketLen*2)
+ reallocateRawData(m_RawPacket->getRawDataLen() + newLayer->getHeaderLen() + m_MaxPacketLen);
+ else
+ reallocateRawData(m_MaxPacketLen*2);
+ }
+
+ size_t appendDataLen = newLayer->getHeaderLen();
+
+ // insert layer data to raw packet
+ int indexToInsertData = 0;
+ if (prevLayer != NULL)
+ indexToInsertData = prevLayer->m_Data+prevLayer->getHeaderLen() - m_RawPacket->getRawData();
+ m_RawPacket->insertData(indexToInsertData, newLayer->m_Data, appendDataLen);
+
+ //delete previous layer data
+ delete[] newLayer->m_Data;
+
+ // add layer to layers linked list
+ if (prevLayer != NULL)
+ {
+ newLayer->setNextLayer(prevLayer->getNextLayer());
+ newLayer->setPrevLayer(prevLayer);
+ prevLayer->setNextLayer(newLayer);
+ }
+ else //prevLayer == NULL
+ {
+ newLayer->setNextLayer(m_FirstLayer);
+ if (m_FirstLayer != NULL)
+ m_FirstLayer->setPrevLayer(newLayer);
+ m_FirstLayer = newLayer;
+ }
+
+ if (newLayer->getNextLayer() == NULL)
+ m_LastLayer = newLayer;
+
+ // assign layer with this packet only
+ newLayer->m_Packet = this;
+
+ // re-calculate all layers data ptr and data length
+ const uint8_t* dataPtr = m_RawPacket->getRawData();
+ int dataLen = m_RawPacket->getRawDataLen();
+
+ Layer* curLayer = m_FirstLayer;
+ while (curLayer != NULL)
+ {
+ curLayer->m_Data = (uint8_t*)dataPtr;
+ curLayer->m_DataLen = dataLen;
+ dataPtr += curLayer->getHeaderLen();
+ dataLen -= curLayer->getHeaderLen();
+ curLayer = curLayer->getNextLayer();
+ }
+
+ // add layer protocol to protocol collection
+ m_ProtocolTypes |= newLayer->getProtocol();
+ return true;
+}
+
+bool Packet::removeLayer(Layer* layer)
+{
+ if (layer == NULL)
+ {
+ LOG_ERROR("Layer is NULL");
+ return false;
+ }
+
+ // verify layer is allocated to a packet
+ if (!layer->isAllocatedToPacket())
+ {
+ LOG_ERROR("Layer isn't allocated to any packet");
+ return false;
+ }
+
+ // verify layer is allocated to *this* packet
+ Layer* curLayer = layer;
+ while (curLayer->m_PrevLayer != NULL)
+ curLayer = curLayer->m_PrevLayer;
+ if (curLayer != m_FirstLayer)
+ {
+ LOG_ERROR("Layer isn't allocated to this packet");
+ return false;
+ }
+
+ // remove data from raw packet
+ size_t numOfBytesToRemove = layer->getHeaderLen();
+ int indexOfDataToRemove = layer->m_Data - m_RawPacket->getRawData();
+ if (!m_RawPacket->removeData(indexOfDataToRemove, numOfBytesToRemove))
+ {
+ LOG_ERROR("Couldn't remove data from packet");
+ return false;
+ }
+
+ // remove layer from layers linked list
+ if (layer->m_PrevLayer != NULL)
+ layer->m_PrevLayer->setNextLayer(layer->m_NextLayer);
+ if (layer->m_NextLayer != NULL)
+ layer->m_NextLayer->setPrevLayer(layer->m_PrevLayer);
+
+ // take care of head and tail ptrs
+ if (m_FirstLayer == layer)
+ m_FirstLayer = layer->m_NextLayer;
+ if (m_LastLayer == layer)
+ m_LastLayer = layer->m_PrevLayer;
+ layer->setNextLayer(NULL);
+ layer->setPrevLayer(NULL);
+
+ // re-calculate all layers data ptr and data length
+ const uint8_t* dataPtr = m_RawPacket->getRawData();
+ int dataLen = m_RawPacket->getRawDataLen();
+
+ curLayer = m_FirstLayer;
+ bool anotherLayerWithSameProtocolExists = false;
+ while (curLayer != NULL)
+ {
+ curLayer->m_Data = (uint8_t*)dataPtr;
+ curLayer->m_DataLen = dataLen;
+ if (curLayer->getProtocol() == layer->getProtocol())
+ anotherLayerWithSameProtocolExists = true;
+ dataPtr += curLayer->getHeaderLen();
+ dataLen -= curLayer->getHeaderLen();
+ curLayer = curLayer->getNextLayer();
+ }
+
+ // remove layer protocol from protocol list if necessary
+ if (!anotherLayerWithSameProtocolExists)
+ m_ProtocolTypes &= ~((uint64_t)layer->getProtocol());
+
+ return true;
+}
+
+bool Packet::extendLayer(Layer* layer, int offsetInLayer, size_t numOfBytesToExtend)
+{
+ if (layer == NULL)
+ {
+ LOG_ERROR("Layer is NULL");
+ return false;
+ }
+
+ // verify layer is allocated to this packet
+ if (!(layer->m_Packet == this))
+ {
+ LOG_ERROR("Layer isn't allocated to this packet");
+ return false;
+ }
+
+ if (m_RawPacket->getRawDataLen() + numOfBytesToExtend > m_MaxPacketLen)
+ {
+ // reallocate to maximum value of: twice the max size of the packet or max size + new required length
+ if (m_RawPacket->getRawDataLen() + numOfBytesToExtend > m_MaxPacketLen*2)
+ reallocateRawData(m_RawPacket->getRawDataLen() + numOfBytesToExtend + m_MaxPacketLen);
+ else
+ reallocateRawData(m_MaxPacketLen*2);
+ }
+
+ // insert layer data to raw packet
+ int indexToInsertData = layer->m_Data + offsetInLayer - m_RawPacket->getRawData();
+ uint8_t* tempData = new uint8_t[numOfBytesToExtend];
+ m_RawPacket->insertData(indexToInsertData, tempData, numOfBytesToExtend);
+ delete[] tempData;
+
+ // re-calculate all layers data ptr and data length
+ const uint8_t* dataPtr = m_RawPacket->getRawData();
+ int dataLen = m_RawPacket->getRawDataLen();
+
+ Layer* curLayer = m_FirstLayer;
+ while (curLayer != NULL)
+ {
+ curLayer->m_Data = (uint8_t*)dataPtr;
+ curLayer->m_DataLen = dataLen;
+ // assuming header length of the layer that requested to be extended hasn't been enlarged yet
+ size_t headerLen = curLayer->getHeaderLen() + (curLayer == layer ? numOfBytesToExtend : 0);
+ dataPtr += headerLen;
+ dataLen -= headerLen;
+ curLayer = curLayer->getNextLayer();
+ }
+
+ return true;
+}
+
+bool Packet::shortenLayer(Layer* layer, int offsetInLayer, size_t numOfBytesToShorten)
+{
+ if (layer == NULL)
+ {
+ LOG_ERROR("Layer is NULL");
+ return false;
+ }
+
+ // verify layer is allocated to this packet
+ if (!(layer->m_Packet == this))
+ {
+ LOG_ERROR("Layer isn't allocated to this packet");
+ return false;
+ }
+
+ // remove data from raw packet
+ int indexOfDataToRemove = layer->m_Data + offsetInLayer - m_RawPacket->getRawData();
+ if (!m_RawPacket->removeData(indexOfDataToRemove, numOfBytesToShorten))
+ {
+ LOG_ERROR("Couldn't remove data from packet");
+ return false;
+ }
+
+ // re-calculate all layers data ptr and data length
+ const uint8_t* dataPtr = m_RawPacket->getRawData();
+ int dataLen = m_RawPacket->getRawDataLen();
+
+ Layer* curLayer = m_FirstLayer;
+ while (curLayer != NULL)
+ {
+ curLayer->m_Data = (uint8_t*)dataPtr;
+ curLayer->m_DataLen = dataLen;
+ // assuming header length of the layer that requested to be extended hasn't been enlarged yet
+ size_t headerLen = curLayer->getHeaderLen() - (curLayer == layer ? numOfBytesToShorten : 0);
+ dataPtr += headerLen;
+ dataLen -= headerLen;
+ curLayer = curLayer->getNextLayer();
+ }
+
+ return true;
+}
+
+
+void Packet::computeCalculateFields()
+{
+ // calculated fields should be calculated from top layer to bottom layer
+
+ Layer* curLayer = m_LastLayer;
+ while (curLayer != NULL)
+ {
+ curLayer->computeCalculateFields();
+ curLayer = curLayer->getPrevLayer();
+ }
+}
+
+Packet::~Packet()
+{
+ destructPacketData();
+}
+
+std::string Packet::printPacketInfo(bool timeAsLocalTime)
+{
+ std::ostringstream dataLenStream;
+ dataLenStream << m_RawPacket->getRawDataLen();
+
+ // convert raw packet timestamp to printable format
+ timeval timestamp = m_RawPacket->getPacketTimeStamp();
+ time_t nowtime = timestamp.tv_sec;
+ struct tm *nowtm = NULL;
+ if (timeAsLocalTime)
+ nowtm = localtime(&nowtime);
+ else
+ nowtm = gmtime(&nowtime);
+
+ char tmbuf[64], buf[64];
+ if (nowtm != NULL)
+ {
+ strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", nowtm);
+ snprintf(buf, sizeof(buf), "%s.%06lu", tmbuf, timestamp.tv_usec);
+ }
+ else
+ snprintf(buf, sizeof(buf), "0000-00-00 00:00:00.000000");
+
+ return "Packet length: " + dataLenStream.str() + " [Bytes], Arrival time: " + std::string(buf);
+}
+
+std::string Packet::printToString(bool timeAsLocalTime)
+{
+ std::vector<std::string> stringList;
+ std::string result;
+ printToStringList(stringList, timeAsLocalTime);
+ for (std::vector<std::string>::iterator iter = stringList.begin(); iter != stringList.end(); iter++)
+ {
+ result += *iter + "\n";
+ }
+
+ return result;
+}
+
+void Packet::printToStringList(std::vector<std::string>& result, bool timeAsLocalTime)
+{
+ result.clear();
+ result.push_back(printPacketInfo(timeAsLocalTime));
+ Layer* curLayer = m_FirstLayer;
+ while (curLayer != NULL)
+ {
+ result.push_back(curLayer->toString());
+ curLayer = curLayer->getNextLayer();
+ }
+}
+
+} // namespace pcpp
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/PacketUtils.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/PacketUtils.cpp b/thirdparty/pcap++/Packet++/src/PacketUtils.cpp
new file mode 100644
index 0000000..224184e
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/PacketUtils.cpp
@@ -0,0 +1,118 @@
+#include <string.h>
+#include "PacketUtils.h"
+#include "IpUtils.h"
+#include "IPv4Layer.h"
+#include "IPv6Layer.h"
+#include "TcpLayer.h"
+#include "UdpLayer.h"
+
+namespace pcpp
+{
+
+uint32_t hash5Tuple(Packet* packet)
+{
+ if (!packet->isPacketOfType(IPv4) && !packet->isPacketOfType(IPv6))
+ return 0;
+
+ if (packet->isPacketOfType(ICMP))
+ return 0;
+
+ if (!(packet->isPacketOfType(TCP)) && (!packet->isPacketOfType(UDP)))
+ return 0;
+
+ ScalarBuffer<uint8_t> vec[5];
+
+ uint16_t portSrc = 0;
+ uint16_t portDst = 0;
+ int srcPosition = 0;
+
+ TcpLayer* tcpLayer = packet->getLayerOfType<TcpLayer>();
+ if (tcpLayer != NULL)
+ {
+ portSrc = tcpLayer->getTcpHeader()->portSrc;
+ portDst = tcpLayer->getTcpHeader()->portDst;
+ }
+ else
+ {
+ UdpLayer* udpLayer = packet->getLayerOfType<UdpLayer>();
+ portSrc = udpLayer->getUdpHeader()->portSrc;
+ portDst = udpLayer->getUdpHeader()->portDst;
+ }
+
+ if (portDst < portSrc)
+ srcPosition = 1;
+
+ vec[0 + srcPosition].buffer = (uint8_t*)&portSrc;
+ vec[0 + srcPosition].len = 2;
+ vec[1 - srcPosition].buffer = (uint8_t*)&portDst;
+ vec[1 - srcPosition].len = 2;
+
+
+ IPv4Layer* ipv4Layer = packet->getLayerOfType<IPv4Layer>();
+ if (ipv4Layer != NULL)
+ {
+ if (portSrc == portDst && ipv4Layer->getIPv4Header()->ipDst < ipv4Layer->getIPv4Header()->ipSrc)
+ srcPosition = 1;
+
+ vec[2 + srcPosition].buffer = (uint8_t*)&ipv4Layer->getIPv4Header()->ipSrc;
+ vec[2 + srcPosition].len = 4;
+ vec[3 - srcPosition].buffer = (uint8_t*)&ipv4Layer->getIPv4Header()->ipDst;
+ vec[3 - srcPosition].len = 4;
+ vec[4].buffer = &(ipv4Layer->getIPv4Header()->protocol);
+ vec[4].len = 1;
+ }
+ else
+ {
+ IPv6Layer* ipv6Layer = packet->getLayerOfType<IPv6Layer>();
+ if (portSrc == portDst && (uint64_t)ipv6Layer->getIPv6Header()->ipDst < (uint64_t)ipv6Layer->getIPv6Header()->ipSrc)
+ srcPosition = 1;
+
+ vec[2 + srcPosition].buffer = ipv6Layer->getIPv6Header()->ipSrc;
+ vec[2 + srcPosition].len = 16;
+ vec[3 - srcPosition].buffer = ipv6Layer->getIPv6Header()->ipDst;
+ vec[3 - srcPosition].len = 16;
+ vec[4].buffer = &(ipv6Layer->getIPv6Header()->nextHeader);
+ vec[4].len = 1;
+ }
+
+ return pcpp::fnv_hash(vec, 5);
+}
+
+
+uint32_t hash2Tuple(Packet* packet)
+{
+ if (!packet->isPacketOfType(IPv4) && !packet->isPacketOfType(IPv6))
+ return 0;
+
+ ScalarBuffer<uint8_t> vec[2];
+
+ IPv4Layer* ipv4Layer = packet->getLayerOfType<IPv4Layer>();
+ if (ipv4Layer != NULL)
+ {
+ int srcPosition = 0;
+ if (ipv4Layer->getIPv4Header()->ipDst < ipv4Layer->getIPv4Header()->ipSrc)
+ srcPosition = 1;
+
+ vec[0 + srcPosition].buffer = (uint8_t*)&ipv4Layer->getIPv4Header()->ipSrc;
+ vec[0 + srcPosition].len = 4;
+ vec[1 - srcPosition].buffer = (uint8_t*)&ipv4Layer->getIPv4Header()->ipDst;
+ vec[1 - srcPosition].len = 4;
+ }
+ else
+ {
+ IPv6Layer* ipv6Layer = packet->getLayerOfType<IPv6Layer>();
+ int srcPosition = 0;
+ if ((uint64_t)ipv6Layer->getIPv6Header()->ipDst < (uint64_t)ipv6Layer->getIPv6Header()->ipSrc
+ && (uint64_t)(ipv6Layer->getIPv6Header()->ipDst+8) < (uint64_t)(ipv6Layer->getIPv6Header()->ipSrc+8))
+ srcPosition = 1;
+
+ vec[0 + srcPosition].buffer = ipv6Layer->getIPv6Header()->ipSrc;
+ vec[0 + srcPosition].len = 16;
+ vec[1 - srcPosition].buffer = ipv6Layer->getIPv6Header()->ipDst;
+ vec[1 - srcPosition].len = 16;
+ }
+
+ return pcpp::fnv_hash(vec, 2);
+}
+
+} // namespace pcpp
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/PayloadLayer.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/PayloadLayer.cpp b/thirdparty/pcap++/Packet++/src/PayloadLayer.cpp
new file mode 100644
index 0000000..ddeb47e
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/PayloadLayer.cpp
@@ -0,0 +1,26 @@
+#define LOG_MODULE PacketLogModulePayloadLayer
+
+#include <PayloadLayer.h>
+#include <string.h>
+#include <sstream>
+
+namespace pcpp
+{
+
+PayloadLayer::PayloadLayer(const uint8_t* data, size_t dataLen, bool dummy) : Layer()
+{
+ m_Data = new uint8_t[dataLen];
+ memcpy(m_Data, data, dataLen);
+ m_DataLen = dataLen;
+ m_Protocol = GenericPayolad;
+}
+
+std::string PayloadLayer::toString()
+{
+ std::ostringstream dataLenStream;
+ dataLenStream << m_DataLen;
+
+ return "Payload Layer, Data length: " + dataLenStream.str() + " [Bytes]";
+}
+
+} // namespace pcpp
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/c0a788b3/thirdparty/pcap++/Packet++/src/RawPacket.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/pcap++/Packet++/src/RawPacket.cpp b/thirdparty/pcap++/Packet++/src/RawPacket.cpp
new file mode 100644
index 0000000..17d73a8
--- /dev/null
+++ b/thirdparty/pcap++/Packet++/src/RawPacket.cpp
@@ -0,0 +1,200 @@
+#define LOG_MODULE PacketLogModuleRawPacket
+
+#include <RawPacket.h>
+#include <string.h>
+#include <Logger.h>
+
+namespace pcpp
+{
+
+void RawPacket::Init()
+{
+ m_pRawData = 0;
+ m_RawDataLen = 0;
+ m_DeleteRawDataAtDestructor = true;
+ m_RawPacketSet = false;
+ m_linkLayerType = LINKTYPE_ETHERNET;
+}
+
+RawPacket::RawPacket(const uint8_t* pRawData, int rawDataLen, timeval timestamp, bool deleteRawDataAtDestructor, LinkLayerType layerType)
+{
+ Init();
+ m_DeleteRawDataAtDestructor = deleteRawDataAtDestructor;
+ setRawData(pRawData, rawDataLen, timestamp, layerType);
+}
+
+RawPacket::RawPacket()
+{
+ Init();
+}
+
+RawPacket::~RawPacket()
+{
+ if (m_DeleteRawDataAtDestructor)
+ {
+ delete[] m_pRawData;
+ }
+}
+
+RawPacket::RawPacket(const RawPacket& other)
+{
+ copyDataFrom(other);
+}
+
+RawPacket& RawPacket::operator=(const RawPacket& other)
+{
+ if (m_pRawData != NULL)
+ delete [] m_pRawData;
+
+ m_RawPacketSet = false;
+
+ copyDataFrom(other);
+
+ return *this;
+}
+
+
+void RawPacket::copyDataFrom(const RawPacket& other, bool allocateData)
+{
+ if (!other.m_RawPacketSet)
+ return;
+
+ m_TimeStamp = other.m_TimeStamp;
+
+ if (allocateData)
+ {
+ m_DeleteRawDataAtDestructor = true;
+ m_pRawData = new uint8_t[other.m_RawDataLen];
+ m_RawDataLen = other.m_RawDataLen;
+ }
+
+ memcpy(m_pRawData, other.m_pRawData, other.m_RawDataLen);
+ m_linkLayerType = other.m_linkLayerType;
+ m_FrameLength = other.m_FrameLength;
+ m_RawPacketSet = true;
+}
+
+bool RawPacket::setRawData(const uint8_t* pRawData, int rawDataLen, timeval timestamp, LinkLayerType layerType, int frameLength)
+{
+ if(frameLength == -1)
+ frameLength = rawDataLen;
+ m_FrameLength = frameLength;
+ if (m_pRawData != 0 && m_DeleteRawDataAtDestructor)
+ {
+ delete[] m_pRawData;
+ }
+
+ m_pRawData = (uint8_t*)pRawData;
+ m_RawDataLen = rawDataLen;
+ m_TimeStamp = timestamp;
+ m_RawPacketSet = true;
+ m_linkLayerType = layerType;
+ return true;
+}
+
+const uint8_t* RawPacket::getRawData()
+{
+ return m_pRawData;
+}
+
+const uint8_t* RawPacket::getRawDataReadOnly() const
+{
+ return m_pRawData;
+}
+
+LinkLayerType RawPacket::getLinkLayerType() const
+{
+ return m_linkLayerType;
+}
+
+int RawPacket::getRawDataLen() const
+{
+ return m_RawDataLen;
+}
+
+int RawPacket::getFrameLength() const
+{
+ return m_FrameLength;
+}
+
+timeval RawPacket::getPacketTimeStamp()
+{
+ return m_TimeStamp;
+}
+
+void RawPacket::clear()
+{
+ if (m_pRawData != 0)
+ delete[] m_pRawData;
+
+ m_pRawData = 0;
+ m_RawDataLen = 0;
+ m_FrameLength = 0;
+ m_RawPacketSet = false;
+}
+
+void RawPacket::appendData(const uint8_t* dataToAppend, size_t dataToAppendLen)
+{
+ memcpy((uint8_t*)m_pRawData+m_RawDataLen, dataToAppend, dataToAppendLen);
+ m_RawDataLen += dataToAppendLen;
+ m_FrameLength = m_RawDataLen;
+}
+
+void RawPacket::insertData(int atIndex, const uint8_t* dataToInsert, size_t dataToInsertLen)
+{
+ int index = m_RawDataLen-1;
+ while (index >= atIndex)
+ {
+ m_pRawData[index+dataToInsertLen] = m_pRawData[index];
+ index--;
+ }
+
+ memcpy((uint8_t*)m_pRawData+atIndex, dataToInsert, dataToInsertLen);
+ m_RawDataLen += dataToInsertLen;
+ m_FrameLength = m_RawDataLen;
+}
+
+bool RawPacket::reallocateData(size_t newBufferLength)
+{
+ if ((int)newBufferLength == m_RawDataLen)
+ return true;
+
+ if ((int)newBufferLength < m_RawDataLen)
+ {
+ LOG_ERROR("Cannot reallocate raw packet to a smaller size. Current data length: %d; requested length: %d", m_RawDataLen, (int)newBufferLength);
+ return false;
+ }
+
+ uint8_t* newBuffer = new uint8_t[newBufferLength];
+ memset(newBuffer, 0, newBufferLength);
+ memcpy(newBuffer, m_pRawData, m_RawDataLen);
+ if (m_DeleteRawDataAtDestructor)
+ delete [] m_pRawData;
+
+ m_DeleteRawDataAtDestructor = true;
+ m_pRawData = newBuffer;
+
+ return true;
+}
+
+bool RawPacket::removeData(int atIndex, size_t numOfBytesToRemove)
+{
+ if ((atIndex + (int)numOfBytesToRemove) > m_RawDataLen)
+ {
+ LOG_ERROR("Remove section is out of raw packet bound");
+ return false;
+ }
+
+ int index = atIndex;
+ while (index < (m_RawDataLen - (int)numOfBytesToRemove))
+ {
+ m_pRawData[index] = m_pRawData[index+numOfBytesToRemove];
+ index++;
+ }
+
+ m_RawDataLen -= numOfBytesToRemove;
+ m_FrameLength = m_RawDataLen;
+ return true;
+}
+
+} // namespace pcpp