/src/wireshark/epan/dissectors/packet-pflog.c
Line | Count | Source |
1 | | /* packet-pflog.c |
2 | | * Routines for pflog (Firewall Logging) packet disassembly |
3 | | * |
4 | | * Copyright 2001 Mike Frantzen |
5 | | * All rights reserved. |
6 | | * |
7 | | * SPDX-License-Identifier: BSD-1-Clause |
8 | | */ |
9 | | |
10 | | /* |
11 | | * Specifications: |
12 | | * |
13 | | * OpenBSD PF log: |
14 | | * |
15 | | * https://cvsweb.openbsd.org/src/sys/net/if_pflog.c |
16 | | * https://cvsweb.openbsd.org/src/sys/net/if_pflog.h |
17 | | * https://cvsweb.openbsd.org/src/sys/net/pfvar.h |
18 | | * |
19 | | * FreeBSD PF log: |
20 | | * |
21 | | * https://cgit.freebsd.org/src/tree/sys/net/if_pflog.h |
22 | | * https://cgit.freebsd.org/src/tree/sys/netpfil/pf/if_pflog.c |
23 | | * https://cgit.freebsd.org/src/tree/sys/netpfil/pf/pf.h |
24 | | * |
25 | | * NetBSD PF log: |
26 | | * |
27 | | * http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dist/pf/net/if_pflog.c |
28 | | * http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dist/pf/net/if_pflog.h |
29 | | * http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dist/pf/net/pfvar.h |
30 | | * |
31 | | * DragonFly BSD PF log: |
32 | | * |
33 | | * https://gitweb.dragonflybsd.org/dragonfly.git/blob/HEAD:/sys/net/pf/if_pflog.c |
34 | | * https://gitweb.dragonflybsd.org/dragonfly.git/blob/HEAD:/sys/net/pf/if_pflog.h |
35 | | * https://gitweb.dragonflybsd.org/dragonfly.git/blob/HEAD:/sys/net/pf/pfvar.h |
36 | | * |
37 | | * macOS/Darwin PF log: |
38 | | * |
39 | | * https://github.com/apple-oss-distributions/xnu/blob/main/bsd/net/if_pflog.c |
40 | | * https://github.com/apple-oss-distributions/xnu/blob/main/bsd/net/if_pflog.h |
41 | | * https://github.com/apple-oss-distributions/xnu/blob/main/bsd/net/pfvar.h |
42 | | */ |
43 | | #include "config.h" |
44 | | |
45 | | #include <epan/packet.h> |
46 | | |
47 | | #include <epan/aftypes.h> |
48 | | #include <epan/addr_resolv.h> |
49 | | #include <epan/expert.h> |
50 | | #include <epan/prefs.h> |
51 | | |
52 | | #include <wsutil/ws_roundup.h> |
53 | | |
54 | | void proto_register_pflog(void); |
55 | | void proto_reg_handoff_pflog(void); |
56 | | void proto_register_old_pflog(void); |
57 | | void proto_reg_handoff_old_pflog(void); |
58 | | |
59 | | static dissector_handle_t old_pflog_handle; |
60 | | static dissector_handle_t pflog_handle; |
61 | | static dissector_handle_t ip_handle, ipv6_handle; |
62 | | |
63 | | /* header fields */ |
64 | | static int proto_pflog; |
65 | | static int hf_pflog_length; |
66 | | static int hf_pflog_af; |
67 | | static int hf_pflog_action; |
68 | | static int hf_pflog_reason; |
69 | | static int hf_pflog_ifname; |
70 | | static int hf_pflog_ruleset; |
71 | | static int hf_pflog_rulenr; |
72 | | static int hf_pflog_subrulenr; |
73 | | static int hf_pflog_uid; |
74 | | static int hf_pflog_pid; |
75 | | static int hf_pflog_rule_uid; |
76 | | static int hf_pflog_rule_pid; |
77 | | static int hf_pflog_dir; |
78 | | static int hf_pflog_rewritten; |
79 | | static int hf_pflog_pad; |
80 | | static int hf_pflog_saddr_ipv4; |
81 | | static int hf_pflog_daddr_ipv4; |
82 | | static int hf_pflog_saddr_ipv6; |
83 | | static int hf_pflog_daddr_ipv6; |
84 | | static int hf_pflog_saddr; |
85 | | static int hf_pflog_daddr; |
86 | | static int hf_pflog_sport; |
87 | | static int hf_pflog_dport; |
88 | | static int ett_pflog; |
89 | | |
90 | | static expert_field ei_pflog_invalid_header_length; |
91 | | |
92 | | /* old header */ |
93 | | static int proto_old_pflog; |
94 | | static int hf_old_pflog_af; |
95 | | static int hf_old_pflog_ifname; |
96 | | static int hf_old_pflog_rnr; |
97 | | static int hf_old_pflog_reason; |
98 | | static int hf_old_pflog_action; |
99 | | static int hf_old_pflog_dir; |
100 | | |
101 | | static int ett_old_pflog; |
102 | | |
103 | | /* |
104 | | * Because ENC_HOST_ENDIAN is either equal to ENC_BIG_ENDIAN or |
105 | | * ENC_LITTLE_ENDIAN, it will be confusing if we use ENC_ values |
106 | | * directly, as, if the current setting is "Host-endian", it'll |
107 | | * look like "Big-endian" on big-endian machines and like |
108 | | * "Little-endian" on little-endian machines, and will display |
109 | | * as such if you open up the preferences. |
110 | | */ |
111 | 0 | #define ID_HOST_ENDIAN 0 |
112 | 0 | #define ID_BIG_ENDIAN 1 |
113 | 0 | #define ID_LITTLE_ENDIAN 2 |
114 | | |
115 | | static int id_endian = ID_HOST_ENDIAN; |
116 | | static const enum_val_t id_endian_vals[] = { |
117 | | { "host", "Host-endian", ID_HOST_ENDIAN }, |
118 | | { "big", "Big-endian", ID_BIG_ENDIAN }, |
119 | | { "little", "Little-endian", ID_LITTLE_ENDIAN }, |
120 | | { NULL, NULL, 0 } |
121 | | }; |
122 | | |
123 | | /* |
124 | | * Length as of OpenBSD 3.4, not including padding. |
125 | | */ |
126 | 0 | #define LEN_PFLOG_OPENBSD_3_4 45 |
127 | | |
128 | | /* |
129 | | * Length as of OpenBSD 3.8, not including padding. |
130 | | * |
131 | | * Also the current length on DragonFly BSD, NetBSD, and Darwin; |
132 | | * those all have the same log message header. |
133 | | */ |
134 | 0 | #define LEN_PFLOG_OPENBSD_3_8 61 |
135 | | |
136 | | /* |
137 | | * Length as of OpenBSD 4.9; there are 2 internal pad bytes, but no |
138 | | * padding at the end. |
139 | | */ |
140 | 0 | #define LEN_PFLOG_OPENBSD_4_9 100 |
141 | | |
142 | | static const value_string pflog_af_vals[] = { |
143 | | { BSD_AF_INET, "IPv4" }, |
144 | | { BSD_AF_INET6_BSD, "IPv6" }, |
145 | | { BSD_AF_INET6_FREEBSD, "IPv6" }, |
146 | | { BSD_AF_INET6_DARWIN, "IPv6" }, |
147 | | { 0, NULL } |
148 | | }; |
149 | | |
150 | | /* |
151 | | * Reason values. |
152 | | * |
153 | | * Past 14, these differ for different OSes. |
154 | | */ |
155 | | static const value_string pflog_reason_vals[] = { |
156 | | { 0, "match" }, |
157 | | { 1, "bad-offset" }, |
158 | | { 2, "fragment" }, |
159 | | { 3, "short" }, |
160 | | { 4, "normalize" }, |
161 | | { 5, "memory" }, |
162 | | { 6, "timestamp" }, |
163 | | { 7, "congestion" }, |
164 | | { 8, "ip-option" }, |
165 | | { 9, "proto-cksum" }, |
166 | | { 10, "state-mismatch" }, |
167 | | { 11, "state-ins-fail" }, |
168 | | { 12, "max-states" }, |
169 | | { 13, "srcnode-limit" }, |
170 | | { 14, "syn-proxy" }, |
171 | | #if defined(__FreeBSD__) |
172 | | { 15, "map-failed" }, |
173 | | #elif defined(__NetBSD__) |
174 | | { 15, "state-locked" }, |
175 | | #elif defined(__OpenBSD__) |
176 | | { 15, "translate" }, |
177 | | { 16, "no-route" }, |
178 | | #elif defined(__APPLE__) |
179 | | { 15, "dummynet" }, |
180 | | #endif |
181 | | { 0, NULL } |
182 | | }; |
183 | | |
184 | | /* |
185 | | * Action values. |
186 | | * |
187 | | * Past 10, these differ for different OSes. |
188 | | */ |
189 | | #define PF_PASS 0 |
190 | | #define PF_DROP 1 |
191 | | #define PF_SCRUB 2 |
192 | | #define PF_NOSCRUB 3 |
193 | | #define PF_NAT 4 |
194 | | #define PF_NONAT 5 |
195 | | #define PF_BINAT 6 |
196 | | #define PF_NOBINAT 7 |
197 | | #define PF_RDR 8 |
198 | | #define PF_NORDR 9 |
199 | | #define PF_SYNPROXY_DROP 10 |
200 | | #if defined(__FreeBSD__) |
201 | | #define PF_DEFER 11 |
202 | | #elif defined(__OpenBSD__) |
203 | | #define PF_DEFER 11 |
204 | | #define PF_MATCH 12 |
205 | | #define PF_DIVERT 13 |
206 | | #define PF_RT 14 |
207 | | #define PF_AFRT 15 |
208 | | #elif defined(__APPLE__) |
209 | | #define PF_DUMMYNET 11 |
210 | | #define PF_NODUMMYNET 12 |
211 | | #define PF_NAT64 13 |
212 | | #define PF_NONAT64 14 |
213 | | #endif |
214 | | |
215 | | static const value_string pflog_action_vals[] = { |
216 | | { PF_PASS, "pass" }, |
217 | | { PF_DROP, "block" }, |
218 | | { PF_SCRUB, "scrub" }, |
219 | | { PF_NAT, "nat" }, |
220 | | { PF_NONAT, "nonat" }, |
221 | | { PF_BINAT, "binat" }, |
222 | | { PF_NOBINAT, "nobinat" }, |
223 | | { PF_RDR, "rdr" }, |
224 | | { PF_NORDR, "nordr" }, |
225 | | { PF_SYNPROXY_DROP, "synproxy-drop" }, |
226 | | #if defined(__FreeBSD__) |
227 | | { PF_DEFER, "defer" }, |
228 | | #elif defined(__OpenBSD__) |
229 | | { PF_DEFER, "defer" }, |
230 | | { PF_MATCH, "match" }, |
231 | | { PF_DIVERT, "divert" }, |
232 | | { PF_RT, "rt" }, |
233 | | { PF_AFRT, "afrt" }, |
234 | | #elif defined(__APPLE__) |
235 | | { PF_DUMMYNET, "dummynet" }, |
236 | | { PF_NODUMMYNET, "nodummynet" }, |
237 | | { PF_NAT64, "nat64" }, |
238 | | { PF_NONAT64, "nonat64" }, |
239 | | #endif |
240 | | { 0, NULL } |
241 | | }; |
242 | | |
243 | | /* Directions */ |
244 | | #define PF_OLD_IN 0 |
245 | | #define PF_OLD_OUT 1 |
246 | | |
247 | | #define PF_INOUT 0 |
248 | | #define PF_IN 1 |
249 | | #define PF_OUT 2 |
250 | | #define PF_FWD 3 /* for now, 3 is only used by OpenBSD */ |
251 | | |
252 | | static const value_string pflog_old_dir_vals[] = { |
253 | | { PF_OLD_IN, "in" }, |
254 | | { PF_OLD_OUT, "out" }, |
255 | | { 0, NULL } |
256 | | }; |
257 | | |
258 | | static const value_string pflog_dir_vals[] = { |
259 | | { PF_INOUT, "inout" }, |
260 | | { PF_IN, "in" }, |
261 | | { PF_OUT, "out" }, |
262 | | { PF_FWD, "fwd" }, |
263 | | { 0, NULL } |
264 | | }; |
265 | | |
266 | | static int |
267 | | dissect_pflog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
268 | 0 | { |
269 | 0 | tvbuff_t *next_tvb; |
270 | 0 | proto_tree *pflog_tree; |
271 | 0 | proto_item *ti = NULL, *ti_len; |
272 | 0 | uint32_t length, padded_length; |
273 | 0 | uint32_t af, action; |
274 | 0 | const uint8_t *ifname; |
275 | 0 | int32_t rulenr; |
276 | 0 | int offset = 0; |
277 | |
|
278 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PFLOG"); |
279 | |
|
280 | 0 | ti = proto_tree_add_item(tree, proto_pflog, tvb, offset, -1, ENC_NA); |
281 | 0 | pflog_tree = proto_item_add_subtree(ti, ett_pflog); |
282 | |
|
283 | 0 | ti_len = proto_tree_add_item_ret_uint(pflog_tree, hf_pflog_length, tvb, offset, 1, ENC_BIG_ENDIAN, &length); |
284 | 0 | if(length < LEN_PFLOG_OPENBSD_3_4) |
285 | 0 | { |
286 | 0 | expert_add_info_format(pinfo, ti_len, &ei_pflog_invalid_header_length, "Invalid header length %u", length); |
287 | 0 | } |
288 | |
|
289 | 0 | padded_length = WS_ROUNDUP_4(length); |
290 | |
|
291 | 0 | offset += 1; |
292 | |
|
293 | 0 | proto_tree_add_item_ret_uint(pflog_tree, hf_pflog_af, tvb, offset, 1, ENC_BIG_ENDIAN, &af); |
294 | 0 | offset += 1; |
295 | |
|
296 | 0 | proto_tree_add_item_ret_uint(pflog_tree, hf_pflog_action, tvb, offset, 1, ENC_BIG_ENDIAN, &action); |
297 | 0 | offset += 1; |
298 | |
|
299 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_reason, tvb, offset, 1, ENC_BIG_ENDIAN); |
300 | 0 | offset += 1; |
301 | |
|
302 | 0 | proto_tree_add_item_ret_string(pflog_tree, hf_pflog_ifname, tvb, offset, 16, ENC_ASCII|ENC_NA, pinfo->pool, &ifname); |
303 | 0 | offset += 16; |
304 | |
|
305 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_ruleset, tvb, offset, 16, ENC_ASCII); |
306 | 0 | offset += 16; |
307 | |
|
308 | 0 | proto_tree_add_item_ret_int(pflog_tree, hf_pflog_rulenr, tvb, offset, 4, ENC_BIG_ENDIAN, &rulenr); |
309 | 0 | offset += 4; |
310 | |
|
311 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_subrulenr, tvb, offset, 4, ENC_BIG_ENDIAN); |
312 | 0 | offset += 4; |
313 | |
|
314 | 0 | if(length >= LEN_PFLOG_OPENBSD_3_8) |
315 | 0 | { |
316 | 0 | int endian; |
317 | |
|
318 | 0 | switch (id_endian) { |
319 | | |
320 | 0 | case ID_HOST_ENDIAN: |
321 | 0 | endian = ENC_HOST_ENDIAN; |
322 | 0 | break; |
323 | | |
324 | 0 | case ID_BIG_ENDIAN: |
325 | 0 | endian = ENC_BIG_ENDIAN; |
326 | 0 | break; |
327 | | |
328 | 0 | case ID_LITTLE_ENDIAN: |
329 | 0 | endian = ENC_LITTLE_ENDIAN; |
330 | 0 | break; |
331 | | |
332 | 0 | default: |
333 | 0 | DISSECTOR_ASSERT_NOT_REACHED(); |
334 | 0 | } |
335 | | |
336 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_uid, tvb, offset, 4, endian); |
337 | 0 | offset += 4; |
338 | |
|
339 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_pid, tvb, offset, 4, endian); |
340 | 0 | offset += 4; |
341 | |
|
342 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_rule_uid, tvb, offset, 4, endian); |
343 | 0 | offset += 4; |
344 | |
|
345 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_rule_pid, tvb, offset, 4, endian); |
346 | 0 | offset += 4; |
347 | 0 | } |
348 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_dir, tvb, offset, 1, ENC_BIG_ENDIAN); |
349 | 0 | offset += 1; |
350 | |
|
351 | 0 | if(length >= LEN_PFLOG_OPENBSD_4_9) |
352 | 0 | { |
353 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_rewritten, tvb, offset, 1, ENC_BIG_ENDIAN); |
354 | 0 | offset += 1; |
355 | | |
356 | | /* Internal padding */ |
357 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_pad, tvb, offset, 2, ENC_NA); |
358 | 0 | offset += 2; |
359 | |
|
360 | 0 | switch (af) { |
361 | | |
362 | 0 | case BSD_AF_INET: |
363 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_saddr_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN); |
364 | 0 | offset += 16; |
365 | |
|
366 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_daddr_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN); |
367 | 0 | offset += 16; |
368 | 0 | break; |
369 | | |
370 | 0 | case BSD_AF_INET6_BSD: |
371 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_saddr_ipv6, tvb, offset, 16, ENC_NA); |
372 | 0 | offset += 16; |
373 | |
|
374 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_daddr_ipv6, tvb, offset, 16, ENC_NA); |
375 | 0 | offset += 16; |
376 | 0 | break; |
377 | | |
378 | 0 | default: |
379 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_saddr, tvb, offset, 16, ENC_NA); |
380 | 0 | offset += 16; |
381 | |
|
382 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_daddr, tvb, offset, 16, ENC_NA); |
383 | 0 | offset += 16; |
384 | 0 | break; |
385 | 0 | } |
386 | | |
387 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_sport, tvb, offset, 2, ENC_BIG_ENDIAN); |
388 | 0 | offset += 2; |
389 | |
|
390 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_dport, tvb, offset, 2, ENC_BIG_ENDIAN); |
391 | 0 | offset += 2; |
392 | 0 | } else { |
393 | | /* End-of-header padding */ |
394 | 0 | proto_tree_add_item(pflog_tree, hf_pflog_pad, tvb, offset, 3, ENC_NA); |
395 | 0 | offset += 3; |
396 | 0 | } |
397 | | |
398 | 0 | proto_item_set_text(ti, "PF Log %s %s on %s by rule %d", |
399 | 0 | val_to_str(pinfo->pool, af, pflog_af_vals, "unknown (%u)"), |
400 | 0 | val_to_str(pinfo->pool, action, pflog_action_vals, "unknown (%u)"), |
401 | 0 | ifname, |
402 | 0 | rulenr); |
403 | 0 | proto_item_set_len(ti, offset); |
404 | | |
405 | | /* Set the tvbuff for the payload after the header */ |
406 | 0 | next_tvb = tvb_new_subset_remaining(tvb, padded_length); |
407 | |
|
408 | 0 | switch (af) { |
409 | | |
410 | 0 | case BSD_AF_INET: |
411 | 0 | call_dissector(ip_handle, next_tvb, pinfo, tree); |
412 | 0 | break; |
413 | | |
414 | 0 | case BSD_AF_INET6_BSD: |
415 | 0 | case BSD_AF_INET6_FREEBSD: |
416 | 0 | case BSD_AF_INET6_DARWIN: |
417 | 0 | call_dissector(ipv6_handle, next_tvb, pinfo, tree); |
418 | 0 | break; |
419 | | |
420 | 0 | default: |
421 | 0 | call_data_dissector(next_tvb, pinfo, tree); |
422 | 0 | break; |
423 | 0 | } |
424 | | |
425 | 0 | col_prepend_fstr(pinfo->cinfo, COL_INFO, "[%s %s/%d] ", |
426 | 0 | val_to_str(pinfo->pool, action, pflog_action_vals, "unknown (%u)"), |
427 | 0 | ifname, |
428 | 0 | rulenr); |
429 | 0 | return tvb_captured_length(tvb); |
430 | 0 | } |
431 | | |
432 | | void |
433 | | proto_register_pflog(void) |
434 | 14 | { |
435 | 14 | static hf_register_info hf[] = { |
436 | 14 | { &hf_pflog_length, |
437 | 14 | { "Header Length", "pflog.length", FT_UINT8, BASE_DEC, NULL, 0x0, |
438 | 14 | "Length of Header", HFILL }}, |
439 | 14 | { &hf_pflog_af, |
440 | 14 | { "Address Family", "pflog.af", FT_UINT32, BASE_DEC, VALS(pflog_af_vals), 0x0, |
441 | 14 | "Protocol (IPv4 vs IPv6)", HFILL }}, |
442 | 14 | { &hf_pflog_action, |
443 | 14 | { "Action", "pflog.action", FT_UINT8, BASE_DEC, VALS(pflog_action_vals), 0x0, |
444 | 14 | "Action taken by PF on the packet", HFILL }}, |
445 | 14 | { &hf_pflog_reason, |
446 | 14 | { "Reason", "pflog.reason", FT_UINT8, BASE_DEC, VALS(pflog_reason_vals), 0x0, |
447 | 14 | "Reason for logging the packet", HFILL }}, |
448 | 14 | { &hf_pflog_ifname, |
449 | 14 | { "Interface", "pflog.ifname", FT_STRING, BASE_NONE, NULL, 0x0, |
450 | 14 | NULL, HFILL }}, |
451 | 14 | { &hf_pflog_ruleset, |
452 | 14 | { "Ruleset", "pflog.ruleset", FT_STRING, BASE_NONE, NULL, 0x0, |
453 | 14 | "Ruleset name in anchor", HFILL }}, |
454 | | /* |
455 | | * XXX - these are u_int32_t/uint32_t in struct pfloghdr, but are |
456 | | * FT_INT32 here, and at least one capture, from issue #6115, has |
457 | | * 0xFFFFFFFF as a sub rule number; that looks suspiciously as |
458 | | * if it's -1. |
459 | | * |
460 | | * At least in OpenBSD, the rule and subrule are unsigned in the |
461 | | * kernel, and -1 - which really means 0xFFFFFFFFU - is used if |
462 | | * there is no subrule. Perhaps we should treat that value |
463 | | * specially and report it as "None" or something such as that. |
464 | | */ |
465 | 14 | { &hf_pflog_rulenr, |
466 | 14 | { "Rule Number", "pflog.rulenr", FT_INT32, BASE_DEC, NULL, 0x0, |
467 | 14 | "Last matched firewall main ruleset rule number", HFILL }}, |
468 | 14 | { &hf_pflog_subrulenr, |
469 | 14 | { "Sub Rule Number", "pflog.subrulenr", FT_INT32, BASE_DEC, NULL, 0x0, |
470 | 14 | "Last matched firewall anchored ruleset rule number", HFILL }}, |
471 | 14 | { &hf_pflog_uid, |
472 | 14 | { "UID", "pflog.uid", FT_INT32, BASE_DEC, NULL, 0x0, |
473 | 14 | NULL, HFILL }}, |
474 | 14 | { &hf_pflog_pid, |
475 | 14 | { "PID", "pflog.pid", FT_INT32, BASE_DEC, NULL, 0x0, |
476 | 14 | NULL, HFILL }}, |
477 | 14 | { &hf_pflog_rule_uid, |
478 | 14 | { "Rule UID", "pflog.rule_uid", FT_INT32, BASE_DEC, NULL, 0x0, |
479 | 14 | NULL, HFILL }}, |
480 | 14 | { &hf_pflog_rule_pid, |
481 | 14 | { "Rule PID", "pflog.rule_pid", FT_INT32, BASE_DEC, NULL, 0x0, |
482 | 14 | NULL, HFILL }}, |
483 | 14 | { &hf_pflog_rewritten, |
484 | 14 | { "Rewritten", "pflog.rewritten", FT_UINT8, BASE_DEC, NULL, 0x0, |
485 | 14 | NULL, HFILL }}, |
486 | 14 | { &hf_pflog_pad, |
487 | 14 | { "Padding", "pflog.pad", FT_BYTES, BASE_NONE, NULL, 0x0, |
488 | 14 | "Must be Zero", HFILL }}, |
489 | 14 | { &hf_pflog_saddr_ipv4, |
490 | 14 | { "Source Address", "pflog.saddr.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, |
491 | 14 | NULL, HFILL }}, |
492 | 14 | { &hf_pflog_daddr_ipv4, |
493 | 14 | { "Destination Address", "pflog.daddr.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, |
494 | 14 | NULL, HFILL }}, |
495 | 14 | { &hf_pflog_saddr_ipv6, |
496 | 14 | { "Source Address", "pflog.saddr.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, |
497 | 14 | NULL, HFILL }}, |
498 | 14 | { &hf_pflog_daddr_ipv6, |
499 | 14 | { "Destination Address", "pflog.daddr.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, |
500 | 14 | NULL, HFILL }}, |
501 | 14 | { &hf_pflog_saddr, |
502 | 14 | { "Source Address", "pflog.saddr.bytes", FT_BYTES, BASE_NONE, NULL, 0x0, |
503 | 14 | NULL, HFILL }}, |
504 | 14 | { &hf_pflog_daddr, |
505 | 14 | { "Destination Address", "pflog.daddr.bytes", FT_BYTES, BASE_NONE, NULL, 0x0, |
506 | 14 | NULL, HFILL }}, |
507 | 14 | { &hf_pflog_sport, |
508 | 14 | { "Source Port", "pflog.sport", FT_UINT16, BASE_DEC, NULL, 0x0, |
509 | 14 | NULL, HFILL }}, |
510 | 14 | { &hf_pflog_dport, |
511 | 14 | { "Destination Port", "pflog.dport", FT_UINT16, BASE_DEC, NULL, 0x0, |
512 | 14 | NULL, HFILL }}, |
513 | 14 | { &hf_pflog_dir, |
514 | 14 | { "Direction", "pflog.dir", FT_UINT8, BASE_DEC, VALS(pflog_dir_vals), 0x0, |
515 | 14 | "Direction of packet in stack (inbound versus outbound)", HFILL }}, |
516 | 14 | }; |
517 | 14 | static int *ett[] = { &ett_pflog }; |
518 | | |
519 | 14 | static ei_register_info ei[] = { |
520 | 14 | { &ei_pflog_invalid_header_length, { "pflog.invalid_header_length", PI_MALFORMED, PI_ERROR, "Invalid header length", EXPFILL }}, |
521 | 14 | }; |
522 | | |
523 | 14 | expert_module_t* expert_pflog; |
524 | 14 | module_t *pflog_module; |
525 | | |
526 | 14 | proto_pflog = proto_register_protocol("OpenBSD Packet Filter log file", "PFLOG", "pflog"); |
527 | 14 | proto_register_field_array(proto_pflog, hf, array_length(hf)); |
528 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
529 | 14 | expert_pflog = expert_register_protocol(proto_pflog); |
530 | 14 | expert_register_field_array(expert_pflog, ei, array_length(ei)); |
531 | | |
532 | 14 | pflog_handle = register_dissector("pflog", dissect_pflog, proto_pflog); |
533 | | |
534 | 14 | pflog_module = prefs_register_protocol(proto_pflog, NULL); |
535 | | |
536 | 14 | prefs_register_enum_preference(pflog_module, "id_endian", |
537 | 14 | "Byte order for UID and PID fields", |
538 | 14 | "Whether or not UID and PID fields are dissected in host, big, or little endian byte order", |
539 | 14 | &id_endian, id_endian_vals, false); |
540 | 14 | prefs_register_obsolete_preference(pflog_module, "uid_endian"); |
541 | 14 | } |
542 | | |
543 | | void |
544 | | proto_reg_handoff_pflog(void) |
545 | 14 | { |
546 | 14 | ip_handle = find_dissector_add_dependency("ip", proto_pflog); |
547 | 14 | ipv6_handle = find_dissector_add_dependency("ipv6", proto_pflog); |
548 | | |
549 | 14 | dissector_add_uint("wtap_encap", WTAP_ENCAP_PFLOG, pflog_handle); |
550 | 14 | } |
551 | | |
552 | | static int |
553 | | dissect_old_pflog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
554 | 0 | { |
555 | 0 | tvbuff_t *next_tvb; |
556 | 0 | proto_tree *pflog_tree; |
557 | 0 | proto_item *ti; |
558 | 0 | uint32_t af; |
559 | 0 | const uint8_t *ifname; |
560 | 0 | uint16_t rnr, action; |
561 | 0 | int offset = 0; |
562 | |
|
563 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PFLOG-OLD"); |
564 | |
|
565 | 0 | ti = proto_tree_add_item(tree, proto_old_pflog, tvb, 0, -1, ENC_NA); |
566 | 0 | pflog_tree = proto_item_add_subtree(ti, ett_pflog); |
567 | |
|
568 | 0 | proto_tree_add_item_ret_uint(pflog_tree, hf_old_pflog_af, tvb, offset, 4, ENC_BIG_ENDIAN, &af); |
569 | 0 | offset +=4; |
570 | |
|
571 | 0 | proto_tree_add_item_ret_string(pflog_tree, hf_old_pflog_ifname, tvb, offset, 16, ENC_ASCII|ENC_NA, pinfo->pool, &ifname); |
572 | 0 | offset +=16; |
573 | |
|
574 | 0 | proto_tree_add_item_ret_uint16(pflog_tree, hf_old_pflog_rnr, tvb, offset, 2, ENC_BIG_ENDIAN, &rnr); |
575 | 0 | offset +=2; |
576 | |
|
577 | 0 | proto_tree_add_item(pflog_tree, hf_old_pflog_reason, tvb, offset, 2, ENC_BIG_ENDIAN); |
578 | 0 | offset +=2; |
579 | |
|
580 | 0 | proto_tree_add_item_ret_uint16(pflog_tree, hf_old_pflog_action, tvb, offset, 2, ENC_BIG_ENDIAN, &action); |
581 | 0 | offset +=2; |
582 | |
|
583 | 0 | proto_tree_add_item(pflog_tree, hf_old_pflog_dir, tvb, offset, 2, ENC_BIG_ENDIAN); |
584 | 0 | offset +=2; |
585 | |
|
586 | 0 | proto_item_set_text(ti, "PF Log (pre 3.4) %s %s on %s by rule %d", |
587 | 0 | val_to_str(pinfo->pool, af, pflog_af_vals, "unknown (%u)"), |
588 | 0 | val_to_str(pinfo->pool, action, pflog_action_vals, "unknown (%u)"), |
589 | 0 | ifname, |
590 | 0 | rnr); |
591 | 0 | proto_item_set_len(ti, offset); |
592 | | |
593 | | /* Set the tvbuff for the payload after the header */ |
594 | 0 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
595 | |
|
596 | 0 | switch (af) { |
597 | | |
598 | 0 | case BSD_AF_INET: |
599 | 0 | offset += call_dissector(ip_handle, next_tvb, pinfo, tree); |
600 | 0 | break; |
601 | | |
602 | 0 | case BSD_AF_INET6_BSD: |
603 | 0 | offset += call_dissector(ipv6_handle, next_tvb, pinfo, tree); |
604 | 0 | break; |
605 | | |
606 | 0 | default: |
607 | 0 | offset += call_data_dissector(next_tvb, pinfo, tree); |
608 | 0 | break; |
609 | 0 | } |
610 | | |
611 | 0 | col_prepend_fstr(pinfo->cinfo, COL_INFO, "[%s %s/#%d] ", |
612 | 0 | val_to_str(pinfo->pool, action, pflog_action_vals, "unknown (%u)"), |
613 | 0 | ifname, |
614 | 0 | rnr); |
615 | |
|
616 | 0 | return offset; |
617 | 0 | } |
618 | | |
619 | | void |
620 | | proto_register_old_pflog(void) |
621 | 14 | { |
622 | 14 | static hf_register_info hf[] = { |
623 | 14 | { &hf_old_pflog_af, |
624 | 14 | { "Address Family", "pflog.af", FT_UINT32, BASE_DEC, VALS(pflog_af_vals), 0x0, |
625 | 14 | "Protocol (IPv4 vs IPv6)", HFILL }}, |
626 | 14 | { &hf_old_pflog_ifname, |
627 | 14 | { "Interface", "pflog.ifname", FT_STRING, BASE_NONE, NULL, 0x0, |
628 | 14 | NULL, HFILL }}, |
629 | 14 | { &hf_old_pflog_rnr, |
630 | 14 | { "Rule Number", "pflog.rnr", FT_UINT16, BASE_DEC, NULL, 0x0, |
631 | 14 | "Last matched firewall rule number", HFILL }}, |
632 | 14 | { &hf_old_pflog_reason, |
633 | 14 | { "Reason", "pflog.reason", FT_UINT16, BASE_DEC, VALS(pflog_reason_vals), 0x0, |
634 | 14 | "Reason for logging the packet", HFILL }}, |
635 | 14 | { &hf_old_pflog_action, |
636 | 14 | { "Action", "pflog.action", FT_UINT16, BASE_DEC, VALS(pflog_action_vals), 0x0, |
637 | 14 | "Action taken by PF on the packet", HFILL }}, |
638 | 14 | { &hf_old_pflog_dir, |
639 | 14 | { "Direction", "pflog.dir", FT_UINT16, BASE_DEC, VALS(pflog_old_dir_vals), 0x0, |
640 | 14 | "Direction of packet in stack (inbound versus outbound)", HFILL }}, |
641 | 14 | }; |
642 | 14 | static int *ett[] = { &ett_old_pflog }; |
643 | | |
644 | 14 | proto_old_pflog = proto_register_protocol("OpenBSD Packet Filter log file, pre 3.4", "PFLOG-OLD", "pflog-old"); |
645 | 14 | proto_register_field_array(proto_old_pflog, hf, array_length(hf)); |
646 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
647 | | |
648 | 14 | old_pflog_handle = register_dissector("pflog-old", dissect_old_pflog, proto_old_pflog); |
649 | 14 | } |
650 | | |
651 | | void |
652 | | proto_reg_handoff_old_pflog(void) |
653 | 14 | { |
654 | 14 | dissector_add_uint("wtap_encap", WTAP_ENCAP_OLD_PFLOG, old_pflog_handle); |
655 | 14 | } |
656 | | /* |
657 | | * Editor modelines |
658 | | * |
659 | | * Local Variables: |
660 | | * c-basic-offset: 2 |
661 | | * tab-width: 8 |
662 | | * indent-tabs-mode: nil |
663 | | * End: |
664 | | * |
665 | | * ex: set shiftwidth=2 tabstop=8 expandtab: |
666 | | * :indentSize=2:tabSize=8:noTabs=true: |
667 | | */ |