Skip to content
Connect an agent

Other diagram kinds

Packet diagrams

A packet diagram lays out the fields of a network header or a binary record bit by bit, in rows of a fixed width, the way RFCs draw them. Use it to document a protocol header, a file format, a register map, or a message on a wire. It is for anyone who writes or reads code that packs bits, and for an agent that has been asked to explain a format.

TL;DR

QuestionAnswer
What is it for?A header or record of fixed-width fields: TCP, UDP, IPv6, a file header, the bits of a hardware register.
How do I start one?Write packet "Title", then one field line for each field with its first and last bit, such as field 0-15 "Source port".
How are bits counted?From 0 at the start of the packet. A row holds 32 bits unless bits= says 8, 16, or 64, and a field that runs past the end of a row carries on in the next.
What does Mermaid convert?packet and packet-beta: every block, by range, by one bit, or by +N. See From Mermaid.
How big can it be?At most 400 fields and 4,096 bits. Warnings start at 64 fields or 16 rows, at bits no field holds, and at a length that is not whole bytes.
How is it drawn?A band for each row with the bit numbers over the first row and each row's bit offset at its left. Each field is a cell with its name across it; a narrow field sets its name on its side, and one too narrow even for that is numbered and named in a key under the rows.

Ask your agent

text
Use Plotwork to draw the TCP header as a packet diagram, 32 bits a row. Name every field, colour the SYN, ACK and RST flags, and mark the options as variable length.
text
Use Plotwork to draw the 8-bit status register of our controller as a packet diagram with the most significant bit on the left. Bit 0 is Carry, bit 1 Zero, bit 7 Global interrupt enable.

Example

The fixed 20 bytes of a TCP header and its options. The flags are one bit each, so their names are set on their side; the options field has a torn edge because its length varies.

A UDP header with next

next takes the bits right after the field before it, so a format made of whole fields can be listed by width alone.

An 8-bit register

bits=8 makes each bit wide enough for its name, and order=descending puts the most significant bit on the left, as a datasheet does.

The language

The header

packet "Title" starts the diagram. Every option is optional.

OptionValuesDefaultMeaning
bits=8, 16, 32, 6432How many bits a row holds.
numbers=on, offonThe bit numbers over the first row and the bit offset of each row.
order=ascending, descendingascendingdescending puts the first bit of each row on the right.
desc=textnoneThe plain-language description, for assistive technology.

Statements

StatementMeaningExample
field <first>-<last> "<Name>"A field from its first bit to its last. Write one number for one bit.field 0-15 "Source port"
next <count> "<Name>"A field of count bits right after the field before it, or from bit 0 for the first.next 16 "Window"
desc "<text>"The plain-language description, the same as desc=.desc "The UDP header."

field and next take the same options.

OptionValuesMeaning
sub=textA short note under the name, such as the unit.
tone=any toneThe field's colour, for a field that matters: a flag, a checksum, a length.
variable=on, offon draws a field of variable length, such as options or a payload, with a torn edge.

Fields and bit ranges

Bits are counted from 0 at the start of the packet, not from the start of the row, so the second 32-bit word starts at bit 32. Write the range with a hyphen and no spaces: 96-99. Fields may be written in any order and are drawn in bit order.

Two fields cannot share a bit: the error names the field already there and the bit to start at. Bits that no field holds are drawn hatched and reported by lint, since they are usually a typo; name them "Reserved" when they are reserved.

Bits per row and bit order

A row is 832 pixels shared among its bits: 104 a bit at 8 bits a row, 26 at 32, and 14 at 64. A field that runs past the end of a row is cut there and carries on in the next row, where its name is drawn again in a quieter ink. With order=descending, bit 0 of each row is on the right and the ruler counts down from the left.

Narrow fields

A name is set across its field when it fits in three lines. A field too narrow for that, such as a flag of one bit, sets its name on its side, reading upward, and its row grows to hold it. A name too long even for that, or a narrow field with a note, gets a number in its cell, and the number, the name, the bits and the note are listed in a key under the rows. Text never leaves its field. Short names, such as URG for the urgent pointer flag, keep every name in the rows.

Limits and warnings

LimitWhat happens
More than 400 fields, or a bit past 4095Refused with E140 before any layout. Draw the payload as one variable field, or split the record.
More than 64 fields, or more than 16 rowsW200: split the record by header or part.
Bits no field holdsW200 names them.
A length that is not a whole number of bytesW200, unless the last field is of variable length.
A name moved to the keyW200 names it, so you can shorten it or use fewer bits a row.
A name or note cut to fitW203. The full text stays in the text description.

From Mermaid

Mermaid packet and packet-beta convert to a packet diagram. Ask your agent to convert it, or use the convert_mermaid tool. The migration guide covers the converter in full.

Mermaid
packettitle UDP Packet0-15: "Source Port"16-31: "Destination Port"32-47: "Length"48-63: "Checksum"64-95: "Data (variable length)"

The converter keeps every block and reports the field it marked variable (M204):

Plotwork
packet "UDP Packet"field 0-15 "Source Port"field 16-31 "Destination Port"field 32-47 "Length"field 48-63 "Checksum"field 64-95 "Data (variable length)" variable=on
MermaidPlotworkReport
packet, packet-betapacket "<title>"none
title X, front matter title:The header titlenone
0-15: "Name"field 0-15 "Name"none
106: "Name"field 106 "Name"none
+16: "Name"next 16 "Name"none
A name ending in (variable length)The name, and variable=onM204
A block that shares bits with an earlier oneDroppedM209
HTML in a nameRemovedM205
A block with no nameDroppedM216
Front matter config: (bitsPerRow, showBits, bitOrder) and %%{init}%%Dropped. Set bits=, numbers= and order= on the header.M200
More than 400 blocks, or a bit past 4095Nothing is converted.M102
A line that cannot be readNothing is converted, or the line is skipped when the conversion is lenient.M110, or M218

See also

DocWhy
Writing diagramsThe rules every kind shares
Examples to copyFinished diagrams with the prompt that gets an agent to write each one
Migrating from MermaidConvert existing Mermaid diagrams, and what is dropped
MatricesA grid of rows and columns, for a table of values rather than bits
Language referenceEvery kind, option and diagnostic
Diagram kindsThe kinds Plotwork draws and the header of each