SHA256
1
0

include IPv4 Option padding and type packing/unpacking

This commit is contained in:
brent saner
2025-08-31 00:29:20 -04:00
parent e48754ae4b
commit cd5570d34b
9 changed files with 586 additions and 24 deletions

View File

@@ -270,7 +270,7 @@ A flag's presence can be checked via a bit-wise `AND` against _flag_ being equal
[%collapsible]
.Example in Go
=====
.`hasflag.go`
.`examples/hasflag.go`
[source,go]
----
include::examples/hasflag.go[]
@@ -390,7 +390,7 @@ IP:P:: <<spec_bcast_protonum, IP/Transport Protocol Number>> _(1 Byte)_
IP:C:: Header Checksum (RFC https://datatracker.ietf.org/doc/html/rfc1071[1071^], https://datatracker.ietf.org/doc/html/rfc1071[1141^], https://datatracker.ietf.org/doc/html/rfc1624[1624^]) _(2 Bytes)_
IP:S:: Source IPv4 Address _(32 Bits/4 Bytes)_
IP:D:: Destination IPv4 Address _(32 Bits/4 Bytes)_
IP:O:: Options (Optional) (See the https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml[IANA Registered IP Parameters^] for details) _(Variable Length)_
IP:O:: Options + Null Padding (Optional) _(Variable Length, see <<xtra_pad_v4opts,Addendum>>)_
[id="spec_bcast_v6"]
==== IPv6
@@ -541,6 +541,7 @@ To *retrieve* the Version and IHL, the value is bit-shifted to the *right* by 4
[%collapsible]
.Example in Go
====
.`examples/vihl.go`
[source,go]
----
include::examples/vihl.go[]
@@ -571,6 +572,7 @@ Notable ECN mentions are:
[%collapsible]
.Example in Go
====
.`examples/de.go`
[source,go]
----
include::examples/de.go[]
@@ -586,12 +588,31 @@ The Fragmentation Flags and Offset are defined in https://datatracker.ietf.org/d
[%collapsible]
.Example in Go
====
.`examples/frag.go`
[source,go]
----
include::examples/frag.go[]
----
====
[id="xtra_bitpacked_ip4opt_t"]
==== IPv4 Option Type
The *Type* field of an <<xtra_pad_v4opts,IPv4 option>> is a single byte that consists of:
* A "Copy" flag _(1 Bit)_
* A "Class" flag _(2 Bits)_
* An Option "Number" _(5 Bits)_
[%collapsible]
.Example in Go
====
.`examples/v4optstype.go`
[source,go]
----
include::examples/v4optstype.go[]
----
====
[id="xtra_bitpacked_vtf"]
==== IP Version, Traffic Class, Flow Label (IPv6)
IPv6 thankfully only has one bitpacking in the header. Unfortunately, it's a triple-whammy.
@@ -607,8 +628,58 @@ The IP Version takes up 4 bits (just as in IPv4, except it will always be `6` th
[%collapsible]
.Example in Go
====
.`examples/vtf.go`
[source,go]
----
include::examples/vtf.go[]
----
====
[id="xtra_pad"]
=== Padded Fields
[id="xtra_pad_v4opts"]
==== IPv4 Options
The IPv4 options, if specified, *must* align to a 32-bit/4-byte multiple size.
(In other words, its total length of bytes *must* be cleanly divisible by 4;
or said another way its total length of bits must be cleanly divisible by 32).
It uses null-byte (`0x00`) padding to achieve this.
[%collapsible]
.Example in Go
====
.`examples/v4optspad.go`
[source,go]
----
include::examples/v4optspad.go[]
----
====
For more extensive details, see https://datatracker.ietf.org/doc/html/rfc791#section-3.1[RFC 791 § 3.1^]
and the https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml[IANA Registered IP Paramaeters^]
(the *Value* column is what should be used as the *Type*, see <<xtra_bitpacked_ip4opt_t>>.
Each option (with two exceptions) is a TLV (<<xtra_pad_v4opts_t,type>> / <<xtra_pad_v4opts_l,length>> / <<xtra_pad_v4opts_v,value>>) structured field.
The two exceptions for the above are `EOOL` (`0x00`) and `NOP` (`0x01`), both of which occupy only a single byte -- they are *unvalued*, so they have no length or value field.
[id="xtra_pad_v4opts_t"]
===== Type
See <<xtra_bitpacked_ip4opt_t>> for details.
[id="xtra_pad_v4opts_l"]
===== Length
The *Length* is the length of this _entire_ option as an 8-bit unsigned integer.
In other words it includes the length of the <<xtra_pad_v4opts_t>> field, the <<xtra_pad_v4opts_l>> field (this field),
*and* the <<xtra_pad_v4opts_v>> field together.
This is not present for `EOOL` (`0x00`) and `NOP` (`0x01`) (or any other "non-valued" options).
[id="xtra_pad_v4opts_v"]
===== Value
Value is the option's value. Its <<xtra_pad_v4opts_l>> is variable depending on the <<xtra_pad_v4opts_t>>.
This is not present for `EOOL` (`0x00`) and `NOP` (`0x01`) (or any other "non-valued" options).