Sometimes brute force is the answer (on Unix)
Suppose that you want to extract all of the IP addresses used by your (OpenBSD) firewall's PF rules, so that you can (for example) validate that all of the internal addresses mentioned still exist.
(For the purposes of this exercise we can ignore IP addresses in PF tables, because those are already easy to dump. Also, I am ignoring IP address ranges, netblocks, and so on; I am just interested in specific IP addresses.)
If you think that parsing PF's
pf.conf file yourself is the answer
to this problem, you have two problems (to riff from a famous remark).
That way lies rewriting PF's rule parser yourself, and the language is
not a simple one.
You could parse the output of '
pfctl -s rules', which dumps the
post-parsed rules in a simplified, expanded form that looks like, for
pass in quick on em1 inet proto tcp from any to IP port = smtp
But with this approach you'd still be writing a parser, and there are a fair number of cases for it to cover.
And then there's brute force in the finest Unix traditions:
pftctl -s rules | tr ' ' '\012' | grep '^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$' | sort -u
We list all the rules, turn spaces into newlines to give us one word per
line, and discard all words that don't look like IP addresses (and then
discard duplicates). That
pfctl separates words for us makes this both
possible and the easiest, simplest approach. It's probably also the most
reliable, since it's counting on almost nothing in
So: sometimes brute force really is the best answer.
Sidebar: sorting IP addresses into ascending order
Because I keep having to do this: assuming that you have regularly
formed IP addresses (using all decimal digits), the incantation on a
modern version of
sort to get them into proper ascending order by IP
sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4
(As I keep forgetting, you have to explicitly tell
sort that each
sort key is only one field long. Otherwise it starts at field N and
goes to the end of the line, which is not what we want.)