I'm currently setting up IPtables to redirect certain UDP payloads to my application.

Here is an example of what I have working so far:

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32  '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12=0x54536F75 && 0>>22&0x3C@16=0x72636520 && 0>>22&0x3C@20=0x456E6769 && 0>>22&0x3C@24=0x6E652051 && 0>>22&0x3C@28=0x75657279' -j REDIRECT --to-port 21015

This is working, it will redirect packets containing the payload:


from one port to my application on another.

The problem is, I have another piece of data I wish to redirect, but it's not the same all the time. The packet looks like this:


However, the packet can also sometimes look like this:


I've tried something such as this:

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32  '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12=0x55' -j REDIRECT --to-port 21015

I'm guessing the problem is something to-do with me trying to match 2 bytes rather than the 4 as normal? The above doesn't error but it also doesn't redirect the packets.


1 Answer 1


That would be at your convenience (in one line, but I had to display it like this to have bold working):

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32 '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12>>24=0x55' -j REDIRECT --to-port 21015


iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32 '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12&0xFF000000=0x55000000' -j REDIRECT --to-port 21015

In both cases you remove from the equation the part you don't want to compare, either by shifting 3 bytes to the right and keeping only the 1st one, or by using a mask that will keep in the equation only the 1st byte. The second one is more flexible.

There's an example in man iptables-extensions similar to the 1st choice:

... 0 >> 22 & 0x3C @ 0 >> 24 = 0"


This is the first 4 bytes of the ICMP payload, of which byte 0 is the ICMP type. Therefore, we simply shift the value 24 to the right to throw out all but the first byte and compare the result with 0.

Also note that since it's the nat table, if the source port doesn't change, only the first UDP packet will be considered. After this conntrack will handle the flow and your rule won't see the other packets. So if each packet is independent, make sure the source port changes, and you might have to use the nfct tool along with a -j CT --timeout rule to shorten conntrack's "memory" and avoid filling its tables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.