IPv4 network packet: GraphViz block diagram (.dot) source

KS implementation details

License: CC0-1.0
Minimal Kaitai Struct required: 0.7

This page hosts a formal specification of IPv4 network packet using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

GraphViz block diagram source

ipv4_packet.dot

digraph {
	rankdir=LR;
	node [shape=plaintext];
	subgraph cluster__ipv4_packet {
		label="Ipv4Packet";
		graph[style=dotted];

		ipv4_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="b1_pos">0</TD><TD PORT="b1_size">1</TD><TD>u1</TD><TD PORT="b1_type">b1</TD></TR>
			<TR><TD PORT="b2_pos">1</TD><TD PORT="b2_size">1</TD><TD>u1</TD><TD PORT="b2_type">b2</TD></TR>
			<TR><TD PORT="total_length_pos">2</TD><TD PORT="total_length_size">2</TD><TD>u2be</TD><TD PORT="total_length_type">total_length</TD></TR>
			<TR><TD PORT="identification_pos">4</TD><TD PORT="identification_size">2</TD><TD>u2be</TD><TD PORT="identification_type">identification</TD></TR>
			<TR><TD PORT="b67_pos">6</TD><TD PORT="b67_size">2</TD><TD>u2be</TD><TD PORT="b67_type">b67</TD></TR>
			<TR><TD PORT="ttl_pos">8</TD><TD PORT="ttl_size">1</TD><TD>u1</TD><TD PORT="ttl_type">ttl</TD></TR>
			<TR><TD PORT="protocol_pos">9</TD><TD PORT="protocol_size">1</TD><TD>u1→ProtocolEnum</TD><TD PORT="protocol_type">protocol</TD></TR>
			<TR><TD PORT="header_checksum_pos">10</TD><TD PORT="header_checksum_size">2</TD><TD>u2be</TD><TD PORT="header_checksum_type">header_checksum</TD></TR>
			<TR><TD PORT="src_ip_addr_pos">12</TD><TD PORT="src_ip_addr_size">4</TD><TD></TD><TD PORT="src_ip_addr_type">src_ip_addr</TD></TR>
			<TR><TD PORT="dst_ip_addr_pos">16</TD><TD PORT="dst_ip_addr_size">4</TD><TD></TD><TD PORT="dst_ip_addr_type">dst_ip_addr</TD></TR>
			<TR><TD PORT="options_pos">20</TD><TD PORT="options_size">(ihl_bytes - 20)</TD><TD>Ipv4Options</TD><TD PORT="options_type">options</TD></TR>
			<TR><TD PORT="body_pos">...</TD><TD PORT="body_size">...</TD><TD>switch (protocol)</TD><TD PORT="body_type">body</TD></TR>
		</TABLE>>];
		ipv4_packet__inst__version [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
			<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
			<TR><TD>version</TD><TD>((b1 &amp; 240) &gt;&gt; 4)</TD></TR>
		</TABLE>>];
		ipv4_packet__inst__ihl [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
			<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
			<TR><TD>ihl</TD><TD>(b1 &amp; 15)</TD></TR>
		</TABLE>>];
		ipv4_packet__inst__ihl_bytes [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
			<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
			<TR><TD>ihl_bytes</TD><TD>(ihl * 4)</TD></TR>
		</TABLE>>];
ipv4_packet__seq_body_switch [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
	<TR><TD BGCOLOR="#F0F2E4">case</TD><TD BGCOLOR="#F0F2E4">type</TD></TR>
	<TR><TD>:protocol_enum_tcp</TD><TD PORT="case0">TcpSegment</TD></TR>
	<TR><TD>:protocol_enum_icmp</TD><TD PORT="case1">IcmpPacket</TD></TR>
	<TR><TD>:protocol_enum_udp</TD><TD PORT="case2">UdpDatagram</TD></TR>
	<TR><TD>:protocol_enum_ipv6</TD><TD PORT="case3">Ipv6Packet</TD></TR>
</TABLE>>];
		subgraph cluster__ipv4_options {
			label="Ipv4Packet::Ipv4Options";
			graph[style=dotted];

			ipv4_options__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="entries_pos">0</TD><TD PORT="entries_size">...</TD><TD>Ipv4Option</TD><TD PORT="entries_type">entries</TD></TR>
				<TR><TD COLSPAN="4" PORT="entries__repeat">repeat to end of stream</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__ipv4_option {
			label="Ipv4Packet::Ipv4Option";
			graph[style=dotted];

			ipv4_option__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="b1_pos">0</TD><TD PORT="b1_size">1</TD><TD>u1</TD><TD PORT="b1_type">b1</TD></TR>
				<TR><TD PORT="len_pos">1</TD><TD PORT="len_size">1</TD><TD>u1</TD><TD PORT="len_type">len</TD></TR>
				<TR><TD PORT="body_pos">2</TD><TD PORT="body_size">(len &gt; 2 ? (len - 2) : 0)</TD><TD></TD><TD PORT="body_type">body</TD></TR>
			</TABLE>>];
			ipv4_option__inst__copy [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>copy</TD><TD>((b1 &amp; 128) &gt;&gt; 7)</TD></TR>
			</TABLE>>];
			ipv4_option__inst__opt_class [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>opt_class</TD><TD>((b1 &amp; 96) &gt;&gt; 5)</TD></TR>
			</TABLE>>];
			ipv4_option__inst__number [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>number</TD><TD>(b1 &amp; 31)</TD></TR>
			</TABLE>>];
		}
	}
	ipv4_packet__inst__ihl_bytes:ihl_bytes_type -> ipv4_packet__seq:options_size [color="#404040"];
	ipv4_packet__seq:options_type -> ipv4_options__seq [style=bold];
	ipv4_packet__seq:body_type -> ipv4_packet__seq_body_switch [style=bold];
	ipv4_packet__seq_body_switch:case0 -> tcp_segment__seq [style=bold];
	ipv4_packet__seq_body_switch:case1 -> icmp_packet__seq [style=bold];
	ipv4_packet__seq_body_switch:case2 -> udp_datagram__seq [style=bold];
	ipv4_packet__seq_body_switch:case3 -> ipv6_packet__seq [style=bold];
	ipv4_packet__seq:protocol_type -> ipv4_packet__seq:body_type [color="#404040"];
	ipv4_packet__seq:b1_type -> ipv4_packet__inst__version [color="#404040"];
	ipv4_packet__seq:b1_type -> ipv4_packet__inst__ihl [color="#404040"];
	ipv4_packet__inst__ihl:ihl_type -> ipv4_packet__inst__ihl_bytes [color="#404040"];
	ipv4_options__seq:entries_type -> ipv4_option__seq [style=bold];
	ipv4_option__seq:len_type -> ipv4_option__seq:body_size [color="#404040"];
	ipv4_option__seq:len_type -> ipv4_option__seq:body_size [color="#404040"];
	ipv4_option__seq:b1_type -> ipv4_option__inst__copy [color="#404040"];
	ipv4_option__seq:b1_type -> ipv4_option__inst__opt_class [color="#404040"];
	ipv4_option__seq:b1_type -> ipv4_option__inst__number [color="#404040"];
}