Please don't forget UDP. For UDP you need to save the original destination, and then implement a control message extension for sending this to userspace together with the packet in response to a recvmsg() call, or hack the kernel to return the original destination in IP_PKTINFO (would be the most natural I think).
See earlier post from me for a lengthy discussion on how one can do this in the current NAT scheme. If you same the address in the actual skb then this becomes even easier. In case of IP_PKTINFO only only two lines.. Reviewing the existing sockopt options the following seems like the correct calls: * For TCP, return the original destination in getsockopt(SOL_IP, IP_PKTOPTIONS...) * For UCP, return the original destination in the IP_PKTINFO recvmsg control message, and if possible, use the same to allow the application to control the source address when sending packets using sendmsg(). What I do not quite get is how TPROXY is supposed to handle return traffic, fragmented packets or ICMP, if you are doing stateless NAT. Also, who is responsible for making sure the application protocol is NAT:ed properly in TPROXY. For example FTP PASV. Is it the kernel, or is it the userspace proxy responsibility to get the correct (foreign) IP address in such case? And what about "related" connections such as an FTP data channel? Sorry if I am making things overly complex here.. In my view (as an application developer, not netfilter hacker) the problems with the standard netfilter approach are: 1. Cannot easily support non-local bind, to allow the userspace proxy application to masquerade as the client 2. Cannot get the original destination of a redirected UDP packet in an easy manner (might be possible by parsing /proc/net/ip_conntrack and quess which is the correct "connection"...) 3. conntrack adds yet another state table, with a bunch of new DOS conditions one must worry about.. Regards Henrik