def _create_client_nodes(self, tx: Transaction, skipt_empty: bool): for client in Client.select(): if skipt_empty and not client.connections and not client.probe_reqs: continue client_data = to_dict(client) client_data.pop("mac") client_node = tx.evaluate( "MERGE (_:Client {mac:$mac}) SET _ += $client RETURN _", client=client_data, mac=self._parse_mac(client.mac)) for connection in client.connections: bss_data = to_dict(connection.bss) bss_data.pop("bssid") bss_node = tx.evaluate( "MERGE (_:BSS {bssid:$bssid}) SET _ += $bss RETURN _", bss=bss_data, bssid=self._parse_mac(connection.bss.bssid)) connection_rel = Relationship(client_node, "CONNECTED", bss_node, **to_dict(connection)) tx.create(connection_rel) for probe in client.probe_reqs: ess_data = to_dict(probe.ess) ess_node = tx.evaluate( "MERGE (_:ESS {ssid:$ssid}) SET _ += $ess RETURN _", ess=ess_data, ssid=probe.ess.ssid) announcement = Relationship(client_node, "PROBES", ess_node, **to_dict(probe)) tx.create(announcement)
def _create_bss_nodes(self, tx: Transaction): for bss in BasicServiceSet.select(): bss_data = to_dict(bss) bss_data.pop("bssid") bss_node = tx.evaluate( "MERGE (_:BSS {bssid:$bssid}) SET _ += $bss RETURN _", bss=bss_data, bssid=self._parse_mac(bss.bssid)) if bss.ess is not None: ess_data = to_dict(bss.ess) ess_node = tx.evaluate( "MERGE (_:ESS {ssid:$ssid}) SET _ += $ess RETURN _", ess=ess_data, ssid=bss.ess.ssid) announcement = Relationship(bss_node, "ANNOUNCES", ess_node) tx.create(announcement)
def _create_client_aggregated_nodes(self, tx: Transaction, skipt_empty: bool): agg_nodes = dict() for client in Client.select(): if skipt_empty and not client.connections and not client.probe_reqs: continue if not client.connections: # Only export single clients when they have connections probes = frozenset(probe.ess.ssid for probe in client.probe_reqs) agg_node = agg_nodes.get(probes, list()) agg_node.append(client) agg_nodes[probes] = agg_node continue client_data = to_dict(client) client_data.pop("mac") client_node = tx.evaluate( "MERGE (_:Client {mac:$mac}) SET _ += $client RETURN _", client=client_data, mac=self._parse_mac(client.mac)) for connection in client.connections: bss_data = to_dict(connection.bss) bss_data.pop("bssid") bss_node = tx.evaluate( "MERGE (_:BSS {bssid:$bssid}) SET _ += $bss RETURN _", bss=bss_data, bssid=self._parse_mac(connection.bss.bssid)) connection_rel = Relationship(client_node, "CONNECTED", bss_node, **to_dict(connection)) tx.create(connection_rel) for probe in client.probe_reqs: ess_data = to_dict(probe.ess) ess_node = tx.evaluate( "MERGE (_:ESS {ssid:$ssid}) SET _ += $ess RETURN _", ess=ess_data, ssid=probe.ess.ssid) announcement = Relationship(client_node, "PROBES", ess_node, **to_dict(probe)) tx.create(announcement) for probe_ssids, clients in agg_nodes.items(): group_id = hash(probe_ssids) self.cmd.pfeedback( "[i] Aggregating {} clients probing for: {}".format( len(clients), ", ".join(probe_ssids))) client_data = { self._parse_mac(client.mac): True for client in clients } client_node = tx.evaluate( "MERGE (_:Client {group_id:$group_id}) SET _ += $client RETURN _", client=client_data, group_id=group_id) for probe_ssid in probe_ssids: ess_node = tx.evaluate("MERGE (_:ESS {ssid:$ssid}) RETURN _", ssid=probe_ssid) announcement = Relationship(client_node, "PROBES", ess_node) tx.create(announcement)
def _get_latest(self, tx: Transaction, sender_id: str): matcher = NodeMatcher(tx) query = matcher.match(sender_id).order_by( "_.created_at desc").limit(1)._query_and_parameters()[0] latest = tx.evaluate(query) return latest