fix: gracefully handling wifi device disconnection

This commit is contained in:
evilsocket 2019-03-30 16:17:26 +01:00
parent 54116f7fbe
commit afe300cd8a
No known key found for this signature in database
GPG key ID: 1564D7F30393A456
4 changed files with 53 additions and 22 deletions

View file

@ -1,7 +1,6 @@
package core package core
import ( import (
"fmt"
"os/exec" "os/exec"
"sort" "sort"
@ -34,7 +33,7 @@ func HasBinary(executable string) bool {
return true return true
} }
func ExecSilent(executable string, args []string) (string, error) { func Exec(executable string, args []string) (string, error) {
path, err := exec.LookPath(executable) path, err := exec.LookPath(executable)
if err != nil { if err != nil {
return "", err return "", err
@ -47,11 +46,3 @@ func ExecSilent(executable string, args []string) (string, error) {
return str.Trim(string(raw)), nil 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
}

View file

@ -561,6 +561,17 @@ func (mod *WiFiModule) Start() error {
return nil 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 { func (mod *WiFiModule) Stop() error {
return mod.SetRunning(false, func() { return mod.SetRunning(false, func() {
// wait any pending write operation // wait any pending write operation

View file

@ -1,11 +1,47 @@
package wifi package wifi
import ( import (
"net"
"time" "time"
"github.com/bettercap/bettercap/network" "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()) { func (mod *WiFiModule) onChannel(channel int, cb func()) {
mod.chanLock.Lock() mod.chanLock.Lock()
defer mod.chanLock.Unlock() defer mod.chanLock.Unlock()
@ -13,11 +49,7 @@ func (mod *WiFiModule) onChannel(channel int, cb func()) {
prev := mod.stickChan prev := mod.stickChan
mod.stickChan = channel mod.stickChan = channel
if err := network.SetInterfaceChannel(mod.iface.Name(), channel); err != nil { mod.hop(channel)
mod.Warning("error while hopping to channel %d: %s", channel, err)
} else {
mod.Debug("hopped on channel %d", channel)
}
cb() cb()
@ -50,13 +82,10 @@ func (mod *WiFiModule) channelHopper() {
channel = mod.stickChan channel = mod.stickChan
} }
mod.Debug("hopping on channel %d", channel) if stop := mod.hop(channel); stop {
mod.forcedStop()
mod.chanLock.Lock() return
if err := network.SetInterfaceChannel(mod.iface.Name(), channel); err != nil {
mod.Warning("error while hopping to channel %d: %s", channel, err)
} }
mod.chanLock.Unlock()
select { select {
case _ = <-mod.hopChanges: case _ = <-mod.hopChanges:

View file

@ -286,7 +286,7 @@ func ActivateInterface(name string) error {
func SetInterfaceTxPower(name string, txpower int) error { func SetInterfaceTxPower(name string, txpower int) error {
if core.HasBinary("iwconfig") { 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 return err
} else if out != "" { } else if out != "" {
return fmt.Errorf("unexpected output while setting txpower to %d for interface %s: %s", txpower, name, out) return fmt.Errorf("unexpected output while setting txpower to %d for interface %s: %s", txpower, name, out)