An undocumented protocol begins as bytes and a few observations. Save the conditions with the trace: software and firmware versions, transport, endpoint roles, capture point, test input, and the exact exchange. A changed version or session can explain a different packet before any field has changed meaning.
Use a system you own or are authorized to test. Capture a baseline, then change one input. Compare lengths, counters, delimiters, checksums, and response timing. Call a field a candidate identifier until a second test supports the idea. Two bytes that happen to look like a timestamp can just as easily be an enum or checksum fragment.
Make a message inventory before writing a parser. Record direction, framing, lengths, known delimiters, response, and whether the message repeats in another session. Then sketch the state sequence. Tie each arrow to an observation: after message A, the device accepted message B. That is more useful than naming an unexplained packet “authentication.”
Next, test the model. Replay a known sequence, alter one field, and save the response. Keep a list of open questions and experiments that could answer them. If a field is encrypted, compressed, or checksummed, write down the hypothesis and what would disprove it. Do not assign semantics by visual resemblance.
A protocol note should name the versions and cases it covers. Timing, errors, cryptographic negotiation, and messages absent from the capture can all change the model. Keep application framing separate from TCP behavior: a retransmission repeats bytes at the transport layer; it does not automatically mean the application retried a request.
The Research diagrams show generic packet and state flows. They contain no private endpoints or work-system details. For the transport underneath, start with RFC 9293; for capture inspection, see the Wireshark User’s Guide.