Skip to content

Commit

Permalink
Merge pull request #15 from jerome-laforge/PR_ORO
Browse files Browse the repository at this point in the history
RFC 3315: Add OptionRequestOption
  • Loading branch information
mdlayher committed Oct 6, 2016
2 parents 6231dda + 3ad91f0 commit bef566a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 16 deletions.
36 changes: 36 additions & 0 deletions miscoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,42 @@ import (
"time"
)

// A OptionRequestOption is a list OptionCode, as defined in RFC 3315, Section 22.7.
//
// The Option Request option is used to identify a list of options in a
// message between a client and a server.
type OptionRequestOption []OptionCode

// MarshalBinary allocates a byte slice containing the data from a OptionRequestOption.
func (oro OptionRequestOption) MarshalBinary() ([]byte, error) {
b := make([]byte, 2*len(oro))
for i, j := range oro {
binary.BigEndian.PutUint16(b[2*i:], uint16(j))
}
return b, nil
}

// UnmarshalBinary unmarshals a raw byte slice into a OptionRequestOption.
//
// If the length of byte slice is not be be divisible by 2,
// errInvalidOptionRequest is returned.
func (oro *OptionRequestOption) UnmarshalBinary(b []byte) error {
// Length must be divisible by 2
if len(b)%2 != 0 {
return errInvalidOptionRequest
}

// Fill slice by parsing every two bytes using index i.
opts := make(OptionRequestOption, len(b)/2)
for i := range opts {
opts[i] = OptionCode(binary.BigEndian.Uint16(b[2*i:]))
}

*oro = opts

return nil
}

// A Preference is a preference value, as defined in RFC 3315, Section 22.8.
//
// A preference value is sent by a server to a client to affect the selection
Expand Down
19 changes: 4 additions & 15 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,26 +212,15 @@ func (o Options) IAAddr() ([]*IAAddr, bool, error) {
// The boolean return value indicates if OptionORO was present in the Options
// map. The error return value indicates if a valid OptionCode slice could be
// parsed from the option.
func (o Options) OptionRequest() ([]OptionCode, bool, error) {
func (o Options) OptionRequest() (OptionRequestOption, bool, error) {
v, ok := o.Get(OptionORO)
if !ok {
return nil, false, nil
}

// Length must be divisible by 2
if len(v)%2 != 0 {
return nil, false, errInvalidOptionRequest
}

// Fill slice by parsing every two bytes using index i,
// and using index j to insert options and track number
// of iterations until no more options exist
opts := make([]OptionCode, len(v)/2, len(v)/2)
for i, j := 0, 0; j < len(v)/2; i, j = i+2, j+1 {
opts[j] = OptionCode(binary.BigEndian.Uint16(v[i : i+2]))
}

return opts, true, nil
var oro OptionRequestOption
err := oro.UnmarshalBinary(v)
return oro, true, err
}

// Preference returns the Preference Option value, as described in RFC 3315,
Expand Down
2 changes: 1 addition & 1 deletion options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ func TestOptionsOptionRequest(t *testing.T) {
var tests = []struct {
desc string
options Options
codes []OptionCode
codes OptionRequestOption
ok bool
err error
}{
Expand Down

0 comments on commit bef566a

Please sign in to comment.