/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 |