diff --git a/dhcpd/dhcpd.go b/dhcpd/dhcpd.go index 9ad0b08f..391389d4 100644 --- a/dhcpd/dhcpd.go +++ b/dhcpd/dhcpd.go @@ -127,7 +127,7 @@ func (s *Server) setConfig(config ServerConfig) error { } subnet, err := parseIPv4(config.SubnetMask) - if err != nil { + if err != nil || !isValidSubnetMask(subnet) { return wrapErrPrint(err, "Failed to parse subnet mask %s", config.SubnetMask) } diff --git a/dhcpd/dhcpd_test.go b/dhcpd/dhcpd_test.go index e5e16b0d..01fafb84 100644 --- a/dhcpd/dhcpd_test.go +++ b/dhcpd/dhcpd_test.go @@ -197,3 +197,15 @@ func TestDB(t *testing.T) { os.Remove("leases.db") } + +func TestIsValidSubnetMask(t *testing.T) { + if !isValidSubnetMask([]byte{255, 255, 255, 0}) { + t.Fatalf("isValidSubnetMask([]byte{255,255,255,0})") + } + if isValidSubnetMask([]byte{255, 255, 253, 0}) { + t.Fatalf("isValidSubnetMask([]byte{255,255,253,0})") + } + if isValidSubnetMask([]byte{0, 255, 255, 255}) { + t.Fatalf("isValidSubnetMask([]byte{255,255,253,0})") + } +} diff --git a/dhcpd/helpers.go b/dhcpd/helpers.go index c3e9f4fe..9553fca9 100644 --- a/dhcpd/helpers.go +++ b/dhcpd/helpers.go @@ -1,6 +1,7 @@ package dhcpd import ( + "encoding/binary" "fmt" "net" @@ -65,3 +66,19 @@ func parseIPv4(text string) (net.IP, error) { } return result.To4(), nil } + +// Return TRUE if subnet mask is correct (e.g. 255.255.255.0) +func isValidSubnetMask(mask net.IP) bool { + var n uint32 + n = binary.BigEndian.Uint32(mask) + for i := 0; i != 32; i++ { + if n == 0 { + break + } + if (n & 0x80000000) == 0 { + return false + } + n <<= 1 + } + return true +}