diff options
author | Christopher Koch <chrisko@google.com> | 2018-12-29 09:16:15 -0800 |
---|---|---|
committer | insomniac <insomniacslk@users.noreply.github.com> | 2019-01-11 19:38:21 +0000 |
commit | 9492662dae0651fd4d6698d35b58ade7300e149e (patch) | |
tree | 77f53ebd6dfded05880c322005909b97a1cf140c /dhcpv4/options.go | |
parent | 512011c2eb80a7c0316405ef7aaae6e0b5b09b1c (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.go | 40 |
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:] + } + } +} |