Interestingly I started writing a perl script to help automate adding new rules to ipf. It started with the need to easily add new blocking rules to IP addresses, either manually via the commandline or (potentially more dangerously) dynamically from other systems (for example from mod_security the apache security module or snort).
Unfortunately I didn't get too far with it, but you're welcome to look at what I did. I'll post the code here... it's probably too embarrassing to post but still who knows you might find it interesting!
#!/usr/bin/perl
# Script for controlling ipfilter rules
use strict;
use Getopt::Std;
my $progname = $0;
$progname =~ s,.*/,,; # use basename only
$progname =~ s/\.\w*$//; # strip extension, if any
if ($< != 0) {
print STDERR "${progname}: Error: you must be root to use $progname\n";
exit(1);
}
my $div="#"x72;
my %opt=();
my @rules=();
my ($err, $verbose);
my ($rule_dir, $order_file);
my ($rule_file, $rule);
my $default_order_file = "order.ipf";
my $default_rule_dir="/usr/local/etc/ipf";
my $ipf = "/sbin/ipf";
my $tmp_file="/tmp/$progname.$$";
# find out what options we're passed:
&getopts('lod:hv', \%opt);
$verbose=1 if $opt{v};
if($opt{d}){
$rule_dir=$opt{d};
}else{
$rule_dir=$default_rule_dir;
}
$order_file="$rule_dir/$default_order_file";
# check order file readable:
if( ! -r $order_file ){
&usage("Cannot read $order_file");
}
# display usage if bad opts:
if($opt{h} || !%opt){
&usage();
}
# get the ruleset based on $order_file:
&ruleset_build($order_file);
if($opt{o}){
foreach (@rules) { print "$_\n" };
}
if($opt{l}){
&load_rules();
}
sub load_rules{
# Write the rules to a temp file:
open(FP, ">>$tmp_file");
foreach (@rules){ print FP "$_\n"; }
close FP;
# Read the rules into the inactive list:
exec("$ipf -I -v -Fa -f $tmp_file");
}
# Build the ruleset from the order file in $rule_dir:
sub ruleset_build {
$order_file = shift;
print "Order File $order_file contains:\n" if($verbose);
open(FD, $order_file);
while($rule_file=<FD>){
chomp $rule_file;
print "$div\n$rule_file:\n" if($verbose);
# skip comments and empty lines:
next if $rule_file=~/^#|^$/;
# if this rule_file is regular file, read the rules:
$rule_file="$rule_dir/$rule_file";
if( -f $rule_file){
&read_rules_file();
}
elsif( -d $rule_file){
my $child_rule_dir = "$rule_file";
if($verbose){
print "Reading rules from directory: $child_rule_dir\n";
}
opendir(DP, $child_rule_dir);
while($rule_file=readdir(DP)){
chomp($rule_file);
next if($rule_file=~/\./);
$rule_file="$child_rule_dir/$rule_file";
print "$div\n$rule_file:\n" if($verbose);
&read_rules_file();
}
}
}
close FD;
}
sub read_rules_file{
open(FR, "$rule_file");
while($rule=<FR>){
chomp $rule;
print("$rule\n") if($verbose);
next if $rule=~/^$/;
push(@rules, $rule);
}
close FR;
}
sub usage{
$err=shift;
$err && (print $err);
die<<"~USAGE~";
Usage: $progname [-d <directory>] [-h] [-o] [-D]
-h Display this help.
-v Be verbose.
-l Load the rules that are found in the rule
directory.
-d <directory> Specify the directory that contains rules
to be used. This directory should contain
the files containing the rules and a file
called 'order.ipf' which specifies the
order in which those rules should be
added.
Defaults to $default_rule_dir
-o Output the list of rules that would be
loaded by -l.
~USAGE~
}
In a real mess, didn't really get anywhere with it

Probably needs some explanation - I was thinking about creating a system that would allow you to dynamically add blocking rules for a given IP address. Moreover I was just trying to tidy up my firewalling system on the FreeBSD machine. I was getting more and more entries in my main ipf rule file, and starting to build up a set of different 'categories' of rule (for example rules for blocking brute force attacks, spammers, web exploiters/abusers, etc).
I wanted to try and tidy this all up such that when I wanted to add a spammer to my rule set, I'd just have to add that spammer's IP address to a single file. Then when ipf was restarted, that ip address would automatically be added to the block list. Same for the other blocking categories.
Unfortunately I never got to finishing it - it turned out to be a little more complicated than I'd bargained on and not really worth the hassle for what I needed. I've still just got a single file containing all the rules which is fine for me.
Some ideas for you anyway, do you have anything done yet?