diff options
author | Anatole Denis <natolumin@unverle.fr> | 2019-10-04 15:39:35 +0200 |
---|---|---|
committer | Chris K <c@chrisko.ch> | 2020-06-20 21:42:12 -0700 |
commit | 79c7b91b466a66dd3d20be0b08a468490d693e78 (patch) | |
tree | 9ecdcaa833c4437d2761ca400ec2c54cc86f2352 /dhcpv4 | |
parent | 0a25ba9f1fa6157f8290cb13954c1c8bea455112 (diff) |
dhcpv4: Also write out 0-length options
When there was a 0-length generic option, it would be omitted.
Rapid commit (option 80) is a 0-length option with a length tag.
There could also be 0-length options in the vendor extensions, and the
RFC states that they should be written out:
> Any options defined subsequent to this document should contain a
> length octet even if the length is fixed or zero.
Signed-off-by: Anatole Denis <natolumin@unverle.fr>
Diffstat (limited to 'dhcpv4')
-rw-r--r-- | dhcpv4/options.go | 10 | ||||
-rw-r--r-- | dhcpv4/options_test.go | 18 |
2 files changed, 26 insertions, 2 deletions
diff --git a/dhcpv4/options.go b/dhcpv4/options.go index ea902f6..058c4ad 100644 --- a/dhcpv4/options.go +++ b/dhcpv4/options.go @@ -185,12 +185,20 @@ func (o Options) Marshal(b *uio.Lexer) { code := uint8(c) // Even if the End option is in there, don't marshal it until // the end. - if code == optEnd { + // Don't write padding either, since the options are sorted + // it would always be written first which isn't useful + if code == optEnd || code == optPad { continue } data := o[code] + // Ensure even 0-length options are written out + if len(data) == 0 { + b.Write8(code) + b.Write8(0) + continue + } // RFC 3396: If more than 256 bytes of data are given, the // option is simply listed multiple times. for len(data) > 0 { diff --git a/dhcpv4/options_test.go b/dhcpv4/options_test.go index 6c5393c..3850d2d 100644 --- a/dhcpv4/options_test.go +++ b/dhcpv4/options_test.go @@ -194,9 +194,25 @@ func TestOptionsMarshal(t *testing.T) { 5, 1, 10, ), }, + { + // Test 0-length options + opts: Options{ + 80: []byte{}, + }, + want: []byte{80, 0}, + }, + { + // Test special options, handled by the message marshalling code + // and ignored by the options marshalling code + opts: Options{ + 0: []byte{}, // Padding + 255: []byte{}, // End of options + }, + want: nil, // not written out + }, } { t.Run(fmt.Sprintf("Test %02d", i), func(t *testing.T) { - require.Equal(t, uio.ToBigEndian(tt.opts), tt.want) + require.Equal(t, tt.want, uio.ToBigEndian(tt.opts)) }) } } |