This page hosts a formal specification of ICMP network packet using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
digraph {
rankdir=LR;
node [shape=plaintext];
subgraph cluster__icmp_packet {
label="IcmpPacket";
graph[style=dotted];
icmp_packet__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="icmp_type_pos">0</TD><TD PORT="icmp_type_size">1</TD><TD>u1→IcmpTypeEnum</TD><TD PORT="icmp_type_type">icmp_type</TD></TR>
<TR><TD PORT="destination_unreachable_pos">1</TD><TD PORT="destination_unreachable_size">3</TD><TD>DestinationUnreachableMsg</TD><TD PORT="destination_unreachable_type">destination_unreachable</TD></TR>
<TR><TD PORT="time_exceeded_pos">4</TD><TD PORT="time_exceeded_size">3</TD><TD>TimeExceededMsg</TD><TD PORT="time_exceeded_type">time_exceeded</TD></TR>
<TR><TD PORT="echo_pos">7</TD><TD PORT="echo_size">...</TD><TD>EchoMsg</TD><TD PORT="echo_type">echo</TD></TR>
</TABLE>>];
subgraph cluster__destination_unreachable_msg {
label="IcmpPacket::DestinationUnreachableMsg";
graph[style=dotted];
destination_unreachable_msg__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="code_pos">0</TD><TD PORT="code_size">1</TD><TD>u1→DestinationUnreachableCode</TD><TD PORT="code_type">code</TD></TR>
<TR><TD PORT="checksum_pos">1</TD><TD PORT="checksum_size">2</TD><TD>u2be</TD><TD PORT="checksum_type">checksum</TD></TR>
</TABLE>>];
}
subgraph cluster__time_exceeded_msg {
label="IcmpPacket::TimeExceededMsg";
graph[style=dotted];
time_exceeded_msg__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="code_pos">0</TD><TD PORT="code_size">1</TD><TD>u1→TimeExceededCode</TD><TD PORT="code_type">code</TD></TR>
<TR><TD PORT="checksum_pos">1</TD><TD PORT="checksum_size">2</TD><TD>u2be</TD><TD PORT="checksum_type">checksum</TD></TR>
</TABLE>>];
}
subgraph cluster__echo_msg {
label="IcmpPacket::EchoMsg";
graph[style=dotted];
echo_msg__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="code_pos">0</TD><TD PORT="code_size">1</TD><TD></TD><TD PORT="code_type">code</TD></TR>
<TR><TD PORT="checksum_pos">1</TD><TD PORT="checksum_size">2</TD><TD>u2be</TD><TD PORT="checksum_type">checksum</TD></TR>
<TR><TD PORT="identifier_pos">3</TD><TD PORT="identifier_size">2</TD><TD>u2be</TD><TD PORT="identifier_type">identifier</TD></TR>
<TR><TD PORT="seq_num_pos">5</TD><TD PORT="seq_num_size">2</TD><TD>u2be</TD><TD PORT="seq_num_type">seq_num</TD></TR>
<TR><TD PORT="data_pos">7</TD><TD PORT="data_size">⇲</TD><TD></TD><TD PORT="data_type">data</TD></TR>
</TABLE>>];
}
}
icmp_packet__seq:destination_unreachable_type -> destination_unreachable_msg__seq [style=bold];
icmp_packet__seq:time_exceeded_type -> time_exceeded_msg__seq [style=bold];
icmp_packet__seq:echo_type -> echo_msg__seq [style=bold];
}