NETWORK_REPORT: finish the BSD mapping (rip_input, tcp_input switches, ICMP checksums)

0x3F61EC00 is rip_input() (raw_ip.c:58): PCB-list walk on protocol/laddr/
faddr, sbappendaddr delivery, and the ips_noproto counter we recorded at
0x96500. The dsj gate compares that PCB field against 1 -- the raw socket
bound to ICMP -- so the 5/8/13..18 skip list is the raw-ICMP filter for types
the kernel answers itself.

The two TCP state tables map onto tcp_input's two switch(tp->t_state) sites
(506 and 865); table A's shared handler for CLOSING/LAST_ACK/TIME_WAIT matches
the source's fallthrough group at 840-842. ICMP checksum verify and reflect
match ip_icmp.c:184 and 522-523.
This commit is contained in:
arti committed 2026-10-30 01:39:37 +02:00
1 parent 3ad5a691b8
commit b8899645d0
1 file changed
+64
+64
View File
@@ -3722,3 +3722,67 @@ This confirms section 50 from a third independent direction and simplifies the
rule: the field is simply `-len`, and for any length under 4096 that always has
the top nibble set. There is no separate "0xF000 convention" to remember — a
positive value is simply wrong.
## 54. Remaining mappings: raw-IP delivery, TCP state switches, ICMP checksums
### 54.1 `0x3F61EC00` is `rip_input()` — raw IP delivery
`sys/netinet/raw_ip.c:58`. The three identifying constructs:
```c
raw_ip.c:65 for (inp = rawinpcb.inp_next; inp != &rawinpcb; inp = inp->inp_next) {
raw_ip.c:66 if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p) continue;
raw_ip.c:68 if (inp->inp_laddr.s_addr && inp->inp_laddr.s_addr != ip->ip_dst.s_addr) continue;
raw_ip.c:70 if (inp->inp_faddr.s_addr && inp->inp_faddr.s_addr != ip->ip_src.s_addr) continue;
raw_ip.c:80 sbappendaddr(&last->so_rcv, (struct sockaddr *)&ripsrc, n, 0)
raw_ip.c:96 sbappendaddr(&last->so_rcv, ...)
raw_ip.c:100 ipstat.ips_noproto++;
```
which are exactly the parts of `0x3F61EC00` measured earlier: a PCB-list walk
comparing a protocol word, a local and a foreign address, delivery through a
queue append, and the **`ips_noproto` counter on no match** — the counter we
recorded at `0x96500` (section 29.2).
The `dsj` gate found in section 46 compares that PCB field against 1, i.e. the
raw socket bound to **ICMP** (`inp->inp_ip.ip_p == IPPROTO_ICMP`); the
5/8/13…18 skip list is then the raw-ICMP socket filter — those are the types the
kernel answers internally, so a raw socket must not also receive them.
### 54.2 The TCP state tables are `tcp_input`'s two switches
`sys/netinet/tcp_input.c` has two dispatches on `tp->t_state`:
```
tcp_input.c:506 switch (tp->t_state) { <-- our table B (0x3F6417C0)
tcp_input.c:823 if (tiflags&TH_RST) switch (tp->t_state) {
tcp_input.c:825 case TCPS_SYN_RECEIVED:
tcp_input.c:829 case TCPS_ESTABLISHED:
tcp_input.c:840 case TCPS_CLOSING:
tcp_input.c:841 case TCPS_LAST_ACK:
tcp_input.c:842 case TCPS_TIME_WAIT:
tcp_input.c:865 switch (tp->t_state) { <-- our table A (0x3F63F350)
tcp_input.c:872 case TCPS_SYN_RECEIVED:
tcp_input.c:897 case TCPS_ESTABLISHED:
```
The grouping matches table A exactly: in section 24.2, states **7 CLOSING,
8 LAST_ACK and 10 TIME_WAIT all share the target `0x3F63F200`** — the same
fallthrough group as `tcp_input.c:840-842`. Table A's SYN_RECEIVED handled
separately and ESTABLISHED family grouped also matches `:872` vs `:897`.
### 54.3 ICMP checksum sites
| ROM | source | evidence |
|---|---|---|
| `0x3F6206D0` (verify) | `ip_icmp.c:184` `if (in_cksum(m, icmplen))` | checksum over the ICMP message before the type switch |
| `0x3F623350` (reflect) | `ip_icmp.c:522-523` `icp->icmp_cksum = 0; icp->icmp_cksum = in_cksum(...)` | zero the field, recompute, store — exactly the sequence at `0x3F62FF60`..`0x3F630000` |
### 54.4 Coverage
With 53 and 54, every function the report gives an address for now has a BSD
counterpart: driver (`leinit`/`lereset`/`ledrinit`/`lestart`/`leintr`/`lerint`),
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`).