In http://www.freebsd.org/doc/handbook/firewalls-ipfw.html, section 18.104.22.168 on NAT and statefull, there is a typo, plus some misleading verbiage.
The last para before the example rules mentions rule 425 which doesn't exist, but I believe should be 420.
The misleading bit occurs in both of the last two paragraphs, specifically the phrase "released on the LAN". It obscures the processing that actually happens with check-state. In the inbound replies to an outbound connection, the check-state match does not do the "release", but causes the same "skipto 500" as in the original match. Rule 500 doesn't match an inbound packet, so natd is skipped, but rule 510 allows the packet. But we're still not released to the LAN as it will traverse ipfw on the inside interface, albeit getting a free pass from rule 2 then.
The inbound connection description is even further off. All the example rules are for services running on the firewall, so the inbound packet never reaches the internal LAN. It says the response to that after matching check-state "is then sent to rule 500", but it's not as the original keep-state rule is for an allow, not a skipto. The connection works because NAT isn't required for a service running on the firewall's external IP.
Finally the inbound connection description ought to cover a service running on an different interior server, too. The matching rule for that will need to use "skipto 500", rather than allow, so that the check-state for the response will go through the NAT. It took me about an hour to ferret that out today.
Rewrite descriptions of outbound and inbound connection processes. Add a rule for an inbound connection to a service running on a different server and describe difference between that and inbound to a service running on the firewall.
For bugs matching the following criteria:
Status: In Progress Changed: (is less than) 2014-06-01
Reset to default assignee and clear in-progress tags.
Mail being skipped