I posted this to the apps devel group last week with no response. Perhaps
someone here would find this useful? I'd love to hear some feedback on
it. My ultimate objective is just to display the rule tree in a
hierarchical form so I can follow all the subchains. So each -J subchain
target would appears as a subtree in the hierarchy (possibly multiple
times if it's used by multiple rules in other chains).
I threw together a bit of Perl to parse the output of iptables-save into
a nested structure, posted inline below. Perhaps someone with nimbler
fingers would like to toss it up on the screen in a Tk::HList, with
color-coding for accept/reject/drop terminal conditions?
For Red Hat users, you can use:
iptables-display.pl < /etc/sysconfig/iptables
to dump the boot-time firewall.
For the in-memory firewall, use:
iptables-save | iptables-display.pl
--
Kenneth Porter
http://www.sewingwitch.com/ken/
Code follows:
#!/usr/bin/perl -w
use strict;
use Text::ParseWords;
use Data:

umper;
my %main_table;
my $current_table;
while (<>) {
# remove trailing newline
chomp;
# split into fields on space, handling quoted strings in log lines
my @Entry = parse_line('\s+', 0, $_);
# first char of iptables-save format is one of:
# * main (-t) table name
# # comment
# : regular (-A) table name
# C COMMIT directive (end of main table)
# [ rule (start of counters)
my $firstchar = substr($Entry[0],0,1);
if ("*" eq $firstchar) {
# new major table
$current_table = substr($Entry[0],1);
} elsif (":" eq $firstchar) {
# new minor table, add it to the major table
$main_table{$current_table}{substr($Entry[0],1)} =
{ "policy" => $Entry[1], "rules" => [ ] };
} elsif ("[" eq $firstchar) {
# get rid of counters on front of list
shift(@Entry);
# fall through....
}
if ("-A" eq $Entry[0]) {
# new rule, append to minor table rules array
my $sub_table = $Entry[1];
# rule is hash indexed by iptables switch name
my %rule = splice(@Entry,2,-1);
push(@{$main_table{$current_table}{$sub_table}{"ru les"}},
\%rule);
}
# ignore all other lines
}
print Dumper(\%main_table);