Files
rebbarb/scripts
Roflin 7b94da0be5 fsp-server: add a raw-ethernet transport, because UDP replies never arrived
The trace settled it: our reply satisfies EVERY check fsplib makes --
fsp_pkt_read's checksum (0x9a computed, 0x9a present), len <= recv_len,
(reply.seq & 0xfff8) == s->seq, cmd match, and fsp_getpro's pos ==
FSP_PRO_BYTES with the flags byte at buf[len].  Yet the console retried the
same transaction (seq 0x8ccb -> 0x8ccc, txn 0x8cc8 try 3 -> try 4).

The decisive evidence is the key: fsplib calls client_set_key(rpkt->key) on any
ACCEPTED reply, so the next request would carry our 0x1234.  Every request
still carries 0x8022.  No reply has ever been accepted -- so they are not
arriving, and the problem was never the protocol.

What differs from the thing that worked: mini-dhcpd.py replies over AF_PACKET
and got a DHCP lease immediately, while this server used a normal UDP socket,
whose reply depends on the kernel having a route to the console, an ARP entry
for it, and choosing the right source address.  (AF_PACKET also never populates
the kernel ARP table, so DHCP succeeding tells us nothing about those.)

--iface <dev> now replies with raw ethernet frames that MIRROR the request's
own addresses -- MACs swapped, IPs swapped, ports swapped -- which removes
routing, ARP and source-address selection in one go.  The UDP path is kept for
when it is not needed.

Frame construction is tested: the reply carries the console's MAC as
destination and ours as source, source IP 10.0.0.1 and destination 10.0.0.64
taken from the request, ports 21 -> 4096, a valid IP checksum, correct UDP
length, and padding to the 60-byte ethernet minimum.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-10 16:26:00 +02:00
..