|
@@ -4,7 +4,6 @@ import (
|
|
|
"context"
|
|
|
"encoding/json"
|
|
|
"fmt"
|
|
|
- "net"
|
|
|
"os/exec"
|
|
|
|
|
|
"goa.design/clue/log"
|
|
@@ -15,11 +14,6 @@ const (
|
|
|
)
|
|
|
|
|
|
type (
|
|
|
- arp struct {
|
|
|
- cmd string
|
|
|
- arping ARPing
|
|
|
- }
|
|
|
-
|
|
|
arpOutput struct {
|
|
|
Version string `json:"__version"`
|
|
|
ARP struct {
|
|
@@ -34,29 +28,7 @@ type (
|
|
|
}
|
|
|
)
|
|
|
|
|
|
-func NewARP(count uint) (ARP, error) {
|
|
|
- cmd, err := exec.LookPath("arp")
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- arping, err := NewARPing(count)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- return &arp{
|
|
|
- cmd: cmd,
|
|
|
- arping: arping,
|
|
|
- }, nil
|
|
|
-}
|
|
|
-
|
|
|
-func (a *arp) Present(ctx context.Context, ifs Interfaces, state State, addrStates HardwareAddrStates) (err error) {
|
|
|
- as := make(map[string]bool, len(addrStates))
|
|
|
- for hw := range addrStates {
|
|
|
- as[hw] = false
|
|
|
- }
|
|
|
-
|
|
|
+func (a *arp) entries(ctx context.Context, ifs Interfaces) (entries []arpEntry, err error) {
|
|
|
cmd := exec.CommandContext(ctx, a.cmd, "--libxo=json", "-an")
|
|
|
if len(ifs) == 1 {
|
|
|
for ifi := range ifs {
|
|
@@ -70,8 +42,7 @@ func (a *arp) Present(ctx context.Context, ifs Interfaces, state State, addrStat
|
|
|
}
|
|
|
|
|
|
o := &arpOutput{}
|
|
|
- err = json.Unmarshal(b, o)
|
|
|
- if err != nil {
|
|
|
+ if err = json.Unmarshal(b, o); err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
@@ -80,38 +51,12 @@ func (a *arp) Present(ctx context.Context, ifs Interfaces, state State, addrStat
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ entries = make([]arpEntry, 0, len(o.ARP.Cache))
|
|
|
for _, e := range o.ARP.Cache {
|
|
|
- log.Debug(ctx, log.KV{K: "IP address", V: e.IPAddress}, log.KV{K: "MAC address", V: e.MACAddress}, log.KV{K: "interface", V: e.Interface})
|
|
|
- if ifs[e.Interface] {
|
|
|
- var hwa net.HardwareAddr
|
|
|
- hwa, err = net.ParseMAC(e.MACAddress)
|
|
|
- if err != nil {
|
|
|
- return
|
|
|
- }
|
|
|
- hw := hwa.String()
|
|
|
-
|
|
|
- if _, ok := as[hw]; ok {
|
|
|
- ok, err = a.arping.Ping(ctx, e.Interface, hw, e.IPAddress)
|
|
|
- if err != nil {
|
|
|
- return
|
|
|
- }
|
|
|
- as[hw] = ok
|
|
|
- }
|
|
|
+ if e.IPAddress != "" {
|
|
|
+ entries = append(entries, e)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- present := false
|
|
|
- for hw, ok := range as {
|
|
|
- addrStates[hw].Set(ok)
|
|
|
- if ok {
|
|
|
- present = true
|
|
|
- }
|
|
|
- }
|
|
|
- state.Set(present)
|
|
|
-
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
-func (a *arp) Count(count uint) {
|
|
|
- a.arping.Count(count)
|
|
|
-}
|