From 727a17d07bc2c8042bd882dd6fcc3001a47933c9 Mon Sep 17 00:00:00 2001 From: Pablo Mazzini Date: Tue, 31 Jul 2018 17:02:36 +0200 Subject: add OptHostName --- dhcpv4/option_domain_name.go | 6 ++--- dhcpv4/option_host_name.go | 49 +++++++++++++++++++++++++++++++++++++++++ dhcpv4/option_host_name_test.go | 41 ++++++++++++++++++++++++++++++++++ dhcpv4/options.go | 2 ++ 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 dhcpv4/option_host_name.go create mode 100644 dhcpv4/option_host_name_test.go (limited to 'dhcpv4') diff --git a/dhcpv4/option_domain_name.go b/dhcpv4/option_domain_name.go index 71d7ef1..e876b05 100644 --- a/dhcpv4/option_domain_name.go +++ b/dhcpv4/option_domain_name.go @@ -2,10 +2,10 @@ package dhcpv4 import "fmt" -// This option implements the server domani name option +// This option implements the domain name option // https://tools.ietf.org/html/rfc2132 -// OptDomainName represents an option encapsulating the server identifier. +// OptDomainName represents an option encapsulating the domain name. type OptDomainName struct { DomainName string } @@ -13,7 +13,7 @@ type OptDomainName struct { // ParseOptDomainName returns a new OptDomainName from a byte // stream, or error if any. func ParseOptDomainName(data []byte) (*OptDomainName, error) { - if len(data) < 2 { + if len(data) < 3 { return nil, ErrShortByteStream } code := OptionCode(data[0]) diff --git a/dhcpv4/option_host_name.go b/dhcpv4/option_host_name.go new file mode 100644 index 0000000..a922a2b --- /dev/null +++ b/dhcpv4/option_host_name.go @@ -0,0 +1,49 @@ +package dhcpv4 + +import "fmt" + +// This option implements the host name option +// https://tools.ietf.org/html/rfc2132 + +// OptHostName represents an option encapsulating the host name. +type OptHostName struct { + HostName string +} + +// ParseOptHostName returns a new OptHostName from a byte stream, or error if +// any. +func ParseOptHostName(data []byte) (*OptHostName, error) { + if len(data) < 3 { + return nil, ErrShortByteStream + } + code := OptionCode(data[0]) + if code != OptionHostName { + return nil, fmt.Errorf("expected code %v, got %v", OptionHostName, code) + } + length := int(data[1]) + if len(data) < 2+length { + return nil, ErrShortByteStream + } + return &OptHostName{HostName: string(data[2 : 2+length])}, nil +} + +// Code returns the option code. +func (o *OptHostName) Code() OptionCode { + return OptionHostName +} + +// ToBytes returns a serialized stream of bytes for this option. +func (o *OptHostName) ToBytes() []byte { + return append([]byte{byte(o.Code()), byte(o.Length())}, []byte(o.HostName)...) +} + +// String returns a human-readable string. +func (o *OptHostName) String() string { + return fmt.Sprintf("Host Name -> %v", o.HostName) +} + +// Length returns the length of the data portion (excluding option code an byte +// length). +func (o *OptHostName) Length() int { + return len(o.HostName) +} diff --git a/dhcpv4/option_host_name_test.go b/dhcpv4/option_host_name_test.go new file mode 100644 index 0000000..7f99100 --- /dev/null +++ b/dhcpv4/option_host_name_test.go @@ -0,0 +1,41 @@ +package dhcpv4 + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestOptHostNameInterfaceMethods(t *testing.T) { + o := OptHostName{HostName: "foo"} + require.Equal(t, OptionHostName, o.Code(), "Code") + require.Equal(t, 3, o.Length(), "Length") + require.Equal(t, []byte{byte(OptionHostName), 3, 'f', 'o', 'o'}, o.ToBytes(), "ToBytes") +} + +func TestParseOptHostName(t *testing.T) { + data := []byte{byte(OptionHostName), 4, 't', 'e', 's', 't'} + o, err := ParseOptHostName(data) + require.NoError(t, err) + require.Equal(t, &OptHostName{HostName: "test"}, o) + + // Short byte stream + data = []byte{byte(OptionHostName)} + _, err = ParseOptHostName(data) + require.Error(t, err, "should get error from short byte stream") + + // Wrong code + data = []byte{54, 2, 1, 1} + _, err = ParseOptHostName(data) + require.Error(t, err, "should get error from wrong code") + + // Bad length + data = []byte{byte(OptionHostName), 6, 1, 1, 1} + _, err = ParseOptHostName(data) + require.Error(t, err, "should get error from bad length") +} + +func TestOptHostNameString(t *testing.T) { + o := OptHostName{HostName: "testy test"} + require.Equal(t, "Host Name -> testy test", o.String()) +} diff --git a/dhcpv4/options.go b/dhcpv4/options.go index 760bc98..4903ab3 100644 --- a/dhcpv4/options.go +++ b/dhcpv4/options.go @@ -44,6 +44,8 @@ func ParseOption(data []byte) (Option, error) { opt, err = ParseOptSubnetMask(data) case OptionRouter: opt, err = ParseOptRouter(data) + case OptionHostName: + opt, err = ParseOptDomainName(data) case OptionRequestedIPAddress: opt, err = ParseOptRequestedIPAddress(data) case OptionIPAddressLeaseTime: -- cgit v1.2.3