Coverage Report

Created: 2026-03-07 06:49

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