I think you could pull this off w/ iptables
and the samplicator
tool if you're using a new enough kernel to support the raw
table.
First, why socat
won't work: Teeing a packet flow with socat
is fairly easy. You'd just do this:
socat - udp4-listen:20000,fork | tee >(socat - udp-sendto:X.X.X.X:20001) >(socat - udp-sendto:Y.Y.Y.Y:20000)
That duplicates the traffic to X.X.X.X:20001
and Y.Y.Y.Y:20000
.
That doesn't help you, though, because the service listening on X.X.X.X:20001 is going to "see" 127.0.0.1 as the source address. That's where samplicator
can help out. Quoth the samplicator
Google code page:
This simple program listens for UDP datagrams on a network port, and sends copies of these datagrams on to a set of destinations. ... Another option is that it can "spoof" the IP source address, so that the copies appear to come from the original source, rather than the relay.
That sounds like exactly what we need re: the source address. (Having said that, I haven't actually tested this tool. The box I'm testing on doesn't have compilers installed and I'm not going to spin up something right now just for Server Fault. >smile<)
The last thing you'd need is to take care of the traffic coming from X.X.X.X:20001
, making it appear to come from X.X.X.X:20000
.
Then, to NAT the replies from X.X.X.X:20001
to "come from" X.X.X.X:20000
:
iptables -t raw -A POSTROUTING -s X.X.X.X -p udp --sport 20001 -j NOTRACK
iptables -t nat -A POSTROUTING -s X.X.X.X -p udp --sport 20001 -j SNAT --to-source :20000
Beware: I haven't tested all of this together. I mocked it up with socat
and it worked fine minus the source address "spoofing" that samplicator
provides.