mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
all: add clients list command to debug Mac discovery
This commit is contained in:
committed by
Cuong Manh Le
parent
61b6431b6e
commit
437fb1b16d
@@ -27,3 +27,20 @@ func (a *arpDiscover) LookupMac(ip string) string {
|
||||
}
|
||||
return val.(string)
|
||||
}
|
||||
|
||||
func (a *arpDiscover) String() string {
|
||||
return "arp"
|
||||
}
|
||||
|
||||
func (a *arpDiscover) List() []string {
|
||||
var ips []string
|
||||
a.ip.Range(func(key, value any) bool {
|
||||
ips = append(ips, value.(string))
|
||||
return true
|
||||
})
|
||||
a.mac.Range(func(key, value any) bool {
|
||||
ips = append(ips, key.(string))
|
||||
return true
|
||||
})
|
||||
return ips
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package clientinfo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -9,25 +11,35 @@ import (
|
||||
|
||||
// IpResolver is the interface for retrieving IP from Mac.
|
||||
type IpResolver interface {
|
||||
fmt.Stringer
|
||||
// LookupIP returns ip of the device with given mac.
|
||||
LookupIP(mac string) string
|
||||
// List returns list of ip known by the resolver.
|
||||
List() []string
|
||||
}
|
||||
|
||||
// MacResolver is the interface for retrieving Mac from IP.
|
||||
type MacResolver interface {
|
||||
fmt.Stringer
|
||||
// LookupMac returns mac of the device with given ip.
|
||||
LookupMac(ip string) string
|
||||
}
|
||||
|
||||
// HostnameByIpResolver is the interface for retrieving hostname from IP.
|
||||
type HostnameByIpResolver interface {
|
||||
// LookupHostnameByIP returns hostname of the given ip.
|
||||
LookupHostnameByIP(ip string) string
|
||||
}
|
||||
|
||||
// HostnameByMacResolver is the interface for retrieving hostname from Mac.
|
||||
type HostnameByMacResolver interface {
|
||||
// LookupHostnameByMac returns hostname of the device with given mac.
|
||||
LookupHostnameByMac(mac string) string
|
||||
}
|
||||
|
||||
// HostnameResolver is the interface for retrieving hostname from either IP or Mac.
|
||||
type HostnameResolver interface {
|
||||
fmt.Stringer
|
||||
HostnameByIpResolver
|
||||
HostnameByMacResolver
|
||||
}
|
||||
@@ -36,6 +48,13 @@ type refresher interface {
|
||||
refresh() error
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
IP netip.Addr
|
||||
Mac string
|
||||
Hostname string
|
||||
Source map[string]struct{}
|
||||
}
|
||||
|
||||
type Table struct {
|
||||
ipResolvers []IpResolver
|
||||
macResolvers []MacResolver
|
||||
@@ -146,9 +165,6 @@ func (t *Table) LookupIP(mac string) string {
|
||||
}
|
||||
|
||||
func (t *Table) LookupMac(ip string) string {
|
||||
t.arp.mac.Range(func(key, value any) bool {
|
||||
return true
|
||||
})
|
||||
for _, r := range t.macResolvers {
|
||||
if mac := r.LookupMac(ip); mac != "" {
|
||||
return mac
|
||||
@@ -169,6 +185,86 @@ func (t *Table) LookupHostname(ip, mac string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type macEntry struct {
|
||||
mac string
|
||||
src string
|
||||
}
|
||||
|
||||
type hostnameEntry struct {
|
||||
name string
|
||||
src string
|
||||
}
|
||||
|
||||
func (t *Table) lookupMacAll(ip string) []*macEntry {
|
||||
var res []*macEntry
|
||||
for _, r := range t.macResolvers {
|
||||
res = append(res, &macEntry{mac: r.LookupMac(ip), src: r.String()})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (t *Table) lookupHostnameAll(ip, mac string) []*hostnameEntry {
|
||||
var res []*hostnameEntry
|
||||
for _, r := range t.hostnameResolvers {
|
||||
src := r.String()
|
||||
if name := r.LookupHostnameByIP(ip); name != "" {
|
||||
res = append(res, &hostnameEntry{name: name, src: src})
|
||||
continue
|
||||
}
|
||||
if name := r.LookupHostnameByMac(mac); name != "" {
|
||||
res = append(res, &hostnameEntry{name: name, src: src})
|
||||
continue
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// ListClients returns list of clients discovered by ctrld.
|
||||
func (t *Table) ListClients() []*Client {
|
||||
for _, r := range t.refreshers {
|
||||
_ = r.refresh()
|
||||
}
|
||||
ipMap := make(map[string]*Client)
|
||||
for _, ir := range t.ipResolvers {
|
||||
for _, ip := range ir.List() {
|
||||
c, ok := ipMap[ip]
|
||||
if !ok {
|
||||
c = &Client{
|
||||
IP: netip.MustParseAddr(ip),
|
||||
Source: map[string]struct{}{ir.String(): {}},
|
||||
}
|
||||
ipMap[ip] = c
|
||||
} else {
|
||||
c.Source[ir.String()] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
for ip := range ipMap {
|
||||
c := ipMap[ip]
|
||||
for _, e := range t.lookupMacAll(ip) {
|
||||
if c.Mac == "" && e.mac != "" {
|
||||
c.Mac = e.mac
|
||||
}
|
||||
if e.mac != "" {
|
||||
c.Source[e.src] = struct{}{}
|
||||
}
|
||||
}
|
||||
for _, e := range t.lookupHostnameAll(ip, c.Mac) {
|
||||
if c.Hostname == "" && e.name != "" {
|
||||
c.Hostname = e.name
|
||||
}
|
||||
if e.name != "" {
|
||||
c.Source[e.src] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
clients := make([]*Client, 0, len(ipMap))
|
||||
for _, c := range ipMap {
|
||||
clients = append(clients, c)
|
||||
}
|
||||
return clients
|
||||
}
|
||||
|
||||
func (t *Table) discoverDHCP() bool {
|
||||
if t.cfg.Service.DiscoverDHCP == nil {
|
||||
return true
|
||||
|
||||
@@ -100,6 +100,23 @@ func (d *dhcp) LookupHostnameByMac(mac string) string {
|
||||
return val.(string)
|
||||
}
|
||||
|
||||
func (d *dhcp) String() string {
|
||||
return "dhcp"
|
||||
}
|
||||
|
||||
func (d *dhcp) List() []string {
|
||||
var ips []string
|
||||
d.ip.Range(func(key, value any) bool {
|
||||
ips = append(ips, value.(string))
|
||||
return true
|
||||
})
|
||||
d.mac.Range(func(key, value any) bool {
|
||||
ips = append(ips, key.(string))
|
||||
return true
|
||||
})
|
||||
return ips
|
||||
}
|
||||
|
||||
// AddLeaseFile adds given lease file for reading/watching clients info.
|
||||
func (d *dhcp) addLeaseFile(name string, format ctrld.LeaseFileFormat) error {
|
||||
if d.watcher == nil {
|
||||
|
||||
@@ -43,6 +43,10 @@ func (m *mdns) LookupHostnameByMac(mac string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *mdns) String() string {
|
||||
return "mdns"
|
||||
}
|
||||
|
||||
func (m *mdns) init(quitCh chan struct{}) error {
|
||||
ifaces, err := multicastInterfaces()
|
||||
if err != nil {
|
||||
|
||||
@@ -65,3 +65,7 @@ func (m *merlinDiscover) parseMerlinCustomClientList(data string) {
|
||||
m.hostname.Store(mac, hostname)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *merlinDiscover) String() string {
|
||||
return "merlin"
|
||||
}
|
||||
|
||||
@@ -36,6 +36,10 @@ func (p *ptrDiscover) LookupHostnameByMac(mac string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *ptrDiscover) String() string {
|
||||
return "ptr"
|
||||
}
|
||||
|
||||
func (p *ptrDiscover) lookupHostname(ip string) string {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
Reference in New Issue
Block a user