From 4d2cfd40eee7dd315385d320534b6c99094449e9 Mon Sep 17 00:00:00 2001 From: Christopher Koch Date: Wed, 9 Jan 2019 13:53:39 -0800 Subject: dhcpv4: simplify host name and boot file handling. --- dhcpv4/bsdp/bsdp_test.go | 4 +-- dhcpv4/dhcpv4.go | 83 +++++++++++++++++++----------------------------- dhcpv4/dhcpv4_test.go | 38 +++++++--------------- 3 files changed, 47 insertions(+), 78 deletions(-) (limited to 'dhcpv4') diff --git a/dhcpv4/bsdp/bsdp_test.go b/dhcpv4/bsdp/bsdp_test.go index 9da86fa..610b8d6 100644 --- a/dhcpv4/bsdp/bsdp_test.go +++ b/dhcpv4/bsdp/bsdp_test.go @@ -274,7 +274,7 @@ func TestNewReplyForInformList(t *testing.T) { require.NoError(t, err) require.Equal(t, net.IP{1, 2, 3, 4}, ack.ClientIPAddr()) require.Equal(t, net.IPv4zero, ack.YourIPAddr()) - require.Equal(t, "bsdp.foo.com", ack.ServerHostNameToString()) + require.Equal(t, "bsdp.foo.com", ack.ServerHostName()) // Validate options. RequireHasOption(t, ack, &dhcpv4.OptMessageType{MessageType: dhcpv4.MessageTypeAck}) @@ -355,7 +355,7 @@ func TestNewReplyForInformSelect(t *testing.T) { require.NoError(t, err) require.Equal(t, net.IP{1, 2, 3, 4}, ack.ClientIPAddr()) require.Equal(t, net.IPv4zero, ack.YourIPAddr()) - require.Equal(t, "bsdp.foo.com", ack.ServerHostNameToString()) + require.Equal(t, "bsdp.foo.com", ack.ServerHostName()) // Validate options. RequireHasOption(t, ack, &dhcpv4.OptMessageType{MessageType: dhcpv4.MessageTypeAck}) diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go index 56554eb..35e1917 100644 --- a/dhcpv4/dhcpv4.go +++ b/dhcpv4/dhcpv4.go @@ -43,8 +43,8 @@ type DHCPv4 struct { serverIPAddr net.IP gatewayIPAddr net.IP clientHwAddr net.HardwareAddr - serverHostName [64]byte - bootFileName [128]byte + serverHostName string + bootFileName string options []Option } @@ -123,11 +123,8 @@ func New() (*DHCPv4, error) { yourIPAddr: net.IPv4zero, serverIPAddr: net.IPv4zero, gatewayIPAddr: net.IPv4zero, + options: make([]Option, 0, 10), } - copy(d.serverHostName[:], []byte{}) - copy(d.bootFileName[:], []byte{}) - - d.options = make([]Option, 0, 10) // the End option has to be added explicitly d.AddOption(&OptionGeneric{OptionCode: OptionEnd}) return &d, nil @@ -295,8 +292,21 @@ func FromBytes(q []byte) (*DHCPv4, error) { buf.ReadBytes(p.clientHwAddr) p.clientHwAddr = p.clientHwAddr[:hwAddrLen] - buf.ReadBytes(p.serverHostName[:]) - buf.ReadBytes(p.bootFileName[:]) + var sname [64]byte + buf.ReadBytes(sname[:]) + length := strings.Index(string(sname[:]), "\x00") + if length == -1 { + length = 64 + } + p.serverHostName = string(sname[:length]) + + var file [128]byte + buf.ReadBytes(file[:]) + length = strings.Index(string(file[:]), "\x00") + if length == -1 { + length = 128 + } + p.bootFileName = string(file[:length]) var cookie [4]byte buf.ReadBytes(cookie[:]) @@ -488,57 +498,25 @@ func (d *DHCPv4) SetClientHwAddr(clientHwAddr net.HardwareAddr) { } // ServerHostName returns the server host name as a sequence of bytes. -func (d *DHCPv4) ServerHostName() [64]byte { +func (d *DHCPv4) ServerHostName() string { return d.serverHostName } -// ServerHostNameToString returns the server host name as a string, after -// trimming the null bytes at the end. -func (d *DHCPv4) ServerHostNameToString() string { - return strings.TrimRight(string(d.serverHostName[:]), "\x00") -} - // SetServerHostName replaces the server host name, from a sequence of bytes, // truncating it to the maximum length of 64. -func (d *DHCPv4) SetServerHostName(serverHostName []byte) { - if len(serverHostName) > 64 { - serverHostName = serverHostName[:64] - } else if len(serverHostName) < 64 { - for i := len(serverHostName) - 1; i < 64; i++ { - serverHostName = append(serverHostName, 0) - } - } - // need an array, not a slice, so let's copy it - var newServerHostName [64]byte - copy(newServerHostName[:], serverHostName) - d.serverHostName = newServerHostName +func (d *DHCPv4) SetServerHostName(serverHostName string) { + d.serverHostName = serverHostName } // BootFileName returns the boot file name as a sequence of bytes. -func (d *DHCPv4) BootFileName() [128]byte { +func (d *DHCPv4) BootFileName() string { return d.bootFileName } -// BootFileNameToString returns the boot file name as a string, after trimming -// the null bytes at the end. -func (d *DHCPv4) BootFileNameToString() string { - return strings.TrimRight(string(d.bootFileName[:]), "\x00") -} - // SetBootFileName replaces the boot file name, from a sequence of bytes, // truncating it to the maximum length oh 128. -func (d *DHCPv4) SetBootFileName(bootFileName []byte) { - if len(bootFileName) > 128 { - bootFileName = bootFileName[:128] - } else if len(bootFileName) < 128 { - for i := len(bootFileName) - 1; i < 128; i++ { - bootFileName = append(bootFileName, 0) - } - } - // need an array, not a slice, so let's copy it - var newBootFileName [128]byte - copy(newBootFileName[:], bootFileName) - d.bootFileName = newBootFileName +func (d *DHCPv4) SetBootFileName(bootFileName string) { + d.bootFileName = bootFileName } // Options returns the DHCPv4 options defined for the packet. @@ -662,8 +640,8 @@ func (d *DHCPv4) Summary() string { d.ServerIPAddr(), d.GatewayIPAddr(), d.ClientHwAddrToString(), - d.ServerHostNameToString(), - d.BootFileNameToString(), + d.ServerHostName(), + d.BootFileName(), ) ret += " options=\n" for _, opt := range d.options { @@ -752,8 +730,13 @@ func (d *DHCPv4) ToBytes() []byte { copy(buf.WriteN(maxHWAddrLen), d.clientHwAddr) - buf.WriteBytes(d.serverHostName[:]) - buf.WriteBytes(d.bootFileName[:]) + var sname [64]byte + copy(sname[:], []byte(d.serverHostName)) + buf.WriteBytes(sname[:]) + + var file [128]byte + copy(file[:], []byte(d.bootFileName)) + buf.WriteBytes(file[:]) // The magic cookie. buf.WriteBytes(magicCookie[:]) diff --git a/dhcpv4/dhcpv4_test.go b/dhcpv4/dhcpv4_test.go index 27df44d..893377d 100644 --- a/dhcpv4/dhcpv4_test.go +++ b/dhcpv4/dhcpv4_test.go @@ -71,10 +71,8 @@ func TestFromBytes(t *testing.T) { require.True(t, d.YourIPAddr().Equal(net.IPv4zero)) require.True(t, d.GatewayIPAddr().Equal(net.IPv4zero)) require.Equal(t, d.ClientHwAddr(), net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}) - hostname := d.ServerHostName() - require.Equal(t, hostname[:], expectedHostname) - bootfileName := d.BootFileName() - require.Equal(t, bootfileName[:], expectedBootfilename) + require.Equal(t, d.ServerHostName(), "") + require.Equal(t, d.BootFileName(), "") // no need to check Magic Cookie as it is already validated in FromBytes // above } @@ -207,26 +205,14 @@ func TestSettersAndGetters(t *testing.T) { d.SetFlags(0) // getter/setter for ServerHostName - serverhostname := d.ServerHostName() - require.Equal(t, expectedHostname, serverhostname[:]) - newHostname := []byte{'t', 'e', 's', 't'} - for i := 0; i < 60; i++ { - newHostname = append(newHostname, 0) - } - d.SetServerHostName(newHostname) - serverhostname = d.ServerHostName() - require.Equal(t, newHostname, serverhostname[:]) + require.Equal(t, "", d.ServerHostName()) + d.SetServerHostName("test") + require.Equal(t, "test", d.ServerHostName()) // getter/setter for BootFileName - bootfilename := d.BootFileName() - require.Equal(t, expectedBootfilename, bootfilename[:]) - newBootfilename := []byte{'t', 'e', 's', 't'} - for i := 0; i < 124; i++ { - newBootfilename = append(newBootfilename, 0) - } - d.SetBootFileName(newBootfilename) - bootfilename = d.BootFileName() - require.Equal(t, newBootfilename, bootfilename[:]) + require.Equal(t, "", d.BootFileName()) + d.SetBootFileName("test") + require.Equal(t, "test", d.BootFileName()) } func TestToStringMethods(t *testing.T) { @@ -263,12 +249,12 @@ func TestToStringMethods(t *testing.T) { require.Equal(t, "aa:bb:cc:dd:ee:ff", d.ClientHwAddrToString()) // ServerHostNameToString - d.SetServerHostName([]byte("my.host.local")) - require.Equal(t, "my.host.local", d.ServerHostNameToString()) + d.SetServerHostName("my.host.local") + require.Equal(t, "my.host.local", d.ServerHostName()) // BootFileNameToString - d.SetBootFileName([]byte("/my/boot/file")) - require.Equal(t, "/my/boot/file", d.BootFileNameToString()) + d.SetBootFileName("/my/boot/file") + require.Equal(t, "/my/boot/file", d.BootFileName()) } func TestNewToBytes(t *testing.T) { -- cgit v1.2.3