{
    my $pf_chain = "PortForwarding_\$\$";
    $OUT .= "# Create a new PortForwarding chain\n";
    $OUT .= "PFC=\$(/sbin/iptables --table nat ";
    $OUT .= "--numeric --list PortForwarding |\\\n";
    $OUT .= "   sed -n '3s/ .*//p')\n";
    $OUT .= "    /sbin/iptables --table nat --new-chain $pf_chain\n";

    my %FDB;

    foreach my $protocol (qw(tcp udp))
    {
        my $uproto = uc $protocol;
        $FDB{$protocol} = esmith::ConfigDB->open("portforward_$protocol")
                || die "Can't open portforward_$protocol database: $!\n";

        foreach my $entry ( $FDB{$protocol}->get_all ) {
            my $port = $entry->key;
            my $ip = $entry->prop('DestHost');
            my $dport = $entry->prop('DestPort') || $port;
            $port =~ s/-/:/;

	    # Map canonical localhost back to our current external IP	
            $ip = '$OUTERNET' if ($ip eq 'localhost');

            my $host_list = $entry->prop("AllowHosts") || '0.0.0.0/0';
            foreach my $host (split(',', $host_list)) {

                $OUT .= "    /sbin/iptables --table nat --append $pf_chain";

                # Set up local port to forward
                $OUT .= " --proto $protocol --destination-port ${port}";
                $OUT .= " --src $host" unless $host eq '0.0.0.0/0';

                # Set up the remote port to forward to
                $OUT .= " -j DNAT --to-destination $ip:$dport\n";

            }

            # And accept the incoming packets. Use the dport if there is one.
            ($port = $dport) =~ s/-/:/ if $dport;

            # If this rule is forwarding to localhost, ExternalIP or LocalIP,
            # then we must allow it on the INPUT chain instead of the FORWARD
            # chain.

            my $target_chain = (($ip eq '$OUTERNET') ?
                "Inbound${uproto}_\$\$" : "Forwarded${uproto}_\$\$");

            foreach my $access_type (("Allow", "Deny")) {
                my $jump_target = (($access_type eq "Allow") ? "ACCEPT" : "denylog");
                my $host_list = $entry->prop("${access_type}Hosts") || "";

                $host_list = "0.0.0.0/0"
                    if (($host_list eq "") and ($access_type eq "Allow"));

                foreach my $host (split(',', $host_list)) {
                    $OUT .= "    /sbin/iptables -A $target_chain";
                    $OUT .= " --proto $protocol --dport $port \\\n        ";
                    $OUT .= " --destination $ip" if ($ip ne '$OUTERNET');
                    $OUT .= " --src $host --jump $jump_target\n";
                }
            }
        }
    }

    # having created a new PortForwarding chain, activate it and destroy
    # the old.
    $OUT .= "    /sbin/iptables --table nat --replace PortForwarding 1 " .
                "--destination \$OUTERNET --jump $pf_chain\n";
    $OUT .= "    /sbin/iptables --table nat --flush \$PFC\n";
    $OUT .= "    /sbin/iptables --table nat --delete-chain \$PFC\n";
}
