summaryrefslogtreecommitdiffhomepage
path: root/dhcpv4
diff options
context:
space:
mode:
authorAnatole Denis <natolumin@unverle.fr>2019-10-04 15:39:35 +0200
committerChris K <c@chrisko.ch>2020-06-20 21:42:12 -0700
commit79c7b91b466a66dd3d20be0b08a468490d693e78 (patch)
tree9ecdcaa833c4437d2761ca400ec2c54cc86f2352 /dhcpv4
parent0a25ba9f1fa6157f8290cb13954c1c8bea455112 (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.go10
-rw-r--r--dhcpv4/options_test.go18
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))
})
}
}