1""" 2Shows 802.11 wireless beacons and related information 3""" 4 5from collections import defaultdict 6from datetime import datetime 7 8import dshell.core 9from dshell.output.output import Output 10 11class DshellPlugin(dshell.core.PacketPlugin): 12 13 OUTPUT_FORMAT = "[%(plugin)s]\t%(dt)s\tInterval: %(interval)s TU,\tSSID: %(ssid)s\t%(count)s\n" 14 15 def __init__(self, *args, **kwargs): 16 super().__init__( 17 name="Wi-fi Beacons", 18 description="Show SSIDs of 802.11 wireless beacons", 19 author="dev195", 20 bpf="wlan type mgt subtype beacon", 21 output=Output(label=__name__, format=self.OUTPUT_FORMAT), 22 optiondict={ 23 "group": {"action": "store_true", "help": "Group beacons together with counts"}, 24 } 25 ) 26 self.group_counts = defaultdict(int) 27 self.group_times = defaultdict(datetime.now) 28 29 def packet_handler(self, pkt): 30 # Extract 802.11 frame from packet 31 try: 32 frame = pkt.pkt.ieee80211 33 except AttributeError: 34 frame = pkt.pkt 35 36 # Confirm that packet is, in fact, a beacon 37 if not frame.is_beacon(): 38 return 39 40 # Extract SSID from frame 41 beacon = frame.beacon 42 ssid = "" 43 try: 44 for param in beacon.params: 45 # Find the SSID parameter 46 if param.id == 0: 47 ssid = param.body_bytes.decode("utf-8") 48 break 49 except IndexError: 50 # Sometimes pypacker fails to parse a packet 51 return 52 53 if self.group: 54 self.group_counts[(ssid, beacon.interval)] += 1 55 self.group_times[(ssid, beacon.interval)] = pkt.ts 56 else: 57 self.write(ssid=ssid, interval=beacon.interval, **pkt.info()) 58 59 return pkt 60 61 def postfile(self): 62 if self.group: 63 for key, val in self.group_counts.items(): 64 ssid, interval = key 65 dt = self.group_times[key] 66 self.write(ssid=ssid, interval=interval, plugin=self.name, dt=dt, count=val) 67