-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
101 lines (84 loc) · 2.37 KB
/
Copy pathmain.go
File metadata and controls
101 lines (84 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package main
import (
"github.com/jessevdk/go-flags"
"github.com/vishvananda/netlink"
"net"
"os"
"syscall"
"unsafe"
)
/*
#include "fill_packet.h"
*/
import "C"
var opts struct {
If string `long:"if",short:"i" description:"interface" required:"true"`
Ip string `long:"addr" description:"ip" required:"true"`
Mask string `long:"mask" description:"mask"`
FlagSetip bool `short:"s" description:"set ip"`
}
func SendGratuitousArp(iface string, req_ip string) {
etherArp := new(C.arp_packet)
size := uint(unsafe.Sizeof(*etherArp))
LogDebug.Println("ArpPacketSize : ", size)
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, syscall.ETH_P_ALL)
if err != nil {
LogError.Println("open ap_packet socket error: " + err.Error())
return
}
LogDebug.Println("obtained fd ", fd)
defer syscall.Close(fd)
// Get Mac address
interf, err := net.InterfaceByName(iface)
if err != nil {
LogError.Printf("could not find %s interface\n", iface)
return
}
LogDebug.Println("interface hw address: ", interf.HardwareAddr)
iface_cstr := C.CString(interf.HardwareAddr.String())
ip_cstr := C.CString(req_ip)
ppacket := C.fill_arp_packet(iface_cstr, ip_cstr)
packet := C.GoBytes(unsafe.Pointer(ppacket), C.int(size))
C.free(unsafe.Pointer(ppacket))
// Send the packet
var addr syscall.SockaddrLinklayer
addr.Protocol = syscall.ETH_P_ARP
addr.Ifindex = interf.Index
addr.Hatype = syscall.ARPHRD_ETHER
err = syscall.Sendto(fd, packet, 0, &addr)
if err != nil {
LogError.Println("sent packet error: ", err.Error())
os.Exit(1)
} else {
LogInfo.Println("sent packet success")
}
}
func AddIp(iface string, req_ip string, mask string) {
dst_if, err := netlink.LinkByName(iface)
if err != nil {
LogError.Printf("get %s error: %s\n", iface, err.Error())
os.Exit(1)
}
addr, err := netlink.ParseAddr(req_ip + "/" + mask)
if err != nil {
LogError.Printf("parse ip %s/%s error: %s\n", req_ip, mask, err.Error())
os.Exit(1)
}
netlink.AddrAdd(dst_if, addr)
}
// ./garp --addr 172.17.5.182 --if wlp4s0
func main() {
_, err := flags.ParseArgs(&opts, os.Args)
if err != nil {
LogError.Println("args error")
os.Exit(1)
}
if len(opts.Mask) == 0 {
opts.Mask = "24"
}
LogDebug.Println("Got interface:", opts.If, "ip:", opts.Ip, "mask:", opts.Mask)
if opts.FlagSetip {
AddIp(opts.If, opts.Ip, opts.Mask)
}
SendGratuitousArp(opts.If, opts.Ip)
}