#!/usr/bin/python from __future__ import print_function from copy import deepcopy import io import json import socket import subprocess import time import string import StringIO class BatmanParser: batadv_vis = 'batadv-vis' mactranslation = string.maketrans('2367abef', '014589cd') def __str__(self): return 'BatmanParser \'{0}\''.format(self.batadv_vis) def sanitycheck(self): testdata = None try: testdata = subprocess.check_output([self.batadv_vis, '-f', 'jsondoc']) except Exception as err: raise Exception("batadv-vis not found or incompatible: " + str(err)) try: check = json.loads(testdata) except Exception as err: raise Exception("batadv-vis does not return valid JSON data: " + str(err)) return True def mac2id(self, mac): temp = str(mac.lower().replace(':', '')) # temp = temp[0] + temp[1].translate(self.mactranslation) + temp[2:] return temp def fetch(self, batadv_dump=None, include_rawdata=False): data = { } ts = int(time.time()) rawdata = subprocess.check_output([self.batadv_vis, '-f', 'jsondoc']) batmandata = json.loads(rawdata) if not batadv_dump is None: jsondata = json.dumps(batmandata, ensure_ascii=False) f = io.open(batadv_dump, 'w') f.write(rawdata) f.close() for item in batmandata['vis']: itemid = self.mac2id(item['primary']) aliases = [] if 'secondary' in item: for mac in item['secondary']: aliases.append(self.mac2id(mac)) neighbours = {} if 'neighbors' in item: for neighbour in item['neighbors']: if neighbour['router'] != item['primary']: #print('node {0}\'s neighbor {1} has unexpected router {2}'.format(itemid, neighbour['neighbor'], neighbour['router'])) neighbours[self.mac2id(neighbour['neighbor'])] = float(neighbour['metric']) data[itemid] = { 'aliases': aliases, 'neighbours': neighbours, 'clients': [ self.mac2id(x) for x in item['clients'] ] if 'clients' in item else [], } return data if __name__ == "__main__": b = BatmanParser() try: b.sanitycheck() except Exception as err: print('SANITY-CHECK failed:', str(err)) import sys sys.exit(1) data = b.fetch() print(json.dumps(data))