...
1 package main
2
3 import (
4 "bytes"
5 "flag"
6 "io"
7 "log"
8 "net"
9 "net/netip"
10
11 "github.com/mdlayher/arp"
12 "github.com/mdlayher/ethernet"
13 )
14
15 var (
16
17 ifaceFlag = flag.String("i", "eth0", "network interface to use for ARP traffic")
18
19
20 ipFlag = flag.String("ip", "", "IP address for device to proxy ARP on behalf of")
21 )
22
23 func main() {
24 flag.Parse()
25
26
27 ifi, err := net.InterfaceByName(*ifaceFlag)
28 if err != nil {
29 log.Fatal(err)
30 }
31 ip, err := netip.ParseAddr(*ipFlag)
32 if err != nil || !ip.Is4() {
33 log.Fatalf("invalid IPv4 address: %q", *ipFlag)
34 }
35
36 client, err := arp.Dial(ifi)
37 if err != nil {
38 log.Fatalf("couldn't create ARP client: %s", err)
39 }
40
41
42
43 for {
44 pkt, eth, err := client.Read()
45 if err != nil {
46 if err == io.EOF {
47 log.Println("EOF")
48 break
49 }
50 log.Fatalf("error processing ARP requests: %s", err)
51 }
52
53
54 if pkt.Operation != arp.OperationRequest {
55 continue
56 }
57
58
59
60 if !bytes.Equal(eth.Destination, ethernet.Broadcast) && !bytes.Equal(eth.Destination, ifi.HardwareAddr) {
61 continue
62 }
63
64 log.Printf("request: who-has %s? tell %s (%s)", pkt.TargetIP, pkt.SenderIP, pkt.SenderHardwareAddr)
65
66
67 if pkt.TargetIP != ip {
68 continue
69 }
70
71 log.Printf(" reply: %s is-at %s", ip, ifi.HardwareAddr)
72 if err := client.Reply(pkt, ifi.HardwareAddr, ip); err != nil {
73 log.Fatal(err)
74 }
75 }
76 }
77
View as plain text