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

@@ -559,7 +559,7 @@ pre.rouge .gs {
<div class="details">
<span id="author" class="author">Brent Saner</span><br>
<span id="email" class="email"><a href="mailto:bts@square-r00t.net">bts@square-r00t.net</a></span><br>
<span id="revdate">Last rendered 2025-08-30 17:05:09 -0400</span>
<span id="revdate">Last rendered 2025-08-31 00:29:24 -0400</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
@@ -625,7 +625,19 @@ pre.rouge .gs {
<li><a href="#xtra_bitpacked_vihl">8.1.1. IP Version, IHL (IPv4)</a></li>
<li><a href="#xtra_bitpacked_de">8.1.2. DSCP, ECN (IPv4)</a></li>
<li><a href="#xtra_bitpacked_frag">8.1.3. Flags, Fragmentation Offset (IPv4)</a></li>
<li><a href="#xtra_bitpacked_vtf">8.1.4. IP Version, Traffic Class, Flow Label (IPv6)</a></li>
<li><a href="#xtra_bitpacked_ip4opt_t">8.1.4. IPv4 Option Type</a></li>
<li><a href="#xtra_bitpacked_vtf">8.1.5. IP Version, Traffic Class, Flow Label (IPv6)</a></li>
</ul>
</li>
<li><a href="#xtra_pad">8.2. Padded Fields</a>
<ul class="sectlevel3">
<li><a href="#xtra_pad_v4opts">8.2.1. IPv4 Options</a>
<ul class="sectlevel4">
<li><a href="#xtra_pad_v4opts_t">8.2.1.1. Type</a></li>
<li><a href="#xtra_pad_v4opts_l">8.2.1.2. Length</a></li>
<li><a href="#xtra_pad_v4opts_v">8.2.1.3. Value</a></li>
</ul>
</li>
</ul>
</li>
</ul>
@@ -1700,7 +1712,7 @@ If using the online version, <em>Part I-2</em> is summarized/starts <a href="htt
<summary class="title">Example in Go</summary>
<div class="content">
<div class="listingblock">
<div class="title"><code>hasflag.go</code></div>
<div class="title"><code>examples/hasflag.go</code></div>
<div class="content">
<pre class="rouge highlight"><code data-lang="go"><span class="k">package</span> <span class="n">main</span>
@@ -2079,7 +2091,7 @@ Its source <em>must</em> be the MAC/PHYS address of the network interface it is
</dd>
<dt class="hdlist1">IP:O</dt>
<dd>
<p>Options (Optional) (See the <a href="https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml" target="_blank" rel="noopener">IANA Registered IP Parameters</a> for details) <em>(Variable Length)</em></p>
<p>Options + Null Padding (Optional) <em>(Variable Length, see <a href="#xtra_pad_v4opts">Addendum</a>)</em></p>
</dd>
</dl>
</div>
@@ -2439,12 +2451,13 @@ IPv6 does not require a header checksum.</p>
<summary class="title">Example in Go</summary>
<div class="content">
<div class="listingblock">
<div class="title"><code>examples/vihl.go</code></div>
<div class="content">
<pre class="rouge highlight"><code data-lang="go"><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">`fmt`</span>
<span class="s">`log`</span>
<span class="s">"fmt"</span>
<span class="s">"log"</span>
<span class="s">"strconv"</span>
<span class="p">)</span>
@@ -2573,12 +2586,13 @@ IPv6 does not require a header checksum.</p>
<summary class="title">Example in Go</summary>
<div class="content">
<div class="listingblock">
<div class="title"><code>examples/de.go</code></div>
<div class="content">
<pre class="rouge highlight"><code data-lang="go"><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">`fmt`</span>
<span class="s">`log`</span>
<span class="s">"fmt"</span>
<span class="s">"log"</span>
<span class="s">"strconv"</span>
<span class="p">)</span>
@@ -2665,12 +2679,13 @@ IPv6 does not require a header checksum.</p>
<summary class="title">Example in Go</summary>
<div class="content">
<div class="listingblock">
<div class="title"><code>examples/frag.go</code></div>
<div class="content">
<pre class="rouge highlight"><code data-lang="go"><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">`fmt`</span>
<span class="s">`log`</span>
<span class="s">"fmt"</span>
<span class="s">"log"</span>
<span class="s">"strconv"</span>
<span class="p">)</span>
@@ -2747,7 +2762,147 @@ IPv6 does not require a header checksum.</p>
</details>
</div>
<div class="sect3">
<h4 id="xtra_bitpacked_vtf"><a class="link" href="#xtra_bitpacked_vtf">8.1.4. IP Version, Traffic Class, Flow Label (IPv6)</a></h4>
<h4 id="xtra_bitpacked_ip4opt_t"><a class="link" href="#xtra_bitpacked_ip4opt_t">8.1.4. IPv4 Option Type</a></h4>
<div class="paragraph">
<p>The <strong>Type</strong> field of an <a href="#xtra_pad_v4opts">IPv4 option</a> is a single byte that consists of:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A "Copy" flag <em>(1 Bit)</em></p>
</li>
<li>
<p>A "Class" flag <em>(2 Bits)</em></p>
</li>
<li>
<p>An Option "Number" <em>(5 Bits)</em></p>
</li>
</ul>
</div>
<details>
<summary class="title">Example in Go</summary>
<div class="content">
<div class="listingblock">
<div class="title"><code>examples/v4optstype.go</code></div>
<div class="content">
<pre class="rouge highlight"><code data-lang="go"><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">"fmt"</span>
<span class="s">"log"</span>
<span class="s">"strconv"</span>
<span class="p">)</span>
<span class="k">const</span> <span class="p">(</span>
<span class="n">ClassControl</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="no">iota</span>
<span class="n">ClassReserved</span>
<span class="n">ClassDebug</span>
<span class="n">ClassReserved2</span>
<span class="p">)</span>
<span class="k">var</span> <span class="p">(</span>
<span class="n">classStr</span> <span class="k">map</span><span class="p">[</span><span class="kt">uint8</span><span class="p">]</span><span class="kt">string</span> <span class="o">=</span> <span class="k">map</span><span class="p">[</span><span class="kt">uint8</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
<span class="n">ClassControl</span><span class="o">:</span> <span class="s">"Control"</span><span class="p">,</span>
<span class="n">ClassReserved</span><span class="o">:</span> <span class="s">"Reserved (1)"</span><span class="p">,</span>
<span class="n">ClassDebug</span><span class="o">:</span> <span class="s">"Debugging/Measurement"</span><span class="p">,</span>
<span class="n">ClassReserved2</span><span class="o">:</span> <span class="s">"Reserved (2)"</span><span class="p">,</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="k">const</span> <span class="p">(</span>
<span class="c">/// This is the same type from examples/v4optspad.go.</span>
<span class="n">ip4OptTypBits</span> <span class="kt">string</span> <span class="o">=</span> <span class="s">"10010100"</span> <span class="c">// [1001 0100], or 148 (0x94)</span>
<span class="p">)</span>
<span class="k">var</span> <span class="p">(</span>
<span class="n">v4TypCpyOffset</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="m">0x80</span> <span class="c">// 128</span>
<span class="n">v4TypCpyMask</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="m">0x01</span> <span class="c">// Mask to 1 bit</span>
<span class="n">v4TypCpyPos</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="m">8</span> <span class="o">-</span> <span class="n">v4TypCpyMask</span> <span class="c">// 7 or 0x07 (8 (bits) - mask = Shifted to 7th bit)</span>
<span class="n">v4TypClsOffset</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="m">0x60</span> <span class="c">// 96</span>
<span class="n">v4TypClsMask</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="m">0x05</span> <span class="c">// mask to 5 bits</span>
<span class="n">v4TypClsPos</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="m">8</span> <span class="o">-</span> <span class="n">v4TypClsMask</span>
<span class="n">v4TypNumOffset</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="m">0x1f</span> <span class="c">// 31</span>
<span class="p">)</span>
<span class="k">func</span> <span class="n">ToV4OptTyp</span><span class="p">(</span><span class="n">copied</span><span class="p">,</span> <span class="n">class</span><span class="p">,</span> <span class="n">num</span> <span class="kt">uint8</span><span class="p">)</span> <span class="p">(</span><span class="n">typ</span> <span class="kt">uint8</span><span class="p">)</span> <span class="p">{</span>
<span class="n">typ</span> <span class="o">=</span> <span class="p">((</span><span class="n">copied</span> <span class="o">&amp;</span> <span class="n">v4TypCpyMask</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">v4TypCpyPos</span><span class="p">)</span> <span class="o">|</span> <span class="p">((</span><span class="n">class</span> <span class="o">&amp;</span> <span class="n">v4TypClsMask</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">v4TypClsPos</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">num</span> <span class="o">&amp;</span> <span class="n">v4TypNumOffset</span><span class="p">)</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">FromV4OptTyp</span><span class="p">(</span><span class="n">typ</span> <span class="kt">uint8</span><span class="p">)</span> <span class="p">(</span><span class="n">copied</span><span class="p">,</span> <span class="n">class</span><span class="p">,</span> <span class="n">num</span> <span class="kt">uint8</span><span class="p">)</span> <span class="p">{</span>
<span class="n">copied</span> <span class="o">=</span> <span class="p">(</span><span class="n">typ</span> <span class="o">&amp;</span> <span class="n">v4TypCpyOffset</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="n">v4TypCpyPos</span>
<span class="n">class</span> <span class="o">=</span> <span class="p">(</span><span class="n">typ</span> <span class="o">&amp;</span> <span class="n">v4TypClsOffset</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="n">v4TypClsPos</span>
<span class="n">num</span> <span class="o">=</span> <span class="p">(</span><span class="n">typ</span> <span class="o">&amp;</span> <span class="n">v4TypNumOffset</span><span class="p">)</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
<span class="k">var</span> <span class="n">err</span> <span class="kt">error</span>
<span class="k">var</span> <span class="n">u64</span> <span class="kt">uint64</span>
<span class="k">var</span> <span class="n">typ</span> <span class="kt">uint8</span>
<span class="k">var</span> <span class="n">cpd</span> <span class="kt">uint8</span>
<span class="k">var</span> <span class="n">cls</span> <span class="kt">uint8</span>
<span class="k">var</span> <span class="n">num</span> <span class="kt">uint8</span>
<span class="c">// Given a type of ip4OptTypBits (see const at top)...</span>
<span class="k">if</span> <span class="n">u64</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">strconv</span><span class="o">.</span><span class="n">ParseUint</span><span class="p">(</span><span class="n">ip4OptTypBits</span><span class="p">,</span> <span class="m">2</span><span class="p">,</span> <span class="m">8</span><span class="p">);</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
<span class="n">log</span><span class="o">.</span><span class="n">Panicln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">typ</span> <span class="o">=</span> <span class="kt">uint8</span><span class="p">(</span><span class="n">u64</span><span class="p">)</span>
<span class="c">// Prints:</span>
<span class="c">/*
Type is: 148 (0x0094)
*/</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Type is:</span><span class="se">\t</span><span class="s">%d (%#04x)</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">typ</span><span class="p">,</span> <span class="n">typ</span><span class="p">)</span>
<span class="n">cpd</span><span class="p">,</span> <span class="n">cls</span><span class="p">,</span> <span class="n">num</span> <span class="o">=</span> <span class="n">FromV4OptTyp</span><span class="p">(</span><span class="n">typ</span><span class="p">)</span>
<span class="c">// Prints:</span>
<span class="c">/*
Copied: 1 (0x0001)
Class: 0 (0x0000)
Number: 20 (0x0014)
*/</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span>
<span class="s">"Copied:</span><span class="se">\t\t</span><span class="s">%d %#04x)</span><span class="se">\n</span><span class="s">"</span><span class="o">+</span>
<span class="s">"Class:</span><span class="se">\t\t</span><span class="s">%d (%#04x)</span><span class="se">\n</span><span class="s">"</span><span class="o">+</span>
<span class="s">"Number:</span><span class="se">\t\t</span><span class="s">%d (%#04x)</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
<span class="n">cpd</span><span class="p">,</span> <span class="n">cpd</span><span class="p">,</span>
<span class="n">cls</span><span class="p">,</span> <span class="n">cls</span><span class="p">,</span>
<span class="n">num</span><span class="p">,</span> <span class="n">num</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">typ</span> <span class="o">=</span> <span class="n">ToV4OptTyp</span><span class="p">(</span><span class="n">cpd</span><span class="p">,</span> <span class="n">cls</span><span class="p">,</span> <span class="n">num</span><span class="p">)</span>
<span class="c">// Prints:</span>
<span class="c">/*
Confirmed Type: 148 (0x94)
*/</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Confirmed Type:</span><span class="se">\t</span><span class="s">%d (%#02x)</span><span class="se">\n\n</span><span class="s">"</span><span class="p">,</span> <span class="n">typ</span><span class="p">,</span> <span class="n">typ</span><span class="p">)</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Class Name:"</span><span class="p">)</span>
<span class="c">// Prints:</span>
<span class="c">/*
Control
*/</span>
<span class="k">for</span> <span class="n">c</span><span class="p">,</span> <span class="n">cNm</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">classStr</span> <span class="p">{</span>
<span class="k">if</span> <span class="n">c</span> <span class="o">==</span> <span class="n">cls</span> <span class="p">{</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">cNm</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
</details>
</div>
<div class="sect3">
<h4 id="xtra_bitpacked_vtf"><a class="link" href="#xtra_bitpacked_vtf">8.1.5. IP Version, Traffic Class, Flow Label (IPv6)</a></h4>
<div class="paragraph">
<p>IPv6 thankfully only has one bitpacking in the header. Unfortunately, it&#8217;s a triple-whammy.</p>
</div>
@@ -2774,12 +2929,13 @@ IPv6 does not require a header checksum.</p>
<summary class="title">Example in Go</summary>
<div class="content">
<div class="listingblock">
<div class="title"><code>examples/vtf.go</code></div>
<div class="content">
<pre class="rouge highlight"><code data-lang="go"><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">`fmt`</span>
<span class="s">`log`</span>
<span class="s">"fmt"</span>
<span class="s">"log"</span>
<span class="s">"strconv"</span>
<span class="p">)</span>
@@ -2866,12 +3022,148 @@ IPv6 does not require a header checksum.</p>
</details>
</div>
</div>
<div class="sect2">
<h3 id="xtra_pad"><a class="link" href="#xtra_pad">8.2. Padded Fields</a></h3>
<div class="sect3">
<h4 id="xtra_pad_v4opts"><a class="link" href="#xtra_pad_v4opts">8.2.1. IPv4 Options</a></h4>
<div class="paragraph">
<p>The IPv4 options, if specified, <strong>must</strong> align to a 32-bit/4-byte multiple size.
(In other words, its total length of bytes <strong>must</strong> be cleanly divisible by 4;
or said another way its total length of bits must be cleanly divisible by 32).</p>
</div>
<div class="paragraph">
<p>It uses null-byte (<code>0x00</code>) padding to achieve this.</p>
</div>
<details>
<summary class="title">Example in Go</summary>
<div class="content">
<div class="listingblock">
<div class="title"><code>examples/v4optspad.go</code></div>
<div class="content">
<pre class="rouge highlight"><code data-lang="go"><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">"bytes"</span>
<span class="s">"fmt"</span>
<span class="p">)</span>
<span class="k">const</span> <span class="p">(</span>
<span class="n">padVal</span> <span class="kt">uint8</span> <span class="o">=</span> <span class="m">0x00</span> <span class="c">// Padded with NUL/null-bytes</span>
<span class="n">alignLen</span> <span class="kt">int</span> <span class="o">=</span> <span class="m">4</span> <span class="c">// 4-Byte alignment</span>
<span class="p">)</span>
<span class="k">var</span> <span class="p">(</span>
<span class="c">// See the examples/v4opts.go for how these bytes are constructed.</span>
<span class="n">opts</span> <span class="p">[]</span><span class="kt">byte</span> <span class="o">=</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">{</span>
<span class="c">// This is an example.</span>
<span class="c">// Option 1</span>
<span class="m">0x94</span><span class="p">,</span> <span class="c">// Type 148, RTRALT (Router Alert) (RFC 2113)</span>
<span class="m">0x04</span><span class="p">,</span> <span class="c">// Length (4 bytes)</span>
<span class="m">0x00</span><span class="p">,</span> <span class="m">0x00</span><span class="p">,</span> <span class="c">// "Router shall examine packet"</span>
<span class="c">// EOOL</span>
<span class="m">0x00</span><span class="p">,</span>
<span class="c">// Padding will go here.</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
<span class="k">var</span> <span class="n">optLen</span> <span class="kt">int</span>
<span class="k">var</span> <span class="n">padLen</span> <span class="kt">int</span>
<span class="k">var</span> <span class="n">pad</span> <span class="p">[]</span><span class="kt">byte</span>
<span class="n">optLen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">opts</span><span class="p">)</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Before padding:"</span><span class="p">)</span>
<span class="c">// Prints:</span>
<span class="c">/*
0x9404000000
(Length: 5)
*/</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"%#02x</span><span class="se">\n</span><span class="s">(Length: %d)</span><span class="se">\n\n</span><span class="s">"</span><span class="p">,</span> <span class="n">opts</span><span class="p">,</span> <span class="n">optLen</span><span class="p">)</span>
<span class="c">/*
The remainder of the current length divided by
alignLen (4) (modulo) is subtracted from the alignLen
to determine how much must be added to reach the next
"boundary". It's then modulo'd *again* to rule out
currently being on an alignment bounary.
*/</span>
<span class="n">padLen</span> <span class="o">=</span> <span class="p">(</span><span class="n">alignLen</span> <span class="o">-</span> <span class="p">(</span><span class="n">optLen</span> <span class="o">%</span> <span class="n">alignLen</span><span class="p">))</span> <span class="o">%</span> <span class="n">alignLen</span>
<span class="c">// Prints:</span>
<span class="c">/*
Pad length needed: 3
*/</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Pad length needed:</span><span class="se">\t</span><span class="s">%d</span><span class="se">\n\n</span><span class="s">"</span><span class="p">,</span> <span class="n">padLen</span><span class="p">)</span>
<span class="n">pad</span> <span class="o">=</span> <span class="n">bytes</span><span class="o">.</span><span class="n">Repeat</span><span class="p">([]</span><span class="kt">byte</span><span class="p">{</span><span class="n">padVal</span><span class="p">},</span> <span class="n">padLen</span><span class="p">)</span>
<span class="n">opts</span> <span class="o">=</span> <span class="nb">append</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">pad</span><span class="o">...</span><span class="p">)</span>
<span class="c">// Alternatively, this can be implemented with a loop, though it's likely less efficient:</span>
<span class="c">/*
for len(opts) % alignLen != 0 {}
opts = append(opts, padVal)
}
*/</span>
<span class="c">// Prints:</span>
<span class="c">/*
Padded:
0x9404000000000000
*/</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Padded:</span><span class="se">\n</span><span class="s">%#x</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
</details>
<div class="paragraph">
<p>For more extensive details, see <a href="https://datatracker.ietf.org/doc/html/rfc791#section-3.1" target="_blank" rel="noopener">RFC 791 § 3.1</a>
and the <a href="https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml" target="_blank" rel="noopener">IANA Registered IP Paramaeters</a>
(the <strong>Value</strong> column is what should be used as the <strong>Type</strong>, see <a href="#xtra_bitpacked_ip4opt_t">IPv4 Option Type</a>.</p>
</div>
<div class="paragraph">
<p>Each option (with two exceptions) is a TLV (<a href="#xtra_pad_v4opts_t">type</a> / <a href="#xtra_pad_v4opts_l">length</a> / <a href="#xtra_pad_v4opts_v">value</a>) structured field.</p>
</div>
<div class="paragraph">
<p>The two exceptions for the above are <code>EOOL</code> (<code>0x00</code>) and <code>NOP</code> (<code>0x01</code>), both of which occupy only a single byte&#8201;&#8212;&#8201;they are <strong>unvalued</strong>, so they have no length or value field.</p>
</div>
<div class="sect4">
<h5 id="xtra_pad_v4opts_t"><a class="link" href="#xtra_pad_v4opts_t">8.2.1.1. Type</a></h5>
<div class="paragraph">
<p>See <a href="#xtra_bitpacked_ip4opt_t">IPv4 Option Type</a> for details.</p>
</div>
</div>
<div class="sect4">
<h5 id="xtra_pad_v4opts_l"><a class="link" href="#xtra_pad_v4opts_l">8.2.1.2. Length</a></h5>
<div class="paragraph">
<p>The <strong>Length</strong> is the length of this <em>entire</em> option as an 8-bit unsigned integer.</p>
</div>
<div class="paragraph">
<p>In other words it includes the length of the <a href="#xtra_pad_v4opts_t">Type</a> field, the <a href="#xtra_pad_v4opts_l">Length</a> field (this field),
<strong>and</strong> the <a href="#xtra_pad_v4opts_v">Value</a> field together.</p>
</div>
<div class="paragraph">
<p>This is not present for <code>EOOL</code> (<code>0x00</code>) and <code>NOP</code> (<code>0x01</code>) (or any other "non-valued" options).</p>
</div>
</div>
<div class="sect4">
<h5 id="xtra_pad_v4opts_v"><a class="link" href="#xtra_pad_v4opts_v">8.2.1.3. Value</a></h5>
<div class="paragraph">
<p>Value is the option&#8217;s value. Its <a href="#xtra_pad_v4opts_l">Length</a> is variable depending on the <a href="#xtra_pad_v4opts_t">Type</a>.</p>
</div>
<div class="paragraph">
<p>This is not present for <code>EOOL</code> (<code>0x00</code>) and <code>NOP</code> (<code>0x01</code>) (or any other "non-valued" options).</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-08-30 16:39:39 -0400
Last updated 2025-08-31 00:25:52 -0400
</div>
</div>
</body>