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