Coverage Report

Created: 2026-05-30 07:22

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
2.11k
  {
34
2.11k
    const auto typeNum = static_cast<uint32_t>(type);
35
2.11k
    NflogTlv tlv = m_TlvReader.getTLVRecord(typeNum, getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
36
37
2.11k
    return tlv;
38
2.11k
  }
39
40
  void NflogLayer::parseNextLayer()
41
2.18k
  {
42
2.18k
    if (m_DataLen <= sizeof(nflog_header))
43
68
    {
44
68
      return;
45
68
    }
46
2.11k
    auto payloadInfo = getTlvByType(NflogTlvType::NFULA_PAYLOAD);
47
2.11k
    if (payloadInfo.isNull())
48
2.11k
    {
49
2.11k
      return;
50
2.11k
    }
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
    {
61
0
      tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
62
0
      break;
63
0
    }
64
0
    case PCPP_WS_NFPROTO_IPV6:
65
0
    {
66
0
      tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
67
0
      break;
68
0
    }
69
0
    default:
70
0
    {
71
0
      constructNextLayer<PayloadLayer>(payload, payloadLen);
72
0
      break;
73
0
    }
74
0
    }
75
0
  }
76
77
  size_t NflogLayer::getHeaderLen() const
78
1.09k
  {
79
1.09k
    size_t headerLen = sizeof(nflog_header);
80
1.09k
    NflogTlv currentTLV = m_TlvReader.getFirstTLVRecord(getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
81
82
1.84k
    while (!currentTLV.isNull() && currentTLV.getType() != static_cast<uint16_t>(NflogTlvType::NFULA_PAYLOAD))
83
754
    {
84
754
      headerLen += currentTLV.getTotalSize();
85
754
      currentTLV = m_TlvReader.getNextTLVRecord(currentTLV, getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
86
754
    }
87
1.09k
    if (!currentTLV.isNull() && currentTLV.getType() == static_cast<uint16_t>(NflogTlvType::NFULA_PAYLOAD))
88
0
    {
89
      // for the length and type of the payload TLV
90
0
      headerLen += 2 * sizeof(uint16_t);
91
0
    }
92
    // nflog_header has not a form of TLV and contains 3 fields (family, resource_id, version)
93
1.09k
    return headerLen;
94
1.09k
  }
95
96
  std::string NflogLayer::toString() const
97
2.18k
  {
98
2.18k
    return "Linux Netfilter NFLOG";
99
2.18k
  }
100
101
  bool NflogLayer::isDataValid(const uint8_t* data, size_t dataLen)
102
2.38k
  {
103
2.38k
    return data && dataLen >= sizeof(nflog_header);
104
2.38k
  }
105
106
}  // namespace pcpp