Coverage Report

Created: 2024-02-25 06:29

/src/PcapPlusPlus/Packet++/header/NflogLayer.h
Line
Count
Source
1
#pragma once
2
3
#include "Layer.h"
4
#include "TLVData.h"
5
#include "GeneralUtils.h"
6
7
/// @file
8
9
/**
10
 * \namespace pcpp
11
 * \brief The main namespace for the PcapPlusPlus lib
12
 */
13
namespace pcpp
14
{
15
  /**
16
   * @struct nflog_header
17
   * Represents Nflog header
18
   */
19
#pragma pack(push, 1)
20
  struct nflog_header
21
  {
22
    /** A Linux AF_ value, so it's 2 for IPv4 and 10 for IPv6 */
23
    uint8_t addressFamily;
24
    /** The version field is 0 for the current version of the pseudo-header */
25
    uint8_t version;
26
    /** The network byte order (big-endian) */
27
    uint16_t resourceId;
28
  };
29
#pragma pack(pop)
30
31
  /**
32
   * @enum NflogTlvType
33
   * Represents TLV types of NFLOG packets
34
  */
35
  enum class NflogTlvType
36
  {
37
    /** the packet header structure */
38
    NFULA_PACKET_HDR      = 1,
39
    /** packet mark from skbuff */
40
    NFULA_MARK          = 2,
41
    /** nflog_timestamp_t for skbuff's time stamp */
42
    NFULA_TIMESTAMP       = 3,
43
    /** ifindex of device on which packet received (possibly bridge group) */
44
    NFULA_IFINDEX_INDEV     = 4,
45
    /** ifindex of device on which packet transmitted (possibly bridge group) */
46
    NFULA_IFINDEX_OUTDEV    = 5,
47
    /** ifindex of physical device on which packet received (not bridge group) */
48
    NFULA_IFINDEX_PHYSINDEV   = 6,
49
    /** ifindex of physical device on which packet transmitted (not bridge group) */
50
    NFULA_IFINDEX_PHYSOUTDEV  = 7,
51
    /** nflog_hwaddr_t for hardware address */
52
    NFULA_HWADDR        = 8,
53
    /** packet payload */
54
    NFULA_PAYLOAD       = 9,
55
    /** text string - null-terminated, count includes NUL */
56
    NFULA_PREFIX        = 10,
57
    /** UID owning socket on which packet was sent/received */
58
    NFULA_UID         = 11,
59
    /** sequence number of packets on this NFLOG socket */
60
    NFULA_SEQ         = 12,
61
    /** sequence number of packets on all NFLOG sockets */
62
    NFULA_SEQ_GLOBAL      = 13,
63
    /** GID owning socket on which packet was sent/received */
64
    NFULA_GID         = 14,
65
    /** ARPHRD_ type of skbuff's device */
66
    NFULA_HWTYPE        = 15,
67
    /** skbuff's MAC-layer header */
68
    NFULA_HWHEADER        = 16,
69
    /** length of skbuff's MAC-layer header */
70
    NFULA_HWLEN         = 17,
71
  };
72
73
  /**
74
   * @class NflogTlv
75
   * A wrapper class for NFLOG TLV fields. This class does not create or modify TLVs related to NFLOG, but rather
76
   * serves as a wrapper and provides useful methods for setting and retrieving data to/from them
77
   */
78
  class NflogTlv
79
  {
80
  private:
81
    struct NflogTLVRawData
82
    {
83
      /** Record length in bytes */
84
      uint16_t recordLen;
85
      /** Record type */
86
      uint16_t recordType;
87
      /** Record value (variable size) */
88
      uint8_t recordValue[];
89
    };
90
    NflogTLVRawData* m_Data;
91
  public:
92
    /**
93
     * A c'tor for this class that gets a pointer to the option raw data (byte array)
94
     * @param[in] recordRawData A pointer to the option raw data
95
     */
96
    explicit NflogTlv(uint8_t* recordRawData)
97
5.89k
    {
98
5.89k
      assign(recordRawData);
99
5.89k
    }
100
101
    /**
102
     * @return recordLen attribute in NflogTLVRawData
103
     */
104
    size_t getTotalSize() const
105
14.2k
    {
106
      // as in https://github.com/the-tcpdump-group/libpcap/blob/766b607d60d8038087b49fc4cf433dac3dcdb49c/pcap-util.c#L371-L374
107
14.2k
      return align<4>(m_Data->recordLen);
108
14.2k
    }
109
110
    /**
111
     * Assign a pointer to the TLV record raw data (byte array)
112
     * @param[in] recordRawData A pointer to the TLV record raw data
113
     */
114
    void assign(uint8_t* recordRawData)
115
13.7k
    {
116
13.7k
      m_Data = (NflogTLVRawData*)recordRawData;
117
13.7k
    }
118
119
    /**
120
     * Check if a pointer can be assigned to the TLV record data
121
     * @param[in] recordRawData A pointer to the TLV record raw data
122
     * @param[in] tlvDataLen The size of the TLV record raw data
123
     * * @return True if data is valid and can be assigned
124
     */
125
    static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
126
5.89k
    {
127
5.89k
      return recordRawData != nullptr && tlvDataLen >= sizeof(NflogTLVRawData::recordLen);
128
5.89k
    }
129
130
    /**
131
     * @return True if the TLV record raw data is nullptr, false otherwise
132
     */
133
    bool isNull() const
134
15.5k
    {
135
15.5k
      return (m_Data == nullptr);
136
15.5k
    }
137
138
    /**
139
     * @return The type field of the record (the 'T' in __Type__-Length-Value)
140
     */
141
2.52k
    uint16_t getType() const { return m_Data->recordType; }
142
143
    /**
144
     * @return A pointer to the TLV record raw data byte stream
145
     */
146
11.7k
    uint8_t* getRecordBasePtr() const { return (uint8_t*)m_Data; }
147
148
    /**
149
     * @return A pointer to the value of the record as byte array (the 'V' in Type-Length- __Value__)
150
     */
151
201
    uint8_t* getValue() const { return m_Data->recordValue; }
152
  };
153
154
  /**
155
   * @class NflogLayer
156
   * Represents an NFLOG protocol layer
157
   */
158
  class NflogLayer : public Layer
159
  {
160
  public:
161
    /**
162
     * A constructor that creates the layer from an existing packet raw data
163
     * @param[in] data A pointer to the raw data (will be casted to ether_header)
164
     * @param[in] dataLen Size of the data in bytes
165
     * @param[in] packet A pointer to the Packet instance where layer will be stored in
166
     */
167
2.88k
    NflogLayer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, NULL, packet) { m_Protocol = NFLOG; }
168
169
2.88k
    ~NflogLayer() {}
170
171
    /**
172
     * Get a pointer to the Nflog header.
173
     * @return A pointer to the nflog_header
174
     */
175
201
    nflog_header* getNflogHeader() const { return (nflog_header*)m_Data; }
176
177
    /**
178
     * Get address family of the packet. e.g. 2 for ipv4 and 10 for ipv6
179
     * @return an unsigned char of address family
180
    */
181
    uint8_t getFamily();
182
183
    /**
184
     * Get Version number inside packet header
185
     * The version field is 0 for the current version of the pseudo-header
186
     * @return an unsigned char for version
187
    */
188
    uint8_t getVersion();
189
190
    /**
191
     * Get Resource Id in packet header
192
     * On one netlink socket it's possible to listen to several nflog groups; the resource ID is the nflog group for the packet
193
    */
194
    uint16_t getResourceId();
195
196
    /**
197
     * Get a TLV object found with the input type. if no tlv is found, the internal value of the object will set to nullptr
198
     * @param[in] type type of tlv by using enum class defined as NflogTlvType
199
     * @return NflogTlv obtained by type
200
    */
201
    NflogTlv getTlvByType(NflogTlvType type) const;
202
203
    // implement abstract methods
204
205
    /**
206
     * Currently identifies the following next layers: IPv4Layer, IPv6Layer using address family
207
     * Otherwise sets PayloadLayer
208
     */
209
    void parseNextLayer();
210
211
    /**
212
     * @return Size of nflog_header
213
     */
214
    size_t getHeaderLen() const;
215
216
    /**
217
     * Does nothing for this layer
218
    */
219
1.40k
    void computeCalculateFields() {};
220
221
    std::string toString() const;
222
223
1.40k
    OsiModelLayer getOsiModelLayer() const { return OsiModelDataLinkLayer; }
224
225
    /**
226
    * A static method that validates the input data
227
    * @param[in] data The pointer to the beginning of a byte stream of an NFLOG packet
228
    * @param[in] dataLen The length of the byte stream
229
    * @return True if the data is valid and can represent an NFLOG packet
230
    */
231
    static bool isDataValid(const uint8_t* data, size_t dataLen);
232
233
  private:
234
4.43k
    uint8_t* getTlvsBasePtr() const { return m_Data + sizeof(nflog_header); }
235
236
    TLVRecordReader<NflogTlv> m_TlvReader;
237
  };
238
239
} // namespace pcpp