1
votes

I'm having trouble receiving a UDP packet sent from an FPGA in a python program. I've checked similar questions and did the following:

  • Checked that Wireshark can the see UDP packet
  • Disabled windows firewall in PC
  • Used sock.bind() since it's UDP packets
  • Manually set the destination MAC address on Ethernet frame since FPGA does not support ARP
  • Set dest IP to broadcast 10.10.255.255 for testing, no packets received
  • Set the UDP checksum of the packet from the sender to 0x0000

Here's the python receiver code:

import socket
import sys

UDP_IP = "10.10.10.87"
UDP_PORT = 4660

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
print("Socket: "+str(sock.getsockname()))
while True:
    data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
    print(data)
    print(addr)
    sys.stdout.flush()

When tested against another python script that sends to 10.10.10.87:4660 (from another PC in the 10.10.10 network) the receiver script works fine. I've even tried to recreate the UDP pcket byte-by-byte in the FPGA from packets that I know are received OK (Differences are source IP, port & MAC, checksums (disabled), identification).

Here's the output for both packets from Wireshark:

Wireshark UDP packet (Python UDP packet that gets received OK on the left, Xilinx FPGA packet that is not received by python on the right)

I'm not sure what else to try. Any help would be appreciated.

1
Aside: Setting UDP_IP to your local address is being overly specific. Instead, do UDP_IP = '' to bind to all interfaces. This won't solve today's problem, but might prevent problems in the future.Robᵩ

1 Answers

2
votes

Apparently the IPv4 header checksum from an FPGA calculation was wrong. It can get confusing to follow since the TTL (Time to Live) changes on a router hop, and the new TTL will also change the IPv4 header, forcing a new checksum per hop until it gets to Wireshark on the receiver end. By default Wireshark has IPv4 checksum validation disabled (as can be seen in the question screenshot), the answer is easier to spot with validation on.

I set the IPv4 checksum during packet construction to zero (x0000). It gets recalculated correctly at the router, and with the correct checksum Python can receive the packet.

I also tested a direct connection (without router) from the FPGA to the host PC. The IPv4 header also gets recalculated correctly (I'm not sure where, probably the PC's NIC?)

Hope this is useful to someone with similar problems.