|
@@ -6,6 +6,7 @@ package file
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"net"
|
|
"net"
|
|
|
|
|
+ "net/netip"
|
|
|
"os"
|
|
"os"
|
|
|
"testing"
|
|
"testing"
|
|
|
"time"
|
|
"time"
|
|
@@ -25,12 +26,11 @@ func TestLoadDHCPv4Records(t *testing.T) {
|
|
|
require.NoError(t, os.Remove(tmp.Name()))
|
|
require.NoError(t, os.Remove(tmp.Name()))
|
|
|
}()
|
|
}()
|
|
|
|
|
|
|
|
- // fill temp file with valid lease lines and some comments
|
|
|
|
|
- _, err = tmp.WriteString("00:11:22:33:44:55 192.0.2.100\n")
|
|
|
|
|
- require.NoError(t, err)
|
|
|
|
|
- _, err = tmp.WriteString("11:22:33:44:55:66 192.0.2.101\n")
|
|
|
|
|
- require.NoError(t, err)
|
|
|
|
|
- _, err = tmp.WriteString("# this is a comment\n")
|
|
|
|
|
|
|
+ // fill temp file with valid lease lines (mixed case) and some comments
|
|
|
|
|
+ _, err = tmp.WriteString(`00:11:22:33:44:aa 192.0.2.100
|
|
|
|
|
+ 11:BB:33:DD:55:FF 192.0.2.101 # arbitrary spaces and trailing comment
|
|
|
|
|
+ # this is a simple comment
|
|
|
|
|
+`)
|
|
|
require.NoError(t, err)
|
|
require.NoError(t, err)
|
|
|
require.NoError(t, tmp.Close())
|
|
require.NoError(t, tmp.Close())
|
|
|
|
|
|
|
@@ -40,11 +40,11 @@ func TestLoadDHCPv4Records(t *testing.T) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if assert.Equal(t, 2, len(records)) {
|
|
if assert.Equal(t, 2, len(records)) {
|
|
|
- if assert.Contains(t, records, "00:11:22:33:44:55") {
|
|
|
|
|
- assert.Equal(t, net.ParseIP("192.0.2.100"), records["00:11:22:33:44:55"])
|
|
|
|
|
|
|
+ if assert.Contains(t, records, "00:11:22:33:44:aa") {
|
|
|
|
|
+ assert.Equal(t, netip.MustParseAddr("192.0.2.100"), records["00:11:22:33:44:aa"])
|
|
|
}
|
|
}
|
|
|
- if assert.Contains(t, records, "11:22:33:44:55:66") {
|
|
|
|
|
- assert.Equal(t, net.ParseIP("192.0.2.101"), records["11:22:33:44:55:66"])
|
|
|
|
|
|
|
+ if assert.Contains(t, records, "11:bb:33:dd:55:ff") {
|
|
|
|
|
+ assert.Equal(t, netip.MustParseAddr("192.0.2.101"), records["11:bb:33:dd:55:ff"])
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
@@ -100,6 +100,45 @@ func TestLoadDHCPv4Records(t *testing.T) {
|
|
|
assert.Error(t, err)
|
|
assert.Error(t, err)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+ t.Run("duplicate MAC address are allowed", func(t *testing.T) {
|
|
|
|
|
+ // setup temp leases file
|
|
|
|
|
+ tmp, err := os.CreateTemp("", "test_plugin_file")
|
|
|
|
|
+ require.NoError(t, err)
|
|
|
|
|
+ defer func() {
|
|
|
|
|
+ require.NoError(t, os.Remove(tmp.Name()))
|
|
|
|
|
+ }()
|
|
|
|
|
+
|
|
|
|
|
+ // add lines with duplicate MAC addresses to check for no error
|
|
|
|
|
+ _, err = tmp.WriteString(`aa:11:11:11:11:11 1.2.3.4
|
|
|
|
|
+AA:11:11:11:11:11 5.6.7.8
|
|
|
|
|
+`)
|
|
|
|
|
+ require.NoError(t, err)
|
|
|
|
|
+ require.NoError(t, tmp.Close())
|
|
|
|
|
+
|
|
|
|
|
+ _, err = LoadDHCPv4Records(tmp.Name())
|
|
|
|
|
+ assert.NoError(t, err)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ t.Run("duplicate IP address are allowed", func(t *testing.T) {
|
|
|
|
|
+ // setup temp leases file
|
|
|
|
|
+ tmp, err := os.CreateTemp("", "test_plugin_file")
|
|
|
|
|
+ require.NoError(t, err)
|
|
|
|
|
+ defer func() {
|
|
|
|
|
+ require.NoError(t, os.Remove(tmp.Name()))
|
|
|
|
|
+ }()
|
|
|
|
|
+
|
|
|
|
|
+ // add line with duplicate IPv4 addresses to check for no error
|
|
|
|
|
+ _, err = tmp.WriteString(`11:11:11:11:11:11 1.2.3.4
|
|
|
|
|
+22:22:22:22:22:22 1.2.3.4
|
|
|
|
|
+33:33:33:33:33:33 1.2.3.4
|
|
|
|
|
+`)
|
|
|
|
|
+ require.NoError(t, err)
|
|
|
|
|
+ require.NoError(t, tmp.Close())
|
|
|
|
|
+
|
|
|
|
|
+ _, err = LoadDHCPv4Records(tmp.Name())
|
|
|
|
|
+ assert.NoError(t, err)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
t.Run("lease with IPv6 address should raise error", func(t *testing.T) {
|
|
t.Run("lease with IPv6 address should raise error", func(t *testing.T) {
|
|
|
// setup temp leases file
|
|
// setup temp leases file
|
|
|
tmp, err := os.CreateTemp("", "test_plugin_file")
|
|
tmp, err := os.CreateTemp("", "test_plugin_file")
|
|
@@ -128,11 +167,10 @@ func TestLoadDHCPv6Records(t *testing.T) {
|
|
|
}()
|
|
}()
|
|
|
|
|
|
|
|
// fill temp file with valid lease lines and some comments
|
|
// fill temp file with valid lease lines and some comments
|
|
|
- _, err = tmp.WriteString("00:11:22:33:44:55 2001:db8::10:1\n")
|
|
|
|
|
- require.NoError(t, err)
|
|
|
|
|
- _, err = tmp.WriteString("11:22:33:44:55:66 2001:db8::10:2\n")
|
|
|
|
|
- require.NoError(t, err)
|
|
|
|
|
- _, err = tmp.WriteString("# this is a comment\n")
|
|
|
|
|
|
|
+ _, err = tmp.WriteString(`00:11:22:33:44:aa 2001:db8::10:1
|
|
|
|
|
+ 11:BB:33:DD:55:FF 2001:db8::10:2 # arbitrary spaces and trailing comment
|
|
|
|
|
+ # this is a simple comment
|
|
|
|
|
+`)
|
|
|
require.NoError(t, err)
|
|
require.NoError(t, err)
|
|
|
require.NoError(t, tmp.Close())
|
|
require.NoError(t, tmp.Close())
|
|
|
|
|
|
|
@@ -142,11 +180,11 @@ func TestLoadDHCPv6Records(t *testing.T) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if assert.Equal(t, 2, len(records)) {
|
|
if assert.Equal(t, 2, len(records)) {
|
|
|
- if assert.Contains(t, records, "00:11:22:33:44:55") {
|
|
|
|
|
- assert.Equal(t, net.ParseIP("2001:db8::10:1"), records["00:11:22:33:44:55"])
|
|
|
|
|
|
|
+ if assert.Contains(t, records, "00:11:22:33:44:aa") {
|
|
|
|
|
+ assert.Equal(t, netip.MustParseAddr("2001:db8::10:1"), records["00:11:22:33:44:aa"])
|
|
|
}
|
|
}
|
|
|
- if assert.Contains(t, records, "11:22:33:44:55:66") {
|
|
|
|
|
- assert.Equal(t, net.ParseIP("2001:db8::10:2"), records["11:22:33:44:55:66"])
|
|
|
|
|
|
|
+ if assert.Contains(t, records, "11:bb:33:dd:55:ff") {
|
|
|
|
|
+ assert.Equal(t, netip.MustParseAddr("2001:db8::10:2"), records["11:bb:33:dd:55:ff"])
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
@@ -202,6 +240,45 @@ func TestLoadDHCPv6Records(t *testing.T) {
|
|
|
assert.Error(t, err)
|
|
assert.Error(t, err)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+ t.Run("duplicate MAC address are allowed", func(t *testing.T) {
|
|
|
|
|
+ // setup temp leases file
|
|
|
|
|
+ tmp, err := os.CreateTemp("", "test_plugin_file")
|
|
|
|
|
+ require.NoError(t, err)
|
|
|
|
|
+ defer func() {
|
|
|
|
|
+ require.NoError(t, os.Remove(tmp.Name()))
|
|
|
|
|
+ }()
|
|
|
|
|
+
|
|
|
|
|
+ // add lines with duplicate MAC addresses to trigger an error
|
|
|
|
|
+ _, err = tmp.WriteString(`aa:11:11:11:11:11 2001:db8::10:1
|
|
|
|
|
+AA:11:11:11:11:11 2001:db8::10:2
|
|
|
|
|
+`)
|
|
|
|
|
+ require.NoError(t, err)
|
|
|
|
|
+ require.NoError(t, tmp.Close())
|
|
|
|
|
+
|
|
|
|
|
+ _, err = LoadDHCPv6Records(tmp.Name())
|
|
|
|
|
+ assert.NoError(t, err)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ t.Run("duplicate IP address are allowed", func(t *testing.T) {
|
|
|
|
|
+ // setup temp leases file
|
|
|
|
|
+ tmp, err := os.CreateTemp("", "test_plugin_file")
|
|
|
|
|
+ require.NoError(t, err)
|
|
|
|
|
+ defer func() {
|
|
|
|
|
+ require.NoError(t, os.Remove(tmp.Name()))
|
|
|
|
|
+ }()
|
|
|
|
|
+
|
|
|
|
|
+ // add lines with duplicate IPv6 addresses to trigger an error
|
|
|
|
|
+ _, err = tmp.WriteString(`11:11:11:11:11:11 2001:db8::10:1
|
|
|
|
|
+22:22:22:22:22:22 2001:db8::10:1
|
|
|
|
|
+33:33:33:33:33:33 2001:db8::10:1
|
|
|
|
|
+`)
|
|
|
|
|
+ require.NoError(t, err)
|
|
|
|
|
+ require.NoError(t, tmp.Close())
|
|
|
|
|
+
|
|
|
|
|
+ _, err = LoadDHCPv6Records(tmp.Name())
|
|
|
|
|
+ assert.NoError(t, err)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
t.Run("lease with IPv4 address should raise error", func(t *testing.T) {
|
|
t.Run("lease with IPv4 address should raise error", func(t *testing.T) {
|
|
|
// setup temp leases file
|
|
// setup temp leases file
|
|
|
tmp, err := os.CreateTemp("", "test_plugin_file")
|
|
tmp, err := os.CreateTemp("", "test_plugin_file")
|
|
@@ -223,7 +300,7 @@ func TestLoadDHCPv6Records(t *testing.T) {
|
|
|
func TestHandler4(t *testing.T) {
|
|
func TestHandler4(t *testing.T) {
|
|
|
t.Run("unknown MAC", func(t *testing.T) {
|
|
t.Run("unknown MAC", func(t *testing.T) {
|
|
|
// prepare DHCPv4 request
|
|
// prepare DHCPv4 request
|
|
|
- mac := "00:11:22:33:44:55"
|
|
|
|
|
|
|
+ mac := "aa:11:22:33:44:55"
|
|
|
claddr, _ := net.ParseMAC(mac)
|
|
claddr, _ := net.ParseMAC(mac)
|
|
|
req := &dhcpv4.DHCPv4{
|
|
req := &dhcpv4.DHCPv4{
|
|
|
ClientHWAddr: claddr,
|
|
ClientHWAddr: claddr,
|
|
@@ -241,7 +318,7 @@ func TestHandler4(t *testing.T) {
|
|
|
|
|
|
|
|
t.Run("known MAC", func(t *testing.T) {
|
|
t.Run("known MAC", func(t *testing.T) {
|
|
|
// prepare DHCPv4 request
|
|
// prepare DHCPv4 request
|
|
|
- mac := "00:11:22:33:44:55"
|
|
|
|
|
|
|
+ mac := "aa:11:22:33:44:55"
|
|
|
claddr, _ := net.ParseMAC(mac)
|
|
claddr, _ := net.ParseMAC(mac)
|
|
|
req := &dhcpv4.DHCPv4{
|
|
req := &dhcpv4.DHCPv4{
|
|
|
ClientHWAddr: claddr,
|
|
ClientHWAddr: claddr,
|
|
@@ -250,8 +327,8 @@ func TestHandler4(t *testing.T) {
|
|
|
assert.Nil(t, resp.ClientIPAddr)
|
|
assert.Nil(t, resp.ClientIPAddr)
|
|
|
|
|
|
|
|
// add lease for the MAC in the lease map
|
|
// add lease for the MAC in the lease map
|
|
|
- clIPAddr := net.ParseIP("192.0.2.100")
|
|
|
|
|
- StaticRecords = map[string]net.IP{
|
|
|
|
|
|
|
+ clIPAddr := netip.MustParseAddr("192.0.2.100")
|
|
|
|
|
+ StaticRecords = map[string]netip.Addr{
|
|
|
mac: clIPAddr,
|
|
mac: clIPAddr,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -260,17 +337,17 @@ func TestHandler4(t *testing.T) {
|
|
|
result, stop := Handler4(req, resp)
|
|
result, stop := Handler4(req, resp)
|
|
|
assert.Same(t, result, resp)
|
|
assert.Same(t, result, resp)
|
|
|
assert.True(t, stop)
|
|
assert.True(t, stop)
|
|
|
- assert.Equal(t, clIPAddr, result.YourIPAddr)
|
|
|
|
|
|
|
+ assert.Equal(t, net.IP(clIPAddr.AsSlice()), result.YourIPAddr)
|
|
|
|
|
|
|
|
// cleanup
|
|
// cleanup
|
|
|
- StaticRecords = make(map[string]net.IP)
|
|
|
|
|
|
|
+ StaticRecords = make(map[string]netip.Addr)
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func TestHandler6(t *testing.T) {
|
|
func TestHandler6(t *testing.T) {
|
|
|
t.Run("unknown MAC", func(t *testing.T) {
|
|
t.Run("unknown MAC", func(t *testing.T) {
|
|
|
// prepare DHCPv6 request
|
|
// prepare DHCPv6 request
|
|
|
- mac := "11:22:33:44:55:66"
|
|
|
|
|
|
|
+ mac := "aa:11:22:33:44:55"
|
|
|
claddr, _ := net.ParseMAC(mac)
|
|
claddr, _ := net.ParseMAC(mac)
|
|
|
req, err := dhcpv6.NewSolicit(claddr)
|
|
req, err := dhcpv6.NewSolicit(claddr)
|
|
|
require.NoError(t, err)
|
|
require.NoError(t, err)
|
|
@@ -287,7 +364,7 @@ func TestHandler6(t *testing.T) {
|
|
|
|
|
|
|
|
t.Run("known MAC", func(t *testing.T) {
|
|
t.Run("known MAC", func(t *testing.T) {
|
|
|
// prepare DHCPv6 request
|
|
// prepare DHCPv6 request
|
|
|
- mac := "11:22:33:44:55:66"
|
|
|
|
|
|
|
+ mac := "aa:11:22:33:44:55"
|
|
|
claddr, _ := net.ParseMAC(mac)
|
|
claddr, _ := net.ParseMAC(mac)
|
|
|
req, err := dhcpv6.NewSolicit(claddr)
|
|
req, err := dhcpv6.NewSolicit(claddr)
|
|
|
require.NoError(t, err)
|
|
require.NoError(t, err)
|
|
@@ -296,8 +373,8 @@ func TestHandler6(t *testing.T) {
|
|
|
assert.Equal(t, 0, len(resp.GetOption(dhcpv6.OptionIANA)))
|
|
assert.Equal(t, 0, len(resp.GetOption(dhcpv6.OptionIANA)))
|
|
|
|
|
|
|
|
// add lease for the MAC in the lease map
|
|
// add lease for the MAC in the lease map
|
|
|
- clIPAddr := net.ParseIP("2001:db8::10:1")
|
|
|
|
|
- StaticRecords = map[string]net.IP{
|
|
|
|
|
|
|
+ clIPAddr := netip.MustParseAddr("2001:db8::10:1")
|
|
|
|
|
+ StaticRecords = map[string]netip.Addr{
|
|
|
mac: clIPAddr,
|
|
mac: clIPAddr,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -311,7 +388,7 @@ func TestHandler6(t *testing.T) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// cleanup
|
|
// cleanup
|
|
|
- StaticRecords = make(map[string]net.IP)
|
|
|
|
|
|
|
+ StaticRecords = make(map[string]netip.Addr)
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -340,7 +417,7 @@ func TestSetupFile(t *testing.T) {
|
|
|
}()
|
|
}()
|
|
|
|
|
|
|
|
t.Run("typical case", func(t *testing.T) {
|
|
t.Run("typical case", func(t *testing.T) {
|
|
|
- _, err = tmp.WriteString("00:11:22:33:44:55 2001:db8::10:1\n")
|
|
|
|
|
|
|
+ _, err = tmp.WriteString("aa:11:22:33:44:55 2001:db8::10:1\n")
|
|
|
require.NoError(t, err)
|
|
require.NoError(t, err)
|
|
|
_, err = tmp.WriteString("11:22:33:44:55:66 2001:db8::10:2\n")
|
|
_, err = tmp.WriteString("11:22:33:44:55:66 2001:db8::10:2\n")
|
|
|
require.NoError(t, err)
|
|
require.NoError(t, err)
|
|
@@ -351,6 +428,8 @@ func TestSetupFile(t *testing.T) {
|
|
|
_, _, err = setupFile(true, tmp.Name())
|
|
_, _, err = setupFile(true, tmp.Name())
|
|
|
if assert.NoError(t, err) {
|
|
if assert.NoError(t, err) {
|
|
|
assert.Equal(t, 2, len(StaticRecords))
|
|
assert.Equal(t, 2, len(StaticRecords))
|
|
|
|
|
+ assert.Equal(t, StaticRecords["aa:11:22:33:44:55"], netip.MustParseAddr("2001:db8::10:1"))
|
|
|
|
|
+ assert.Equal(t, StaticRecords["11:22:33:44:55:66"], netip.MustParseAddr("2001:db8::10:2"))
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -361,8 +440,9 @@ func TestSetupFile(t *testing.T) {
|
|
|
}
|
|
}
|
|
|
// we add more leases to the file
|
|
// we add more leases to the file
|
|
|
// this should trigger an event to refresh the leases database
|
|
// this should trigger an event to refresh the leases database
|
|
|
- // without calling setupFile again
|
|
|
|
|
- _, err = tmp.WriteString("22:33:44:55:66:77 2001:db8::10:3\n")
|
|
|
|
|
|
|
+ // without calling setupFile again.
|
|
|
|
|
+ // Note that the IPv6 address is uppercase (allowed but not best practice)
|
|
|
|
|
+ _, err = tmp.WriteString("22:33:44:55:66:77 2001:DB8::10:3\n")
|
|
|
require.NoError(t, err)
|
|
require.NoError(t, err)
|
|
|
// since the event is processed asynchronously, give it a little time
|
|
// since the event is processed asynchronously, give it a little time
|
|
|
time.Sleep(time.Millisecond * 100)
|
|
time.Sleep(time.Millisecond * 100)
|
|
@@ -372,5 +452,6 @@ func TestSetupFile(t *testing.T) {
|
|
|
defer recLock.RUnlock()
|
|
defer recLock.RUnlock()
|
|
|
|
|
|
|
|
assert.Equal(t, 3, len(StaticRecords))
|
|
assert.Equal(t, 3, len(StaticRecords))
|
|
|
|
|
+ assert.Equal(t, StaticRecords["22:33:44:55:66:77"], netip.MustParseAddr("2001:db8::10:3"))
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|