summaryrefslogtreecommitdiffhomepage
path: root/dhcpv4/options.go
diff options
context:
space:
mode:
authorChristopher Koch <chrisko@google.com>2018-12-29 09:16:15 -0800
committerinsomniac <insomniacslk@users.noreply.github.com>2019-01-11 19:38:21 +0000
commit9492662dae0651fd4d6698d35b58ade7300e149e (patch)
tree77f53ebd6dfded05880c322005909b97a1cf140c /dhcpv4/options.go
parent512011c2eb80a7c0316405ef7aaae6e0b5b09b1c (diff)
dhcpv4: simplify marshaling options to binary.
- Consolidate writing the option code and length to Options.Marshal rather than doing it in each individual option. - Use uio in marshaling code.
Diffstat (limited to 'dhcpv4/options.go')
-rw-r--r--dhcpv4/options.go40
1 files changed, 40 insertions, 0 deletions
diff --git a/dhcpv4/options.go b/dhcpv4/options.go
index d5162f4..ce2fdcd 100644
--- a/dhcpv4/options.go
+++ b/dhcpv4/options.go
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io"
+ "math"
"github.com/u-root/u-root/pkg/uio"
)
@@ -208,3 +209,42 @@ func OptionsFromBytesWithParser(data []byte, parser OptionParser, checkEndOption
}
return opts, nil
}
+
+// Marshal writes options binary representations to b.
+func (o Options) Marshal(b *uio.Lexer) {
+ for _, opt := range o {
+ code := opt.Code()
+
+ // Even if the End option is in there, don't marshal it until
+ // the end.
+ if code == OptionEnd {
+ continue
+ } else if code == OptionPad {
+ // Some DHCPv4 options have fixed length and do not put
+ // length on the wire.
+ b.Write8(uint8(code))
+ continue
+ }
+
+ data := opt.ToBytes()
+
+ // RFC 3396: If more than 256 bytes of data are given, the
+ // option is simply listed multiple times.
+ for len(data) > 0 {
+ // 1 byte: option code
+ b.Write8(uint8(code))
+
+ n := len(data)
+ if n > math.MaxUint8 {
+ n = math.MaxUint8
+ }
+
+ // 1 byte: option length
+ b.Write8(uint8(n))
+
+ // N bytes: option data
+ b.WriteBytes(data[:n])
+ data = data[n:]
+ }
+ }
+}