forked from bettercap/bettercap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lan_endpoint.go
152 lines (127 loc) · 3.59 KB
/
lan_endpoint.go
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package network
import (
"encoding/binary"
"fmt"
"net"
"strconv"
"strings"
"time"
"github.com/bettercap/bettercap/core"
)
type OnHostResolvedCallback func(e *Endpoint)
type Endpoint struct {
Index int `json:"-"`
IP net.IP `json:"-"`
Net *net.IPNet `json:"-"`
IPv6 net.IP `json:"-"`
HW net.HardwareAddr `json:"-"`
IpAddress string `json:"ipv4"`
Ip6Address string `json:"ipv6"`
SubnetBits uint32 `json:"-"`
IpAddressUint32 uint32 `json:"-"`
HwAddress string `json:"mac"`
Hostname string `json:"hostname"`
Alias string `json:"alias"`
Vendor string `json:"vendor"`
ResolvedCallback OnHostResolvedCallback `json:"-"`
FirstSeen time.Time `json:"first_seen"`
LastSeen time.Time `json:"last_seen"`
Meta *Meta `json:"meta"`
}
func NewEndpointNoResolve(ip, mac, name string, bits uint32) *Endpoint {
mac = NormalizeMac(mac)
hw, _ := net.ParseMAC(mac)
now := time.Now()
e := &Endpoint{
IP: nil,
IpAddress: ip,
IpAddressUint32: 0,
Net: nil,
HW: hw,
SubnetBits: bits,
HwAddress: mac,
Hostname: name,
Vendor: OuiLookup(mac),
ResolvedCallback: nil,
FirstSeen: now,
LastSeen: now,
Meta: NewMeta(),
}
e.SetIP(ip)
e.SetBits(bits)
return e
}
func NewEndpoint(ip, mac string) *Endpoint {
e := NewEndpointNoResolve(ip, mac, "", 0)
// start resolver goroutine
go func() {
if names, err := net.LookupAddr(e.IpAddress); err == nil && len(names) > 0 {
e.Hostname = names[0]
if e.ResolvedCallback != nil {
e.ResolvedCallback(e)
}
}
}()
return e
}
func NewEndpointWithAlias(ip, mac, alias string) *Endpoint {
e := NewEndpoint(ip, mac)
e.Alias = alias
return e
}
func ip2int(ip net.IP) uint32 {
if len(ip) == 16 {
return binary.BigEndian.Uint32(ip[12:16])
}
return binary.BigEndian.Uint32(ip)
}
func (t *Endpoint) SetNetwork(netw string) {
parts := strings.Split(netw, "/")
address := parts[0]
bits, _ := strconv.Atoi(parts[1])
t.SetIP(address)
t.SetBits(uint32(bits))
}
func (t *Endpoint) SetIPv6(netw string) {
parts := strings.SplitN(netw, "/", 2)
address := parts[0]
// bits, _ := strconv.Atoi(parts[1])
t.IPv6 = net.ParseIP(address)
if t.IPv6 != nil {
t.Ip6Address = t.IPv6.String()
}
}
func (t *Endpoint) SetIP(ip string) {
addr := net.ParseIP(ip)
t.IP = addr
t.IpAddress = ip
t.IpAddressUint32 = ip2int(addr)
}
func (t *Endpoint) SetBits(bits uint32) {
t.SubnetBits = bits
_, netw, _ := net.ParseCIDR(t.CIDR())
t.Net = netw
}
func (t *Endpoint) Name() string {
return t.Hostname
}
func (t *Endpoint) CIDR() string {
shift := 32 - t.SubnetBits
address := t.IpAddressUint32
ip := make(net.IP, 4)
binary.BigEndian.PutUint32(ip, (address>>shift)<<shift)
return fmt.Sprintf("%s/%d", ip.String(), t.SubnetBits)
}
func (t *Endpoint) IsMonitor() bool {
return t.IpAddress == MonitorModeAddress
}
func (t *Endpoint) String() string {
if t.HwAddress == "" {
return t.IpAddress
} else if t.Vendor == "" {
return fmt.Sprintf("%s : %s", t.IpAddress, t.HwAddress)
} else if t.Hostname == "" {
return fmt.Sprintf("%s : %s ( %s )", t.IpAddress, t.HwAddress, t.Vendor)
}
return fmt.Sprintf("%s : %s ( %s ) - %s", t.IpAddress, t.HwAddress, t.Vendor, core.Bold(t.Hostname))
}