batman.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/python
  2. from __future__ import print_function
  3. from copy import deepcopy
  4. import io
  5. import json
  6. import socket
  7. import subprocess
  8. import time
  9. import string
  10. import StringIO
  11. class BatmanParser:
  12. batadv_vis = 'batadv-vis'
  13. mactranslation = string.maketrans('2367abef', '014589cd')
  14. def __str__(self):
  15. return 'BatmanParser \'{0}\''.format(self.batadv_vis)
  16. def sanitycheck(self):
  17. testdata = None
  18. try:
  19. testdata = subprocess.check_output([self.batadv_vis, '-f', 'jsondoc'])
  20. except Exception as err:
  21. raise Exception("batadv-vis not found or incompatible: " + str(err))
  22. try:
  23. check = json.loads(testdata)
  24. except Exception as err:
  25. raise Exception("batadv-vis does not return valid JSON data: " + str(err))
  26. return True
  27. def mac2id(self, mac):
  28. temp = str(mac.lower().replace(':', ''))
  29. # temp = temp[0] + temp[1].translate(self.mactranslation) + temp[2:]
  30. return temp
  31. def fetch(self, batadv_dump=None, include_rawdata=False):
  32. data = { }
  33. ts = int(time.time())
  34. rawdata = subprocess.check_output([self.batadv_vis, '-f', 'jsondoc'])
  35. batmandata = json.loads(rawdata)
  36. if not batadv_dump is None:
  37. jsondata = json.dumps(batmandata, ensure_ascii=False)
  38. f = io.open(batadv_dump, 'w')
  39. f.write(rawdata)
  40. f.close()
  41. for item in batmandata['vis']:
  42. itemid = self.mac2id(item['primary'])
  43. aliases = []
  44. if 'secondary' in item:
  45. for mac in item['secondary']:
  46. aliases.append(self.mac2id(mac))
  47. neighbours = {}
  48. if 'neighbors' in item:
  49. for neighbour in item['neighbors']:
  50. #if neighbour['router'] != item['primary']:
  51. # print('node {0}\'s neighbor {1} has unexpected router {2}'.format(itemid, neighbour['neighbor'], neighbour['router']))
  52. neighbours[self.mac2id(neighbour['neighbor'])] = float(neighbour['metric'])
  53. data[itemid] = {
  54. 'aliases': aliases,
  55. 'neighbours': neighbours,
  56. 'clients': [ self.mac2id(x) for x in item['clients'] ] if 'clients' in item else [],
  57. '__UPDATED__': { 'batadv': ts, },
  58. }
  59. return data
  60. if __name__ == "__main__":
  61. b = BatmanParser()
  62. try:
  63. b.sanitycheck()
  64. except Exception as err:
  65. print('SANITY-CHECK failed:', str(err))
  66. import sys
  67. sys.exit(1)
  68. data = b.fetch()
  69. print(json.dumps(data))