summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv4/option_broadcast_address.go56
-rw-r--r--dhcpv4/option_broadcast_address_test.go44
-rw-r--r--dhcpv4/option_server_identifier_test.go8
-rw-r--r--dhcpv4/options.go2
4 files changed, 106 insertions, 4 deletions
diff --git a/dhcpv4/option_broadcast_address.go b/dhcpv4/option_broadcast_address.go
new file mode 100644
index 0000000..ffa57e3
--- /dev/null
+++ b/dhcpv4/option_broadcast_address.go
@@ -0,0 +1,56 @@
+package dhcpv4
+
+import (
+ "fmt"
+ "net"
+)
+
+// This option implements the server identifier option
+// https://tools.ietf.org/html/rfc2132
+
+// OptBroadcastAddress represents an option encapsulating the server identifier.
+type OptBroadcastAddress struct {
+ BroadcastAddress net.IP
+}
+
+// ParseOptBroadcastAddress returns a new OptBroadcastAddress from a byte
+// stream, or error if any.
+func ParseOptBroadcastAddress(data []byte) (*OptBroadcastAddress, error) {
+ if len(data) < 2 {
+ return nil, ErrShortByteStream
+ }
+ code := OptionCode(data[0])
+ if code != OptionBroadcastAddress {
+ return nil, fmt.Errorf("expected code %v, got %v", OptionBroadcastAddress, code)
+ }
+ length := int(data[1])
+ if length != 4 {
+ return nil, fmt.Errorf("unexepcted length: expected 4, got %v", length)
+ }
+ if len(data) < 6 {
+ return nil, ErrShortByteStream
+ }
+ return &OptBroadcastAddress{BroadcastAddress: net.IP(data[2 : 2+length])}, nil
+}
+
+// Code returns the option code.
+func (o *OptBroadcastAddress) Code() OptionCode {
+ return OptionBroadcastAddress
+}
+
+// ToBytes returns a serialized stream of bytes for this option.
+func (o *OptBroadcastAddress) ToBytes() []byte {
+ ret := []byte{byte(o.Code()), byte(o.Length())}
+ return append(ret, o.BroadcastAddress.To4()...)
+}
+
+// String returns a human-readable string.
+func (o *OptBroadcastAddress) String() string {
+ return fmt.Sprintf("Broadcast Address -> %v", o.BroadcastAddress.String())
+}
+
+// Length returns the length of the data portion (excluding option code an byte
+// length).
+func (o *OptBroadcastAddress) Length() int {
+ return len(o.BroadcastAddress.To4())
+}
diff --git a/dhcpv4/option_broadcast_address_test.go b/dhcpv4/option_broadcast_address_test.go
new file mode 100644
index 0000000..3572dc0
--- /dev/null
+++ b/dhcpv4/option_broadcast_address_test.go
@@ -0,0 +1,44 @@
+package dhcpv4
+
+import (
+ "net"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestOptBroadcastAddressInterfaceMethods(t *testing.T) {
+ ip := net.IP{192, 168, 0, 1}
+ o := OptBroadcastAddress{BroadcastAddress: ip}
+
+ require.Equal(t, OptionBroadcastAddress, o.Code(), "Code")
+
+ expectedBytes := []byte{byte(OptionBroadcastAddress), 4, 192, 168, 0, 1}
+ require.Equal(t, expectedBytes, o.ToBytes(), "ToBytes")
+
+ require.Equal(t, 4, o.Length(), "Length")
+
+ require.Equal(t, "Broadcast Address -> 192.168.0.1", o.String(), "String")
+}
+
+func TestParseOptBroadcastAddress(t *testing.T) {
+ var (
+ o *OptBroadcastAddress
+ err error
+ )
+ o, err = ParseOptBroadcastAddress([]byte{})
+ require.Error(t, err, "empty byte stream")
+
+ o, err = ParseOptBroadcastAddress([]byte{byte(OptionBroadcastAddress), 4, 192})
+ require.Error(t, err, "short byte stream")
+
+ o, err = ParseOptBroadcastAddress([]byte{byte(OptionBroadcastAddress), 3, 192, 168, 0, 1})
+ require.Error(t, err, "wrong IP length")
+
+ o, err = ParseOptBroadcastAddress([]byte{53, 4, 192, 168, 1})
+ require.Error(t, err, "wrong option code")
+
+ o, err = ParseOptBroadcastAddress([]byte{byte(OptionBroadcastAddress), 4, 192, 168, 0, 1})
+ require.NoError(t, err)
+ require.Equal(t, net.IP{192, 168, 0, 1}, o.BroadcastAddress)
+}
diff --git a/dhcpv4/option_server_identifier_test.go b/dhcpv4/option_server_identifier_test.go
index 94fb542..efd6299 100644
--- a/dhcpv4/option_server_identifier_test.go
+++ b/dhcpv4/option_server_identifier_test.go
@@ -13,7 +13,7 @@ func TestOptRequestedIPAddressInterfaceMethods(t *testing.T) {
require.Equal(t, OptionRequestedIPAddress, o.Code(), "Code")
- expectedBytes := []byte{50, 4, 192, 168, 0, 1}
+ expectedBytes := []byte{byte(OptionRequestedIPAddress), 4, 192, 168, 0, 1}
require.Equal(t, expectedBytes, o.ToBytes(), "ToBytes")
require.Equal(t, 4, o.Length(), "Length")
@@ -29,16 +29,16 @@ func TestParseOptRequestedIPAddress(t *testing.T) {
o, err = ParseOptRequestedIPAddress([]byte{})
require.Error(t, err, "empty byte stream")
- o, err = ParseOptRequestedIPAddress([]byte{50, 4, 192})
+ o, err = ParseOptRequestedIPAddress([]byte{byte(OptionRequestedIPAddress), 4, 192})
require.Error(t, err, "short byte stream")
- o, err = ParseOptRequestedIPAddress([]byte{50, 3, 192, 168, 0, 1})
+ o, err = ParseOptRequestedIPAddress([]byte{byte(OptionRequestedIPAddress), 3, 192, 168, 0, 1})
require.Error(t, err, "wrong IP length")
o, err = ParseOptRequestedIPAddress([]byte{53, 4, 192, 168, 1})
require.Error(t, err, "wrong option code")
- o, err = ParseOptRequestedIPAddress([]byte{50, 4, 192, 168, 0, 1})
+ o, err = ParseOptRequestedIPAddress([]byte{byte(OptionRequestedIPAddress), 4, 192, 168, 0, 1})
require.NoError(t, err)
require.Equal(t, net.IP{192, 168, 0, 1}, o.RequestedAddr)
}
diff --git a/dhcpv4/options.go b/dhcpv4/options.go
index acc2bf5..efbfb74 100644
--- a/dhcpv4/options.go
+++ b/dhcpv4/options.go
@@ -48,6 +48,8 @@ func ParseOption(data []byte) (Option, error) {
opt, err = ParseOptRequestedIPAddress(data)
case OptionServerIdentifier:
opt, err = ParseOptServerIdentifier(data)
+ case OptionBroadcastAddress:
+ opt, err = ParseOptBroadcastAddress(data)
case OptionMaximumDHCPMessageSize:
opt, err = ParseOptMaximumDHCPMessageSize(data)
case OptionClassIdentifier: