== OpenBSD pf rule numbers and tcpdump filtering OpenBSD's pf packet filter can log packets to a pflog virtual network device if you ask it to; in normal configurations such logged packets appear on _pflog0_ and then wind up saved in _/var/log/pflog_. Around here we log most rejections and some stuff that we accept, partly because this makes tracking down firewall issues much easier. If you use '_tcpdump -e_' on a pflog device or log file, it will print the rule number of the rule that caused the packet to be logged (or possibly the last rule number, I'm not sure) as part of the output. It will also try to print some information about the rule itself, but I suspect that this can become inaccurate for saved log files if you add, delete, or reorder rules in your _pf.conf_. (Well, if you use OpenBSD's _tcpdump_. I doubt anyone else's version understands this stuff.) In theory you can use tcpdump to filter by rule number, with the '_rnr_' or '_rulenum_' filtering condition. In practice this is tricky to use because of two issues. First, you need to determine the number of the pf rule that you want to match against, which is not as simple as counting rule lines in your pf.conf. The authoritative source of rule numbers is to use '_pfctl -vv_' when dumping either the filter rules or the NAT rules (and who knows, maybe queue rules too). You want the lines that start with '@'; the number after the '@' is the rule number. Thus: > _pfctl -vvsn | fgrep @_ \\ > _pfctl -vvsr | fgrep @_ If you do this you will immediately discover the second issue: separate sorts of rules number their rules independently. I believe that _block_ and _pass_ rules share one sequence, and then _nat_, _rdr_, and _binat_ rules are each numbered separately; I don't know about _scrub_ rules. (This is what we see on our OpenBSD firewalls, at least; on some of them, we have four different rules that are all 'rule number 0'.) You can restrict which sort of rule you are matching with the filter '_action _', eg '_action rdr and (rnr ...)_'. Helpfully (or not), you can match blocks and passes separately. On the whole I think that it's easier to match with IP addresses and the like, and I expect this to be more robust for looking through old logged data. If you have to keep extra logging that is making this verbose, _action_ filter rules may help. (One of the things that may make this necessary is that, to the best of my understanding, rules that rewrite packet addresses log the post-rewrite address. Thus, using '_action rdr and ..._' can help you see only the packets that got rewritten to an active host's address, instead of all traffic involving that host's regular address that you're logging.)