#define LOG_MODULE PacketLogModuleIPSecLayer
#include "EndianPortable.h"
#include "GeneralUtils.h"
#include "IPSecLayer.h"
#include "IPv4Layer.h"
#include "IPv6Layer.h"
#include "UdpLayer.h"
#include "TcpLayer.h"
#include "PayloadLayer.h"
#include <sstream>
namespace pcpp
{
uint32_t AuthenticationHeaderLayer::getSPI() const
{
return be32toh(getAHHeader()->spi);
}
uint32_t AuthenticationHeaderLayer::getSequenceNumber() const
{
return be32toh(getAHHeader()->sequenceNumber);
}
size_t AuthenticationHeaderLayer::getICVLength() const
{
return (getAHHeader()->payloadLen - 1)*4;
}
uint8_t* AuthenticationHeaderLayer::getICVBytes() const
{
size_t icvLength = getICVLength();
if (icvLength > 0)
return m_Data + sizeof(ipsec_authentication_header);
return nullptr;
}
std::string AuthenticationHeaderLayer::getICVHexStream() const
{
uint8_t* bytes = getICVBytes();
if (bytes == nullptr)
return "";
return byteArrayToHexString(bytes, getICVLength());
}
void AuthenticationHeaderLayer::parseNextLayer()
{
size_t headerLen = getHeaderLen();
if (m_DataLen <= headerLen)
return;
uint8_t* payload = m_Data + headerLen;
size_t payloadLen = m_DataLen - headerLen;
switch (getAHHeader()->nextHeader)
{
case PACKETPP_IPPROTO_UDP:
if (payloadLen >= sizeof(udphdr))
m_NextLayer = new UdpLayer(payload, payloadLen, this, m_Packet);
break;
case PACKETPP_IPPROTO_TCP:
m_NextLayer = TcpLayer::isDataValid(payload, payloadLen)
? static_cast<Layer*>(new TcpLayer(payload, payloadLen, this, m_Packet))
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
break;
case PACKETPP_IPPROTO_IPIP:
{
uint8_t ipVersion = *payload >> 4;
if (ipVersion == 4 && IPv4Layer::isDataValid(payload, payloadLen))
m_NextLayer = new IPv4Layer(payload, payloadLen, this, m_Packet);
else if (ipVersion == 6 && IPv6Layer::isDataValid(payload, payloadLen))
m_NextLayer = new IPv6Layer(payload, payloadLen, this, m_Packet);
else
m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);
break;
}
case PACKETPP_IPPROTO_ESP:
m_NextLayer = ESPLayer::isDataValid(payload, payloadLen)
? static_cast<Layer*>(new ESPLayer(payload, payloadLen, this, m_Packet))
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
break;
default:
m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);
}
}
std::string AuthenticationHeaderLayer::toString() const
{
return "Authentication Header Layer";
}
uint32_t ESPLayer::getSPI() const
{
return be32toh(getESPHeader()->spi);
}
uint32_t ESPLayer::getSequenceNumber() const
{
return be32toh(getESPHeader()->sequenceNumber);
}
void ESPLayer::parseNextLayer()
{
size_t headerLen = getHeaderLen();
if (m_DataLen <= headerLen)
return;
m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet);
}
std::string ESPLayer::toString() const
{
std::ostringstream stream;
stream << "ESP Layer, SPI: 0x" << std::hex << getSPI();
return stream.str();
}
}