mirror of
https://github.com/bettercap/bettercap
synced 2025-08-19 04:59:25 -07:00
refact: big refactoring and improvements of wifi.* modules
This commit is contained in:
parent
d0d3ce3ec7
commit
da5d1d46d4
6 changed files with 266 additions and 123 deletions
|
@ -19,31 +19,30 @@ func (s EventsStream) viewLogEvent(e session.Event) {
|
|||
e.Data.(session.LogMessage).Message)
|
||||
}
|
||||
|
||||
func (s EventsStream) viewStationEvent(e session.Event) {
|
||||
st := e.Data.(*network.Station)
|
||||
func (s EventsStream) viewApEvent(e session.Event) {
|
||||
ap := e.Data.(*network.AccessPoint)
|
||||
vend := ""
|
||||
if st.Vendor != "" {
|
||||
vend = fmt.Sprintf(" (%s)", st.Vendor)
|
||||
if ap.Vendor != "" {
|
||||
vend = fmt.Sprintf(" (%s)", ap.Vendor)
|
||||
}
|
||||
|
||||
if e.Tag == "wifi.station.new" {
|
||||
fmt.Printf("[%s] WiFi station %s detected as %s%s.\n",
|
||||
if e.Tag == "wifi.ap.new" {
|
||||
fmt.Printf("[%s] WiFi access point %s detected as %s%s.\n",
|
||||
e.Time.Format(eventTimeFormat),
|
||||
core.Bold(st.ESSID()),
|
||||
core.Green(st.BSSID()),
|
||||
core.Bold(ap.ESSID()),
|
||||
core.Green(ap.BSSID()),
|
||||
vend)
|
||||
} else if e.Tag == "wifi.station.lost" {
|
||||
fmt.Printf("[%s] WiFi station %s (%s) lost.\n",
|
||||
} else if e.Tag == "wifi.ap.lost" {
|
||||
fmt.Printf("[%s] WiFi access point %s (%s) lost.\n",
|
||||
e.Time.Format(eventTimeFormat),
|
||||
core.Red(st.ESSID()),
|
||||
st.BSSID())
|
||||
core.Red(ap.ESSID()),
|
||||
ap.BSSID())
|
||||
} else {
|
||||
fmt.Printf("[%s] [%s] %s\n",
|
||||
e.Time.Format(eventTimeFormat),
|
||||
core.Green(e.Tag),
|
||||
st)
|
||||
ap)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s EventsStream) viewEndpointEvent(e session.Event) {
|
||||
|
@ -101,8 +100,8 @@ func (s *EventsStream) View(e session.Event, refresh bool) {
|
|||
s.viewLogEvent(e)
|
||||
} else if strings.HasPrefix(e.Tag, "endpoint.") {
|
||||
s.viewEndpointEvent(e)
|
||||
} else if strings.HasPrefix(e.Tag, "wifi.station.") {
|
||||
s.viewStationEvent(e)
|
||||
} else if strings.HasPrefix(e.Tag, "wifi.ap.") {
|
||||
s.viewApEvent(e)
|
||||
} else if strings.HasPrefix(e.Tag, "mod.") {
|
||||
s.viewModuleEvent(e)
|
||||
} else if strings.HasPrefix(e.Tag, "net.sniff.") {
|
||||
|
|
|
@ -31,14 +31,16 @@ type WiFiRecon struct {
|
|||
handle *pcap.Handle
|
||||
channel int
|
||||
frequencies []int
|
||||
apBSSID net.HardwareAddr
|
||||
ap *network.AccessPoint
|
||||
stickChan int
|
||||
}
|
||||
|
||||
func NewWiFiRecon(s *session.Session) *WiFiRecon {
|
||||
w := &WiFiRecon{
|
||||
SessionModule: session.NewSessionModule("wifi.recon", s),
|
||||
channel: 0,
|
||||
apBSSID: nil,
|
||||
stickChan: 0,
|
||||
ap: nil,
|
||||
}
|
||||
|
||||
w.AddHandler(session.NewModuleHandler("wifi.recon on", "",
|
||||
|
@ -56,41 +58,33 @@ func NewWiFiRecon(s *session.Session) *WiFiRecon {
|
|||
w.AddHandler(session.NewModuleHandler("wifi.recon MAC", "wifi.recon ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2}))",
|
||||
"Set 802.11 base station address to filter for.",
|
||||
func(args []string) error {
|
||||
var err error
|
||||
w.Session.WiFi.Clear()
|
||||
w.apBSSID, err = net.ParseMAC(args[0])
|
||||
bssid, err := net.ParseMAC(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
} else if ap, found := w.Session.WiFi.Get(bssid.String()); found == true {
|
||||
w.ap = ap
|
||||
w.stickChan = mhz2chan(ap.Frequency)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Could not find station with BSSID %s", args[0])
|
||||
}))
|
||||
|
||||
w.AddHandler(session.NewModuleHandler("wifi.recon clear", "",
|
||||
"Remove the 802.11 base station filter.",
|
||||
func(args []string) error {
|
||||
w.Session.WiFi.Clear()
|
||||
w.apBSSID = nil
|
||||
w.ap = nil
|
||||
w.stickChan = 0
|
||||
return nil
|
||||
}))
|
||||
|
||||
w.AddHandler(session.NewModuleHandler("wifi.deauth AP-BSSID TARGET-BSSID", `wifi\.deauth ([a-fA-F0-9\s:]+)`,
|
||||
"Start a 802.11 deauth attack, while the AP-BSSID is mandatory, if no TARGET-BSSID is specified the deauth will be executed against every connected client.",
|
||||
w.AddHandler(session.NewModuleHandler("wifi.deauth AP-BSSID TARGET-BSSID", `wifi\.deauth ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2}))`,
|
||||
"Start a 802.11 deauth attack, if an access point BSSID is provided, every client will be deauthenticated, otherwise only the selected client.",
|
||||
func(args []string) error {
|
||||
err := (error)(nil)
|
||||
apMac := (net.HardwareAddr)(nil)
|
||||
clMac := (net.HardwareAddr)(nil)
|
||||
parts := strings.SplitN(args[0], " ", 2)
|
||||
|
||||
if len(parts) == 2 {
|
||||
if apMac, err = net.ParseMAC(parts[0]); err != nil {
|
||||
return err
|
||||
} else if clMac, err = net.ParseMAC(parts[1]); err != nil {
|
||||
bssid, err := net.ParseMAC(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if apMac, err = net.ParseMAC(parts[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return w.startDeauth(apMac, clMac)
|
||||
return w.startDeauth(bssid)
|
||||
}))
|
||||
|
||||
w.AddHandler(session.NewModuleHandler("wifi.show", "",
|
||||
|
@ -115,7 +109,7 @@ func (w WiFiRecon) Description() string {
|
|||
}
|
||||
|
||||
func (w WiFiRecon) Author() string {
|
||||
return "Gianluca Braga <matrix86@protonmail.com>"
|
||||
return "Gianluca Braga <matrix86@protonmail.com> && Simone Margaritelli <evilsocket@protonmail.com>>"
|
||||
}
|
||||
|
||||
func (w *WiFiRecon) getRow(station *network.Station) []string {
|
||||
|
@ -164,6 +158,11 @@ func (w *WiFiRecon) getRow(station *network.Station) []string {
|
|||
seen,
|
||||
}
|
||||
} else {
|
||||
// this is ugly, but necessary in order to have this
|
||||
// method handle both access point and clients
|
||||
// transparently
|
||||
ap, _ := w.Session.WiFi.Get(station.HwAddress)
|
||||
|
||||
return []string{
|
||||
fmt.Sprintf("%d dBm", station.RSSI),
|
||||
bssid,
|
||||
|
@ -171,6 +170,7 @@ func (w *WiFiRecon) getRow(station *network.Station) []string {
|
|||
station.Vendor,
|
||||
encryption,
|
||||
strconv.Itoa(mhz2chan(station.Frequency)),
|
||||
strconv.Itoa(ap.NumClients()),
|
||||
sent,
|
||||
recvd,
|
||||
seen,
|
||||
|
@ -200,11 +200,23 @@ func (w *WiFiRecon) showTable(header []string, rows [][]string) {
|
|||
}
|
||||
|
||||
func (w *WiFiRecon) isApSelected() bool {
|
||||
return w.apBSSID != nil
|
||||
return w.ap != nil
|
||||
}
|
||||
|
||||
func (w *WiFiRecon) Show(by string) error {
|
||||
stations := w.Session.WiFi.List()
|
||||
var stations []*network.Station
|
||||
|
||||
apSelected := w.isApSelected()
|
||||
if apSelected {
|
||||
if ap, found := w.Session.WiFi.Get(w.ap.HwAddress); found == true {
|
||||
stations = ap.Clients()
|
||||
} else {
|
||||
return fmt.Errorf("Could not find station %s", w.ap.HwAddress)
|
||||
}
|
||||
} else {
|
||||
stations = w.Session.WiFi.Stations()
|
||||
}
|
||||
|
||||
if by == "seen" {
|
||||
sort.Sort(ByWiFiSeenSorter(stations))
|
||||
} else if by == "essid" {
|
||||
|
@ -221,15 +233,15 @@ func (w *WiFiRecon) Show(by string) error {
|
|||
}
|
||||
nrows := len(rows)
|
||||
|
||||
columns := []string{"RSSI", "BSSID", "SSID", "Vendor", "Encryption", "Channel", "Sent", "Recvd", "Last Seen"}
|
||||
if w.isApSelected() {
|
||||
columns := []string{"RSSI", "BSSID", "SSID", "Vendor", "Encryption", "Channel", "Clients", "Sent", "Recvd", "Last Seen"}
|
||||
if apSelected {
|
||||
// these are clients
|
||||
columns = []string{"RSSI", "MAC", "Vendor", "Channel", "Sent", "Received", "Last Seen"}
|
||||
|
||||
if nrows == 0 {
|
||||
fmt.Printf("\nNo authenticated clients detected for %s.\n", w.apBSSID.String())
|
||||
fmt.Printf("\nNo authenticated clients detected for %s.\n", w.ap.HwAddress)
|
||||
} else {
|
||||
fmt.Printf("\n%s clients:\n", w.apBSSID.String())
|
||||
fmt.Printf("\n%s clients:\n", w.ap.HwAddress)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +317,20 @@ func (w *WiFiRecon) sendDeauthPacket(ap net.HardwareAddr, client net.HardwareAdd
|
|||
}
|
||||
}
|
||||
|
||||
func (w *WiFiRecon) startDeauth(apMac net.HardwareAddr, clMac net.HardwareAddr) error {
|
||||
func (w *WiFiRecon) onChannel(channel int, cb func()) {
|
||||
prev := w.stickChan
|
||||
w.stickChan = channel
|
||||
|
||||
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
|
||||
log.Warning("Error while hopping to channel %d: %s", channel, err)
|
||||
}
|
||||
|
||||
cb()
|
||||
|
||||
w.stickChan = prev
|
||||
}
|
||||
|
||||
func (w *WiFiRecon) startDeauth(to net.HardwareAddr) error {
|
||||
// if not already running, temporarily enable the pcap handle
|
||||
// for packet injection
|
||||
if w.Running() == false {
|
||||
|
@ -315,21 +340,34 @@ func (w *WiFiRecon) startDeauth(apMac net.HardwareAddr, clMac net.HardwareAddr)
|
|||
defer w.handle.Close()
|
||||
}
|
||||
|
||||
// deauth a specific client
|
||||
if clMac != nil {
|
||||
log.Info("Deauthing client %s from AP %s ...", clMac.String(), apMac.String())
|
||||
w.sendDeauthPacket(apMac, clMac)
|
||||
} else {
|
||||
log.Info("Deauthing clients from AP %s ...", apMac.String())
|
||||
// deauth every authenticated client
|
||||
for _, station := range w.Session.WiFi.List() {
|
||||
if station.IsAP == false {
|
||||
w.sendDeauthPacket(apMac, station.HW)
|
||||
bssid := to.String()
|
||||
|
||||
// are we deauthing every client of a given access point?
|
||||
if ap, found := w.Session.WiFi.Get(bssid); found == true {
|
||||
clients := ap.Clients()
|
||||
log.Info("Deauthing %d clients from AP %s ...", len(clients), ap.ESSID())
|
||||
w.onChannel(mhz2chan(ap.Frequency), func() {
|
||||
for _, c := range clients {
|
||||
w.sendDeauthPacket(ap.HW, c.HW)
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// search for a client
|
||||
aps := w.Session.WiFi.List()
|
||||
for _, ap := range aps {
|
||||
if c, found := ap.Get(bssid); found == true {
|
||||
log.Info("Deauthing client %s from AP %s ...", c.HwAddress, ap.ESSID())
|
||||
w.onChannel(mhz2chan(ap.Frequency), func() {
|
||||
w.sendDeauthPacket(ap.HW, c.HW)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return fmt.Errorf("%s is an unknown BSSID.", bssid)
|
||||
}
|
||||
|
||||
func (w *WiFiRecon) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||
|
@ -337,17 +375,17 @@ func (w *WiFiRecon) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layer
|
|||
if ok, ssid := packets.Dot11ParseIDSSID(packet); ok == true {
|
||||
bssid := dot11.Address3.String()
|
||||
frequency := int(radiotap.ChannelFrequency)
|
||||
w.Session.WiFi.AddIfNew(ssid, bssid, true, frequency, radiotap.DBMAntennaSignal)
|
||||
w.Session.WiFi.AddIfNew(ssid, bssid, frequency, radiotap.DBMAntennaSignal)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WiFiRecon) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, ap net.HardwareAddr, packet gopacket.Packet) {
|
||||
func (w *WiFiRecon) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||
w.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) {
|
||||
// packet going to this specific BSSID?
|
||||
if packets.Dot11IsDataFor(dot11, ap) == true {
|
||||
src := dot11.Address2
|
||||
frequency := int(radiotap.ChannelFrequency)
|
||||
w.Session.WiFi.AddIfNew("", src.String(), false, frequency, radiotap.DBMAntennaSignal)
|
||||
if packets.Dot11IsDataFor(dot11, ap.HW) == true {
|
||||
ap.AddClient(dot11.Address2.String(), int(radiotap.ChannelFrequency), radiotap.DBMAntennaSignal)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (w *WiFiRecon) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||
|
@ -387,6 +425,12 @@ func (w *WiFiRecon) channelHopper() {
|
|||
|
||||
for _, frequency := range w.frequencies {
|
||||
channel := mhz2chan(frequency)
|
||||
// stick to the access point channel as long as it's selected
|
||||
// or as long as we're deauthing on it
|
||||
if w.stickChan != 0 {
|
||||
channel = w.stickChan
|
||||
}
|
||||
|
||||
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
|
||||
log.Warning("Error while hopping to channel %d: %s", channel, err)
|
||||
}
|
||||
|
@ -438,15 +482,9 @@ func (w *WiFiRecon) Start() error {
|
|||
|
||||
// perform initial dot11 parsing and layers validation
|
||||
if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok == true {
|
||||
// keep collecting traffic statistics
|
||||
w.updateStats(dot11, packet)
|
||||
// no access point bssid selected, keep scanning for other aps
|
||||
if w.isApSelected() == false {
|
||||
w.discoverAccessPoints(radiotap, dot11, packet)
|
||||
} else {
|
||||
// discover stations connected to the selected access point bssid
|
||||
w.discoverClients(radiotap, dot11, w.apBSSID, packet)
|
||||
}
|
||||
w.discoverClients(radiotap, dot11, packet)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -6,25 +6,25 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type StationNewCallback func(s *Station)
|
||||
type StationLostCallback func(s *Station)
|
||||
type APNewCallback func(ap *AccessPoint)
|
||||
type APLostCallback func(ap *AccessPoint)
|
||||
|
||||
type WiFi struct {
|
||||
sync.Mutex
|
||||
|
||||
stations map[string]*Station
|
||||
aps map[string]*AccessPoint
|
||||
iface *Endpoint
|
||||
newCb StationNewCallback
|
||||
lostCb StationLostCallback
|
||||
newCb APNewCallback
|
||||
lostCb APLostCallback
|
||||
}
|
||||
|
||||
type wifiJSON struct {
|
||||
Stations []*Station `json:"stations"`
|
||||
AccessPoints []*AccessPoint `json:"aps"`
|
||||
}
|
||||
|
||||
func NewWiFi(iface *Endpoint, newcb StationNewCallback, lostcb StationLostCallback) *WiFi {
|
||||
func NewWiFi(iface *Endpoint, newcb APNewCallback, lostcb APLostCallback) *WiFi {
|
||||
return &WiFi{
|
||||
stations: make(map[string]*Station),
|
||||
aps: make(map[string]*AccessPoint),
|
||||
iface: iface,
|
||||
newCb: newcb,
|
||||
lostCb: lostcb,
|
||||
|
@ -33,23 +33,43 @@ func NewWiFi(iface *Endpoint, newcb StationNewCallback, lostcb StationLostCallba
|
|||
|
||||
func (w *WiFi) MarshalJSON() ([]byte, error) {
|
||||
doc := wifiJSON{
|
||||
Stations: make([]*Station, 0),
|
||||
AccessPoints: make([]*AccessPoint, 0),
|
||||
}
|
||||
|
||||
for _, s := range w.stations {
|
||||
doc.Stations = append(doc.Stations, s)
|
||||
for _, ap := range w.aps {
|
||||
doc.AccessPoints = append(doc.AccessPoints, ap)
|
||||
}
|
||||
|
||||
return json.Marshal(doc)
|
||||
}
|
||||
|
||||
func (w *WiFi) List() (list []*Station) {
|
||||
func (w *WiFi) EachAccessPoint(cb func(mac string, ap *AccessPoint)) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
for m, ap := range w.aps {
|
||||
cb(m, ap)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WiFi) Stations() (list []*Station) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
list = make([]*Station, 0)
|
||||
for _, t := range w.stations {
|
||||
list = append(list, t)
|
||||
for _, ap := range w.aps {
|
||||
list = append(list, ap.Station)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *WiFi) List() (list []*AccessPoint) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
list = make([]*AccessPoint, 0)
|
||||
for _, ap := range w.aps {
|
||||
list = append(list, ap)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -58,45 +78,45 @@ func (w *WiFi) Remove(mac string) {
|
|||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
if s, found := w.stations[mac]; found {
|
||||
delete(w.stations, mac)
|
||||
if ap, found := w.aps[mac]; found {
|
||||
delete(w.aps, mac)
|
||||
if w.lostCb != nil {
|
||||
w.lostCb(s)
|
||||
w.lostCb(ap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WiFi) AddIfNew(ssid, mac string, isAp bool, frequency int, rssi int8) *Station {
|
||||
func (w *WiFi) AddIfNew(ssid, mac string, frequency int, rssi int8) *AccessPoint {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
mac = NormalizeMac(mac)
|
||||
if station, found := w.stations[mac]; found {
|
||||
station.LastSeen = time.Now()
|
||||
station.RSSI = rssi
|
||||
return station
|
||||
if ap, found := w.aps[mac]; found {
|
||||
ap.LastSeen = time.Now()
|
||||
ap.RSSI = rssi
|
||||
return ap
|
||||
}
|
||||
|
||||
newStation := NewStation(ssid, mac, isAp, frequency, rssi)
|
||||
w.stations[mac] = newStation
|
||||
newAp := NewAccessPoint(ssid, mac, frequency, rssi)
|
||||
w.aps[mac] = newAp
|
||||
|
||||
if w.newCb != nil {
|
||||
w.newCb(newStation)
|
||||
w.newCb(newAp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *WiFi) Get(mac string) (*Station, bool) {
|
||||
func (w *WiFi) Get(mac string) (*AccessPoint, bool) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
mac = NormalizeMac(mac)
|
||||
station, found := w.stations[mac]
|
||||
return station, found
|
||||
ap, found := w.aps[mac]
|
||||
return ap, found
|
||||
}
|
||||
|
||||
func (w *WiFi) Clear() error {
|
||||
w.stations = make(map[string]*Station)
|
||||
w.aps = make(map[string]*AccessPoint)
|
||||
return nil
|
||||
}
|
||||
|
|
88
network/wifi_ap.go
Normal file
88
network/wifi_ap.go
Normal file
|
@ -0,0 +1,88 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AccessPoint struct {
|
||||
*Station
|
||||
sync.Mutex
|
||||
|
||||
clients map[string]*Station
|
||||
}
|
||||
|
||||
type apJSON struct {
|
||||
*Station
|
||||
Clients []*Station `json:"clients"`
|
||||
}
|
||||
|
||||
func NewAccessPoint(essid, bssid string, frequency int, rssi int8) *AccessPoint {
|
||||
return &AccessPoint{
|
||||
Station: NewStation(essid, bssid, frequency, rssi),
|
||||
clients: make(map[string]*Station),
|
||||
}
|
||||
}
|
||||
|
||||
func (ap *AccessPoint) MarshalJSON() ([]byte, error) {
|
||||
doc := apJSON{
|
||||
Station: ap.Station,
|
||||
Clients: make([]*Station, 0),
|
||||
}
|
||||
|
||||
for _, c := range ap.clients {
|
||||
doc.Clients = append(doc.Clients, c)
|
||||
}
|
||||
|
||||
return json.Marshal(doc)
|
||||
}
|
||||
|
||||
func (ap *AccessPoint) Get(bssid string) (*Station, bool) {
|
||||
ap.Lock()
|
||||
defer ap.Unlock()
|
||||
|
||||
bssid = NormalizeMac(bssid)
|
||||
if s, found := ap.clients[bssid]; found == true {
|
||||
return s, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (ap *AccessPoint) AddClient(bssid string, frequency int, rssi int8) *Station {
|
||||
ap.Lock()
|
||||
defer ap.Unlock()
|
||||
|
||||
bssid = NormalizeMac(bssid)
|
||||
|
||||
if s, found := ap.clients[bssid]; found == true {
|
||||
// update
|
||||
s.Frequency = frequency
|
||||
s.RSSI = rssi
|
||||
s.LastSeen = time.Now()
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
s := NewStation("", bssid, frequency, rssi)
|
||||
ap.clients[bssid] = s
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (ap *AccessPoint) NumClients() int {
|
||||
ap.Lock()
|
||||
defer ap.Unlock()
|
||||
return len(ap.clients)
|
||||
}
|
||||
|
||||
func (ap *AccessPoint) Clients() (list []*Station) {
|
||||
ap.Lock()
|
||||
defer ap.Unlock()
|
||||
|
||||
list = make([]*Station, 0)
|
||||
for _, c := range ap.clients {
|
||||
list = append(list, c)
|
||||
}
|
||||
return
|
||||
}
|
|
@ -2,18 +2,16 @@ package network
|
|||
|
||||
type Station struct {
|
||||
*Endpoint
|
||||
IsAP bool
|
||||
Frequency int
|
||||
RSSI int8
|
||||
Sent uint64
|
||||
Received uint64
|
||||
Encryption string
|
||||
Frequency int `json:"frequency"`
|
||||
RSSI int8 `json:"rssi"`
|
||||
Sent uint64 `json:"sent"`
|
||||
Received uint64 `json:"received"`
|
||||
Encryption string `json:"encryption"`
|
||||
}
|
||||
|
||||
func NewStation(essid, bssid string, isAp bool, frequency int, rssi int8) *Station {
|
||||
func NewStation(essid, bssid string, frequency int, rssi int8) *Station {
|
||||
return &Station{
|
||||
Endpoint: NewEndpointNoResolve(MonitorModeAddress, bssid, essid, 0),
|
||||
IsAP: isAp,
|
||||
Frequency: frequency,
|
||||
RSSI: rssi,
|
||||
}
|
||||
|
|
|
@ -378,10 +378,10 @@ func (s *Session) Start() error {
|
|||
|
||||
s.Firewall = firewall.Make(s.Interface)
|
||||
|
||||
s.WiFi = network.NewWiFi(s.Interface, func(st *network.Station) {
|
||||
s.Events.Add("wifi.station.new", st)
|
||||
}, func(st *network.Station) {
|
||||
s.Events.Add("wifi.station.lost", st)
|
||||
s.WiFi = network.NewWiFi(s.Interface, func(ap *network.AccessPoint) {
|
||||
s.Events.Add("wifi.ap.new", ap)
|
||||
}, func(ap *network.AccessPoint) {
|
||||
s.Events.Add("wifi.ap.lost", ap)
|
||||
})
|
||||
|
||||
s.Lan = network.NewLAN(s.Interface, s.Gateway, func(e *network.Endpoint) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue