8 "github.com/vishvananda/netlink/nl"
24 // Neighbor Cache Entry States.
54 func deserializeNdmsg(b []byte) *Ndmsg {
56 return (*Ndmsg)(unsafe.Pointer(&b[0:unsafe.Sizeof(dummy)][0]))
59 func (msg *Ndmsg) Serialize() []byte {
60 return (*(*[unsafe.Sizeof(*msg)]byte)(unsafe.Pointer(msg)))[:]
63 func (msg *Ndmsg) Len() int {
64 return int(unsafe.Sizeof(*msg))
67 // NeighAdd will add an IP to MAC mapping to the ARP table
68 // Equivalent to: `ip neigh add ....`
69 func NeighAdd(neigh *Neigh) error {
70 return pkgHandle.NeighAdd(neigh)
73 // NeighAdd will add an IP to MAC mapping to the ARP table
74 // Equivalent to: `ip neigh add ....`
75 func (h *Handle) NeighAdd(neigh *Neigh) error {
76 return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL)
79 // NeighSet will add or replace an IP to MAC mapping to the ARP table
80 // Equivalent to: `ip neigh replace....`
81 func NeighSet(neigh *Neigh) error {
82 return pkgHandle.NeighSet(neigh)
85 // NeighSet will add or replace an IP to MAC mapping to the ARP table
86 // Equivalent to: `ip neigh replace....`
87 func (h *Handle) NeighSet(neigh *Neigh) error {
88 return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE)
91 // NeighAppend will append an entry to FDB
92 // Equivalent to: `bridge fdb append...`
93 func NeighAppend(neigh *Neigh) error {
94 return pkgHandle.NeighAppend(neigh)
97 // NeighAppend will append an entry to FDB
98 // Equivalent to: `bridge fdb append...`
99 func (h *Handle) NeighAppend(neigh *Neigh) error {
100 return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_APPEND)
103 // NeighAppend will append an entry to FDB
104 // Equivalent to: `bridge fdb append...`
105 func neighAdd(neigh *Neigh, mode int) error {
106 return pkgHandle.neighAdd(neigh, mode)
109 // NeighAppend will append an entry to FDB
110 // Equivalent to: `bridge fdb append...`
111 func (h *Handle) neighAdd(neigh *Neigh, mode int) error {
112 req := h.newNetlinkRequest(syscall.RTM_NEWNEIGH, mode|syscall.NLM_F_ACK)
113 return neighHandle(neigh, req)
116 // NeighDel will delete an IP address from a link device.
117 // Equivalent to: `ip addr del $addr dev $link`
118 func NeighDel(neigh *Neigh) error {
119 return pkgHandle.NeighDel(neigh)
122 // NeighDel will delete an IP address from a link device.
123 // Equivalent to: `ip addr del $addr dev $link`
124 func (h *Handle) NeighDel(neigh *Neigh) error {
125 req := h.newNetlinkRequest(syscall.RTM_DELNEIGH, syscall.NLM_F_ACK)
126 return neighHandle(neigh, req)
129 func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
131 if neigh.Family > 0 {
132 family = neigh.Family
134 family = nl.GetIPFamily(neigh.IP)
138 Family: uint8(family),
139 Index: uint32(neigh.LinkIndex),
140 State: uint16(neigh.State),
141 Type: uint8(neigh.Type),
142 Flags: uint8(neigh.Flags),
146 ipData := neigh.IP.To4()
148 ipData = neigh.IP.To16()
151 dstData := nl.NewRtAttr(NDA_DST, ipData)
154 if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil {
155 hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
159 _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
163 // NeighList gets a list of IP-MAC mappings in the system (ARP table).
164 // Equivalent to: `ip neighbor show`.
165 // The list can be filtered by link and ip family.
166 func NeighList(linkIndex, family int) ([]Neigh, error) {
167 return pkgHandle.NeighList(linkIndex, family)
170 // NeighProxyList gets a list of neighbor proxies in the system.
171 // Equivalent to: `ip neighbor show proxy`.
172 // The list can be filtered by link and ip family.
173 func NeighProxyList(linkIndex, family int) ([]Neigh, error) {
174 return pkgHandle.NeighProxyList(linkIndex, family)
177 // NeighList gets a list of IP-MAC mappings in the system (ARP table).
178 // Equivalent to: `ip neighbor show`.
179 // The list can be filtered by link and ip family.
180 func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
181 return h.neighList(linkIndex, family, 0)
184 // NeighProxyList gets a list of neighbor proxies in the system.
185 // Equivalent to: `ip neighbor show proxy`.
186 // The list can be filtered by link, ip family.
187 func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
188 return h.neighList(linkIndex, family, NTF_PROXY)
191 func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
192 req := h.newNetlinkRequest(syscall.RTM_GETNEIGH, syscall.NLM_F_DUMP)
194 Family: uint8(family),
195 Index: uint32(linkIndex),
200 msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWNEIGH)
206 for _, m := range msgs {
207 ndm := deserializeNdmsg(m)
208 if linkIndex != 0 && int(ndm.Index) != linkIndex {
209 // Ignore messages from other interfaces
213 neigh, err := NeighDeserialize(m)
218 res = append(res, *neigh)
224 func NeighDeserialize(m []byte) (*Neigh, error) {
225 msg := deserializeNdmsg(m)
228 LinkIndex: int(msg.Index),
229 Family: int(msg.Family),
230 State: int(msg.State),
232 Flags: int(msg.Flags),
235 attrs, err := nl.ParseRouteAttr(m[msg.Len():])
240 for _, attr := range attrs {
241 switch attr.Attr.Type {
243 neigh.IP = net.IP(attr.Value)
245 neigh.HardwareAddr = net.HardwareAddr(attr.Value)