Question for the GOD LLM - why does 100 REJECT our username-accepted LAPB frame?¶
Setup¶
Our C# TAD responder is node 102 (d102). Node 100 (retrocore) does @connect-to d102.
Connect, session-setup, terminal-setup, and the MOTD/banner all work: 100 renders the banner
and the ENTER prompt. The user types a username (ds + CR). Our responder answers with the
section-21/22.15 login ladder. That answer is where it breaks.
Everything below is from our runner log (both directions logged) plus the decoded capture
E:\Dev\Ronny\X25Emulator\pcap\conn-to-d102-from-100.md. No guesses - byte evidence only.
The failing exchange (our runner log)¶
After 100 sends the username as a BDAT (100->102, LAPB N(S)=5):
rx a=0x89 I ns=5 nr=5 ...0108DD07 2100 96 84 ... 0103 E4F38D (BDAT "ds"+CR, parity)
TX a=0x09 I ns=5 nr=6 09CA 21130003 0064 0066 0005 0001 DE 19 (routing ACK of 100's datagram 0x0005)
TX a=0x09 I ns=6 nr=6 09CC 2113000E 0064 0066 0007 0108 DD 05 2100 96 00 00 6402AA 0066 0211 01080000 000B 01020D0A130200030E0100 (USERNAME-ACCEPTED: BDAT CRLF + SYCN 0003 + CESC 00)
TX a=0x09 I ns=7 nr=6 09CE 2113000E 0064 0066 0008 0108 DD 04 2100 96 00 00 6402AA 0066 0211 01080000 0012 010A 50415353574F52443A20 000301FF 0200 (PASSWORD prompt: BDAT "PASSWORD: " + ECKM FF + RFI)
rx a=0x09 RR nr=6 09C1 0064 D970
rx a=0x09 REJ nr=6 09C9 0064 1BB6
PASSWORD:.
Interpretation: 100's V(R) stays 6 the whole time. REJ nr=6 = 100 received an out-of-sequence
I-frame (it got ns=7 while expecting ns=6) and wants ns=6 resent. So 100 never accepted ns=6.
What we VERIFIED (so you can rule these out)¶
- Our ns=6 frame is VALID HDLC. We ran its exact logged body through our own encoder+deframer (Fcs16, reflected CRC poly 0x8408, init 0xFFFF, ~crc, low byte first): it round-trips with a good FCS and exact byte recovery. So the frame we build is not malformed.
- The transmit path writes each encoded frame verbatim and in order (independent byte arrays, no buffer reuse, no concatenation). So the wire bytes ARE our valid ns=6.
- The transport is a TCP bridge (reliable) to
nd100x --hdlc. Bytes are not "lost". - ns=6's XMSG content is byte-identical to the capture's ACCEPTED username-accepted frame
(see below): same payload
01020d0a130200030e0100, XMLEN 000B, frameFlags 96, role 00, XMCSM 01080000, flags2 0108. - Our MOTD/banner frame earlier in THIS session used LAPB address 0x09 and 100 ACCEPTED it (acked Flags1 0x0006, rendered ENTER). So 100 accepts our 0x09 data I-frames.
The one wire-level difference we can see¶
Capture's ACCEPTED username-accepted frame (d102->100), conn-to-d102-from-100.md:164:
89cc 2113000e 0064 0066 0136 0108 db d6 2100 96 00 00 6402ab 0066 04c2 01080000 000b 01020d0a130200030e0100 f56b
09cc 2113000e 0064 0066 0007 0108 dd 05 2100 96 00 00 6402aa 0066 0211 01080000 000b 01020d0a130200030e0100 (fcs)
0x89, ours 0x09.
- Flags1 / counter / channel-epoch / ports: session-specific (capture is a long epoch-2 session
on channel 0xDB counter 0xD6; ours is a fresh epoch-0 session on 0xDD counter 0x05). These are
expected to differ and our envelope is internally consistent (Counter = seed - (Flags2 and 0xFF)
- Flags1; the earlier accepted frames 0x0000..0x0006 follow the same formula).
The XMSG payload is identical.
The address puzzle (please resolve)¶
In the capture, d102->100 LAPB I-frames split by XMSG subtype:
- routing ACK I-frames (subtype 0x03): address 0x09 (e.g. line 145)
- XMSG-DATA I-frames (subtype 0x0E, terminal data): address 0x89 (lines 164, 173, 223)
Our LapbLayer hardcodes ONE address 0x09 for every I/RR/RNR/REJ. So we send data I-frames as
0x09. BUT our banner (subtype 0x0E, 0x09) was accepted this session - so "data must be 0x89"
cannot be the whole rule.
Questions:
1. What determines the LAPB address 0x09 vs 0x89 for a d102->100 frame? Is the 0x80 bit the
LAPB command/response (C/R) bit, a poll marker, or something the ND stack sets from the payload?
Give the exact rule from the captures.
2. Does the username-accepted frame specifically REQUIRE 0x89 while the banner tolerates 0x09?
If 100 silently drops a data I-frame with the wrong address (looking like a lost frame -> REJ),
that would match our symptom exactly. Is that what the ND LAPB does?
3. If address is NOT it: what ELSE in the capture's accepted username-accepted frame differs from
ours in a way 100 enforces here but not for the banner? We have ruled out FCS, stuffing, length
(11 odd is fine - capture is 11 too), content, ports, and the envelope counter/channel.
4. Is there a frame or step the real d102 sends BETWEEN the username BDAT and the username-accepted
that we omit (e.g. an echo of the typed line, an extra ACK), such that our username-accepted
arrives when 100's LAPB/TAD is not ready for it?
What we need back¶
The precise reason 100 does not accept our ns=6 username-accepted frame, and the exact fix (e.g. "data I-frames must carry LAPB address 0x89; set it for subtype 0x0E"). Cite the capture frames. Mark anything inferred as INFERRED.