This morning I was trying to do what should be a trivial operation with any modern operating system: forward traffic destined for a UDP port on my machine to a different port on the same machine. Specifically, I wanted to redirect SNMP traffic coming in to UDP port 161 over to UDP port 10161 so a user program could receive the packets.
My first feeble attempts to achieve this with netcat
(or nc
) met with failure, when the sending netcat process terminated after processing the first UDP datagram:
# This processes one packet then dies :-(
$ sudo nc -u -l 161 | nc -k -u localhost 10161
Perhaps there’s some way to get the second process not to die when it receives the data, but I couldn’t see how to do it.
The second approach I tried was using my Mac’s firewall tool, ipfw
. This is the BSD industrial-strength firewall tool and should definitely be up to the task.
You need to enable the firewall via System Preferences, Security, then add the rule via ipfw
. Here’s the rule I added:
# This logs that it is redirecting traffic but doesn't seem to do it
$ sudo ipfw add fwd localhost,10161 log udp from any to any dst-port 161 in
Again, this seems like it should work, the system logs indicated it was working, but no data arrived on port 10161 when I configured the listening process. Here are the configured rules listed by ipfw
:
$ sudo ipfw list
00100 fwd 127.0.0.1,10161 log udp from any to any dst-port 161 in
65535 allow ip from any to any
Solution
After all these false starts, my actual solution was to install and use socat, a multi-purpose networking relay tool. Here’s the relevant command:
$ sudo socat UDP4-RECVFROM:161,fork UDP4-SENDTO:localhost:10161
Running this in the background redirects all the traffic from UDP port 161 to port 10161 on the localhost
loopback interface. I also ended up redirecting stderr to /dev/null/
to avoid useless errors when the listening process on port 10161 wasn’t running.
If you know a way to get the same thing working with either of the tools above, please let me know. I’d be glad to have it posted here for posterity.
Update 15 November: UDP4-RECVFROM
and UDP4-SENDTO
are better options for use with an unreliable receiving server.