To allow exactly this behaviour, there are "connection tracker" modules in most firewall implementations, they work along the lines of:
- On the outgoing leg, the firewall reads what goes over the wire (and in many cases manipulates it). This way the firewall knows when an incoming connection,"ordered" by an outgoing one is imminent.
- When this incoming connection arrives, the firewall forwards it to the initiating machine.
In your case, the IP and port in the PORT
segment of the FTP command channel is read, parsed and manipulated by the firewall: The Internal IP of your PC (as sent by your FTP client) and port are replaced by the external IP of the firewall and most possibly a different port. This pair of tuples is stored together with an expiration time.
When the FTP server connects back to this IP and port, the tuple is looked up and if not expired connected back to your PC and thus FTP client. The pair of tuples is then discarded, as it is valid only once.
While this behaviour is not strictly necessary for FTP (just use passive mode), it is very usefull for other protocols which need a connect-back feature. Remember: NAT is rather a new concept, that was not anticipated when the IP protocol suite was invented.