Project

General

Profile

Bug #367 ยป neighbor_extend_dump.py

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

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

    
4
from pyroute2.common import map_namespace
5
from pyroute2.netlink import genlmsg
6
from pyroute2.netlink.generic import GenericNetlinkSocket
7
from pyroute2.netlink.nlsocket import Marshal
8
from pyroute2.netlink import NLM_F_REQUEST
9
from pyroute2.netlink import NLM_F_DUMP
10
from socket import if_nametoindex
11
from socket import if_indextoname
12

    
13

    
14
BATADV_CMD_UNSPEC = 0
15
BATADV_CMD_GET_MESH_INFO = 1
16
BATADV_CMD_TP_METER = 2
17
BATADV_CMD_TP_METER_CANCEL = 3
18
BATADV_CMD_GET_ROUTING_ALGOS = 4
19
BATADV_CMD_GET_HARDIFS = 5
20
BATADV_CMD_GET_TRANSTABLE_LOCAL = 6
21
BATADV_CMD_GET_TRANSTABLE_GLOBAL = 7
22
BATADV_CMD_GET_ORIGINATORS = 8
23
BATADV_CMD_GET_NEIGHBORS = 9
24
BATADV_CMD_GET_GATEWAYS = 10
25
BATADV_CMD_GET_BLA_CLAIM = 11
26
BATADV_CMD_GET_BLA_BACKBONE = 12
27
BATADV_CMD_GET_DAT_CACHE = 13
28
BATADV_CMD_GET_MCAST_FLAGS = 14
29
BATADV_CMD_MAX = BATADV_CMD_GET_MCAST_FLAGS
30

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

    
33

    
34
class batadvcmd(genlmsg):
35
    prefix = 'BATADV_ATTR_'
36

    
37
    '''
38
    Message class that will be used to communicate
39
    with the kernel module
40
    '''
41
    nla_map = (('BATADV_ATTR_UNSPEC', 'none'),
42
               ('BATADV_ATTR_VERSION', 'asciiz'),
43
               ('BATADV_ATTR_ALGO_NAME', 'asciiz'),
44
               ('BATADV_ATTR_MESH_IFINDEX', 'uint32'),
45
               ('BATADV_ATTR_MESH_IFNAME', 'asciiz'),
46
               ('BATADV_ATTR_MESH_ADDRESS', 'l2addr'),
47
               ('BATADV_ATTR_HARD_IFINDEX', 'uint32'),
48
               ('BATADV_ATTR_HARD_IFNAME', 'asciiz'),
49
               ('BATADV_ATTR_HARD_ADDRESS', 'l2addr'),
50
               ('BATADV_ATTR_ORIG_ADDRESS', 'l2addr'),
51
               ('BATADV_ATTR_TPMETER_RESULT', 'uint8'),
52
               ('BATADV_ATTR_TPMETER_TEST_TIME', 'uint32'),
53
               ('BATADV_ATTR_TPMETER_BYTES', 'uint64'),
54
               ('BATADV_ATTR_TPMETER_COOKIE', 'uint32'),
55
               ('BATADV_ATTR_PAD', 'none'),
56
               ('BATADV_ATTR_ACTIVE', 'flag'),
57
               ('BATADV_ATTR_TT_ADDRESS', 'l2addr'),
58
               ('BATADV_ATTR_TT_TTVN', 'uint8'),
59
               ('BATADV_ATTR_TT_LAST_TTVN', 'uint8'),
60
               ('BATADV_ATTR_TT_CRC32', 'uint32'),
61
               ('BATADV_ATTR_TT_VID', 'uint16'),
62
               ('BATADV_ATTR_TT_FLAGS', 'uint32'),
63
               ('BATADV_ATTR_FLAG_BEST', 'flag'),
64
               ('BATADV_ATTR_LAST_SEEN_MSECS', 'uint32'),
65
               ('BATADV_ATTR_NEIGH_ADDRESS', 'l2addr'),
66
               ('BATADV_ATTR_TQ', 'uint8'),
67
               ('BATADV_ATTR_THROUGHPUT', 'uint32'),
68
               ('BATADV_ATTR_BANDWIDTH_UP', 'uint32'),
69
               ('BATADV_ATTR_BANDWIDTH_DOWN', 'uint32'),
70
               ('BATADV_ATTR_ROUTER', 'l2addr'),
71
               ('BATADV_ATTR_BLA_OWN', 'flag'),
72
               ('BATADV_ATTR_BLA_ADDRESS', 'l2addr'),
73
               ('BATADV_ATTR_BLA_VID', 'uint16'),
74
               ('BATADV_ATTR_BLA_BACKBONE', 'l2addr'),
75
               ('BATADV_ATTR_BLA_CRC', 'uint16'),
76
               ('BATADV_ATTR_DAT_CACHE_IP4ADDRESS', 'ip4addr'),
77
               ('BATADV_ATTR_DAT_CACHE_HWADDRESS', 'l2addr'),
78
               ('BATADV_ATTR_DAT_CACHE_VID', 'uint16'),
79
               ('BATADV_ATTR_MCAST_FLAGS', 'uint32'),
80
               ('BATADV_ATTR_MCAST_FLAGS_PRIV', 'uint32'))
81

    
82

    
83
class MarshalBatadv(Marshal):
84
    msg_map = {BATADV_CMD_UNSPEC: batadvcmd,
85
               BATADV_CMD_GET_MESH_INFO: batadvcmd,
86
               BATADV_CMD_TP_METER: batadvcmd,
87
               BATADV_CMD_TP_METER_CANCEL: batadvcmd,
88
               BATADV_CMD_GET_ROUTING_ALGOS: batadvcmd,
89
               BATADV_CMD_GET_HARDIFS: batadvcmd,
90
               BATADV_CMD_GET_TRANSTABLE_LOCAL: batadvcmd,
91
               BATADV_CMD_GET_TRANSTABLE_GLOBAL: batadvcmd,
92
               BATADV_CMD_GET_ORIGINATORS: batadvcmd,
93
               BATADV_CMD_GET_NEIGHBORS: batadvcmd,
94
               BATADV_CMD_GET_GATEWAYS: batadvcmd,
95
               BATADV_CMD_GET_BLA_CLAIM: batadvcmd,
96
               BATADV_CMD_GET_BLA_BACKBONE: batadvcmd,
97
               BATADV_CMD_GET_DAT_CACHE: batadvcmd,
98
               BATADV_CMD_GET_MCAST_FLAGS: batadvcmd}
99

    
100

    
101
class BatadvSocket(GenericNetlinkSocket):
102
    def __init__(self):
103
        GenericNetlinkSocket.__init__(self)
104
        self.marshal = MarshalBatadv()
105

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

    
110
class Batadv(BatadvSocket):
111

    
112
    __meshif = 'bat0'
113
    __meshif_index = 0
114

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

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

    
122
        self.__meshif_index = if_nametoindex(self.__meshif)
123

    
124
        try:
125
            self.bind()
126
        except:
127
            super(Batadv, self).close()
128
            raise
129

    
130
    def get_neighbors(self):
131
        msg = batadvcmd()
132
        msg['cmd'] = BATADV_NAMES['BATADV_CMD_GET_NEIGHBORS']
133
        msg['attrs'] = [
134
            ['BATADV_ATTR_MESH_IFINDEX', self.__meshif_index],
135
        ]
136

    
137
        return self.nlm_request(msg,
138
                                msg_type=self.prid,
139
                                msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
140

    
141
    def get_originators(self):
142
        msg = batadvcmd()
143
        msg['cmd'] = BATADV_NAMES['BATADV_CMD_GET_ORIGINATORS']
144
        msg['attrs'] = [
145
            ['BATADV_ATTR_MESH_IFINDEX', self.__meshif_index],
146
        ]
147

    
148
        return self.nlm_request(msg,
149
                                msg_type=self.prid,
150
                                msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
151

    
152
def main():
153
    batadv = Batadv()
154

    
155
    orig2tq = {}
156
    for q in batadv.get_originators():
157
        tq = q.get_attr('BATADV_ATTR_TQ')
158
        if not tq:
159
            continue
160

    
161
        neigh = q.get_attr('BATADV_ATTR_NEIGH_ADDRESS')
162
        if not neigh:
163
            continue
164

    
165
        orig = q.get_attr('BATADV_ATTR_ORIG_ADDRESS')
166
        if not orig:
167
            continue
168

    
169
        hardif = q.get_attr('BATADV_ATTR_HARD_IFINDEX')
170
        if not hardif:
171
            continue
172

    
173
        if orig != neigh:
174
            continue
175

    
176
        orig2tq[(neigh, hardif)] = tq
177

    
178
    print("IF             Neighbor              last-seen	TQ")
179

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

    
185
        hardif = q.get_attr('BATADV_ATTR_HARD_IFINDEX')
186
        if not hardif:
187
            continue
188

    
189
        last_seen = q.get_attr('BATADV_ATTR_LAST_SEEN_MSECS')
190
        if not last_seen:
191
            continue
192

    
193
        neigh = q.get_attr('BATADV_ATTR_NEIGH_ADDRESS')
194
        if not neigh:
195
            continue
196

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

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

    
205
    batadv.close()
206

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