Coverage Report

Created: 2026-02-14 06:19

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
681
#define PCPP_WS_NFPROTO_IPV4 2
14
/// IPv6 protocol
15
7
#define PCPP_WS_NFPROTO_IPV6 10
16
17
  uint8_t NflogLayer::getFamily()
18
698
  {
19
698
    return getNflogHeader()->addressFamily;
20
698
  }
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.88k
  {
34
1.88k
    const auto typeNum = static_cast<uint32_t>(type);
35
1.88k
    NflogTlv tlv = m_TlvReader.getTLVRecord(typeNum, getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
36
37
1.88k
    return tlv;
38
1.88k
  }
39
40
  void NflogLayer::parseNextLayer()
41
2.05k
  {
42
2.05k
    if (m_DataLen <= sizeof(nflog_header))
43
168
    {
44
168
      return;
45
168
    }
46
1.88k
    auto payloadInfo = getTlvByType(NflogTlvType::NFULA_PAYLOAD);
47
1.88k
    if (payloadInfo.isNull())
48
1.18k
    {
49
1.18k
      return;
50
1.18k
    }
51
52
698
    uint8_t* payload = payloadInfo.getValue();
53
698
    size_t payloadLen = payloadInfo.getTotalSize() - sizeof(uint16_t) * 2;
54
55
698
    uint8_t family = getFamily();
56
57
698
    switch (family)
58
698
    {
59
681
    case PCPP_WS_NFPROTO_IPV4:
60
681
    {
61
681
      tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
62
681
      break;
63
0
    }
64
7
    case PCPP_WS_NFPROTO_IPV6:
65
7
    {
66
7
      tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
67
7
      break;
68
0
    }
69
10
    default:
70
10
    {
71
10
      constructNextLayer<PayloadLayer>(payload, payloadLen);
72
10
      break;
73
0
    }
74
698
    }
75
698
  }
76
77
  size_t NflogLayer::getHeaderLen() const
78
1.15k
  {
79
1.15k
    size_t headerLen = sizeof(nflog_header);
80
1.15k
    NflogTlv currentTLV = m_TlvReader.getFirstTLVRecord(getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
81
82
3.79k
    while (!currentTLV.isNull() && currentTLV.getType() != static_cast<uint16_t>(NflogTlvType::NFULA_PAYLOAD))
83
2.63k
    {
84
2.63k
      headerLen += currentTLV.getTotalSize();
85
2.63k
      currentTLV = m_TlvReader.getNextTLVRecord(currentTLV, getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
86
2.63k
    }
87
1.15k
    if (!currentTLV.isNull() && currentTLV.getType() == static_cast<uint16_t>(NflogTlvType::NFULA_PAYLOAD))
88
480
    {
89
      // for the length and type of the payload TLV
90
480
      headerLen += 2 * sizeof(uint16_t);
91
480
    }
92
    // nflog_header has not a form of TLV and contains 3 fields (family, resource_id, version)
93
1.15k
    return headerLen;
94
1.15k
  }
95
96
  std::string NflogLayer::toString() const
97
1.59k
  {
98
1.59k
    return "Linux Netfilter NFLOG";
99
1.59k
  }
100
101
  bool NflogLayer::isDataValid(const uint8_t* data, size_t dataLen)
102
2.06k
  {
103
2.06k
    return data && dataLen >= sizeof(nflog_header);
104
2.06k
  }
105
106
}  // namespace pcpp