func main() { flag.Parse() // Ensure valid network interface ifi, err := net.InterfaceByName(*ifaceFlag) if err != nil { log.Fatal(err) } // Set up ARP client with socket c, err := arp.NewClient(ifi) if err != nil { log.Fatal(err) } // Set request deadline from flag if err := c.SetDeadline(time.Now().Add(*durFlag)); err != nil { log.Fatal(err) } // Request hardware address for IP address ip := net.ParseIP(*ipFlag).To4() mac, err := c.Resolve(ip) if err != nil { log.Fatal(err) } fmt.Printf("%s -> %s", ip, mac) // Clean up ARP client socket _ = c.Close() }
func SendGratuitousARPReply(ip string, iface string) error { // Set up ARP client with socket ifi, err := net.InterfaceByName(iface) if err != nil { return err } c, err := arp.NewClient(ifi) if err != nil { return err } // Set request deadline from flag if err := c.SetDeadline(time.Now().Add(1 * time.Second)); err != nil { return err } srcIp := net.ParseIP(ip).To4() packet, err := arp.NewPacket(arp.OperationReply, ifi.HardwareAddr, srcIp, ethernetBroadcast, net.IPv4bcast) if err != nil { return err } if err := c.WriteTo(packet, ethernetBroadcast); err != nil { return err } // Clean up ARP client socket _ = c.Close() return nil }
func ListenAndServe(db store.Store, ifaceName string) error { listenIface, err := net.InterfaceByName(ifaceName) if err != nil { return err } client, err := arp.NewClient(listenIface) if err != nil { return err } logrus.Infof("Listening for ARP requests on %s", ifaceName) for { arpRequest, iface, err := client.Read() if err != nil { return err } if arpRequest.Operation != arp.OperationRequest || (!bytes.Equal(iface.Destination, ethernet.Broadcast) && !bytes.Equal(iface.Destination, listenIface.HardwareAddr)) { continue } targetIp := arpRequest.TargetIP.String() logrus.Debugf("Arp request for %s", targetIp) if db.IsRemote(targetIp) { logrus.Debugf("Sending arp reply for %s", targetIp) if err := client.Reply(arpRequest, listenIface.HardwareAddr, arpRequest.TargetIP); err != nil { return err } } } }
func initClient(ifaceName string) (*arp.Client, error) { iface, err := net.InterfaceByName(ifaceName) if err != nil { return nil, err } return arp.NewClient(iface) }
func main() { flag.Parse() // Ensure valid interface and IPv4 address ifi, err := net.InterfaceByName(*ifaceFlag) if err != nil { log.Fatal(err) } ip := net.ParseIP(*ipFlag).To4() if ip == nil { log.Fatalf("invalid IPv4 address: %q", *ipFlag) } client, err := arp.NewClient(ifi) if err != nil { log.Fatalf("couldn't create ARP client: %s", err) } // Handle ARP requests bound for designated IPv4 address, using proxy ARP // to indicate that the address belongs to this machine for { pkt, eth, err := client.Read() if err != nil { if err == io.EOF { log.Println("EOF") break } log.Fatalf("error processing ARP requests: %s", err) } // Ignore ARP replies if pkt.Operation != arp.OperationRequest { continue } // Ignore ARP requests which are not broadcast or bound directly for // this machine if !bytes.Equal(eth.Destination, ethernet.Broadcast) && !bytes.Equal(eth.Destination, ifi.HardwareAddr) { continue } log.Printf("request: who-has %s? tell %s (%s)", pkt.TargetIP, pkt.SenderIP, pkt.SenderHardwareAddr) // Ignore ARP requests which do not indicate the target IP if !pkt.TargetIP.Equal(ip) { continue } log.Printf(" reply: %s is-at %s", ip, ifi.HardwareAddr) if err := client.Reply(pkt, ifi.HardwareAddr, ip); err != nil { log.Fatal(err) } } }