diff --git a/internal/router/client_info.go b/internal/router/client_info.go index dff4ede..f6a13fb 100644 --- a/internal/router/client_info.go +++ b/internal/router/client_info.go @@ -2,6 +2,7 @@ package router import ( "bytes" + "io" "log" "net" "os" @@ -78,10 +79,27 @@ func GetClientInfoByMac(mac string) *ctrld.ClientInfo { } func readClientInfoFile(name string) error { + f, err := os.Open(name) + if err != nil { + return err + } + defer f.Close() + return readClientInfoReader(f) + +} + +func readClientInfoReader(reader io.Reader) error { r := routerPlatform.Load() - return lineread.File(name, func(line []byte) error { + return lineread.Reader(reader, func(line []byte) error { fields := bytes.Fields(line) + if len(fields) != 5 { + return nil + } mac := string(fields[1]) + if _, err := net.ParseMAC(mac); err != nil { + // The second field is not a mac, skip. + return nil + } ip := normalizeIP(string(fields[2])) if net.ParseIP(ip) == nil { log.Printf("invalid ip address entry: %q", ip) diff --git a/internal/router/client_info_test.go b/internal/router/client_info_test.go index 13b0648..2b228c2 100644 --- a/internal/router/client_info_test.go +++ b/internal/router/client_info_test.go @@ -1,6 +1,11 @@ package router -import "testing" +import ( + "strings" + "testing" + + "github.com/Control-D-Inc/ctrld" +) func Test_normalizeIP(t *testing.T) { tests := []struct { @@ -23,3 +28,43 @@ func Test_normalizeIP(t *testing.T) { }) } } + +func Test_readClientInfoReader(t *testing.T) { + tests := []struct { + name string + in string + mac string + }{ + { + "good", + `1683329857 e6:20:59:b8:c1:6d 192.168.1.186 * 01:e6:20:59:b8:c1:6d +`, + "e6:20:59:b8:c1:6d", + }, + { + "bad seen on UDMdream machine", + `1683329857 e6:20:59:b8:c1:6e 192.168.1.111 * 01:e6:20:59:b8:c1:6e +duid 00:01:00:01:2b:e4:2e:2c:52:52:14:26:dc:1c +1683322985 117442354 2600:4040:b0e6:b700::111 ASDASD 00:01:00:01:2a:d0:b9:81:00:07:32:4c:1c:07 +`, + "e6:20:59:b8:c1:6e", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + r := routerPlatform.Load() + r.mac.Delete(tc.mac) + if err := readClientInfoReader(strings.NewReader(tc.in)); err != nil { + t.Errorf("readClientInfoReader() error = %v", err) + } + info, existed := r.mac.Load(tc.mac) + if !existed { + t.Error("client info missing") + } + if ci, ok := info.(*ctrld.ClientInfo); ok && existed && ci.Mac != tc.mac { + t.Errorf("mac mismatched, got: %q, want: %q", ci.Mac, tc.mac) + } + }) + } +}