Coverage Report

Created: 2025-11-16 07:13

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