From c55284429e3a7574db38953dacdac26f7fff852c Mon Sep 17 00:00:00 2001 From: Daniel Rodriguez Date: Sat, 20 Jan 2018 17:04:21 +0100 Subject: [PATCH 1/2] Replace arp from net-tools by ip from iproute2 (linux) --- net/arp_parser_darwin.go | 3 +++ net/arp_parser_linux.go | 5 ++++- net/arp_unix.go | 10 +++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/net/arp_parser_darwin.go b/net/arp_parser_darwin.go index c32af75b..45eaa28f 100644 --- a/net/arp_parser_darwin.go +++ b/net/arp_parser_darwin.go @@ -4,3 +4,6 @@ import "regexp" var ArpTableParser = regexp.MustCompile("^[^\\d\\.]+([\\d\\.]+).+\\s+([a-f0-9:]{11,17})\\s+on\\s+([^\\s]+)\\s+.+$") var ArpTableTokens = 4 +var ArpTableTokenIndex = []uint{1, 2, 3} +var ArpCmd = "arp" +var ArpCmdOpts = []string{"-a", "-n"} diff --git a/net/arp_parser_linux.go b/net/arp_parser_linux.go index 438e178f..fa81c8fa 100644 --- a/net/arp_parser_linux.go +++ b/net/arp_parser_linux.go @@ -2,5 +2,8 @@ package net import "regexp" -var ArpTableParser = regexp.MustCompile("^[^\\d\\.]+([\\d\\.]+).+\\s+([a-f0-9:]{17}).+\\s+(.+)$") +var ArpTableParser = regexp.MustCompile("^([\\d\\.]+)\\s+dev\\s+(\\w+)\\s+\\w+\\s+([a-f0-9:]{17})\\s+\\w+$") var ArpTableTokens = 4 +var ArpTableTokenIndex = []uint{1, 3, 2} +var ArpCmd = "ip" +var ArpCmdOpts = []string{"neigh"} diff --git a/net/arp_unix.go b/net/arp_unix.go index 620f5990..3ee8554a 100644 --- a/net/arp_unix.go +++ b/net/arp_unix.go @@ -12,8 +12,8 @@ func ArpUpdate(iface string) (ArpTable, error) { // Signal we parsed the ARP table at least once. arp_parsed = true - // Run "arp -an" and parse the output. - output, err := core.Exec("arp", []string{"-a", "-n"}) + // Run "arp -an" (darwin) or "ip neigh" (linux) and parse the output + output, err := core.Exec(ArpCmd, ArpCmdOpts) if err != nil { return arp_table, err } @@ -22,9 +22,9 @@ func ArpUpdate(iface string) (ArpTable, error) { for _, line := range strings.Split(output, "\n") { m := ArpTableParser.FindStringSubmatch(line) if len(m) == ArpTableTokens { - address := m[1] - mac := m[2] - ifname := m[3] + address := m[ArpTableTokenIndex[0]] + mac := m[ArpTableTokenIndex[1]] + ifname := m[ArpTableTokenIndex[2]] if ifname == iface { new_table[address] = mac From 881126941ba356edec3814aa89a8ef7e9cf29efb Mon Sep 17 00:00:00 2001 From: Daniel Rodriguez Date: Sat, 20 Jan 2018 21:11:17 +0100 Subject: [PATCH 2/2] Replace netstat from net-tools by ip from iproute2 (linux) --- net/net.go | 38 +++++--------------------------------- net/net_darwin.go | 20 ++++++++++++++++++++ net/net_linux.go | 20 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 33 deletions(-) create mode 100644 net/net_darwin.go create mode 100644 net/net_linux.go diff --git a/net/net.go b/net/net.go index 108b162b..dc13f983 100644 --- a/net/net.go +++ b/net/net.go @@ -4,20 +4,12 @@ import ( "fmt" "net" "regexp" - "runtime" "strconv" "strings" "github.com/evilsocket/bettercap-ng/core" ) -var IPv4RouteParser = regexp.MustCompile("^([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([A-Z]+)\\s+\\d+\\s+\\d+\\s+\\d+\\s+(.+)$") -var IPv4RouteTokens = 6 -var IPv4RouteParserMac = regexp.MustCompile("^([a-z]+)+\\s+(\\d+\\.+\\d+.\\d.+\\d)+\\s+([a-zA-z]+)+\\s+(\\d+)+\\s+(\\d+)+\\s+([a-zA-Z]+\\d+)$") -var IPv4RouteTokensMac = 7 -var IPv4RouteGWFlags = "UG" -var IPv4RouteGWFlagsMac = "UGSc" - func FindInterface(name string) (*Endpoint, error) { ifaces, err := net.Interfaces() if err != nil { @@ -75,35 +67,15 @@ func FindInterface(name string) (*Endpoint, error) { } func FindGateway(iface *Endpoint) (*Endpoint, error) { - var routeParser = IPv4RouteParser - var routeTokens = IPv4RouteTokens - var flagsIndex = 4 - var ifnameIndex = 5 - var gwFlags = IPv4RouteGWFlags - - if runtime.GOOS == "darwin" { - // "MacOS detected" - routeParser = IPv4RouteParserMac - routeTokens = IPv4RouteTokensMac - flagsIndex = 3 - ifnameIndex = 6 - gwFlags = IPv4RouteGWFlagsMac - } - - output, err := core.Exec("netstat", []string{"-n", "-r"}) + output, err := core.Exec(IPv4RouteCmd, IPv4RouteCmdOpts) if err != nil { return nil, err } for _, line := range strings.Split(output, "\n") { - m := routeParser.FindStringSubmatch(line) - if len(m) == routeTokens { - // destination := m[1] - // mask := m[3] - flags := m[flagsIndex] - ifname := m[ifnameIndex] - if ifname == iface.Name() && flags == gwFlags { - gateway := m[2] + m := IPv4RouteParser.FindStringSubmatch(line) + if len(m) == IPv4RouteTokens { + return IPv4RouteIsGateway(iface.Name(), m, func(gateway string) (*Endpoint, error) { if gateway == iface.IpAddress { return iface, nil } else { @@ -114,7 +86,7 @@ func FindGateway(iface *Endpoint) (*Endpoint, error) { } return NewEndpoint(gateway, mac), nil } - } + }) } } diff --git a/net/net_darwin.go b/net/net_darwin.go new file mode 100644 index 00000000..89c0ae7d --- /dev/null +++ b/net/net_darwin.go @@ -0,0 +1,20 @@ +package net + +import "regexp" + +var IPv4RouteParser = regexp.MustCompile("^([a-z]+)+\\s+(\\d+\\.+\\d+.\\d.+\\d)+\\s+([a-zA-z]+)+\\s+(\\d+)+\\s+(\\d+)+\\s+([a-zA-Z]+\\d+)$") +var IPv4RouteTokens = 7 +var IPv4RouteCmd = "netstat" +var IPv4RouteCmdOpts = []string{"-n", "-r"} + +func IPv4RouteIsGateway(ifname string, tokens []string, f func(gateway string) (*Endpoint, error)) (*Endpoint, error) { + ifname2 := tokens[6] + flags := tokens[3] + + if ifname == ifname2 && flags == "UGSc" { + gateway := tokens[2] + return f(gateway) + } + + return nil, nil +} diff --git a/net/net_linux.go b/net/net_linux.go new file mode 100644 index 00000000..179d26a5 --- /dev/null +++ b/net/net_linux.go @@ -0,0 +1,20 @@ +package net + +import "regexp" + +// only matches gateway lines +var IPv4RouteParser = regexp.MustCompile("^(default|[0-9\\.]+)\\svia\\s([0-9\\.]+)\\sdev\\s(\\w+)\\s.*$") +var IPv4RouteTokens = 4 +var IPv4RouteCmd = "ip" +var IPv4RouteCmdOpts = []string{"route"} + +func IPv4RouteIsGateway(ifname string, tokens []string, f func(gateway string) (*Endpoint, error)) (*Endpoint, error) { + ifname2 := tokens[3] + + if ifname == ifname2 { + gateway := tokens[2] + return f(gateway) + } + + return nil, nil +}