Coverage Report

Created: 2024-02-25 06:29

/src/PcapPlusPlus/Packet++/src/NflogLayer.cpp
Line
Count
Source (jump to first uncovered line)
1
#define LOG_MODULE PacketLogModuleNflogLayer
2
3
#include "NflogLayer.h"
4
#include "IPv4Layer.h"
5
#include "IPv6Layer.h"
6
#include "PayloadLayer.h"
7
#include "GeneralUtils.h"
8
#include "EndianPortable.h"
9
10
#include <string.h>
11
12
13
namespace pcpp
14
{
15
  /** IPv4 protocol */
16
4
  #define PCPP_WS_NFPROTO_IPV4    2
17
  /** IPv6 protocol */
18
8
  #define PCPP_WS_NFPROTO_IPV6    10
19
20
21
uint8_t NflogLayer::getFamily()
22
201
{
23
201
  return getNflogHeader()->addressFamily;
24
201
}
25
26
uint8_t NflogLayer::getVersion()
27
0
{
28
0
  return getNflogHeader()->version;
29
0
}
30
31
uint16_t NflogLayer::getResourceId()
32
0
{
33
0
  return be16toh(getNflogHeader()->resourceId);
34
0
}
35
36
NflogTlv NflogLayer::getTlvByType(NflogTlvType type) const
37
2.29k
{
38
2.29k
  NflogTlv tlv = m_TlvReader.getTLVRecord(
39
2.29k
    static_cast<uint32_t> (type),
40
2.29k
    getTlvsBasePtr(),
41
2.29k
    m_DataLen - sizeof(nflog_header));
42
43
2.29k
  return tlv;
44
2.29k
}
45
46
void NflogLayer::parseNextLayer()
47
2.88k
{
48
2.88k
  if (m_DataLen <= sizeof(nflog_header))
49
586
    return;
50
2.29k
  auto payloadInfo = getTlvByType(NflogTlvType::NFULA_PAYLOAD);
51
2.29k
  if (payloadInfo.isNull())
52
2.09k
  {
53
2.09k
    return;
54
2.09k
  }
55
56
201
  uint8_t* payload = payloadInfo.getValue();
57
201
  size_t payloadLen = payloadInfo.getTotalSize() - sizeof(uint16_t) * 2;
58
59
201
  uint8_t family = getFamily();
60
61
201
  switch (family)
62
201
  {
63
4
  case PCPP_WS_NFPROTO_IPV4:
64
4
    m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
65
4
      ? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, m_Packet))
66
4
      : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
67
4
    break;
68
8
  case PCPP_WS_NFPROTO_IPV6:
69
8
    m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
70
8
      ? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, m_Packet))
71
8
      : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
72
8
    break;
73
189
  default:
74
189
    m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);
75
201
  }
76
77
201
}
78
79
size_t NflogLayer::getHeaderLen() const
80
1.40k
{
81
1.40k
  size_t headerLen = sizeof(nflog_header);
82
1.40k
  NflogTlv currentTLV =  m_TlvReader.getFirstTLVRecord(
83
1.40k
    getTlvsBasePtr(),
84
1.40k
    m_DataLen - sizeof(nflog_header));
85
86
2.13k
  while (!currentTLV.isNull() && currentTLV.getType() != static_cast<uint16_t> (NflogTlvType::NFULA_PAYLOAD))
87
729
  {
88
729
    headerLen += currentTLV.getTotalSize();
89
729
    currentTLV = m_TlvReader.getNextTLVRecord(currentTLV, getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
90
729
  }
91
1.40k
  if (!currentTLV.isNull() && currentTLV.getType() == static_cast<uint16_t> (NflogTlvType::NFULA_PAYLOAD))
92
66
  {
93
    // for the length and type of the payload TLV
94
66
    headerLen += 2 * sizeof (uint16_t);
95
66
  }
96
  // nflog_header has not a form of TLV and contains 3 fields (family, resource_id, version)
97
1.40k
  return headerLen;
98
1.40k
}
99
100
std::string NflogLayer::toString() const
101
2.81k
{
102
2.81k
  return "Linux Netfilter NFLOG";
103
2.81k
}
104
105
bool NflogLayer::isDataValid(const uint8_t* data, size_t dataLen)
106
2.90k
{
107
2.90k
  return data && dataLen >= sizeof(nflog_header);
108
2.90k
}
109
110
} // namespace pcpp