I love writing applications and script. I wrote an IP-Blocklist package for the pfsense router. There is no PeerGuardian2 available for freeBSD so I made one.

This package is really sweet because you can upload list URLs and add manual IPs to block. The IPFW adds a drop entry for each IP. A perl script converts the addresses from the URL list to a ipfw friendly command.

#!/usr/bin/perl -w
use strict;

if($#ARGV != 1) {
    print("Usage: $0 <input file> <output file>\n");

my ($line,$title,$iprange,$cidr);
my $i = 30000;

open(INFILE,'<‘,$ARGV[0]) or die("Could not open input file $ARGV[0]");
open(OUTFILE,’>>’,$ARGV[1]) or die("Could not open output file $ARGV[1]");

foreach $line (<INFILE>) {
    $line =~ s/:((\d{1,3}[-\.]*){8})//;
    $iprange = $1;
    print OUTFILE "#$line\n";
    foreach $cidr (split(/\n/,range($iprange))) {
        print OUTFILE "ipfw -q add 1000 drop ip from any to $cidr\n";     
        print OUTFILE "ipfw -q add 1001 drop ip from $cidr to any\n";     


sub ntoa {
    return join ".",unpack("CCCC",pack("N",shift));
sub aton {
    return unpack ‘N’, pack ‘C4’, split/\./, shift;
sub deaggregate {
    my $thirtytwobits = 4294967295;
    my $start = shift;
    my $end = shift;
    my $base = $start;
    my ($step,$output);
    while ($base <= $end) {
        $step = 0;
        while (($base | (1 << $step)) != $base) {
            if (($base | (((~0) & $thirtytwobits) >> (31-$step))) > $end) {
        if($step == 0) {
            $output .= ntoa($base);
            $output .= ntoa($base)."/" .(32-$step);
        $output .= "\n";
        $base += 1 << $step;
    return $output;
sub range {
    my ($address,$address2) = split /-/, shift;
    $address = aton($address);
    $address2 = aton($address2);
    return deaggregate($address,$address2);

Using this I can process the over 225 thousand line lists in a matter of minutes. The really long lists take more than an hour but it pays off. Now you can block spam, hackers, and bogon addresses.


There are some limits though.

Lists can have any extension BUT if the list is compressed only .gz is supported.
Long lists take a very LONG time to process. A level1 list (225,000 lines) will take over 1h or more
The Firewall entries are lost on several occasions (when config.inc is processed) such as Rebooting, restarting the WebGUI, restarting SSH, etc…