From a97780bfafcbeb0af69cd29911dc1b4f87523881 Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 28 Oct 2026 23:11:43 +0100 Subject: [PATCH 1/2] ieee80211: every MSDU is RFC 1042's, and the bridge-tunnel header is refused The selective translation table of ISO/IEC TR 11802-5:1997 (formerly IEEE Std 802.1H) sends AppleTalk's AARP (0x80F3) and IPX (0x8137) under the bridge-tunnel OUI 00-00-F8. ToyOS sends and receives neither, so the table moved nothing ToyOS carries, and checking its two entries would have meant buying a document for protocols ToyOS will never speak. It goes: every EtherType is sent under RFC 1042's header, and a header under any other OUI, the bridge-tunnel one included, is refused `UnknownOui`. The `TranslatedType` refusal goes with it: an RFC 1042 header carrying 0x8137 is an ordinary MSDU now. Co-Authored-By: Claude Opus 5.5 --- issues/there-is-no-wifi.md | 11 +++++++---- lib/ieee80211/src/data.rs | 17 +++++------------ lib/ieee80211/src/lib.rs | 3 +-- lib/ieee80211/tests/refusals.rs | 17 +++++++++-------- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/issues/there-is-no-wifi.md b/issues/there-is-no-wifi.md index a669a92f52e..406d6317aaa 100644 --- a/issues/there-is-no-wifi.md +++ b/issues/there-is-no-wifi.md @@ -233,7 +233,7 @@ Depends on: nothing; W6 waits on it. - the elements: SSID, rates, DS, TIM, country, RSN, RSNXE, HT, VHT, HE, extended capabilities and WMM; - A-MSDU; - - 802.11 to Ethernet and back (RFC 1042, bridge-tunnel); + - 802.11 to Ethernet and back (RFC 1042); - the reorder window. - **Exit:** host tests of every refusal and hostile length, a malformed country element among them; a seeded structured fuzz of a fixed count, as @@ -242,9 +242,12 @@ Depends on: nothing; W6 waits on it. pinned by hash. - **Landed** in #924 and #930; the exit is met, the readings checked against the text (#924, issuecomment-6173453493). -- **Owed:** the bridge-tunnel OUI 00-00-F8 and its EtherTypes 0x80F3 and - 0x8137 checked against ISO/IEC TR 11802-5:1997. Owner: the orchestrator. - Exit: checked, and fixed in `lib/ieee80211/src/data.rs` if contradicted. +- **No bridge-tunnel.** Every MSDU is sent under RFC 1042's header, and one + under any other OUI is refused `UnknownOui`, the bridge-tunnel one + included. Its selective translation table (ISO/IEC TR 11802-5:1997, + formerly IEEE Std 802.1H) carries only AppleTalk's AARP and IPX, which + ToyOS neither sends nor receives, so under zero legacy it carries nothing + ToyOS needs, and no fact of it remains to check. **W2, the handshakes, in `wlan`**, sans-IO: the 4-way and group-key handshakes, SAE by hash-to-element, PMF's keys, and the Transition Disable diff --git a/lib/ieee80211/src/data.rs b/lib/ieee80211/src/data.rs index c14890226e7..292e3052247 100644 --- a/lib/ieee80211/src/data.rs +++ b/lib/ieee80211/src/data.rs @@ -1,7 +1,7 @@ //! Data frame bodies: the CCMP header (§12.5.2.2), A-MSDU (§9.3.2.2), and translation between an -//! MSDU and an Ethernet II frame as §5.1.4 recommends, by ISO/IEC TR 11802-5:1997 (formerly IEEE -//! Std 802.1H): an RFC 1042 LLC/SNAP header, or the bridge-tunnel one for the two EtherTypes its -//! selective translation table sends that way. +//! MSDU and an Ethernet II frame by an RFC 1042 LLC/SNAP header, every EtherType alike. The +//! bridge-tunnel header, which only AppleTalk's AARP and IPX are sent under, is refused as any +//! other OUI is: ToyOS speaks neither. use crate::frame::Data; use crate::read::Reader; @@ -109,10 +109,6 @@ pub struct Ethernet<'a> { } const SNAP: [u8; 6] = [0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00]; -const BRIDGE_TUNNEL: [u8; 6] = [0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8]; -/// The EtherTypes the selective translation table carries under the bridge-tunnel OUI: AppleTalk -/// AARP and IPX. -const TUNNELED: [u16; 2] = [0x80F3, 0x8137]; /// The least type: IEEE Std 802.3-2022 §3.2.6 reads a Length/Type value of at most 1500 as a /// length and one of at least 1536 (0x0600) as a type. const MIN_ETHERTYPE: u16 = 0x0600; @@ -128,10 +124,7 @@ impl<'a> Ethernet<'a> { if [llc0, llc1, llc2] != [0xAA, 0xAA, 0x03] { return Err(Refused::NotSnap); } - if header == SNAP && TUNNELED.contains(ðertype) { - return Err(Refused::TranslatedType); - } - if header != SNAP && header != BRIDGE_TUNNEL { + if header != SNAP { return Err(Refused::UnknownOui); } if ethertype < MIN_ETHERTYPE { @@ -146,7 +139,7 @@ pub fn llc_snap(ethertype: u16) -> Result<[u8; LLC_SNAP_LEN], Refused> { if ethertype < MIN_ETHERTYPE { return Err(Refused::LengthField); } - let [oui0, oui1, oui2, oui3, oui4, oui5] = if TUNNELED.contains(ðertype) { BRIDGE_TUNNEL } else { SNAP }; + let [oui0, oui1, oui2, oui3, oui4, oui5] = SNAP; let [t0, t1] = ethertype.to_be_bytes(); Ok([oui0, oui1, oui2, oui3, oui4, oui5, t0, t1]) } diff --git a/lib/ieee80211/src/lib.rs b/lib/ieee80211/src/lib.rs index 9138d5abbd0..8a92acacf42 100644 --- a/lib/ieee80211/src/lib.rs +++ b/lib/ieee80211/src/lib.rs @@ -119,8 +119,7 @@ refusals! { SubframePadding = Malformed, "an A-MSDU subframe whose padding runs past the MPDU"; SnapHeaderAsAddress = Malformed, "an A-MSDU whose first destination is an LLC/SNAP header"; NotSnap = Unsupported, "an MSDU that is not LLC/SNAP"; - UnknownOui = Unsupported, "an LLC/SNAP header with an OUI other than RFC 1042's or bridge-tunnel's"; - TranslatedType = Unsupported, "an RFC 1042 header carrying a type the selective translation table sends by bridge-tunnel"; + UnknownOui = Unsupported, "an LLC/SNAP header with an OUI other than RFC 1042's"; LengthField = Unsupported, "a Length/Type value below 0x0600, which IEEE Std 802.3-2022 §3.2.6 does not read as a type"; ExtendedIvClear = Malformed, "a CCMP header without its Ext IV bit"; // The reordering buffer, §10.25.6.6. diff --git a/lib/ieee80211/tests/refusals.rs b/lib/ieee80211/tests/refusals.rs index 9ab7d159e33..4dfc1442039 100644 --- a/lib/ieee80211/tests/refusals.rs +++ b/lib/ieee80211/tests/refusals.rs @@ -132,7 +132,6 @@ fn cases() -> Vec<(Refused, Refused)> { (SnapHeaderAsAddress, amsdu(&[0xAA, 0xAA, 0x03, 0, 0, 0, 0x08, 0x00, 0x45, 0, 0, 0, 0, 0])), (NotSnap, ethernet(&[0xF0, 0xF0, 0x03, 0, 0, 0, 0x08, 0x00])), (UnknownOui, ethernet(&[0xAA, 0xAA, 0x03, 0x00, 0x10, 0x18, 0x08, 0x00])), - (TranslatedType, ethernet(&[0xAA, 0xAA, 0x03, 0, 0, 0, 0x81, 0x37])), (LengthField, ethernet(&[0xAA, 0xAA, 0x03, 0, 0, 0, 0x05, 0xFF])), (ExtendedIvClear, refusal(CcmpHeader::split(&[1, 0, 0, 0, 0, 0, 0, 0]))), (WindowSize, refusal(Window::::new(Seq::new(0), 257))), @@ -408,17 +407,19 @@ fn an_rsnxe_ignores_octets_past_its_field() { } #[test] -fn llc_snap_refuses_a_length_and_tunnels_aarp_and_ipx() { +fn llc_snap_refuses_a_length_and_is_rfc_1042_for_every_type() { assert_eq!(llc_snap(0x05FF), Err(Refused::LengthField)); - assert_eq!(llc_snap(0x8137).unwrap()[..6], [0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8]); - assert_eq!(llc_snap(0x80F3).unwrap()[..6], [0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8]); - assert_eq!(llc_snap(0x0800).unwrap(), [0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00]); + for ethertype in [0x0800, 0x8137, 0x80F3] { + let [t0, t1] = u16::to_be_bytes(ethertype); + assert_eq!(llc_snap(ethertype).unwrap(), [0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, t0, t1]); + } } +/// A bridge-tunnel header is an OUI ToyOS does not decode, whatever type it carries. #[test] -fn a_bridge_tunnel_msdu_is_its_ethertype_on_ethernet() { - let eth = Ethernet::from_msdu(Msdu { da: STA, sa: PEER, payload: &[0xAA, 0xAA, 0x03, 0, 0, 0xF8, 0x81, 0x37, 9] }).unwrap(); - assert_eq!((eth.ethertype, eth.payload), (0x8137, &[9][..])); +fn a_bridge_tunnel_msdu_is_refused_as_an_unknown_oui() { + let msdu = Msdu { da: STA, sa: PEER, payload: &[0xAA, 0xAA, 0x03, 0, 0, 0xF8, 0x81, 0x37, 9] }; + assert_eq!(Ethernet::from_msdu(msdu), Err(Refused::UnknownOui)); } #[test] From 65c6ac3e9d2e6fc51e58df7a8d07a39cf272482c Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 28 Oct 2026 23:45:56 +0100 Subject: [PATCH 2/2] review r1 of #1109: the record rests on what the captures show, not on the table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The table's contents stay unchecked and nothing depends on them; what the decision rests on is ToyOS's own EtherTypes arriving under RFC 1042, which the capture corpus shows for IPv4 and ARP. The module header cites §5.1.4 as the recommendation it departs from, and a test's comment that restated its name and claimed more than it tries goes. Co-Authored-By: Claude Opus 5.5 --- issues/there-is-no-wifi.md | 10 ++++++---- lib/ieee80211/src/data.rs | 5 ++--- lib/ieee80211/tests/refusals.rs | 1 - 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/issues/there-is-no-wifi.md b/issues/there-is-no-wifi.md index 406d6317aaa..3d2e80104dc 100644 --- a/issues/there-is-no-wifi.md +++ b/issues/there-is-no-wifi.md @@ -244,10 +244,12 @@ Depends on: nothing; W6 waits on it. against the text (#924, issuecomment-6173453493). - **No bridge-tunnel.** Every MSDU is sent under RFC 1042's header, and one under any other OUI is refused `UnknownOui`, the bridge-tunnel one - included. Its selective translation table (ISO/IEC TR 11802-5:1997, - formerly IEEE Std 802.1H) carries only AppleTalk's AARP and IPX, which - ToyOS neither sends nor receives, so under zero legacy it carries nothing - ToyOS needs, and no fact of it remains to check. + included: a departure from §5.1.4's recommendation of ISO/IEC TR + 11802-5:1997's translation. What the selective translation table holds + stays unchecked (#924, issuecomment-6173453493, row 62) and nothing + depends on it. The decision rests instead on ToyOS's own EtherTypes + arriving under RFC 1042, which the capture corpus shows for IPv4 and ARP; + it holds no IPv6 or EAPOL frame. **W2, the handshakes, in `wlan`**, sans-IO: the 4-way and group-key handshakes, SAE by hash-to-element, PMF's keys, and the Transition Disable diff --git a/lib/ieee80211/src/data.rs b/lib/ieee80211/src/data.rs index 292e3052247..448bf3488a2 100644 --- a/lib/ieee80211/src/data.rs +++ b/lib/ieee80211/src/data.rs @@ -1,7 +1,6 @@ //! Data frame bodies: the CCMP header (§12.5.2.2), A-MSDU (§9.3.2.2), and translation between an -//! MSDU and an Ethernet II frame by an RFC 1042 LLC/SNAP header, every EtherType alike. The -//! bridge-tunnel header, which only AppleTalk's AARP and IPX are sent under, is refused as any -//! other OUI is: ToyOS speaks neither. +//! MSDU and an Ethernet II frame under RFC 1042's LLC/SNAP header alone, every EtherType alike: +//! §5.1.4's bridge-tunnel translation is not implemented, and its OUI is refused as any other. use crate::frame::Data; use crate::read::Reader; diff --git a/lib/ieee80211/tests/refusals.rs b/lib/ieee80211/tests/refusals.rs index 4dfc1442039..62b21aed5cd 100644 --- a/lib/ieee80211/tests/refusals.rs +++ b/lib/ieee80211/tests/refusals.rs @@ -415,7 +415,6 @@ fn llc_snap_refuses_a_length_and_is_rfc_1042_for_every_type() { } } -/// A bridge-tunnel header is an OUI ToyOS does not decode, whatever type it carries. #[test] fn a_bridge_tunnel_msdu_is_refused_as_an_unknown_oui() { let msdu = Msdu { da: STA, sa: PEER, payload: &[0xAA, 0xAA, 0x03, 0, 0, 0xF8, 0x81, 0x37, 9] };