Few folks who read this blog will need to know this, but I guess that's true of most of the stuff I post.
I switched ISPs for my home DSL to one who only gives me one IP address, and serves it by DHCP (meaning that my IP address changes over time). I have multiple computers in the house, so I needed to set up a NAT to allow them all to share the one address.
My NETGEAR DG814 modem/router works fine for this setup, but NATs tend not to work with interesting protocols, so I wanted to be able to run program on the NAT router, which meant that I had to roll my own box. I chose FreeBSD because that's what I use on all my servers. It's flexible, it works, and it's well-supported. Unfortunately, that meant that I had to get a new DSL modem, since I couldn't figure out how to put the NETGEAR into bridge mode.
The FreeBSD handbook said I should use one method for NAT that required recompiling the kernel, which I did, but I couldn't get the NAT to work. So, I sent a question to the FreeBSD general questions mailing list, and got back a reply that told me I should be using a different method called ipnat. With a bit more help from the person who answered my original question, I have the spare FreeBSD box running as a NAT. If I need to add services on the box, I can.
The gory details are that I used ipnat.
My system gets its external address from my ISP's DHCP server on interface em0. The machines in my house are connected to a switch that is attached to itnerface rl0.
Relevant stuff in /etc/rc.conf:
ifconfig_em0="DHCP"
ifconfig_rl0="inet 10.20.30.1 netmask 255.255.255.0"
gateway_enable="YES"
ipfilter_enable="YES"
ipnat_enable="YES"
ipnat_rules="/etc/ipnat.conf"
Contents of /etc/ipnat.conf:
map em0 10.20.30.0/24 -> 0/32
That's it. I have a great NAT, there's no firewall getting in the way of things, I can put services on the box if I need to gateway them to the NAT, and so on. I did this on a recent fast box that I have, but you can set up a NAT on any old creaky PC that has almost any tiny amount of RAM. FreeBSD wins again.