Conversation
…iaTek Frames were sent as REMOTE_NDIS_PACKET_MSG with a 48-byte header and DataOffset 40. The vivo X200 Pro mini (MediaTek) rejects those frames: they are counted as receive errors and dropped, so the relay never sees a DHCP offer and the tunnel never comes up. The in-tree Linux host driver (rndis_host.c) uses a 44-byte header with DataOffset 36, and the same device accepts it immediately. Switch to the canonical layout and add a unit test that pins it. Additionally: - drain stale encapsulated control responses before the handshake; the device can otherwise hand back completions from a previous session and desync INIT/QUERY/SET; - select the data interface explicitly (SET_INTERFACE alt 0) and clear any stale endpoint halt before first use: some gadgets keep their bulk endpoints disabled until SET_INTERFACE, and transfers to a halted pipe NAK until they time out; - re-apply OID_GEN_CURRENT_PACKET_FILTER after the data interface has been opened. SET_INTERFACE resets the filter to zero on vivo, which makes the phone drop its own broadcast traffic (DHCP offers) silently. Tested against vivo X200 Pro mini on macOS 26 (Apple Silicon): DHCP OFFER/ACK complete and traffic flows over the USB link.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
With a vivo X200 Pro mini (MediaTek) on macOS 26 the tunnel never comes up: the phone keeps
rx_packets=0whilerx_errsgrows, and both the DHCP Discover and the keepalive frames are dropped. Every RNDIS data frame is rejected by the phone.Root causes found on the wire:
REMOTE_NDIS_PACKET_MSGwith a 48-byte header andDataOffset = 40. The vivo gadget rejects those as receive errors. The in-tree Linux host driver (rndis_host.c) uses a 44-byte header withDataOffset = 36, and the same device accepts it immediately (verified by A/B testing both layouts byte-for-byte, same session, repeated).SET_INTERFACEon the data interface resetsOID_GEN_CURRENT_PACKET_FILTERto 0 on this device, so the phone silently stops sending broadcast traffic — the DHCP offer never leaves it (tx_packets=0). Re-applying the filter after the interface is open fixes it: before, zero replies; after, the DHCP OFFER arrives.Changes
EncapsulatePacketemits the canonical 44-byte header (DataOffset 36) and ships with a unit test pinning the layout and the decode round-trip.SET_INTERFACE(alt 0)plusCLEAR_FEATURE(HALT)on the data endpoints before first use (some gadgets keep endpoints disabled untilSET_INTERFACE; a halted pipe NAKs until it times out).Testing
go test ./...— newinternal/rndistests pass.utuninterface is configured, ping/curl over the USB link work.The crash-on-disconnect fix is in the companion PR.