Route IP Packets with Same Source and Dest IP


I am hand-crafting ethernet packets using socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP)), and have successfully sent UDP packets from my PC to my router this way. Using tcpdump on both ends, I can see that the PC sends out a packet with the intended contents, and the router receives it. Specifically, I am using the following command to watch for my constructed packets with source port = 0 and dest port = 34567: sudo tcpdump -i any -e -x udp port 34567 -vvv

I am seeing some unexpected behavior, however, depending on what I put in the source and dest IPs in the v4 header. Specifically, if I set the source and dest IP both to the PC address, I see the outbound packet on the PC, but I don't see any message on the router that the nic received it. If I set source = <pc> and dest = <router> I see a message (obviously), and if I set source = and dest = <pc>, I see the message, too. But in no cases does the router send the packet back to the PC.

So my questions are:

  1. Why does having source = dest = <pc> in the IPv4 header prevent tcpdump from showing the packet?
  2. Why isn't my router forwarding on the packet with dest = <pc>? Note that I tried adding an iptables rule -A FORWARD -i enp2s0 -o enp2s0 -j ACCEPT where enp2s0 is my LAN-connected nic, but it didn't help.

For additional context, see my earlier question: Route Local-Interface-Destined Packets to Gateway

Best Answer

I was finally able to get it to work. There were a number of reasons things weren't getting through:

  1. Setting the source and dest IP to the same value in the IPv4 header is apparently classified as a LAND Attack. While the specific packet I crafted wouldn't trigger DOS (since it demands no reply), I suspect something deep in the linux kernel is dropping the packet before it even gets to tcpdump. I was able to work around it by spoofing a public IP.
  2. My router FORWARD chain only had rules for LAN>WAN and WAN>LAN. Adding a new ACCEPT rule for LAN>LAN allowed the packet to be sent back to the PC.
  3. My PC INPUT chain allowing ESTABLISHED/RELATED packets, but because of the address spoofing, the firewall did not classify the forwarded packet as NEW, even though it was just sent as an outgoing packet. Adding a new rule to explicitly ACCEPT the packet fixed it.

Proof for posterity:

Hello, Raw!
Listening on port 34567 (0x8707)
Building ethernet packet with 64 bytes comprised of headers of size 14 (ETH) + 20 (IP) + 8 (UDP)
Interface eno1 at index 2
Interface eno1 has mac <redacted>
Sent 64 bytes:
 <redacted> 08 00
 45 00 00 32 00 00 00 00 40 11 B4 BE <redacted> C0 A8 03 53
 00 00 87 07 00 0C 08 61
 3F 4F 6B 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Server successfully read message from client: [?Ok!]
Related Question