mirror of
https://github.com/bettercap/bettercap
synced 2025-08-14 10:46:57 -07:00
new: new ble.show.filter, ble.show.limit and ble.show.sort parameters
This commit is contained in:
parent
93a68bee27
commit
d62090267e
3 changed files with 112 additions and 13 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
golog "log"
|
||||
"time"
|
||||
|
||||
"github.com/bettercap/bettercap/modules/utils"
|
||||
"github.com/bettercap/bettercap/network"
|
||||
"github.com/bettercap/bettercap/session"
|
||||
|
||||
|
@ -26,6 +27,7 @@ type BLERecon struct {
|
|||
connTimeout time.Duration
|
||||
quit chan bool
|
||||
done chan bool
|
||||
selector *utils.ViewSelector
|
||||
}
|
||||
|
||||
func NewBLERecon(s *session.Session) *BLERecon {
|
||||
|
@ -39,6 +41,10 @@ func NewBLERecon(s *session.Session) *BLERecon {
|
|||
connected: false,
|
||||
}
|
||||
|
||||
mod.selector = utils.ViewSelectorFor(&mod.SessionModule,
|
||||
"ble.show",
|
||||
[]string{"rssi", "mac", "seen"}, "rssi asc")
|
||||
|
||||
mod.AddHandler(session.NewModuleHandler("ble.recon on", "",
|
||||
"Start Bluetooth Low Energy devices discovery.",
|
||||
func(args []string) error {
|
||||
|
|
|
@ -12,5 +12,22 @@ type ByBLERSSISorter []*network.BLEDevice
|
|||
func (a ByBLERSSISorter) Len() int { return len(a) }
|
||||
func (a ByBLERSSISorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a ByBLERSSISorter) Less(i, j int) bool {
|
||||
if a[i].RSSI == a[j].RSSI {
|
||||
return a[i].Device.ID() < a[j].Device.ID()
|
||||
}
|
||||
return a[i].RSSI > a[j].RSSI
|
||||
}
|
||||
|
||||
type ByBLEMacSorter []*network.BLEDevice
|
||||
|
||||
func (a ByBLEMacSorter) Len() int { return len(a) }
|
||||
func (a ByBLEMacSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a ByBLEMacSorter) Less(i, j int) bool {
|
||||
return a[i].Device.ID() < a[j].Device.ID()
|
||||
}
|
||||
|
||||
type ByBLESeenSorter []*network.BLEDevice
|
||||
|
||||
func (a ByBLESeenSorter) Len() int { return len(a) }
|
||||
func (a ByBLESeenSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a ByBLESeenSorter) Less(i, j int) bool { return a[i].LastSeen.Before(a[j].LastSeen) }
|
||||
|
|
|
@ -24,8 +24,20 @@ var (
|
|||
)
|
||||
|
||||
func (mod *BLERecon) getRow(dev *network.BLEDevice) []string {
|
||||
// ref. https://www.metageek.com/training/resources/understanding-rssi-2.html
|
||||
rssi := fmt.Sprintf("%d dBm", dev.RSSI)
|
||||
if dev.RSSI >= -67 {
|
||||
rssi = tui.Green(rssi)
|
||||
} else if dev.RSSI >= -70 {
|
||||
rssi = tui.Dim(tui.Green(rssi))
|
||||
} else if dev.RSSI >= -80 {
|
||||
rssi = tui.Yellow(rssi)
|
||||
} else {
|
||||
rssi = tui.Dim(tui.Red(rssi))
|
||||
}
|
||||
|
||||
address := network.NormalizeMac(dev.Device.ID())
|
||||
vendor := dev.Vendor
|
||||
vendor := tui.Dim(dev.Vendor)
|
||||
sinceSeen := time.Since(dev.LastSeen)
|
||||
lastSeen := dev.LastSeen.Format("15:04:05")
|
||||
|
||||
|
@ -36,13 +48,13 @@ func (mod *BLERecon) getRow(dev *network.BLEDevice) []string {
|
|||
address = tui.Dim(address)
|
||||
}
|
||||
|
||||
isConnectable := tui.Red("no")
|
||||
isConnectable := tui.Red("✖")
|
||||
if dev.Advertisement.Connectable {
|
||||
isConnectable = tui.Green("yes")
|
||||
isConnectable = tui.Green("✔")
|
||||
}
|
||||
|
||||
return []string{
|
||||
fmt.Sprintf("%d dBm", dev.RSSI),
|
||||
rssi,
|
||||
address,
|
||||
dev.Device.Name(),
|
||||
vendor,
|
||||
|
@ -51,24 +63,88 @@ func (mod *BLERecon) getRow(dev *network.BLEDevice) []string {
|
|||
}
|
||||
}
|
||||
|
||||
func (mod *BLERecon) Show() error {
|
||||
devices := mod.Session.BLE.Devices()
|
||||
func (mod *BLERecon) doFilter(dev *network.BLEDevice) bool {
|
||||
if mod.selector.Expression == nil {
|
||||
return true
|
||||
}
|
||||
return mod.selector.Expression.MatchString(dev.Device.ID()) ||
|
||||
mod.selector.Expression.MatchString(dev.Device.Name()) ||
|
||||
mod.selector.Expression.MatchString(dev.Vendor)
|
||||
}
|
||||
|
||||
sort.Sort(ByBLERSSISorter(devices))
|
||||
func (mod *BLERecon) doSelection() (err error, devices []*network.BLEDevice) {
|
||||
if err = mod.selector.Update(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
devices = mod.Session.BLE.Devices()
|
||||
filtered := []*network.BLEDevice{}
|
||||
for _, dev := range devices {
|
||||
if mod.doFilter(dev) {
|
||||
filtered = append(filtered, dev)
|
||||
}
|
||||
}
|
||||
devices = filtered
|
||||
|
||||
switch mod.selector.SortField {
|
||||
case "mac":
|
||||
sort.Sort(ByBLEMacSorter(devices))
|
||||
case "seen":
|
||||
sort.Sort(ByBLESeenSorter(devices))
|
||||
default:
|
||||
sort.Sort(ByBLERSSISorter(devices))
|
||||
}
|
||||
|
||||
// default is asc
|
||||
if mod.selector.Sort == "desc" {
|
||||
// from https://github.com/golang/go/wiki/SliceTricks
|
||||
for i := len(devices)/2 - 1; i >= 0; i-- {
|
||||
opp := len(devices) - 1 - i
|
||||
devices[i], devices[opp] = devices[opp], devices[i]
|
||||
}
|
||||
}
|
||||
|
||||
if mod.selector.Limit > 0 {
|
||||
limit := mod.selector.Limit
|
||||
max := len(devices)
|
||||
if limit > max {
|
||||
limit = max
|
||||
}
|
||||
devices = devices[0:limit]
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (mod *BLERecon) colNames() []string {
|
||||
colNames := []string{"RSSI", "MAC", "Name", "Vendor", "Connectable", "Seen"}
|
||||
switch mod.selector.SortField {
|
||||
case "rssi":
|
||||
colNames[0] += " " + mod.selector.SortSymbol
|
||||
case "mac":
|
||||
colNames[1] += " " + mod.selector.SortSymbol
|
||||
case "seen":
|
||||
colNames[5] += " " + mod.selector.SortSymbol
|
||||
}
|
||||
return colNames
|
||||
}
|
||||
|
||||
func (mod *BLERecon) Show() error {
|
||||
err, devices := mod.doSelection()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rows := make([][]string, 0)
|
||||
for _, dev := range devices {
|
||||
rows = append(rows, mod.getRow(dev))
|
||||
}
|
||||
nrows := len(rows)
|
||||
|
||||
columns := []string{"RSSI", "Address", "Name", "Vendor", "Connectable", "Last Seen"}
|
||||
|
||||
if nrows > 0 {
|
||||
tui.Table(os.Stdout, columns, rows)
|
||||
if len(rows) > 0 {
|
||||
tui.Table(os.Stdout, mod.colNames(), rows)
|
||||
mod.Session.Refresh()
|
||||
}
|
||||
|
||||
mod.Session.Refresh()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue