38 lines
943 B
Go
38 lines
943 B
Go
package vip
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
|
|
"github.com/mdlayher/arp"
|
|
"github.com/mdlayher/ethernet"
|
|
)
|
|
|
|
func sendARP(ip net.IP, iface *net.Interface) error {
|
|
c, err := arp.Dial(iface)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, op := range []arp.Operation{arp.OperationRequest, arp.OperationReply} {
|
|
pkt, err := arp.NewPacket(op, iface.HardwareAddr, ip, ethernet.Broadcast, ip)
|
|
if err != nil {
|
|
return fmt.Errorf("assembling %q gratuitous packet for %q: %s", op, ip, err)
|
|
}
|
|
if err = c.WriteTo(pkt, ethernet.Broadcast); err != nil {
|
|
return fmt.Errorf("writing %q gratuitous packet for %q: %s", op, ip, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func ARPSendGratuitous(cidr, iface string) error {
|
|
i, err := net.InterfaceByName(iface)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get interface %q: %v", iface, err)
|
|
}
|
|
ip, _, err := net.ParseCIDR(cidr)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse cidr: %s", cidr)
|
|
}
|
|
return sendARP(ip, i)
|
|
}
|