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
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
}

View file

@ -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

View file

@ -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:

View file

@ -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)