summaryrefslogtreecommitdiffhomepage
path: root/dhcpv4/option_userclass.go
diff options
context:
space:
mode:
Diffstat (limited to 'dhcpv4/option_userclass.go')
-rw-r--r--dhcpv4/option_userclass.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/dhcpv4/option_userclass.go b/dhcpv4/option_userclass.go
new file mode 100644
index 0000000..8aa02d6
--- /dev/null
+++ b/dhcpv4/option_userclass.go
@@ -0,0 +1,78 @@
+package dhcpv4
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
+
+// OptUserClass represents a DHCPv4 User Class option
+type OptUserClass struct {
+ UserClasses [][]byte
+}
+
+// Code returns the option code
+func (op *OptUserClass) Code() OptionCode {
+ return OptionUserClassInformation
+}
+
+// ToBytes serializes the option and returns it as a sequence of bytes
+func (op *OptUserClass) ToBytes() []byte {
+ buf := []byte{byte(op.Code()), byte(op.Length())}
+ for _, uc := range op.UserClasses {
+ buf = append(buf, byte(len(uc)))
+ buf = append(buf, uc...)
+ }
+ return buf
+}
+
+// Length returns the option length
+func (op *OptUserClass) Length() int {
+ ret := 0
+ for _, uc := range op.UserClasses {
+ ret += 1 + len(uc)
+ }
+ return ret
+}
+
+func (op *OptUserClass) String() string {
+ ucStrings := make([]string, 0)
+ for _, uc := range op.UserClasses {
+ ucStrings = append(ucStrings, string(uc))
+ }
+ return fmt.Sprintf("OptUserClass{userclass=[%s]}", strings.Join(ucStrings, ", "))
+}
+
+// ParseOptUserClass returns a new OptUserClass from a byte stream or
+// error if any
+func ParseOptUserClass(data []byte) (*OptUserClass, error) {
+ opt := OptUserClass{}
+
+ if len(data) < 4 {
+ return nil, ErrShortByteStream
+ }
+ code := OptionCode(data[0])
+ if code != OptionUserClassInformation {
+ return nil, fmt.Errorf("expected code %v, got %v", OptionUserClassInformation, code)
+ }
+ data = data[2:]
+
+ for {
+ if len(data) == 0 {
+ break
+ }
+ if len(data) < 1 {
+ return nil, errors.New("ParseOptUserClass: short data: missing length field")
+ }
+ ucLen := int(data[0])
+ if len(data) < ucLen+1 {
+ return nil, fmt.Errorf("ParseOptUserClass: short data: less than %d bytes", ucLen+2)
+ }
+ opt.UserClasses = append(opt.UserClasses, data[1:ucLen+1])
+ data = data[1+ucLen:]
+ }
+ if len(opt.UserClasses) < 1 {
+ return nil, errors.New("ParseOptUserClass: at least one user class is required")
+ }
+ return &opt, nil
+}