summaryrefslogtreecommitdiff
path: root/haircontrol/discovery.py
blob: d454283b898a24e48b99d577c17e3a3cef9b93c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import re
import xml.etree.ElementTree
from haircontrol.data import Equipment

class Discovery:
    def __init__(self, inspector):
        self.inspector = inspector
        self.equipments = {}
        self.ip2mac = {}
        self.mac2ip = {}

    def add_equipment(self,e):
        old = self.equipments.get(e.mgmtip)
        if old:
            print("Warn : %s replaced by %s"%(old,e))
        self.equipments[e.mgmtip] = e

    def index_mac_ip(self,mac, ip):
        oldmac = self.ip2mac.get(ip)
        if oldmac:
            print("Warn : %s replaced by %s for %s"%(oldmac, mac, ip))
        oldip = self.mac2ip.get(mac)
        if oldip:
            print("Warn : %s replaced by %s for %s"%(oldip, ip, mac))
        self.ip2mac[ip] = mac
        self.mac2ip[mac] = ip

    def discover_hinting_from_lldp(self, lldpnode):
        self.inspector.connect(lldpnode)
        fd = self.inspector.command('lldp')
        root = xml.etree.ElementTree.parse(fd).getroot()
        for iface in root.iter('interface'):
            ifname = iface.get('name')
            chassis = iface.find('chassis')
            e = Equipment()
            e.name = chassis.find('name').text
            e.mgmtip = chassis.find('mgmt-ip').text
            self.add_equipment(e)
            for port in iface.findall('port'):
                #remote_ifname = port.find('id').text
                e.add_seen_mac(ifname, 'lldp') #XXX
        fd.close()
        self.inspector.disconnect()

    def discover_from_root(self, rootnode):
        self.inspector.connect(rootnode)
        fd = self.inspector.command('ip-neigh')
        IPNEIGH = re.compile("^(?P<ip>[a-f0-9:.]+) dev (?P<ifname>.*) lladdr (?P<mac>[a-f0-9:]*)")
        for line in fd:
            matches = IPNEIGH.search(line)
            if matches:
                ip, ifname, mac = [ matches.group(k) for k in ['ip','ifname','mac'] ]
                self.index_mac_ip(mac, ip)
                rootnode.add_seen_mac(ifname, mac)
        fd.close()
        self.inspector.disconnect()

# fe80::8300 dev eth1 lladdr 10:fe:ed:f1:e1:f3 router STALE
# 172.16.11.46 dev eth1 lladdr 24:a4:3c:ee:89:ca STALE
# 172.16.20.3 dev eth1 lladdr 00:27:22:0e:74:15 STALE
# 172.16.20.210 dev eth1 lladdr c0:4a:00:fe:1f:87 REACHABLE
# 172.16.21.69 dev eth1 lladdr e8:de:27:b5:f2:b1 DELAY
# 172.16.20.216 dev eth1 lladdr c0:4a:00:fe:09:bd PERMANENT
# 172.16.11.41 dev eth1 lladdr 04:18:d6:0e:37:d4 STALE
# 172.16.11.104 dev eth1 lladdr 00:15:6d:8e:22:46 STALE
# 172.16.10.8 dev eth1 lladdr 00:27:22:0e:67:f9 STALE
#