diff --git a/core/core.go b/core/core.go index f79e6ffc..3761a6c7 100644 --- a/core/core.go +++ b/core/core.go @@ -1,7 +1,6 @@ package core import ( - "fmt" "os/exec" "sort" @@ -34,7 +33,7 @@ func HasBinary(executable string) bool { return true } -func ExecSilent(executable string, args []string) (string, error) { +func Exec(executable string, args []string) (string, error) { path, err := exec.LookPath(executable) if err != nil { return "", err @@ -47,11 +46,3 @@ func ExecSilent(executable string, args []string) (string, error) { return str.Trim(string(raw)), nil } } - -func Exec(executable string, args []string) (string, error) { - out, err := ExecSilent(executable, args) - if err != nil { - fmt.Printf("ERROR for '%s %s': %s\n", executable, args, err) - } - return out, err -} diff --git a/modules/wifi/wifi.go b/modules/wifi/wifi.go index 4ac37e34..2a48b4a1 100644 --- a/modules/wifi/wifi.go +++ b/modules/wifi/wifi.go @@ -561,6 +561,17 @@ func (mod *WiFiModule) Start() error { return nil } +func (mod *WiFiModule) forcedStop() error { + return mod.SetRunning(false, func() { + // signal the main for loop we want to exit + if !mod.pktSourceChanClosed { + mod.pktSourceChan <- nil + } + // close the pcap handle to make the main for exit + mod.handle.Close() + }) +} + func (mod *WiFiModule) Stop() error { return mod.SetRunning(false, func() { // wait any pending write operation diff --git a/modules/wifi/wifi_hopping.go b/modules/wifi/wifi_hopping.go index 79fea79e..99fdbf07 100644 --- a/modules/wifi/wifi_hopping.go +++ b/modules/wifi/wifi_hopping.go @@ -1,11 +1,47 @@ package wifi import ( + "net" "time" "github.com/bettercap/bettercap/network" ) +func (mod *WiFiModule) isInterfaceConnected() bool { + ifaces, err := net.Interfaces() + if err != nil { + mod.Error("error while enumerating interfaces: %s", err) + return false + } + + for _, iface := range ifaces { + if mod.iface.HwAddress == network.NormalizeMac(iface.HardwareAddr.String()) { + return true + } + } + + return false +} + +func (mod *WiFiModule) hop(channel int) (mustStop bool) { + mod.chanLock.Lock() + defer mod.chanLock.Unlock() + + mod.Debug("hopping on channel %d", channel) + + if err := network.SetInterfaceChannel(mod.iface.Name(), channel); err != nil { + // check if the device has been disconnected + if mod.isInterfaceConnected() == false { + mod.Error("interface %s disconnected, stopping module", mod.iface.Name()) + mustStop = true + } else { + mod.Warning("error while hopping to channel %d: %s", channel, err) + } + } + + return +} + func (mod *WiFiModule) onChannel(channel int, cb func()) { mod.chanLock.Lock() defer mod.chanLock.Unlock() @@ -13,11 +49,7 @@ func (mod *WiFiModule) onChannel(channel int, cb func()) { prev := mod.stickChan mod.stickChan = channel - if err := network.SetInterfaceChannel(mod.iface.Name(), channel); err != nil { - mod.Warning("error while hopping to channel %d: %s", channel, err) - } else { - mod.Debug("hopped on channel %d", channel) - } + mod.hop(channel) cb() @@ -50,13 +82,10 @@ func (mod *WiFiModule) channelHopper() { channel = mod.stickChan } - mod.Debug("hopping on channel %d", channel) - - mod.chanLock.Lock() - if err := network.SetInterfaceChannel(mod.iface.Name(), channel); err != nil { - mod.Warning("error while hopping to channel %d: %s", channel, err) + if stop := mod.hop(channel); stop { + mod.forcedStop() + return } - mod.chanLock.Unlock() select { case _ = <-mod.hopChanges: diff --git a/network/net.go b/network/net.go index 37123537..47be68d8 100644 --- a/network/net.go +++ b/network/net.go @@ -286,7 +286,7 @@ func ActivateInterface(name string) error { func SetInterfaceTxPower(name string, txpower int) error { if core.HasBinary("iwconfig") { - if out, err := core.ExecSilent("iwconfig", []string{name, "txpower", fmt.Sprintf("%d", txpower)}); err != nil { + if out, err := core.Exec("iwconfig", []string{name, "txpower", fmt.Sprintf("%d", txpower)}); err != nil { return err } else if out != "" { return fmt.Errorf("unexpected output while setting txpower to %d for interface %s: %s", txpower, name, out)