This is a series of patches (almost all) based on work at Ironport (pre Cisco buyout) by Julian Elischer and others. The core is simple - disable the "is the IP address local?" check in the bind() syscall path, and populate the PCB with non-local IP addresses. It happens to be fine with this. Contrast to the Linux TPROXY2 support, which implemented the above with double-NAT'ing so the source IP address spoof stuff didn't touch the TCP layer - and how badly that performed. (The TPROXY4 support does something quite similar to this work.) The tricky bit is then convincing the IP path to try doing a PCB lookup with packets that aren't on local IP addresses. That requires some IPFW related trickery. There are a few patches, with more coming. spoof_bind_sys.diff This implements the basic source IP address spoofing support. It introduces a new kernel build option (IP_NONLOCALBIND) to enable the code in the kernel, a sysctl to enable the functionality and a socket option to set to enable non-local IP address bind()'ing. Spoofing is implemented as follows: * Compile a kernel with option IP_NONLOCALBIND * sysctl net.inet.ip.nonlocalok=1 * create a socket to connect() with a spoofed address * Set the IP protocol socket option IP_NONLOCALOK to 1 * bind() to a non-local IP which you'll be spoofing * connect() to the remote host. Overview: The user has to use ipfw trickery to fool the kernel into handling packets which aren't necessarily destined for itself. Normally the kernel would only try matching on PCB's for packets destined to what are considered "local" IP addresses. Without any ipfw modifications, packets can be "fooled" into being handled locally if required; at least enough for testing. I do this as such: * Put the interception box inline between two subnets - so its acting as a router. * enable ip forwarding :) * Add in the following rules: # the clients are on bge1, the servers are on bge0 ipfw add 1000 fwd 127.0.0.1,8080 tcp from any to any 80 in via bge1 ipfw add 1020 fwd 127.0.0.1 tcp from any 80 to any in via bge0 * Enable ipfw * Squid (or whatever) will see the requests coming in on localhost:8080 and can create outbound sockets with the client IP address This ruleset will only redirect port 80; it doesn't redirect arbitrary packets for the PCB lookup. You probably don't want to do that. spoof_bind_sys_bridge.diff This bit of code implements some smarts in the bridging code to redirect packets into the IP layer if the ipfw layer says so (via a "fwd" rule.) spoof_bind_sys_ipfw.diff This is the kernel side of the IPFW changes to introduce a "for-me" rule which will do the PCB lookup as required, rather than any other hackery with uid lookups or the above fwd'ing. TODO: * generate a patch for the ipfw userland * documentation * test and debug the bridge/ipfw changes; make sure they're "correct"