fix: refactored routing logic (fixes #701)

This commit is contained in:
Simone Margaritelli 2021-04-10 21:55:00 +02:00
commit 43a93fd866
11 changed files with 202 additions and 80 deletions

17
routing/route.go Normal file
View file

@ -0,0 +1,17 @@
package routing
type RouteType int
const (
IPv4 RouteType = 0
IPv6 RouteType = 1
)
type Route struct {
Type RouteType
Default bool
Device string
Destination string
Gateway string
Flags string
}

39
routing/tables.go Normal file
View file

@ -0,0 +1,39 @@
package routing
import "sync"
var (
lock = sync.RWMutex{}
table = make([]Route, 0)
)
func Table() []Route {
lock.RLock()
defer lock.RUnlock()
return table
}
func Update() ([]Route, error) {
lock.Lock()
defer lock.Unlock()
return update()
}
func Gateway(ip RouteType, device string) (string, error) {
Update()
lock.RLock()
defer lock.RUnlock()
for _, r := range table {
if r.Type == ip {
if device == "" || r.Device == device || r.Device == "" /* windows case */ {
if r.Default {
return r.Gateway, nil
}
}
}
}
return "", nil
}

44
routing/update_darwin.go Normal file
View file

@ -0,0 +1,44 @@
package routing
import (
"github.com/bettercap/bettercap/core"
"github.com/evilsocket/islazy/str"
"regexp"
"strings"
)
var parser = regexp.MustCompile(`^([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+).*$`)
func update() ([]Route, error) {
table = make([]Route, 0)
output, err := core.Exec("netstat", []string{"-n", "-r"})
if err != nil {
return nil, err
}
for _, line := range strings.Split(output, "\n") {
if line = str.Trim(line); len(line) > 0 {
matches := parser.FindStringSubmatch(line)
if num := len(matches); num == 5 && matches[1] != "Destination" {
route := Route{
Destination: matches[1],
Gateway: matches[2],
Flags: matches[3],
Device: matches[4],
Default: matches[1] == "default",
}
if strings.ContainsRune(route.Destination, '.') || strings.ContainsRune(route.Gateway, '.') {
route.Type = IPv4
} else {
route.Type = IPv6
}
table = append(table, route)
}
}
}
return table, nil
}

45
routing/update_linux.go Normal file
View file

@ -0,0 +1,45 @@
package routing
import (
"github.com/bettercap/bettercap/core"
"github.com/evilsocket/islazy/str"
"regexp"
"strings"
)
var parser = regexp.MustCompile(`^(.+)\sdev\s([^\s]+)\s(.+)$`)
func update() ([]Route, error) {
table = make([]Route, 0)
for ip, inet := range map[RouteType]string{IPv4: "inet", IPv6: "inet6"} {
output, err := core.Exec("ip", []string{"-f", inet, "route"})
if err != nil {
return nil, err
}
for _, line := range strings.Split(output, "\n") {
if line = str.Trim(line); len(line) > 0 {
matches := parser.FindStringSubmatch(line)
if num := len(matches); num == 4 {
route := Route{
Type: ip,
Destination: matches[1],
Device: matches[2],
Flags: matches[3],
Default: strings.Index(matches[1], "default ") == 0,
}
if idx := strings.Index(route.Destination, " via "); idx >= 0 {
route.Gateway = route.Destination[idx + len(" via "):]
route.Destination = route.Destination[:idx]
}
table = append(table, route)
}
}
}
}
return table, nil
}

44
routing/update_windows.go Normal file
View file

@ -0,0 +1,44 @@
package routing
import (
"github.com/bettercap/bettercap/core"
"github.com/evilsocket/islazy/str"
"regexp"
"strings"
)
var parser = regexp.MustCompile(`^.+\d+\s+([^\s]+)\s+\d+\s+(.+)$`)
func update() ([]Route, error) {
table = make([]Route, 0)
for ip, inet := range map[RouteType]string{IPv4: "ipv4", IPv6: "ipv6"} {
output, err := core.Exec("netsh", []string{"interface", inet, "show", "route"})
if err != nil {
return nil, err
}
for _, line := range strings.Split(output, "\n") {
if line = str.Trim(line); len(line) > 0 {
matches := parser.FindStringSubmatch(line)
if num := len(matches); num == 3 {
route := Route{
Type: ip,
Destination: matches[1],
Device: matches[2],
}
if route.Destination == "0.0.0.0/0" || route.Destination == "::/0" {
route.Default = true
route.Gateway = route.Device
route.Device = ""
}
table = append(table, route)
}
}
}
}
return table, nil
}