feat(ui): add responsive dashboard and LuCI states

This commit is contained in:
benya
2026-07-21 00:51:05 +03:00
parent 9cf6e44508
commit 23282f6f5c
11 changed files with 1241 additions and 50 deletions
+32
View File
@@ -301,6 +301,7 @@ func buildInventory(cfg config) map[string]any {
"default_route": firstLine(commandOutput("ip", "route", "show", "default")),
"wan_ip": wanIP(),
"dhcp_leases": dhcpLeases(),
"neighbors": neighbors(),
"wifi_clients": wifiClients(),
}
}
@@ -1357,6 +1358,37 @@ func dhcpLeases() []map[string]string {
return leases
}
func neighbors() []map[string]string {
return parseIPNeighbors(commandOutput("ip", "neigh", "show"))
}
func parseIPNeighbors(output string) []map[string]string {
result := make([]map[string]string, 0)
for _, line := range strings.Split(output, "\n") {
fields := strings.Fields(line)
if len(fields) < 3 {
continue
}
neighbor := map[string]string{
"ip": fields[0],
"state": strings.ToUpper(fields[len(fields)-1]),
}
for index := 1; index+1 < len(fields); index++ {
switch fields[index] {
case "dev":
neighbor["interface"] = fields[index+1]
case "lladdr":
neighbor["mac"] = strings.ToUpper(fields[index+1])
}
}
if neighbor["interface"] == "" {
continue
}
result = append(result, neighbor)
}
return result
}
func wifiClients() []map[string]string {
if _, err := exec.LookPath("iwinfo"); err != nil {
return []map[string]string{}
+20
View File
@@ -78,6 +78,26 @@ func TestLooksLikeMAC(t *testing.T) {
}
}
func TestParseIPNeighbors(t *testing.T) {
output := `10.10.10.2 dev br-lan lladdr 10:ff:e0:21:bc:b9 REACHABLE
10.10.10.190 dev br-lan FAILED
fe80::1234 dev br-lan lladdr aa:bb:cc:dd:ee:ff router STALE`
neighbors := parseIPNeighbors(output)
if len(neighbors) != 3 {
t.Fatalf("expected 3 neighbors, got %d", len(neighbors))
}
if neighbors[0]["mac"] != "10:FF:E0:21:BC:B9" || neighbors[0]["state"] != "REACHABLE" {
t.Fatalf("unexpected reachable neighbor: %#v", neighbors[0])
}
if neighbors[1]["ip"] != "10.10.10.190" || neighbors[1]["state"] != "FAILED" {
t.Fatalf("unexpected failed neighbor: %#v", neighbors[1])
}
if neighbors[2]["interface"] != "br-lan" || neighbors[2]["state"] != "STALE" {
t.Fatalf("unexpected stale neighbor: %#v", neighbors[2])
}
}
func TestParsePacketLossBusyBox(t *testing.T) {
output := `PING 10.10.10.10 (10.10.10.10): 56 data bytes
64 bytes from 10.10.10.10: seq=0 ttl=64 time=1.157 ms