/src/wireshark/epan/dissectors/packet-nflog.c
Line | Count | Source |
1 | | /* packet-nflog.c |
2 | | * Copyright 2011,2012 Jakub Zawadzki <darkjames-ws@darkjames.pl> |
3 | | * |
4 | | * Wireshark - Network traffic analyzer |
5 | | * By Gerald Combs <gerald@wireshark.org> |
6 | | * Copyright 1998 |
7 | | * |
8 | | * SPDX-License-Identifier: GPL-2.0-or-later |
9 | | */ |
10 | | #include "config.h" |
11 | | |
12 | | #include <epan/etypes.h> |
13 | | #include <epan/packet.h> |
14 | | #include <wiretap/wtap.h> |
15 | | #include <wsutil/ws_roundup.h> |
16 | | |
17 | | #include "packet-arp.h" |
18 | | #include "packet-netlink.h" |
19 | | |
20 | | void proto_register_nflog(void); |
21 | | void proto_reg_handoff_nflog(void); |
22 | | |
23 | | /* nfulnl_attr_type enum from <linux/netfilter/nfnetlink_log.h> */ |
24 | | enum ws_nfulnl_attr_type { |
25 | | WS_NFULA_UNSPEC, |
26 | | WS_NFULA_PACKET_HDR, |
27 | | WS_NFULA_MARK, /* __u32 nfmark */ |
28 | | WS_NFULA_TIMESTAMP, /* nfulnl_msg_packet_timestamp */ |
29 | | WS_NFULA_IFINDEX_INDEV, /* __u32 ifindex */ |
30 | | WS_NFULA_IFINDEX_OUTDEV, /* __u32 ifindex */ |
31 | | WS_NFULA_IFINDEX_PHYSINDEV, /* __u32 ifindex */ |
32 | | WS_NFULA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */ |
33 | | WS_NFULA_HWADDR, /* nfulnl_msg_packet_hw */ |
34 | | WS_NFULA_PAYLOAD, /* opaque data payload */ |
35 | | WS_NFULA_PREFIX, /* string prefix */ |
36 | | WS_NFULA_UID, /* user id of socket */ |
37 | | WS_NFULA_SEQ, /* instance-local sequence number */ |
38 | | WS_NFULA_SEQ_GLOBAL, /* global sequence number */ |
39 | | WS_NFULA_GID, /* group id of socket */ |
40 | | WS_NFULA_HWTYPE, /* hardware type */ |
41 | | WS_NFULA_HWHEADER, /* hardware header */ |
42 | | WS_NFULA_HWLEN, /* hardware header length */ |
43 | | WS_NFULA_CT, /* nfnetlink_conntrack.h */ |
44 | | WS_NFULA_CT_INFO, /* enum ip_conntrack_info */ |
45 | | }; |
46 | | |
47 | | static const value_string nflog_tlv_vals[] = { |
48 | | { WS_NFULA_UNSPEC, "NFULA_UNSPEC" }, |
49 | | { WS_NFULA_PACKET_HDR, "NFULA_PACKET_HDR" }, |
50 | | { WS_NFULA_MARK, "NFULA_MARK" }, |
51 | | { WS_NFULA_TIMESTAMP, "NFULA_TIMESTAMP" }, |
52 | | { WS_NFULA_IFINDEX_INDEV, "NFULA_IFINDEX_INDEV" }, |
53 | | { WS_NFULA_IFINDEX_OUTDEV, "NFULA_IFINDEX_OUTDEV" }, |
54 | | { WS_NFULA_IFINDEX_PHYSINDEV, "NFULA_IFINDEX_PHYSINDEV" }, |
55 | | { WS_NFULA_IFINDEX_PHYSOUTDEV, "NFULA_IFINDEX_PHYSOUTDEV" }, |
56 | | { WS_NFULA_HWADDR, "NFULA_HWADDR" }, |
57 | | { WS_NFULA_PAYLOAD, "NFULA_PAYLOAD" }, |
58 | | { WS_NFULA_PREFIX, "NFULA_PREFIX" }, |
59 | | { WS_NFULA_UID, "NFULA_UID" }, |
60 | | { WS_NFULA_SEQ, "NFULA_SEQ" }, |
61 | | { WS_NFULA_SEQ_GLOBAL, "NFULA_SEQ_GLOBAL" }, |
62 | | { WS_NFULA_GID, "NFULA_GID" }, |
63 | | { WS_NFULA_HWTYPE, "NFULA_HWTYPE" }, |
64 | | { WS_NFULA_HWHEADER, "NFULA_HWHEADER" }, |
65 | | { WS_NFULA_HWLEN, "NFULA_HWLEN" }, |
66 | | { WS_NFULA_CT, "NFULA_CT" }, |
67 | | { WS_NFULA_CT_INFO, "NFULA_CT_INFO" }, |
68 | | { 0, NULL } |
69 | | }; |
70 | | |
71 | | static int proto_nflog; |
72 | | |
73 | | static int hf_nflog_tlv_ct; |
74 | | static int hf_nflog_tlv_ct_info; |
75 | | static int hf_nflog_family; |
76 | | static int hf_nflog_resid; |
77 | | static int hf_nflog_tlv; |
78 | | static int hf_nflog_tlv_gid; |
79 | | static int hf_nflog_tlv_hook; |
80 | | static int hf_nflog_tlv_hw_type; |
81 | | static int hf_nflog_tlv_hwheader_len; |
82 | | static int hf_nflog_tlv_hwprotocol; |
83 | | static int hf_nflog_tlv_ifindex_indev; |
84 | | static int hf_nflog_tlv_ifindex_outdev; |
85 | | static int hf_nflog_tlv_ifindex_physindev; |
86 | | static int hf_nflog_tlv_ifindex_physoutdev; |
87 | | static int hf_nflog_tlv_length; |
88 | | static int hf_nflog_tlv_prefix; |
89 | | static int hf_nflog_tlv_timestamp; |
90 | | static int hf_nflog_tlv_type; |
91 | | static int hf_nflog_tlv_uid; |
92 | | static int hf_nflog_tlv_unknown; |
93 | | static int hf_nflog_version; |
94 | | |
95 | | static int ett_nflog; |
96 | | static int ett_nflog_tlv; |
97 | | |
98 | | static dissector_handle_t ip_handle; |
99 | | static dissector_handle_t ip6_handle; |
100 | | static dissector_handle_t eth_handle; |
101 | | static dissector_table_t ethertype_table; |
102 | | static dissector_handle_t nflog_handle; |
103 | | |
104 | | static bool eth_ip_layout_inside = true; |
105 | | |
106 | | static int |
107 | | dissect_nflog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
108 | 1 | { |
109 | 1 | const int start_tlv_offset = 4; |
110 | | |
111 | 1 | proto_tree *nflog_tree = NULL; |
112 | 1 | proto_item *ti; |
113 | | |
114 | 1 | unsigned offset = 0; |
115 | | |
116 | 1 | struct { |
117 | 1 | proto_tree *parent; |
118 | 1 | tvbuff_t *buffer; |
119 | 1 | } payload = {NULL, NULL}, hwheader = {NULL, NULL}; |
120 | | |
121 | 1 | int pf; |
122 | 1 | uint16_t hw_protocol = 0; |
123 | | |
124 | 1 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "NFLOG"); |
125 | 1 | col_clear(pinfo->cinfo, COL_INFO); |
126 | | |
127 | 1 | pf = tvb_get_uint8(tvb, 0); |
128 | | |
129 | | /* Header */ |
130 | 1 | if (proto_field_is_referenced(tree, proto_nflog)) { |
131 | 1 | ti = proto_tree_add_item(tree, proto_nflog, tvb, 0, -1, ENC_NA); |
132 | 1 | nflog_tree = proto_item_add_subtree(ti, ett_nflog); |
133 | | |
134 | 1 | proto_tree_add_item(nflog_tree, hf_nflog_family, tvb, offset, 1, ENC_NA); |
135 | 1 | offset += 1; |
136 | | |
137 | 1 | proto_tree_add_item(nflog_tree, hf_nflog_version, tvb, offset, 1, ENC_NA); |
138 | 1 | offset += 1; |
139 | | |
140 | 1 | proto_tree_add_item(nflog_tree, hf_nflog_resid, tvb, offset, 2, ENC_BIG_ENDIAN); |
141 | | /*offset += 2;*/ |
142 | 1 | } |
143 | | |
144 | 1 | offset = start_tlv_offset; |
145 | | /* TLVs */ |
146 | 1 | while (tvb_reported_length_remaining(tvb, offset) >= 4) { |
147 | 1 | uint16_t tlv_len = tvb_get_h_uint16(tvb, offset + 0); |
148 | 1 | uint16_t tlv_type; |
149 | 1 | uint16_t value_len; |
150 | | |
151 | 1 | proto_tree *tlv_tree; |
152 | | |
153 | | /* malformed */ |
154 | 1 | if (tlv_len < 4) |
155 | 1 | return offset; |
156 | | |
157 | 0 | value_len = tlv_len - 4; |
158 | 0 | tlv_type = (tvb_get_h_uint16(tvb, offset + 2) & 0x7fff); |
159 | |
|
160 | 0 | bool handled = false; |
161 | 0 | ti = proto_tree_add_bytes_format(nflog_tree, hf_nflog_tlv, |
162 | 0 | tvb, offset, tlv_len, NULL, |
163 | 0 | "TLV Type: %s (%u), Length: %u", |
164 | 0 | val_to_str_const(tlv_type, nflog_tlv_vals, "Unknown"), |
165 | 0 | tlv_type, tlv_len); |
166 | 0 | tlv_tree = proto_item_add_subtree(ti, ett_nflog_tlv); |
167 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_length, tvb, offset + 0, 2, ENC_HOST_ENDIAN); |
168 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_type, tvb, offset + 2, 2, ENC_HOST_ENDIAN); |
169 | 0 | switch (tlv_type) { |
170 | 0 | case WS_NFULA_PACKET_HDR: |
171 | 0 | if (value_len == 4) { |
172 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_hwprotocol, |
173 | 0 | tvb, offset + 4, 2, ENC_BIG_ENDIAN); |
174 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_hook, |
175 | 0 | tvb, offset + 6, 1, ENC_NA); |
176 | 0 | hw_protocol = tvb_get_ntohs(tvb, offset + 4); |
177 | 0 | handled = true; |
178 | 0 | } |
179 | 0 | break; |
180 | 0 | case WS_NFULA_IFINDEX_INDEV: |
181 | 0 | if (value_len == 4) { |
182 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_ifindex_indev, tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
183 | 0 | handled = true; |
184 | 0 | } |
185 | 0 | break; |
186 | 0 | case WS_NFULA_IFINDEX_OUTDEV: |
187 | 0 | if (value_len == 4) { |
188 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_ifindex_outdev, tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
189 | 0 | handled = true; |
190 | 0 | } |
191 | 0 | break; |
192 | 0 | case WS_NFULA_IFINDEX_PHYSINDEV: |
193 | 0 | if (value_len == 4) { |
194 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_ifindex_physindev, tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
195 | 0 | handled = true; |
196 | 0 | } |
197 | 0 | break; |
198 | 0 | case WS_NFULA_IFINDEX_PHYSOUTDEV: |
199 | 0 | if (value_len == 4) { |
200 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_ifindex_physoutdev, tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
201 | 0 | handled = true; |
202 | 0 | } |
203 | 0 | break; |
204 | 0 | case WS_NFULA_PAYLOAD: |
205 | 0 | payload.buffer = tvb_new_subset_length(tvb, offset + 4, value_len); |
206 | 0 | payload.parent = tlv_tree; |
207 | 0 | handled = true; |
208 | 0 | break; |
209 | 0 | case WS_NFULA_PREFIX: |
210 | 0 | if (value_len >= 1) { |
211 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_prefix, |
212 | 0 | tvb, offset + 4, value_len, ENC_ASCII); |
213 | 0 | handled = true; |
214 | 0 | } |
215 | 0 | break; |
216 | 0 | case WS_NFULA_UID: |
217 | 0 | if (value_len == 4) { |
218 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_uid, |
219 | 0 | tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
220 | 0 | handled = true; |
221 | 0 | } |
222 | 0 | break; |
223 | 0 | case WS_NFULA_GID: |
224 | 0 | if (value_len == 4) { |
225 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_gid, |
226 | 0 | tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
227 | 0 | handled = true; |
228 | 0 | } |
229 | 0 | break; |
230 | 0 | case WS_NFULA_TIMESTAMP: |
231 | 0 | if (value_len == 16) { |
232 | | /* |
233 | | * 64-bit seconds and 64-bit microseconds. |
234 | | * |
235 | | * XXX - add an "expert info" warning if the |
236 | | * microseconds are >= 10^6? |
237 | | */ |
238 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_timestamp, |
239 | 0 | tvb, offset + 4, value_len, |
240 | 0 | ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN); |
241 | 0 | handled = true; |
242 | 0 | } |
243 | 0 | break; |
244 | 0 | case WS_NFULA_HWTYPE: |
245 | 0 | if (value_len == 2) { |
246 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_hw_type, |
247 | 0 | tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
248 | 0 | handled = true; |
249 | 0 | } |
250 | 0 | break; |
251 | 0 | case WS_NFULA_HWHEADER: |
252 | 0 | hwheader.buffer = tvb_new_subset_length(tvb, offset + 4, value_len); |
253 | 0 | hwheader.parent = tlv_tree; |
254 | 0 | handled = true; |
255 | 0 | break; |
256 | 0 | case WS_NFULA_HWLEN: |
257 | 0 | if (value_len == 2 || value_len == 4) { |
258 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_hwheader_len, |
259 | 0 | tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
260 | 0 | handled = true; |
261 | 0 | } |
262 | 0 | break; |
263 | 0 | case WS_NFULA_CT: |
264 | 0 | if (value_len > 0) { |
265 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_ct, |
266 | 0 | tvb, offset + 4, value_len, ENC_ASCII); |
267 | 0 | handled = true; |
268 | 0 | } |
269 | 0 | break; |
270 | 0 | case WS_NFULA_CT_INFO: |
271 | 0 | if (value_len == 4) { |
272 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_ct_info, |
273 | 0 | tvb, offset + 4, value_len, ENC_BIG_ENDIAN); |
274 | 0 | handled = true; |
275 | 0 | } |
276 | 0 | break; |
277 | 0 | } |
278 | | |
279 | 0 | if (!handled) |
280 | 0 | proto_tree_add_item(tlv_tree, hf_nflog_tlv_unknown, |
281 | 0 | tvb, offset + 4, value_len, ENC_NA); |
282 | 0 | offset += WS_ROUNDUP_4(tlv_len); /* next TLV aligned to 4B */ |
283 | 0 | } |
284 | | |
285 | 0 | if (hwheader.buffer && eth_handle) { |
286 | 0 | proto_tree *parent = eth_ip_layout_inside ? hwheader.parent : tree; |
287 | | // for others it is not guaranteed to be full, just for avoiding errors |
288 | 0 | if (hw_protocol == ETHERTYPE_IP) { |
289 | 0 | call_dissector(eth_handle, hwheader.buffer, pinfo, parent); |
290 | 0 | } else { |
291 | 0 | call_data_dissector(hwheader.buffer, pinfo, parent); |
292 | 0 | } |
293 | 0 | } |
294 | |
|
295 | 0 | if (payload.buffer) { |
296 | 0 | proto_tree *parent = eth_ip_layout_inside ? payload.parent : tree; |
297 | 0 | if (hw_protocol) { |
298 | 0 | if (!dissector_try_uint(ethertype_table, hw_protocol, payload.buffer, pinfo, parent)) |
299 | 0 | call_data_dissector(payload.buffer, pinfo, parent); |
300 | 0 | } else { |
301 | 0 | switch (pf) { |
302 | | /* Note: NFPROTO_INET is not supposed to appear here, it is mapped |
303 | | * to NFPROTO_IPV4 or NFPROTO_IPV6 */ |
304 | 0 | case WS_NFPROTO_IPV4: |
305 | 0 | call_dissector(ip_handle, payload.buffer, pinfo, parent); |
306 | 0 | break; |
307 | 0 | case WS_NFPROTO_IPV6: |
308 | 0 | call_dissector(ip6_handle, payload.buffer, pinfo, parent); |
309 | 0 | break; |
310 | 0 | default: |
311 | 0 | call_data_dissector(payload.buffer, pinfo, parent); |
312 | 0 | break; |
313 | 0 | } |
314 | 0 | } |
315 | 0 | } |
316 | 0 | return tvb_captured_length(tvb); |
317 | 0 | } |
318 | | |
319 | | void |
320 | | proto_register_nflog(void) |
321 | 16 | { |
322 | 16 | static hf_register_info hf[] = { |
323 | 16 | { &hf_nflog_family, |
324 | 16 | { "Family", "nflog.family", |
325 | 16 | FT_UINT8, BASE_DEC, VALS(nfproto_family_vals), 0x00, |
326 | 16 | NULL, HFILL } |
327 | 16 | }, |
328 | 16 | { &hf_nflog_version, |
329 | 16 | { "Version", "nflog.version", |
330 | 16 | FT_UINT8, BASE_DEC, NULL, 0x00, |
331 | 16 | NULL, HFILL } |
332 | 16 | }, |
333 | 16 | { &hf_nflog_resid, |
334 | 16 | { "Resource id", "nflog.res_id", |
335 | 16 | FT_UINT16, BASE_DEC, NULL, 0x00, |
336 | 16 | NULL, HFILL } |
337 | 16 | }, |
338 | 16 | { &hf_nflog_tlv, |
339 | 16 | { "TLV", "nflog.tlv", |
340 | 16 | FT_BYTES, BASE_NONE, NULL, 0x00, |
341 | 16 | NULL, HFILL } |
342 | 16 | }, |
343 | 16 | { &hf_nflog_tlv_length, |
344 | 16 | { "Length", "nflog.tlv_length", |
345 | 16 | FT_UINT16, BASE_DEC, NULL, 0x00, |
346 | 16 | "TLV Length", HFILL } |
347 | 16 | }, |
348 | 16 | { &hf_nflog_tlv_type, |
349 | 16 | { "Type", "nflog.tlv_type", |
350 | 16 | FT_UINT16, BASE_DEC, VALS(nflog_tlv_vals), 0x7fff, |
351 | 16 | "TLV Type", HFILL } |
352 | 16 | }, |
353 | 16 | { &hf_nflog_tlv_hwprotocol, |
354 | 16 | { "HW protocol", "nflog.protocol", |
355 | 16 | FT_UINT16, BASE_HEX, VALS(etype_vals), 0x00, |
356 | 16 | NULL, HFILL } |
357 | 16 | }, |
358 | 16 | { &hf_nflog_tlv_hw_type, |
359 | 16 | { "HW Type", "nflog.hwtype", |
360 | 16 | FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0x00, |
361 | 16 | NULL, HFILL } |
362 | 16 | }, |
363 | 16 | { &hf_nflog_tlv_hwheader_len, |
364 | 16 | { "Hardware header length", "nflog.hwhdr_len", |
365 | 16 | FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL } |
366 | 16 | }, |
367 | 16 | { &hf_nflog_tlv_hook, |
368 | 16 | { "Netfilter hook", "nflog.hook", |
369 | 16 | FT_UINT8, BASE_DEC, VALS(netfilter_hooks_vals), 0x00, |
370 | 16 | NULL, HFILL } |
371 | 16 | }, |
372 | 16 | { &hf_nflog_tlv_ifindex_indev, |
373 | 16 | { "IFINDEX_INDEV", "nflog.ifindex_indev", |
374 | 16 | FT_UINT32, BASE_DEC, NULL, 0x00, |
375 | 16 | NULL, HFILL } |
376 | 16 | }, |
377 | 16 | { &hf_nflog_tlv_ifindex_outdev, |
378 | 16 | { "IFINDEX_OUTDEV", "nflog.ifindex_outdev", |
379 | 16 | FT_UINT32, BASE_DEC, NULL, 0x00, |
380 | 16 | NULL, HFILL } |
381 | 16 | }, |
382 | 16 | { &hf_nflog_tlv_ifindex_physindev, |
383 | 16 | { "IFINDEX_PHYSINDEV", "nflog.ifindex_physindev", |
384 | 16 | FT_UINT32, BASE_DEC, NULL, 0x00, |
385 | 16 | NULL, HFILL } |
386 | 16 | }, |
387 | 16 | { &hf_nflog_tlv_ifindex_physoutdev, |
388 | 16 | { "IFINDEX_PHYSOUTDEV", "nflog.ifindex_physoutdev", |
389 | 16 | FT_UINT32, BASE_DEC, NULL, 0x00, |
390 | 16 | NULL, HFILL } |
391 | 16 | }, |
392 | 16 | { &hf_nflog_tlv_prefix, |
393 | 16 | { "Prefix", "nflog.prefix", |
394 | 16 | FT_STRINGZ, BASE_NONE, NULL, 0x00, |
395 | 16 | "TLV Prefix Value", HFILL } |
396 | 16 | }, |
397 | 16 | { &hf_nflog_tlv_uid, |
398 | 16 | { "UID", "nflog.uid", |
399 | 16 | FT_INT32, BASE_DEC, NULL, 0x00, |
400 | 16 | "TLV UID Value", HFILL } |
401 | 16 | }, |
402 | 16 | { &hf_nflog_tlv_gid, |
403 | 16 | { "GID", "nflog.gid", |
404 | 16 | FT_INT32, BASE_DEC, NULL, 0x00, |
405 | 16 | "TLV GID Value", HFILL } |
406 | 16 | }, |
407 | 16 | { &hf_nflog_tlv_timestamp, |
408 | 16 | { "Timestamp", "nflog.timestamp", |
409 | 16 | FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00, |
410 | 16 | "TLV Timestamp Value", HFILL } |
411 | 16 | }, |
412 | 16 | { &hf_nflog_tlv_ct_info, |
413 | 16 | { "CT INFO", "nflog.ctinfo", |
414 | 16 | FT_INT32, BASE_DEC, VALS(nfq_ctinfo_vals), 0x00, |
415 | 16 | "TLV CT INFO", HFILL } |
416 | 16 | }, |
417 | 16 | { &hf_nflog_tlv_ct, |
418 | 16 | { "CT", "nflog.ct", |
419 | 16 | FT_STRINGZ, BASE_NONE, NULL, 0x00, |
420 | 16 | "TLV CT", HFILL } |
421 | 16 | }, |
422 | 16 | { &hf_nflog_tlv_unknown, |
423 | 16 | { "Value", "nflog.tlv_value", |
424 | 16 | FT_BYTES, BASE_NONE, NULL, 0x00, |
425 | 16 | "TLV Value", HFILL } |
426 | 16 | }, |
427 | 16 | }; |
428 | | |
429 | 16 | static int *ett[] = { |
430 | 16 | &ett_nflog, |
431 | 16 | &ett_nflog_tlv |
432 | 16 | }; |
433 | | |
434 | 16 | module_t *nflog_module; |
435 | | |
436 | 16 | proto_nflog = proto_register_protocol("Linux Netfilter NFLOG", "NFLOG", "nflog"); |
437 | 16 | nflog_handle = register_dissector("nflog", dissect_nflog, proto_nflog); |
438 | 16 | proto_register_field_array(proto_nflog, hf, array_length(hf)); |
439 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
440 | | // user preferences |
441 | 16 | nflog_module = prefs_register_protocol(proto_nflog, NULL); |
442 | 16 | prefs_register_bool_preference(nflog_module, "eth_ip_layout_inside", |
443 | 16 | "Place ip and eth inside", |
444 | 16 | "Place ip and eth sections inside appropriate TLV's " |
445 | 16 | "(payload and hw header respectively). If false, then place on top level", |
446 | 16 | ð_ip_layout_inside); |
447 | 16 | } |
448 | | |
449 | | void |
450 | | proto_reg_handoff_nflog(void) |
451 | 16 | { |
452 | 16 | ip_handle = find_dissector_add_dependency("ip", proto_nflog); |
453 | 16 | ip6_handle = find_dissector_add_dependency("ipv6", proto_nflog); |
454 | 16 | eth_handle = find_dissector_add_dependency("eth_header", proto_nflog); |
455 | | |
456 | 16 | dissector_add_uint("wtap_encap", WTAP_ENCAP_NFLOG, nflog_handle); |
457 | 16 | ethertype_table = find_dissector_table("ethertype"); |
458 | 16 | } |
459 | | |
460 | | /* |
461 | | * Editor modelines |
462 | | * |
463 | | * Local Variables: |
464 | | * c-basic-offset: 4 |
465 | | * tab-width: 8 |
466 | | * indent-tabs-mode: nil |
467 | | * End: |
468 | | * |
469 | | * ex: set shiftwidth=4 tabstop=8 expandtab: |
470 | | * :indentSize=4:tabSize=8:noTabs=true: |
471 | | */ |