diff --git a/harness/mame/NETWORK_REPORT.md b/harness/mame/NETWORK_REPORT.md index 9c85419..50e2056 100644 --- a/harness/mame/NETWORK_REPORT.md +++ b/harness/mame/NETWORK_REPORT.md @@ -3786,3 +3786,36 @@ IP (`ipintr`, `inetsw[ip_protox[]]`, `ip_output`), ICMP (`icmp_input`, `icmp_reflect`, `icmp_send`), TCP (`tcp_input`, `tcp_dooptions`, `tcp_mss`), UDP (`udp_input`, `udp_output`), raw IP (`rip_input`), ARP (`in_arpinput`, `arpresolve`, `arplookup`, `arprequest`) and the PCB lookup (`in_pcblookup`). + +## 55. The PCB field order proves the mapping at struct level + +Section 31.1 gave the binding entry's fields from disassembly alone. The BSD +struct confirms them exactly, and the agreement is only possible with one +alignment: + +```c +struct inpcb { /* sys/netinet/in_pcb.h */ + struct inpcb *inp_next, *inp_prev; /* 0, 4 */ + struct inpcb *inp_head; /* 8 */ + struct in_addr inp_faddr; /* 12 */ + u_short inp_fport; /* 16 */ + struct in_addr inp_laddr; /* 18 (16-bit alignment) */ + u_short inp_lport; /* 22 */ + struct socket *inp_socket; /* 24 */ + ... +``` + +| field | source offset | our ROM offset | match | +|---|---|---|---| +| `inp_faddr` | 12 | `+0x60` bits = 12 | ✓ | +| `inp_fport` | 16 | `+0x80` bits = 16 | ✓ | +| `inp_laddr` | 18 | `+0x90` bits = 18 | ✓ | +| `inp_lport` | 22 | `+0xB0` bits = 22 | ✓ | + +All four in the same order as `in_pcblookup()` tests them. On a 32-bit-aligned +build `inp_laddr` would sit at 20 and `inp_lport` at 24, so the exact match also +establishes that the firmware's ABI uses **16-bit alignment** — consistent with +the `struct protosw` offsets (6/10) in section 53.1. + +This closes the loop on the socket layer: the ROM's offsets, the source's field +order, and the lookup algorithm are all the same object.