fix: fixed and refactored network.FindInterface because it was shit

This commit is contained in:
evilsocket 2018-02-24 18:13:20 +01:00
commit f0158342d6
2 changed files with 94 additions and 78 deletions

View file

@ -87,6 +87,15 @@ func NewEndpointWithAlias(ip, mac, alias string) *Endpoint {
return e
}
func (t *Endpoint) SetIP(ip string) {
addr := net.ParseIP(ip)
t.IP = addr
t.IpAddress = ip
t.IpAddressUint32 = ip2int(addr)
}
func (t *Endpoint) Name() string {
return t.Hostname
}

View file

@ -1,6 +1,7 @@
package network
import (
"errors"
"fmt"
"net"
"regexp"
@ -10,6 +11,8 @@ import (
"github.com/bettercap/bettercap/core"
)
var ErrNoIfaces = errors.New("No active interfaces found.")
const (
MonitorModeAddress = "0.0.0.0"
BroadcastSuffix = ".255"
@ -39,76 +42,34 @@ func NormalizeMac(mac string) string {
return strings.Join(parts, ":")
}
func FindInterface(name string) (*Endpoint, error) {
ifaces, err := net.Interfaces()
func buildEndpointFromInterface(iface net.Interface) (*Endpoint, error) {
addrs, err := iface.Addrs()
if err != nil {
return nil, err
}
for _, iface := range ifaces {
ifName := getInterfaceName(iface)
mac := iface.HardwareAddr.String()
addrs, err := iface.Addrs()
if err != nil {
fmt.Printf("%s\n", err)
continue
}
nAddrs := len(addrs)
e := NewEndpointNoResolve(MonitorModeAddress, iface.HardwareAddr.String(), "", 0)
// fmt.Printf("iface=%v\n", iface)
e.Hostname = iface.Name
e.Index = iface.Index
/*
* If no interface has been specified, return the first active
* one with at least an ip address, otherwise just the match
* whatever it has, in order to also consider monitor interfaces
* if passed explicitly.
*/
doCheck := false
if name != "" && name == mac {
doCheck = true
} else if name == "" && ifName != "lo" && ifName != "lo0" && nAddrs > 0 {
doCheck = true
} else if ifName == name {
doCheck = true
}
// Also search by ip if needed.
hasIPv4 := false
for _, a := range addrs {
if IPv4Validator.MatchString(a.String()) {
hasIPv4 = true
}
if name != "" && (a.String() == name || strings.HasPrefix(a.String(), name)) {
doCheck = true
}
}
if doCheck {
var e *Endpoint = nil
// interface is in monitor mode (or it's just down and the user is dumb, or
// it only has an IPv6 address).
if nAddrs == 0 || hasIPv4 == false {
e = NewEndpointNoResolve(MonitorModeAddress, mac, ifName, 0)
} else {
// For every address of the interface.
for _, addr := range addrs {
ip := addr.String()
// Make sure this is an IPv4 address.
if IPv4Validator.MatchString(ip) {
if strings.IndexRune(ip, '/') == -1 {
// plain ip
e = NewEndpointNoResolve(ip, mac, ifName, 0)
e.SetIP(ip)
} else {
// ip/bits
parts := strings.Split(ip, "/")
ip_part := parts[0]
bits, err := strconv.Atoi(parts[1])
if err == nil {
e = NewEndpointNoResolve(ip_part, mac, ifName, uint32(bits))
bits, _ := strconv.Atoi(parts[1])
e.SetIP(ip_part)
e.SubnetBits = uint32(bits)
}
}
} else if e != nil {
} else {
parts := strings.SplitN(ip, "/", 2)
e.IPv6 = net.ParseIP(parts[0])
if e.IPv6 != nil {
@ -116,23 +77,69 @@ func FindInterface(name string) (*Endpoint, error) {
}
}
}
}
if e != nil {
if len(e.HW) == 0 {
return nil, fmt.Errorf("Could not detect interface hardware address.")
}
e.Index = iface.Index
return e, nil
}
func matchByAddress(iface net.Interface, name string) bool {
ifMac := iface.HardwareAddr.String()
if NormalizeMac(ifMac) == NormalizeMac(name) {
return true
}
addrs, err := iface.Addrs()
if err == nil {
for _, addr := range addrs {
ip := addr.String()
if ip == name || strings.HasPrefix(ip, name) {
return true
}
}
}
if name == "" {
return nil, fmt.Errorf("Could not find default network interface.")
} else {
return nil, fmt.Errorf("Could not find interface '%s'.", name)
return false
}
func findInterfaceByName(name string, ifaces []net.Interface) (*Endpoint, error) {
for _, iface := range ifaces {
if iface.Name == name || matchByAddress(iface, name) {
return buildEndpointFromInterface(iface)
}
}
return nil, fmt.Errorf("No interface matching '%s' found.", name)
}
func FindInterface(name string) (*Endpoint, error) {
ifaces, err := net.Interfaces()
if err != nil {
return nil, err
}
name = core.Trim(name)
if name != "" {
return findInterfaceByName(name, ifaces)
}
// user did not provide an interface name,
// return the first one with a valid ipv4
// address
for _, iface := range ifaces {
addrs, err := iface.Addrs()
if err != nil {
fmt.Printf("WTF of the day: %s", err)
continue
}
for _, address := range addrs {
ip := address.String()
if strings.Contains(ip, "127.0.0.1") == false && IPv4Validator.MatchString(ip) {
return buildEndpointFromInterface(iface)
}
}
}
return nil, ErrNoIfaces
}
func FindGateway(iface *Endpoint) (*Endpoint, error) {