"""Devices abstraction."""
from .base_interface import BaseInterface
[docs]class Devices(BaseInterface):
"""Devices abstraction."""
kwargs_defaults = {"ts": 0}
url_template = "devices/last-time/{ts}/devices.ekjson"
[docs] def all(self, callback=None, callback_args=None, **kwargs):
"""Yield all devices, one at a time.
If callback is set, nothing will be returned.
Args:
callback: Callback function.
callback_args: Arguments for callback.
Keyword args:
ts (int): Starting last-seen timestamp in seconds since Epoch.
Yield:
dict: Device json, or None if callback is set.
"""
callback_settings = {}
if callback:
callback_settings["callback"] = callback
if callback_args:
callback_settings["callback_args"] = callback_args
query_args = self.kwargs_defaults.copy()
query_args.update(kwargs)
url = self.url_template.format(**query_args)
for result in self.interact_yield("POST", url, **callback_settings):
yield result
[docs] def by_mac(self, callback=None, callback_args=None, **kwargs):
"""Yield devices matching provided MAC addresses or masked MAC groups.
Args:
callback: Callback function.
callback_args: Arguments for callback.
Keyword args:
devices (list): List of device MACs or MAC masks.
fields (list): List of fields to return.
Yield:
dict: Device json, or None if callback is set.
"""
call_settings = {}
if callback:
call_settings["callback"] = callback
if callback_args:
call_settings["callback_args"] = callback_args
valid_kwargs = ["fields", "devices"]
call_settings["payload"] = {kword: kwargs[kword]
for kword in valid_kwargs
if kword in kwargs}
url = "devices/multimac/devices.ekjson"
for result in self.interact_yield("POST", url, **call_settings):
yield result
[docs] def by_key(self, device_key, field=None, fields=None):
"""Return a dictionary representing one device, identified by ``key``.
Fetch a complete device record by the Kismet key (unique key per Kismet
session) or fetch a specific sub-field by path.
Return:
dict: Dictionary object describing one device.
"""
url = "devices/by-key/{}/device.json".format(device_key)
if not fields and field:
url = "{}/{}".format(url, field)
elif fields:
payload = {"fields": fields}
return self.interact("POST", url, payload=payload)
return self.interact("POST", url)
[docs] def dot11_clients_of(self, ap_id, callback=None, callback_args=None,
**kwargs):
"""List clients of an 802.11 AP.
List devices which are clients of a given 802.11 access point, using
the /phy/phy80211/clients-of endpoint.
Returned devices can be summarized/simplified by the fields list.
If a callback is given, it will be called for each device in the
result. If no callback is provided, the results will be yielded.
Args:
ap_id (str): ID of AP to return clients for.
callback: Callback function.
callback_args: Arguments for callback.
Yield:
dict: Dictionary describing a client of the identified AP.
"""
call_settings = {}
if callback:
call_settings["callback"] = callback
if callback_args:
call_settings["callback_args"] = callback_args
valid_kwargs = ["fields"]
call_settings["payload"] = {kword: kwargs[kword]
for kword in valid_kwargs
if kword in kwargs}
url = "phy/phy80211/clients-of/{}/clients.ekjson".format(ap_id)
for result in self.interact_yield("POST", url, **call_settings):
yield result
[docs] def dot11_access_points(self, callback=None, callback_args=None, **kwargs):
"""Return a list of dot11 access points.
List devices which are considered to be 802.11 access points, using the
/devices/views/phydot11_accesspoints/ view
Returned devices can be summarized/simplified by the fields list.
If a timestamp is given, only devices modified more recently than the
timestamp (and matching any other conditions) will be returned.
If a regex is given, only devices matching the regex (and any other
conditions) will be returned.
If a callback is given, it will be called for each device in the
result. If no callback is provided, the results will be yielded as
dictionary objects.
Args:
callback (obj): Callback for processing individual results.
cbargs (list): List of arguments for callback.
Keyword args:
last_time (int): Unix epoch timestamp
regex (str): Regular expression for filtering results.
fields (list): Fields for filtering.
Yield:
dict: Dictionary-type objects which describe access points.
Keys describing access points:
``dot11.device``,
``kismet.device.base.basic_crypt_set``,
``kismet.device.base.basic_type_set``,
``kismet.device.base.channel``,
``kismet.device.base.commonname``,
``kismet.device.base.crypt``,
``kismet.device.base.datasize``,
``kismet.device.base.datasize.rrd``,
``kismet.device.base.first_time``,
``kismet.device.base.freq_khz_map``,
``kismet.device.base.frequency``,
``kismet.device.base.key``,
``kismet.device.base.last_time``,
``kismet.device.base.macaddr``,
``kismet.device.base.manuf``,
``kismet.device.base.mod_time``,
``kismet.device.base.name``,
``kismet.device.base.num_alerts``,
``kismet.device.base.packet.bin.250``,
``kismet.device.base.packet.bin.500``,
``kismet.device.base.packets.crypt``,
``kismet.device.base.packets.data``,
``kismet.device.base.packets.error``,
``kismet.device.base.packets.filtered``,
``kismet.device.base.packets.llc``,
``kismet.device.base.packets.rrd``,
``kismet.device.base.packets.rx``,
``kismet.device.base.packets.total``,
``kismet.device.base.packets.tx``,
``kismet.device.base.phyname``,
``kismet.device.base.seenby``,
``kismet.device.base.server_uuid``,
``kismet.device.base.signal``,
``kismet.device.base.tags``,
``kismet.device.base.type``.
"""
valid_kwargs = ["last_time", "regex", "fields"]
url = "devices/views/phydot11_accesspoints/devices.ekjson"
call_settings = {}
if callback:
call_settings["callback"] = callback
if callback_args:
call_settings["callback_args"] = callback_args
call_settings["payload"] = {kword: kwargs[kword]
for kword in valid_kwargs
if kword in kwargs}
for result in self.interact_yield("POST", url, **call_settings):
yield result