File: neigh.go

package info (click to toggle)
golang-github-jsimonetti-rtnetlink 2.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,264 kB
  • sloc: makefile: 2
file content (60 lines) | stat: -rw-r--r-- 1,495 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package rtnl

import (
	"net"

	"github.com/jsimonetti/rtnetlink/v2"
)

// Neigh represents a neighbour table entry (e.g. an entry in the ARP table)
type Neigh struct {
	HwAddr    net.HardwareAddr // Link-layer address
	IP        net.IP           // Network-layer address
	Interface *net.Interface   // Network interface

	// Bitfield representing the state of the neighbor entry,
	// corresponding to the NUD_ constants.
	State uint16
}

// Neighbours lists entries from the neighbor table (e.g. the ARP table).
func (c *Conn) Neighbours(ifc *net.Interface, family int) (r []*Neigh, err error) {
	rx, err := c.Conn.Neigh.List()
	if err != nil {
		return nil, err
	}
	match := func(v *rtnetlink.NeighMessage, ifc *net.Interface, family int) bool {
		if ifc != nil && v.Index != uint32(ifc.Index) {
			return false
		}
		if family != 0 && v.Family != uint16(family) {
			return false
		}
		return true
	}
	ifcache := map[int]*net.Interface{}
	for _, m := range rx {
		if !match(&m, ifc, family) {
			continue
		}
		ifindex := int(m.Index)
		iface, ok := ifcache[ifindex]
		if !ok {
			iface, err = c.LinkByIndex(ifindex)
			if err != nil {
				// Received a neigh entry for a link that no longer exists, so we cannot
				// populate the Interface field. Skip the entry.
				continue
			}
			ifcache[ifindex] = iface
		}
		p := &Neigh{
			HwAddr:    m.Attributes.LLAddress,
			IP:        m.Attributes.Address,
			Interface: iface,
			State:     m.State,
		}
		r = append(r, p)
	}
	return r, nil
}