Project

General

Profile

Bug #367 ยป neighbor_extend_dump.py

Sven Eckelmann, 12/18/2018 05:55 PM

 
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from pyroute2.common import map_namespace
from pyroute2.netlink import genlmsg
from pyroute2.netlink.generic import GenericNetlinkSocket
from pyroute2.netlink.nlsocket import Marshal
from pyroute2.netlink import NLM_F_REQUEST
from pyroute2.netlink import NLM_F_DUMP
from socket import if_nametoindex
from socket import if_indextoname


BATADV_CMD_UNSPEC = 0
BATADV_CMD_GET_MESH_INFO = 1
BATADV_CMD_TP_METER = 2
BATADV_CMD_TP_METER_CANCEL = 3
BATADV_CMD_GET_ROUTING_ALGOS = 4
BATADV_CMD_GET_HARDIFS = 5
BATADV_CMD_GET_TRANSTABLE_LOCAL = 6
BATADV_CMD_GET_TRANSTABLE_GLOBAL = 7
BATADV_CMD_GET_ORIGINATORS = 8
BATADV_CMD_GET_NEIGHBORS = 9
BATADV_CMD_GET_GATEWAYS = 10
BATADV_CMD_GET_BLA_CLAIM = 11
BATADV_CMD_GET_BLA_BACKBONE = 12
BATADV_CMD_GET_DAT_CACHE = 13
BATADV_CMD_GET_MCAST_FLAGS = 14
BATADV_CMD_MAX = BATADV_CMD_GET_MCAST_FLAGS

(BATADV_NAMES, BATADV_VALUES) = map_namespace('BATADV_CMD_', globals())


class batadvcmd(genlmsg):
prefix = 'BATADV_ATTR_'

'''
Message class that will be used to communicate
with the kernel module
'''
nla_map = (('BATADV_ATTR_UNSPEC', 'none'),
('BATADV_ATTR_VERSION', 'asciiz'),
('BATADV_ATTR_ALGO_NAME', 'asciiz'),
('BATADV_ATTR_MESH_IFINDEX', 'uint32'),
('BATADV_ATTR_MESH_IFNAME', 'asciiz'),
('BATADV_ATTR_MESH_ADDRESS', 'l2addr'),
('BATADV_ATTR_HARD_IFINDEX', 'uint32'),
('BATADV_ATTR_HARD_IFNAME', 'asciiz'),
('BATADV_ATTR_HARD_ADDRESS', 'l2addr'),
('BATADV_ATTR_ORIG_ADDRESS', 'l2addr'),
('BATADV_ATTR_TPMETER_RESULT', 'uint8'),
('BATADV_ATTR_TPMETER_TEST_TIME', 'uint32'),
('BATADV_ATTR_TPMETER_BYTES', 'uint64'),
('BATADV_ATTR_TPMETER_COOKIE', 'uint32'),
('BATADV_ATTR_PAD', 'none'),
('BATADV_ATTR_ACTIVE', 'flag'),
('BATADV_ATTR_TT_ADDRESS', 'l2addr'),
('BATADV_ATTR_TT_TTVN', 'uint8'),
('BATADV_ATTR_TT_LAST_TTVN', 'uint8'),
('BATADV_ATTR_TT_CRC32', 'uint32'),
('BATADV_ATTR_TT_VID', 'uint16'),
('BATADV_ATTR_TT_FLAGS', 'uint32'),
('BATADV_ATTR_FLAG_BEST', 'flag'),
('BATADV_ATTR_LAST_SEEN_MSECS', 'uint32'),
('BATADV_ATTR_NEIGH_ADDRESS', 'l2addr'),
('BATADV_ATTR_TQ', 'uint8'),
('BATADV_ATTR_THROUGHPUT', 'uint32'),
('BATADV_ATTR_BANDWIDTH_UP', 'uint32'),
('BATADV_ATTR_BANDWIDTH_DOWN', 'uint32'),
('BATADV_ATTR_ROUTER', 'l2addr'),
('BATADV_ATTR_BLA_OWN', 'flag'),
('BATADV_ATTR_BLA_ADDRESS', 'l2addr'),
('BATADV_ATTR_BLA_VID', 'uint16'),
('BATADV_ATTR_BLA_BACKBONE', 'l2addr'),
('BATADV_ATTR_BLA_CRC', 'uint16'),
('BATADV_ATTR_DAT_CACHE_IP4ADDRESS', 'ip4addr'),
('BATADV_ATTR_DAT_CACHE_HWADDRESS', 'l2addr'),
('BATADV_ATTR_DAT_CACHE_VID', 'uint16'),
('BATADV_ATTR_MCAST_FLAGS', 'uint32'),
('BATADV_ATTR_MCAST_FLAGS_PRIV', 'uint32'))


class MarshalBatadv(Marshal):
msg_map = {BATADV_CMD_UNSPEC: batadvcmd,
BATADV_CMD_GET_MESH_INFO: batadvcmd,
BATADV_CMD_TP_METER: batadvcmd,
BATADV_CMD_TP_METER_CANCEL: batadvcmd,
BATADV_CMD_GET_ROUTING_ALGOS: batadvcmd,
BATADV_CMD_GET_HARDIFS: batadvcmd,
BATADV_CMD_GET_TRANSTABLE_LOCAL: batadvcmd,
BATADV_CMD_GET_TRANSTABLE_GLOBAL: batadvcmd,
BATADV_CMD_GET_ORIGINATORS: batadvcmd,
BATADV_CMD_GET_NEIGHBORS: batadvcmd,
BATADV_CMD_GET_GATEWAYS: batadvcmd,
BATADV_CMD_GET_BLA_CLAIM: batadvcmd,
BATADV_CMD_GET_BLA_BACKBONE: batadvcmd,
BATADV_CMD_GET_DAT_CACHE: batadvcmd,
BATADV_CMD_GET_MCAST_FLAGS: batadvcmd}


class BatadvSocket(GenericNetlinkSocket):
def __init__(self):
GenericNetlinkSocket.__init__(self)
self.marshal = MarshalBatadv()

def bind(self, groups=0, **kwarg):
GenericNetlinkSocket.bind(self, 'batadv', batadvcmd,
groups, None, **kwarg)

class Batadv(BatadvSocket):

__meshif = 'bat0'
__meshif_index = 0

def __init__(self, *argv, **kwarg):
# continue with init
super(Batadv, self).__init__(*argv, **kwarg)

if 'meshif' in kwarg:
self.__meshif = kwarg.pop('meshif')

self.__meshif_index = if_nametoindex(self.__meshif)

try:
self.bind()
except:
super(Batadv, self).close()
raise

def get_neighbors(self):
msg = batadvcmd()
msg['cmd'] = BATADV_NAMES['BATADV_CMD_GET_NEIGHBORS']
msg['attrs'] = [
['BATADV_ATTR_MESH_IFINDEX', self.__meshif_index],
]

return self.nlm_request(msg,
msg_type=self.prid,
msg_flags=NLM_F_REQUEST | NLM_F_DUMP)

def get_originators(self):
msg = batadvcmd()
msg['cmd'] = BATADV_NAMES['BATADV_CMD_GET_ORIGINATORS']
msg['attrs'] = [
['BATADV_ATTR_MESH_IFINDEX', self.__meshif_index],
]

return self.nlm_request(msg,
msg_type=self.prid,
msg_flags=NLM_F_REQUEST | NLM_F_DUMP)

def main():
batadv = Batadv()

orig2tq = {}
for q in batadv.get_originators():
tq = q.get_attr('BATADV_ATTR_TQ')
if not tq:
continue

neigh = q.get_attr('BATADV_ATTR_NEIGH_ADDRESS')
if not neigh:
continue

orig = q.get_attr('BATADV_ATTR_ORIG_ADDRESS')
if not orig:
continue

hardif = q.get_attr('BATADV_ATTR_HARD_IFINDEX')
if not hardif:
continue

if orig != neigh:
continue

orig2tq[(neigh, hardif)] = tq

print("IF Neighbor last-seen TQ")

# this is not really necessary when we actually have done the orig == neigh
# check before - so printing orig2tq is nearly enough
for q in batadv.get_neighbors():
tq = '?'

hardif = q.get_attr('BATADV_ATTR_HARD_IFINDEX')
if not hardif:
continue

last_seen = q.get_attr('BATADV_ATTR_LAST_SEEN_MSECS')
if not last_seen:
continue

neigh = q.get_attr('BATADV_ATTR_NEIGH_ADDRESS')
if not neigh:
continue

if (neigh, hardif) in orig2tq:
tq = str(orig2tq[(neigh, hardif)])

ifname = if_indextoname(hardif)
print(" %10s %s %4i.%03is %s" % (ifname, neigh,
last_seen / 1000,
last_seen % 1000, tq))

batadv.close()

if __name__ == "__main__":
main()
    (1-1/1)