feat: packet highlight#146
Draft
YuanYuYuan wants to merge 15 commits into
Draft
Conversation
Each field in the Wireshark protocol tree now highlights exactly the bytes that encode it in the hex pane, rather than the entire parent message. Key changes: - span.rs: SpanCursor (Reader + BacktrackableReader) wraps a byte slice and tracks read position; ByteSpan, SpanMap, RecordSpans - zenoh_spans.rs: hand-written RecordSpans for each TransportMessage variant, following the wire format in zenoh-codec order - tree.rs: TreeArgs gains spans: Option<&SpanMap>; make_subtree and field_span() look up per-field byte ranges from the map - macros.rs: impl_for_struct! consults args.field_span() before proto_tree_add_string instead of using the parent message range - lib.rs: after rbatch.decode(), build SpanMap via record_spans on the raw TVB bytes (non-compression path), shift spans to absolute TVB offsets, pass into TreeArgs per message Fields covered: version, whatami, zid, resolution, batch_size, lease, initial_sn, cookie, sn. Header-embedded fields (reliability, session, more) fall back to the parent message range.
iext encoding is in bits 5-6 (ENC_MASK = 0x60), not bits 0-1. ENC_UNIT has no body, ENC_Z64 has a VLE u64, ENC_ZBUF has a u32-bounded length-prefixed buffer. The previous skip_extensions assumed all extensions had a VLE body length, causing InitSyn/InitAck span recording to fail and fall back to parent-message range for all fields.
- WireExpr sub-field spans: scope (VLE) and suffix (VLE-len + string) - NetworkMessage spans: Push wire_expr, Declare body id and wire_expr, Request/Response wire_expr and id - Extension spans: all network message extensions (ext_qos, ext_tstamp, ext_nodeid) and transport extensions (ext_qos, ext_auth, ext_mlink, ext_qos_link) - Disambiguate extensions with same ID but different encoding via (enc_bits | id) matching Verified with tshark -T pdml: wire_expr shows correct byte ranges (27B for 25-char key, 14B/5B for declare sub-fields), extension ext_qos in InitAck shows 1B (unit extension).
Register dissector for UDP port 7446. Detect scouting messages by checking if the first byte mid is SCOUT(0x01) or HELLO(0x02), then decode with Zenoh080::read() into ScoutingMessage. Add impl_for_struct!/impl_for_enum! for Scout, HelloProto, ScoutingBody, ScoutingMessage types. Register all scouting HF/ST fields via ZenohProtocol::generate_hf_map/generate_subtree_names.
- tree.rs: field_span fallback changed from (start, full_length) to (start, 0) so unrecorded fields show no highlight instead of highlighting the entire message (Bug 3 fix) - span.rs: add skip_remaining() helper for consuming payload bytes - zenoh_spans.rs: add span recording for previously-missing fields: * Frame.ext_qos extension * Close.reason byte * Put.encoding, Put.timestamp, Put.payload (via record_put_body_spans) - zenoh_impl.rs: registration tests (catch Bugs 1/2 from zids-and-trees), integration test dissector.rs verifies Bug 3 (nested field sizes) passes - Cargo.toml: crate-type includes "rlib" to enable cargo test
When a Frame payload contains multiple Declare sub-messages, all messages share the same span-map prefix key (tree uses fixed field names, not indices). Recording all messages and letting later ones overwrite caused the first Declare's fields to highlight the second Declare's bytes. Fix: record spans only for the first NetworkMessage in the payload loop. The first message highlights correctly; subsequent messages show size=0 (no highlight) rather than pointing to wrong bytes. Integration test added: two-Declare Frame asserts that DeclareKeyExpr.id has size=1 at the correct position, catching the overwrite regression.
…message frames
Root cause: the #[dissect(vec)] renderer passed the same TreeArgs (with
one shared span map) to all NetworkMessages in a Frame payload. Spans
were recorded with the same keys regardless of which message they
belonged to, causing the last message's spans to overwrite earlier ones.
Fix:
- zenoh_spans.rs: record indexed keys per message: "{payload}[{i}].…"
- macros.rs: #[dissect(vec)] now builds a per-item local_spans by
filtering and remapping "{vec}[{i}].…" → "{vec}.…" for each item i
- tree.rs: add local_spans: Option<SpanMap> to TreeArgs; field_span
checks it before shared spans; make_subtree propagates it so nested
field lookups in subtrees also use the remapped keys
All NetworkMessages in a Frame now highlight their own correct bytes.
The HACK in impl_for_struct! that resets tree args for recursive descent was resetting local_spans to None. This broke span lookup for any field reached via #[dissect(expand)], including all NetworkBody variants (Push, Request, Declare, etc.) which are reached through NetworkMessage.expand(body: NetworkBody). Fix: preserve local_spans via .clone() instead of setting it to None.
- Transport prefix: body_prefix -> tp (zenoh.body.* -> zenoh.transport.*)
- Frame payload: payload_prefix now zenoh.transport.frame.network.*
- Network dispatcher: remove stale .body infix from sub-function calls
- Declare variants: remove .body. from declare key paths
- Scouting: remove spurious .body. prefix (zenoh.body.scout -> zenoh.scout)
- Fragment: record reliability from header byte alongside more flag
- Undeclare: add span recording for U_KEYEXPR/U_SUBSCRIBER/U_QUERYABLE/U_TOKEN
- Put payload: skip VLE length prefix, record only the payload bytes
- Put prefix: pass "{prefix}.push" not "{prefix}.push.payload" to record_put_body_spans
Unit tests updated to match new key paths.
Add tshark-based integration tests covering all message types:
- KeepAlive, Close: basic decode
- Fragment: reliability + sn fields
- Join: version, whatami, zid, lease
- Push/Put: wire_expr, encoding, payload
- Declare{KeyExpr,Subscriber,Queryable,Token}: id + wire_expr
- Undeclare{KeyExpr,Subscriber}: id field
- DeclareFinal: presence check
- Request: id + wire_expr
- Response/ResponseFinal: rid + wire_expr
- Scout/Hello (UDP scouting): version, what/whatami, zid
- Multi-message frame: correct per-item byte offsets
- sample-data.pcap: all encoded fields have size>0 (no unclaimed fields)
Also add: ethernet_ipv4_udp_packet helper, UDP pcap writer,
tshark -d udp.port==7446,zenoh dissector override, unclaimed_fields
filter extended to exclude subtree nodes and ZID/batch overlay fields.
e1f223b to
50d36a6
Compare
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.
No description provided.