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