1# encoding: utf-8
2"""
3neighbor.py
4
5Created by Thomas Mangin on 2015-03-31.
6Copyright (c) 2009-2017 Exa Networks. All rights reserved.
7License: 3-clause BSD. (See the COPYRIGHT file)
8"""
9
10import socket
11from struct import calcsize
12from collections import namedtuple
13
14from exabgp.netlink.message import Message
15
16
17# 0                   1                   2                   3
18# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
19# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20# |   Family    |    Reserved1  |           Reserved2           |
21# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22# |                     Interface Index                         |
23# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24# |           State             |     Flags     |     Type      |
25# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26
27
28class Neighbor(Message):
29    class Header(object):
30        # linux/if_addr.h
31        PACK = 'BxxxiHBB'
32        LEN = calcsize(PACK)
33
34    format = namedtuple('Neighbor', 'family index state flags type attributes')
35
36    class Command(object):
37        RTM_NEWNEIGH = 0x1C
38        RTM_DELNEIGH = 0x1D
39        RTM_GETNEIGH = 0x1E
40
41    class Type(object):
42        class Family(object):
43            AF_INET = socket.AF_INET
44            AF_INET6 = socket.AF_INET6
45
46        class State(object):
47            NUD_INCOMPLETE = 0x01  # Still attempting to resolve
48            NUD_REACHABLE = 0x02  # A confirmed working cache entry
49            NUD_STALE = 0x04  # an expired cache entry
50            NUD_DELAY = 0x08  # Neighbor no longer reachable.  Traffic sent, waiting for confirmatio.
51            NUD_PROBE = 0x10  # A cache entry that is currently being re-solicited
52            NUD_FAILED = 0x20  # An invalid cache entry
53            # Dummy states
54            NUD_NOARP = 0x40  # A device which does not do neighbor discovery (ARP)
55            NUD_PERMANENT = 0x80  # A static entry
56            NUD_NONE = 0x00
57
58        class Flag(object):
59            NTF_USE = 0x01
60            NTF_PROXY = 0x08  # A proxy ARP entry
61            NTF_ROUTER = 0x80  # An IPv6 router
62
63        class Attribute(object):
64            # XXX : Not sure - starts at zero or one ... ??
65            NDA_UNSPEC = 0x00  # Unknown type
66            NDA_DST = 0x01  # A neighbour cache network. layer destination address
67            NDA_LLADDR = 0x02  # A neighbor cache link layer address.
68            NDA_CACHEINFO = 0x03  # Cache statistics
69            NDA_PROBES = 0x04
70
71    @classmethod
72    def getNeighbors(cls):
73        return cls.extract(Neighbor.Command.RTM_GETNEIGH)
74