0

I receive UDP broadcast packets on wlan0 on my Raspberry Pi which I'd like to forward to my desktop for analysis via eth0.

I'm running a modified WiFi firmware on a raspberrypi which sends UDP packets on wlan0. I can capture them with tcpdump on the raspberrypi:

root@raspberrypi:/home/pi# tcpdump -i wlan0 dst port 5500 -vv
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
07:13:15.368931 IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto UDP (17), length 1070)
    10.10.10.10.5500 > 255.255.255.255.5500: [no cksum] UDP, length 1042
07:13:15.470352 IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto UDP (17), length 1070)
    10.10.10.10.5500 > 255.255.255.255.5500: [no cksum] UDP, length 1042
07:13:15.573735 IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto UDP (17), length 1070)
    10.10.10.10.5500 > 255.255.255.255.5500: [no cksum] UDP, length 1042
07:13:15.675052 IP (tos 0x0, ttl 1, id 1, offset 0, flags [none], proto UDP (17), length 1070)

As you can see they are UDP packets from 10.10.10.10:5500 destined to 255.255.255.255:5500. To forward them, I've tried using netfilter:

table ip nexmoncsi {
    chain PRERT {
        type nat hook prerouting priority dstnat; policy accept;
        ip saddr 10.10.10.10 ip daddr 255.255.255.255 udp sport 5500 udp dport 5500 dnat to IP-Desktop
    }

    chain POSTRT {
        type nat hook postrouting priority srcnat; policy accept;
        ip saddr 10.10.10.10 ip daddr 255.255.255.255 udp sport 5500 udp dport 5500 snat to IP-Raspberrypi
    }
}

I've enabled forarding with sysctl

sysctl net.ipv4.ip_forward=1

sysctl net.ipv4.conf.eth0.forwarding=1
sysctl net.ipv4.conf.wlan0.forwarding=1

sysctl net.ipv4.conf.eth0.bc_forwarding=1
sysctl net.ipv4.conf.wlan0.bc_forwarding=1

I ran the same tcpdump command on the desktop to get the packets, but there are none. tcpdump on the pi still reports packets, which I'm guessing shouldn't happen if they're forwarded.

I've verified that the matches are correct and that netfilter sees the packets with count in a filter chain. Incidentally the count in the filter chain stops working when the preroute and postroute chains are added.

ufw is disabled on the desktop, and nft ruleset on it has empty chains with no rules. What could be making the forwarding not work?

1 Answer 1

1

Broadcasts packets are ignored when forwarding.

They are sent to a router and the router then broadcasts them to devices it knows about, but they aren't meant to be forwarded, especially not across subnets/devices.

And so dnat ignores broadcast packets. If your router forwarded broadcasts in your network to the internet, the internet would be filled with random broadcasts from people across the world.

Now, to send broadcast packets, duplicate the packets, and tell them your device is the router. They reach your target device with the intention of being broadcasted inside the subnet.

iptables -t mangle -A INPUT -i wlan0 -d 255.255.255.255 -j TEE --gateway IP-desktop

It's also possible to use the target's network's broadcast IP to broadcast the forwarded packets again. More information here: https://odi.ch/weblog/posting.php?posting=731

Converting this to nftables using iptables-restore-translate, this is what I ended up with:

sudo nft add table ip mangle
sudo nft 'add chain ip mangle INPUT { type filter hook input priority -150; policy accept; }'
sudo nft add rule  ip mangle INPUT iifname "wlan0" ip protocol udp ip saddr 10.10.10.10 ip daddr 255.255.255.255 udp sport 5500 udp dport 5500 counter dup to IP-desktop

And my nftables ruleset is:

# sudo nft list ruleset

table ip mangle {
    chain INPUT {
        type filter hook input priority mangle; policy accept;
        iifname "wlan0" ip saddr 10.10.10.10 ip daddr 255.255.255.255 udp sport 5500 udp dport 5500 counter packets 4343 bytes 4647010 dup to IP-desktop
    }
}

Note that the destination IP address is still 255.255.255.255. It's possible to change this. mark the broadcast packets, and in the output hook, mangle the IP headers of packets with the mark.

nft add table ip mangle

nft 'add chain ip mangle input  { type filter hook input  priority -150; policy accept; }'
nft 'add chain ip mangle output { type filter hook output priority  150; policy accept; }'

nft add rule ip mangle input  iifname "wlan0" ip protocol udp ip saddr 10.10.10.10 ip daddr 255.255.255.255 udp sport 5500 udp dport 5500 counter mark set 900 dup to IP-desktop device "eth0"
nft add rule ip mangle output oifname "eth0"  meta mark 900 counter ip saddr set IP-source ip daddr set IP-desktop
# sudo nft list ruleset

table ip mangle {
    chain input {
        type filter hook input priority mangle; policy accept;
        iifname "wlan0" ip saddr 10.10.10.10 ip daddr 255.255.255.255 udp sport 5500 udp dport 5500 counter packets 192445194 bytes 107384418252 meta mark set 0x00000384 dup to IP-desktop device "eth0"
    }

    chain output {
        type filter hook output priority 150; policy accept;
        oifname "eth0" meta mark 0x00000384 counter packets 192445135 bytes 107384385330 ip daddr set IP-desktop ip saddr set IP-source
    }
}

Additional resources:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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