В итоге сделал так:
ipfw nat 1 config if em0 reset \ //Настройка первого набора NAT правил
redirect_port tcp 192.168.1.10:20-21 20-21 //Правило переадресации порта для FTP
ipfw nat 2 config if em2 reset \ // Настройка второго набора NAT правил
redirect_port tcp 192.168.1.10:20-21 20-21 //Правило переадресации порта для FTP
ipfw add skipto 1000 tcp from 192.168.1.10 20-21 to any xmit em0 // переход к 1000му правилу, если ответ FTP сервера проходит через интерфейс em0
ipfw add skipto 2000 tcp from 192.168.1.10 20-21 to 192.168.0.0/24 // переход к 2000му правилу, если ответ FTP сервера идет во вторую локальную сеть (можно сделать аналогично предыдущему правилу, xmit em2)
ipfw add 1000 nat 1 tcp from any to 10.0.2.15 20-21
ipfw add 1100 nat 1 tcp from 192.168.1.10 to any
ipfw add 1200 nat 1 ip from any to any via em0
ipfw add 2000 nat 2 tcp from any to 192.168.0.1 20-21
ipfw add 2100 nat 2 tcp from 192.168.1.10 to any
Данные правила должны работать по следующей логике:
Если пакет не передается по 20-21 порту, то он спокойно доходит до 1200 правила и пропускается файрволлом. Но если пакет относится к FTP, то вначале он доходит до 1000го правила, если он отправлен на em0 и до 2000, если на em2, оттуда он пересылается на FTP сервер. Skipto правила нужны, чтобы правильно распределить ответ сервера, тк 1100 и 2100 правила релевентны и без skipto могут неверно применяться правила NAT (вместо nat 2 ответы машин во второй локальной сети будут обрабатываться nat 1).
Пример делал, чисто как учебный, потому не самый безопасный. Вроде работает.