I worked more on this, and success! (almost). It is starting to work. The journey to get there was... tough to say the least. And it does not help that tools are old or non existent.
I managed to communicate with my mac - turns out I was doing the CRC wrong (d'oh). Once the CRC was ok my mac started responding back to pings. The difficult part here was that aecho from netatalk depends, well, on netatalk so I had to write a stripped down version by myself (in the file nbp.c, I know, originally it was meant to do nbp, I will fix it next time
. I could see the pings in tcpdump but they would never show in recvfrom(). I could never get any data actually - I saw it (properly decoded) with tcpdump but it never made it to userspace.
After lots of debugging and sweat turns out there is some magic happening with the DDP header which I don't completely understand. ddp.c in the Kernel says:
/*
* Receive a LocalTalk frame. We make some demands on the caller here.
* Caller must provide enough headroom on the packet to pull the short
* header and append a long one.
*/
What does that mean? Well the clue comes later:
/*
* The push leaves us with a ddephdr not an shdr, and
* handily the port bytes in the right place preset.
*/
ddp = skb_push(skb, sizeof(*ddp) - 4);
It replaces the shotr DDP header from localtalk with the extended one. Fair enough. But it does not work and printing bytes shows that the data offsets are wrong. Well cops.c comes to the rescue when pushing data:
skb_reset_mac_header(skb); /* Point to entire packet. */
skb_pull(skb, 3);
skb_reset_transport_header(skb); /* Point to data (Skip header). */
The magic like is the skb_pull, which makes it possible to neatly overlay the header with the incoming data. Sincerely now I'm super tired and I can't figure out why it works, but it works. Adding that like makes the pings come back!
24 bytes from 0.56: aep_seq=17. time=16. ms
Why didn't I copy that like of code originally? well, it breaks tcpdump! I always (incorrectly) assumed the data I saw with tcpdump was exactly the data sent out by the ddp layer, but it is not. So now tcpdump is broken but DDP actually works. This means netatalk is the next step. Ah yes and also addressing, now tashtalk is hardcoded as device 2.