Coverage Report

Created: 2026-11-12 06:50

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
  constexpr uint8_t NflogFamilyIpv4 = 2;
14
  /// IPv6 protocol
15
  constexpr uint8_t NflogFamilyIpv6 = 10;
16
17
  uint8_t NflogLayer::getFamily() const
18
192
  {
19
192
    return getNflogHeader()->addressFamily;
20
192
  }
21
22
  uint8_t NflogLayer::getVersion() const
23
0
  {
24
0
    return getNflogHeader()->version;
25
0
  }
26
27
  uint16_t NflogLayer::getResourceId() const
28
0
  {
29
0
    return be16toh(getNflogHeader()->resourceId);
30
0
  }
31
32
  NflogTlv NflogLayer::getTlvByType(NflogTlvType type) const
33
4.47k
  {
34
4.47k
    const auto typeNum = static_cast<uint32_t>(type);
35
4.47k
    NflogTlv tlv = m_TlvReader.getTLVRecord(typeNum, getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
36
37
4.47k
    return tlv;
38
4.47k
  }
39
40
  void NflogLayer::parseNextLayer()
41
4.69k
  {
42
4.69k
    if (m_DataLen <= sizeof(nflog_header))
43
218
    {
44
218
      return;
45
218
    }
46
4.47k
    auto payloadInfo = getTlvByType(NflogTlvType::NFULA_PAYLOAD);
47
4.47k
    if (payloadInfo.isNull())
48
4.28k
    {
49
4.28k
      return;
50
4.28k
    }
51
52
192
    uint8_t* payload = payloadInfo.getValue();
53
192
    size_t payloadLen = payloadInfo.getTotalSize() - sizeof(uint16_t) * 2;
54
55
192
    uint8_t family = getFamily();
56
57
192
    switch (family)
58
192
    {
59
165
    case NflogFamilyIpv4:
60
165
    {
61
165
      tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
62
165
      break;
63
0
    }
64
0
    case NflogFamilyIpv6:
65
0
    {
66
0
      tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
67
0
      break;
68
0
    }
69
27
    default:
70
27
    {
71
27
      constructNextLayer<PayloadLayer>(payload, payloadLen);
72
27
      break;
73
0
    }
74
192
    }
75
192
  }
76
77
  size_t NflogLayer::getHeaderLen() const
78
2.33k
  {
79
2.33k
    size_t headerLen = sizeof(nflog_header);
80
2.33k
    NflogTlv currentTLV = m_TlvReader.getFirstTLVRecord(getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
81
82
4.79k
    while (!currentTLV.isNull() && currentTLV.getType() != static_cast<uint16_t>(NflogTlvType::NFULA_PAYLOAD))
83
2.46k
    {
84
2.46k
      headerLen += currentTLV.getTotalSize();
85
2.46k
      currentTLV = m_TlvReader.getNextTLVRecord(currentTLV, getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
86
2.46k
    }
87
2.33k
    if (!currentTLV.isNull() && currentTLV.getType() == static_cast<uint16_t>(NflogTlvType::NFULA_PAYLOAD))
88
83
    {
89
      // for the length and type of the payload TLV
90
83
      headerLen += 2 * sizeof(uint16_t);
91
83
    }
92
    // nflog_header has not a form of TLV and contains 3 fields (family, resource_id, version)
93
2.33k
    return headerLen;
94
2.33k
  }
95
96
  std::string NflogLayer::toString() const
97
4.57k
  {
98
4.57k
    return "Linux Netfilter NFLOG";
99
4.57k
  }
100
101
  bool NflogLayer::isDataValid(const uint8_t* data, size_t dataLen)
102
4.89k
  {
103
4.89k
    return data && dataLen >= sizeof(nflog_header);
104
4.89k
  }
105
106
  const FieldDescriptor NflogLayer::SerializedFields::Family{ Layer::SerializedFields::MaxID + 1, "family" };
107
  const FieldDescriptor NflogLayer::SerializedFields::Version{ Layer::SerializedFields::MaxID + 2, "version" };
108
  const FieldDescriptor NflogLayer::SerializedFields::ResourceID{ Layer::SerializedFields::MaxID + 3, "resourceID" };
109
  const FieldDescriptor NflogLayer::SerializedFields::Attributes{ Layer::SerializedFields::MaxID + 4, "attributes" };
110
  const FieldDescriptor NflogLayer::SerializedFields::Attribute{ 0, "attribute" };
111
112
  static const char* getAttributeTypeAsString(const NflogTlv& attribute)
113
0
  {
114
0
    switch (attribute.getType())
115
0
    {
116
0
    case 1:
117
0
      return "NFULA_PACKET_HDR";
118
0
    case 2:
119
0
      return "NFULA_MARK";
120
0
    case 3:
121
0
      return "NFULA_TIMESTAMP";
122
0
    case 4:
123
0
      return "NFULA_IFINDEX_INDEV";
124
0
    case 5:
125
0
      return "NFULA_IFINDEX_OUTDEV";
126
0
    case 6:
127
0
      return "NFULA_IFINDEX_PHYSINDEV";
128
0
    case 7:
129
0
      return "NFULA_IFINDEX_PHYSOUTDEV";
130
0
    case 8:
131
0
      return "NFULA_HWADDR";
132
0
    case 9:
133
0
      return "NFULA_PAYLOAD";
134
0
    case 10:
135
0
      return "NFULA_PREFIX";
136
0
    case 11:
137
0
      return "NFULA_UID";
138
0
    case 12:
139
0
      return "NFULA_SEQ";
140
0
    case 13:
141
0
      return "NFULA_SEQ_GLOBAL";
142
0
    case 14:
143
0
      return "NFULA_GID";
144
0
    case 15:
145
0
      return "NFULA_HWTYPE";
146
0
    case 16:
147
0
      return "NFULA_HWHEADER";
148
0
    case 17:
149
0
      return "NFULA_HWLEN";
150
0
    default:
151
0
      return "Unknown";
152
0
    }
153
0
  }
154
155
  void NflogLayer::serializeLayer(ObjectScope& serializer) const
156
0
  {
157
0
    serializer.writeField(SerializedFields::Family, getFamily());
158
0
    serializer.writeField(SerializedFields::Version, getVersion());
159
0
    serializer.writeField(SerializedFields::ResourceID, getResourceId());
160
0
    {
161
0
      auto attributesArray = serializer.writeArray(SerializedFields::Attributes);
162
0
      for (auto currentAttr = m_TlvReader.getFirstTLVRecord(getTlvsBasePtr(), m_DataLen - sizeof(nflog_header));
163
0
           !currentAttr.isNull(); currentAttr = m_TlvReader.getNextTLVRecord(currentAttr, getTlvsBasePtr(),
164
0
                                                                             m_DataLen - sizeof(nflog_header)))
165
0
      {
166
0
        attributesArray.writeField(SerializedFields::Attribute, getAttributeTypeAsString(currentAttr));
167
0
      }
168
0
    }
169
0
  }
170
}  // namespace pcpp