diff options
-rw-r--r-- | dhcpv6/option_statuscode.go | 40 | ||||
-rw-r--r-- | dhcpv6/option_statuscode_test.go | 34 | ||||
-rw-r--r-- | iana/statuscodes.go | 32 |
3 files changed, 78 insertions, 28 deletions
diff --git a/dhcpv6/option_statuscode.go b/dhcpv6/option_statuscode.go index 7740f4d..e6bd8ae 100644 --- a/dhcpv6/option_statuscode.go +++ b/dhcpv6/option_statuscode.go @@ -6,12 +6,14 @@ package dhcpv6 import ( "encoding/binary" "fmt" + + "github.com/insomniacslk/dhcp/iana" ) // OptStatusCode represents a DHCPv6 Status Code option type OptStatusCode struct { - statusCode uint16 - statusMessage []byte + StatusCode iana.StatusCode + StatusMessage []byte } // Code returns the option code @@ -24,38 +26,20 @@ func (op *OptStatusCode) ToBytes() []byte { buf := make([]byte, 6) binary.BigEndian.PutUint16(buf[0:2], uint16(OPTION_STATUS_CODE)) binary.BigEndian.PutUint16(buf[2:4], uint16(op.Length())) - binary.BigEndian.PutUint16(buf[4:6], op.statusCode) - buf = append(buf, op.statusMessage...) + binary.BigEndian.PutUint16(buf[4:6], uint16(op.StatusCode)) + buf = append(buf, op.StatusMessage...) return buf } -// StatusCode returns the status code -func (op *OptStatusCode) StatusCode() uint16 { - return op.statusCode -} - -// SetStatusCode sets the status code -func (op *OptStatusCode) SetStatusCode(code uint16) { - op.statusCode = code -} - -// StatusMessage returns the status message -func (op *OptStatusCode) StatusMessage() []byte { - return op.statusMessage -} - -// SetStatusMessage sets the status message -func (op *OptStatusCode) SetStatusMessage(message []byte) { - op.statusMessage = message -} - // Length returns the option length func (op *OptStatusCode) Length() int { - return 2 + len(op.statusMessage) + return 2 + len(op.StatusMessage) } func (op *OptStatusCode) String() string { - return fmt.Sprintf("OptStatusCode{code=%v, message=%v}", op.statusCode, string(op.statusMessage)) + return fmt.Sprintf("OptStatusCode{code=%s (%d), message=%v}", + iana.StatusCodeToString(op.StatusCode), op.StatusCode, + string(op.StatusMessage)) } // ParseOptStatusCode builds an OptStatusCode structure from a sequence of @@ -65,7 +49,7 @@ func ParseOptStatusCode(data []byte) (*OptStatusCode, error) { return nil, fmt.Errorf("Invalid OptStatusCode data: length is shorter than 2") } opt := OptStatusCode{} - opt.statusCode = binary.BigEndian.Uint16(data[0:2]) - opt.statusMessage = append(opt.statusMessage, data[2:]...) + opt.StatusCode = iana.StatusCode(binary.BigEndian.Uint16(data[0:2])) + opt.StatusMessage = append(opt.StatusMessage, data[2:]...) return &opt, nil } diff --git a/dhcpv6/option_statuscode_test.go b/dhcpv6/option_statuscode_test.go new file mode 100644 index 0000000..95c785e --- /dev/null +++ b/dhcpv6/option_statuscode_test.go @@ -0,0 +1,34 @@ +package dhcpv6 + +import ( + "testing" + + "github.com/insomniacslk/dhcp/iana" + "github.com/stretchr/testify/require" +) + +func TestParseOptStatusCode(t *testing.T) { + data := []byte{ + 0, 5, // StatusUseMulticast + 'u', 's', 'e', ' ', 'm', 'u', 'l', 't', 'i', 'c', 'a', 's', 't', + } + opt, err := ParseOptStatusCode(data) + require.NoError(t, err) + require.Equal(t, opt.StatusCode, iana.StatusUseMulticast) + require.Equal(t, opt.StatusMessage, []byte("use multicast")) +} + +func TestOptStatusCodeToBytes(t *testing.T) { + expected := []byte{ + 0, 13, // OPTION_STATUS_CODE + 0, 9, // length + 0, 0, // StatusSuccess + 's', 'u', 'c', 'c', 'e', 's', 's', + } + opt := OptStatusCode{ + iana.StatusSuccess, + []byte("success"), + } + actual := opt.ToBytes() + require.Equal(t, expected, actual) +} diff --git a/iana/statuscodes.go b/iana/statuscodes.go new file mode 100644 index 0000000..47e8110 --- /dev/null +++ b/iana/statuscodes.go @@ -0,0 +1,32 @@ +package iana + +// StatusCode represents a IANA status code for DHCPv6 +type StatusCode uint16 + +// IANA status codes as defined by rfc 3315 par. 24..4 +const ( + StatusSuccess StatusCode = 0 + StatusUnspecFail StatusCode = 1 + StatusNoAddrsAvail StatusCode = 2 + StatusNoBinding StatusCode = 3 + StatusNotOnLink StatusCode = 4 + StatusUseMulticast StatusCode = 5 +) + +// StatusCodeToString returns a mnemonic name for a given status code +func StatusCodeToString(s StatusCode) string { + if sc := StatusCodeToStringMap[s]; sc != "" { + return sc + } + return "Unknown" +} + +// StatusCodeToStringMap maps status codes to their names +var StatusCodeToStringMap = map[StatusCode]string{ + StatusSuccess: "Success", + StatusUnspecFail: "UnspecFail", + StatusNoAddrsAvail: "NoAddrsAvail", + StatusNoBinding: "NoBinding", + StatusNotOnLink: "NotOnLink", + StatusUseMulticast: "UseMulticast", +} |