diff options
-rw-r--r-- | dhcpv4/option_userclass.go | 17 | ||||
-rw-r--r-- | dhcpv4/option_userclass_test.go | 28 |
2 files changed, 37 insertions, 8 deletions
diff --git a/dhcpv4/option_userclass.go b/dhcpv4/option_userclass.go index 307a128..fc088fa 100644 --- a/dhcpv4/option_userclass.go +++ b/dhcpv4/option_userclass.go @@ -66,6 +66,23 @@ func ParseOptUserClass(data []byte) (*OptUserClass, error) { totalLength, len(data)) } + // Check if option is Microsoft style instead of RFC compliant, issue #113 + + // User-class options are, according to RFC3004, supposed to contain a set + // of strings each with length UC_Len_i. Here we check that this is so, + // by seeing if all the UC_Len_i lengths are consistent with the overall + // option length. If the lengths don't add up, we assume that the option + // is a single string and non RFC3004 compliant + var counting int + for counting < totalLength { + // UC_Len_i does not include itself so add 1 + counting += int(data[counting]) + 1 + } + if counting != totalLength { + opt.UserClasses = append(opt.UserClasses, data[:totalLength]) + return &opt, nil + } + for i := 0; i < totalLength; { ucLen := int(data[i]) if ucLen == 0 { diff --git a/dhcpv4/option_userclass_test.go b/dhcpv4/option_userclass_test.go index 492cabd..02b6f94 100644 --- a/dhcpv4/option_userclass_test.go +++ b/dhcpv4/option_userclass_test.go @@ -38,6 +38,26 @@ func TestParseOptUserClassNone(t *testing.T) { require.Error(t, err) } +func TestParseOptUserClassMicrosoft(t *testing.T) { + expected := []byte{ + 77, 9, 'l', 'i', 'n', 'u', 'x', 'b', 'o', 'o', 't', + } + opt, err := ParseOptUserClass(expected) + require.NoError(t, err) + require.Equal(t, 1, len(opt.UserClasses)) + require.Equal(t, []byte("linuxboot"), opt.UserClasses[0]) +} + +func TestParseOptUserClassMicrosoftLongerThanLength(t *testing.T) { + expected := []byte{ + 77, 9, 'l', 'i', 'n', 'u', 'x', 'b', 'o', 'o', 't', 'X', + } + opt, err := ParseOptUserClass(expected) + require.NoError(t, err) + require.Equal(t, 1, len(opt.UserClasses)) + require.Equal(t, []byte("linuxboot"), opt.UserClasses[0]) +} + func TestParseOptUserClass(t *testing.T) { expected := []byte{ 77, 10, 9, 'l', 'i', 'n', 'u', 'x', 'b', 'o', 'o', 't', @@ -75,14 +95,6 @@ func TestParseOptUserClassLongerThanLength(t *testing.T) { require.Equal(t, []byte("linuxboot"), opt.UserClasses[0]) } -func TestParseOptUserClassShorterThanLength(t *testing.T) { - expected := []byte{ - 77, 10, 10, 'l', 'i', 'n', 'u', 'x', 'b', 'o', 'o', 't', - } - _, err := ParseOptUserClass(expected) - require.Error(t, err) -} - func TestParseOptUserClassShorterTotalLength(t *testing.T) { expected := []byte{ 77, 11, 10, 'l', 'i', 'n', 'u', 'x', 'b', 'o', 'o', 't', |