mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-11 17:47:20 +10:00
69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
//go:build linux
|
|
|
|
package route
|
|
|
|
import (
|
|
"net"
|
|
"net/netip"
|
|
"slices"
|
|
|
|
"github.com/sagernet/sing-box/adapter"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
|
|
"github.com/jsimonetti/rtnetlink"
|
|
"github.com/mdlayher/netlink"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func ReadNeighborEntries() ([]adapter.NeighborEntry, error) {
|
|
connection, err := rtnetlink.Dial(nil)
|
|
if err != nil {
|
|
return nil, E.Cause(err, "dial rtnetlink")
|
|
}
|
|
defer connection.Close()
|
|
neighbors, err := connection.Neigh.List()
|
|
if err != nil {
|
|
return nil, E.Cause(err, "list neighbors")
|
|
}
|
|
var entries []adapter.NeighborEntry
|
|
for _, neighbor := range neighbors {
|
|
if neighbor.Attributes == nil {
|
|
continue
|
|
}
|
|
if neighbor.Attributes.LLAddress == nil || len(neighbor.Attributes.Address) == 0 {
|
|
continue
|
|
}
|
|
address, ok := netip.AddrFromSlice(neighbor.Attributes.Address)
|
|
if !ok {
|
|
continue
|
|
}
|
|
entries = append(entries, adapter.NeighborEntry{
|
|
Address: address,
|
|
MACAddress: slices.Clone(neighbor.Attributes.LLAddress),
|
|
})
|
|
}
|
|
return entries, nil
|
|
}
|
|
|
|
func ParseNeighborMessage(message netlink.Message) (address netip.Addr, macAddress net.HardwareAddr, isDelete bool, ok bool) {
|
|
var neighMessage rtnetlink.NeighMessage
|
|
err := neighMessage.UnmarshalBinary(message.Data)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if neighMessage.Attributes == nil || len(neighMessage.Attributes.Address) == 0 {
|
|
return
|
|
}
|
|
address, ok = netip.AddrFromSlice(neighMessage.Attributes.Address)
|
|
if !ok {
|
|
return
|
|
}
|
|
isDelete = message.Header.Type == unix.RTM_DELNEIGH
|
|
if !isDelete && neighMessage.Attributes.LLAddress == nil {
|
|
ok = false
|
|
return
|
|
}
|
|
macAddress = slices.Clone(neighMessage.Attributes.LLAddress)
|
|
return
|
|
}
|