Esempio n. 1
0
    def __init__(self, site, request, url=url):
        self.site = site
        self.request = request
        rtparm = 1
        if url.endswith('cgi'):
            rtparm = 2
        if 'interfaces' in self.request or 'ips' in self.request:
            rt = Routes(site=site, url=url + '?post_routes=%s' % rtparm)
            dt = Details(site=site, url=url + '?post_olsr=1')
            self.version = rt.version
            interfaces = {}
            ips = {}
            base = 0
            for count, (ip, ifname) in enumerate(pyk.iteritems(rt.ip_dev)):
                i4 = Inet4(ip, None, None, iface=ifname)
                # ignore interfaces with unroutable IPs
                if unroutable(i4.ip):
                    #print ("Unroutable: %s" % i4)
                    continue
                ips[i4] = 1
                iface = Interface(count, ifname, None)
                iface.is_wlan = False
                interfaces[ifname] = iface
                iface.append_inet4(i4)
                base = count
            base += 1
            for count, (ip, ifname) in enumerate(pyk.iteritems(dt.ip_dev)):
                i4 = Inet4(ip, None, None, iface=ifname)
                is_wlan = sum(x == 1.0 for x in dt.metric[ip]) != 3
                #print ("ip", ip, dt.metric [ip])
                if unroutable(i4.ip):
                    continue
                if i4 in ips:
                    if ifname not in interfaces:
                        iface = Interface(base + count, ifname, None)
                        interfaces[ifname] = iface
                        iface.append_inet4(i4)
                    else:
                        iface = interfaces[ifname]
                        if i4 not in iface.inet4:
                            #print ("Oops:", ifname, i4, iface.inet4 [0])
                            del iface.inet4[0]
                            iface.append_inet4(i4)
                    iface.is_wlan = is_wlan
                    continue
                ips[i4] = 1
                iface = Interface(base + count, ifname, None)
                iface.is_wlan = is_wlan
                interfaces[ifname] = iface
                iface.append_inet4(i4)

            # check own ip
            n = 'unknown'
            i4 = Inet4(self.request['ip'], None, None, iface=n)
            assert i4 in ips

            self.request['ips'] = ips
            self.request['interfaces'] = interfaces
            self.request['version'] = rt.version
Esempio n. 2
0
    def __init__ (self, site, request, url = url) :
        self.site    = site
        self.request = request
        rtparm = 1
        if url.endswith ('cgi') :
            rtparm = 2
        if 'interfaces' in self.request or 'ips' in self.request :
            rt = Routes  (site = site, url = url + '?post_routes=%s' % rtparm)
            dt = Details (site = site, url = url + '?post_olsr=1')
            self.version = rt.version
            interfaces   = {}
            ips          = {}
            base         = 0
            for count, (ip, ifname) in enumerate (rt.ip_dev.iteritems ()) :
                i4 = Inet4 (ip, None, None, iface = ifname)
                # ignore interfaces with unroutable IPs
                if unroutable (i4.ip) :
                    #print "Unroutable: %s" % i4
                    continue
                ips [i4] = 1
                iface = Interface (count, ifname, None)
                iface.is_wlan = False
                interfaces [ifname] = iface
                iface.append_inet4 (i4)
                base = count
            base += 1
            for count, (ip, ifname) in enumerate (dt.ip_dev.iteritems ()) :
                i4 = Inet4 (ip, None, None, iface = ifname)
                is_wlan = sum (x == 1.0 for x in dt.metric [ip]) != 3
                #print "ip", ip, dt.metric [ip]
                if unroutable (i4.ip) :
                    continue
                if i4 in ips :
                    if ifname not in interfaces :
                        iface = Interface (base + count, ifname, None)
                        interfaces [ifname] = iface
                        iface.append_inet4 (i4)
                    else :
                        iface = interfaces [ifname]
                        if i4 not in iface.inet4 :
                            #print "Oops:", ifname, i4, iface.inet4 [0]
                            del iface.inet4 [0]
                            iface.append_inet4 (i4)
                    iface.is_wlan = is_wlan
                    continue
                ips [i4] = 1
                iface = Interface (base + count, ifname, None)
                iface.is_wlan = is_wlan
                interfaces [ifname] = iface
                iface.append_inet4 (i4)

            # check own ip
            n  = 'unknown'
            i4 = Inet4 (self.request ['ip'], None, None, iface = n)
            assert i4 in ips

            self.request ['ips']        = ips
            self.request ['interfaces'] = interfaces
            self.request ['version']    = rt.version
Esempio n. 3
0
 def _check_interface(self, iface, is_wlan=False):
     found = False
     for ip4 in iface.inet4:
         if unroutable(ip4.ip):
             continue
         found = True
         self.ips[ip4] = True
     if found:
         self.if_by_name[iface.name] = iface
         iface.is_wlan = is_wlan
Esempio n. 4
0
File: freifunk.py Progetto: FFM/FFM
 def _check_interface (self, iface, is_wlan = False) :
     found = False
     for ip4 in iface.inet4 :
         if unroutable (ip4.ip) :
             continue
         found = True
         self.ips [ip4] = True
     if found :
         self.if_by_name [iface.name] = iface
         iface.is_wlan = is_wlan
Esempio n. 5
0
 def parse (self) :
     root = self.tree.getroot ()
     self.if_by_name = {}
     self.ips        = {}
     for div in root.findall (".//%s" % tag ("div")) :
         self.try_get_version (div)
         if div.get ('id') == 'maincontent' and not self.if_by_name :
             tbl = div.find (".//%s" % tag ("table"))
             for n, tr in enumerate (tbl) :
                 if tr [0].tag == tag ('th') :
                     assert tr [0].text in ('Interface', 'Schnittstelle') \
                         , tr [0].text
                     continue
                 name, status, mtu, wlan, ip, mask, bcast = \
                     (x.text for x in tr)
                 if name in self.if_by_name :
                     iface = self.if_by_name [name]
                 else :
                     iface = Interface (n, name, mtu)
                     iface.is_wlan = self.yesno.get (wlan, False)
                 if status == 'DOWN' :
                     continue
                 # append IP address to interface if there is one
                 if ip is not None :
                     if ':' in ip :
                         i6 = Inet6 (ip, mask, bcast, iface = name)
                         iface.append_inet6 (i6)
                     else :
                         i4 = Inet4 (ip, mask, bcast, iface = name)
                         iface.append_inet4 (i4)
                         if not unroutable (i4.ip) :
                             self.if_by_name [name] = iface
                             self.ips [i4] = True
     self.set_version (root)
     if not self.if_by_name :
         raise ValueError, "No interface config found"
     bfw = Backfire_WLAN_Config (site = self.site)
     for d in bfw.wlans :
         if d.name in self.if_by_name :
             iface = self.if_by_name [d.name]
             iface.wlan_info = d
Esempio n. 6
0
 def parse (self) :
     root = self.tree.getroot ()
     self.if_by_name = {}
     self.ips        = {}
     for div in root.findall (".//%s" % tag ("div")) :
         self.try_get_version (div)
         if div.get ('id') == 'maincontent' and not self.if_by_name :
             tbl = div.find (".//%s" % tag ("table"))
             for n, tr in enumerate (tbl) :
                 if tr [0].tag == tag ('th') :
                     assert tr [0].text in ('Interface', 'Schnittstelle') \
                         , tr [0].text
                     continue
                 name, status, mtu, wlan, ip, mask, bcast = \
                     (x.text for x in tr)
                 if name in self.if_by_name :
                     iface = self.if_by_name [name]
                 else :
                     iface = Interface (n, name, mtu)
                     iface.is_wlan = self.yesno.get (wlan, False)
                 if status == 'DOWN' :
                     continue
                 # append IP address to interface if there is one
                 if ip is not None :
                     if ':' in ip :
                         i6 = Inet6 (ip, mask, bcast, iface = name)
                         iface.append_inet6 (i6)
                     else :
                         i4 = Inet4 (ip, mask, bcast, iface = name)
                         iface.append_inet4 (i4)
                         if not unroutable (i4.ip) :
                             self.if_by_name [name] = iface
                             self.ips [i4] = True
     self.set_version (root)
     if not self.if_by_name :
         raise ValueError, "No interface config found"
     bfw = Backfire_WLAN_Config (site = self.site)
     for d in bfw.wlans :
         if d.name in self.if_by_name :
             iface = self.if_by_name [d.name]
             iface.wlan_info = d
Esempio n. 7
0
    def build_device_structure (self) :
        for n in self.contents ['nodes'] :
            self.node_by_id [n.id] = n
        for d in self.contents ['devices'] :
            if d.id_nodes not in self.dev_by_node :
                self.dev_by_node [d.id_nodes] = []
            self.dev_by_node [d.id_nodes].append (d)
            self.cons_dev [d.id] = Consolidated_Device (self, d)
        for ip in self.contents ['ips'] :
            self.ip_by_ip [IP4_Address (ip.ip)] = ip
            if ip.id_devices :
                did = ip.id_devices
                self.cons_dev [did].add_redeemer_ip (ip)
            net = IP4_Address (ip.ip, ip.cidr)
            if net not in self.ip4nets :
                pyk.fprint ("WARN: Adding network reservation: %s" % net)
                self.ip4nets [net] = True
        # consistency check of olsr data against redeemer db
        # check nodes from topology
        for ip4 in self.olsr_nodes :
            if ip4 not in self.ip_by_ip :
                pyk.fprint ("WARN: ip %s from olsr topo not in ips" % ip4)
                del self.olsr_nodes [ip4]
        # check mid table
        midkey = []
        midtbl = {}
        for ip4, aliases in self.olsr_mid.iteritems () :
            if ip4 not in self.ip_by_ip :
                pyk.fprint ("WARN: key ip %s from olsr mid not in ips" % ip4)
                midkey.append (ip4)
            for a in aliases :
                if a not in self.ip_by_ip :
                    pyk.fprint ("WARN: ip %s from olsr mid not in ips" % a)
                    if ip4 not in midtbl :
                        midtbl [ip4] = []
                    midtbl [ip4].append (a)
        assert not midkey
        for k, v in midtbl.iteritems () :
            x = dict.fromkeys (self.olsr_mid [k])
            for ip4 in v :
                del x [ip4]
            self.olsr_mid [k] = x.keys ()
        # consolidate devices using information from spider data
        node_by_sdev = {}
        for mainip, sdev in sorted (self.spider_devs.iteritems ()) :
            if sdev.done :
                continue
            sdev.done = True
            seen_ip = {}
            nodeid  = None
            for sif in sorted (sdev.interfaces.itervalues ()) :
                assert not sif.done
                sif.done = True
                for in4 in sorted (sif.inet4) :
                    if unroutable (in4.ip) :
                        continue
                    seen_ip [in4.ip] = 1
                    i4 = IP4_Address (in4.ip)
                    ip = self.ip_by_ip.get (i4)
                    if not ip :
                        pyk.fprint \
                            ("WARN: ip %s from spider not in redeemer" % i4)
                        continue
                    if not ip.id_devices :
                        pyk.fprint ("ERR: ip %s from spider has no device" % i4)
                        continue
                    d = self.cons_dev [ip.id_devices]
                    if sdev not in node_by_sdev :
                        node_by_sdev [sdev] = {}
                    if d.id_nodes not in node_by_sdev [sdev] :
                        node_by_sdev [sdev] [d.id_nodes] = {}
                    if d.id not in node_by_sdev [sdev] [d.id_nodes] :
                        node_by_sdev [sdev] [d.id_nodes] [d.id] = {}
                    node_by_sdev [sdev] [d.id_nodes] [d.id] [in4.ip] = True
            assert mainip in seen_ip
        for sdev, nodes in sorted (node_by_sdev.iteritems ()) :
            if len (nodes) > 1 :
                pyk.fprint \
                    ( "WARN: spider device %s expands to %s nodes: %s"
                    % ( sdev.mainip
                      , len (nodes)
                      , ', '.join
                        (self.node_by_id [n].name for n in nodes.iterkeys ())
                      )
                    )
            for n, devs in sorted (nodes.iteritems ()) :
                sdevs = {}
                sifs  = {}
                dev1  = None
                err   = False
                for devid, ips in sorted (devs.iteritems ()) :
                    d = self.cons_dev [devid]
                    if d.merged :
                        pyk.fprint \
                            ("ERR: %s already merged to %s" % (d, d.merged))
                        err = True
                        continue
                    if dev1 and d.id != dev1.id :
                        if self.verbose :
                            pyk.fprint \
                                ( "Spider %-15s: Merging device %s.%s to %s.%s"
                                % ( sdev.mainip
                                  , d.node.name
                                  , d.name
                                  , dev1.node.name
                                  , dev1.name
                                  )
                                )
                        assert dev1 != d
                        assert not dev1.merged
                        dev1.merge (d)
                    else :
                        dev1 = d
                    for ip in sorted (ips.iterkeys ()) :
                        sdevs [self.spider_devs  [ip]] = True
                        if self.spider_iface [ip] not in sifs :
                            sifs  [self.spider_iface [ip]] = {}
                        sifs  [self.spider_iface [ip]] [ip] = True

                if not err :
                    assert len (sdevs) == 1
                    if sdev not in sdevs :
                        pyk.fprint ("ERR:  Merged interface differ:")
                        pyk.fprint ("------------------------------")
                        pyk.fprint (sdevs.keys () [0].verbose_repr ())
                        pyk.fprint ("------------------------------")
                        pyk.fprint (sdev.verbose_repr ())
                        pyk.fprint ("------------------------------")
                    assert len (sifs)  >= 1
                    assert dev1
                for sif, ips in sorted (sifs.iteritems ()) :
                    l = len (ips)
                    assert l >= 1
                    ifaces = {}
                    for ip in ips :
                        ifaces [ip] = dev1.interfaces [ip]
                    assert len (ifaces) == len (ips)
                    if1 = ip1 = None
                    for ip, ifc in sorted (ifaces.iteritems ()) :
                        if if1 :
                            pyk.fprint \
                                ( "Spider %-15s: "
                                  "Merging iface %s.%s:%s to %s.%s:%s"
                                % ( sdev.mainip
                                  , d.node.name
                                  , d.name
                                  , ip
                                  , dev1.node.name
                                  , dev1.name
                                  , ip1
                                  )
                                )
                            if1.merge (ifc)
                        else :
                            if1 = ifc
                            ip1 = ip
                            if sif.is_wlan :
                                if1.is_wlan   = True
                                if1.wlan_info = getattr (sif, 'wlan_info', None)
                            if1.names = sif.names
                            if1.spider_ip = sif.device.mainip
        # compound devices from mid table
        # We index nodes by mid-table entry (by the mid key-ip address)
        # for each mid entry there can be several nodes (config bug)
        for ip4, aliases in sorted (self.olsr_mid.iteritems ()) :
            nodes = {}
            ip    = self.ip_by_ip [ip4]
            if ip.id_devices :
                d = self.cons_dev [ip.id_devices]
                d.mid_ip = ip4
                nodes [d.id_nodes] = d
            else :
                pyk.fprint ("ERR:  key %s from mid has no device" % ip4)
            for a in sorted (aliases) :
                ip = self.ip_by_ip [a]
                if not ip.id_devices :
                    pyk.fprint ("ERR:  %s from mid %s has no device" % (a, ip4))
                    continue
                d  = self.cons_dev [ip.id_devices]
                d.mid_ip = ip4
                if d.id_nodes not in nodes :
                    nodes [d.id_nodes] = d
                elif d != nodes [d.id_nodes] :
                    if d.merged :
                        if d.merged != nodes [d.id_nodes] :
                            pyk.fprint \
                                ( "ERR: %s already merged to %s "
                                  "not merging to %s"
                                % (d, d.merged, nodes [d.id_nodes])
                                )
                        continue
                    assert not nodes [d.id_nodes].merged
                    nodes [d.id_nodes].merge (d)
            if len (nodes) > 1 :
                pyk.fprint \
                    ("WARN: mid %s expands to %s nodes" % (ip4, len (nodes)))
Esempio n. 8
0
    def __init__ (self, cmd, scope, debug = False) :
        self.debug     = debug
        self.verbose   = cmd.verbose
        self.anonymize = cmd.anonymize
        if len (cmd.argv) > 0 :
            f  = open (cmd.argv [0])
        else :
            f = sys.stdin
        self.ip4nets = {}
        self.ip6nets = {}
        if cmd.network :
            for n in cmd.network :
                ip, comment = n.split (';', 1)
                if ':' in ip :
                    ip = IP6_Address (ip)
                    self.ip6nets [ip] = comment
                else :
                    ip = IP4_Address (ip)
                    self.ip4nets [ip] = comment
        olsr = get_olsr_container (cmd.olsr_file)
        self.olsr_nodes   = {}
        for t in olsr.topo.forward.iterkeys () :
            self.olsr_nodes [t]   = True
        for t in olsr.topo.reverse.iterkeys () :
            self.olsr_nodes [t]   = True
        self.olsr_mid     = olsr.mid.by_ip
        self.olsr_hna     = olsr.hna
        self.rev_mid      = {}
        for k, v in self.olsr_mid.iteritems () :
            if k not in self.olsr_nodes :
                pyk.fprint ("WARN: MIB %s: not in OLSR Topology" % k)
            #assert k in self.olsr_nodes
            for mid in v :
                assert mid not in self.rev_mid
                self.rev_mid [mid] = True
        self.spider_info  = pickle.load (open (cmd.spider_dump, 'rb'))
        self.spider_devs  = {}
        self.spider_iface = {}
        for ip, dev in self.spider_info.iteritems () :
            if self.verbose :
                pyk.fprint ("IP:", ip)
            # ignore spider errors
            if not isinstance (dev, Guess) :
                continue
            dev.mainip = ip
            dev.done   = False
            for iface in dev.interfaces.itervalues () :
                iface.done = False
                for ip4 in iface.inet4 :
                    i4 = ip4.ip
                    # ignore rfc1918, link local, localnet
                    if unroutable (i4) :
                        continue
                    if  (   i4 in self.spider_devs
                        and self.spider_devs [i4] != dev
                        ) :
                        pyk.fprint ("WARN: Device %s/%s not equal:" % (ip, i4))
                        pyk.fprint ("=" * 60)
                        pyk.fprint (dev.verbose_repr ())
                        pyk.fprint ("-" * 60)
                        pyk.fprint (self.spider_devs [i4].verbose_repr ())
                        pyk.fprint ("=" * 60)
                    elif (   i4 in self.spider_iface
                         and self.spider_iface [i4] != iface
                         ) :
                        assert dev == self.spider_devs [i4]
                        spif = self.spider_iface [i4]
                        pyk.fprint \
                            ( "WARN: Interfaces %s/%s of dev-ip %s share ip %s"
                            % (iface.name, spif.name, ip, i4)
                            )
                        spif.names.append (iface.name)
                        if iface.is_wlan :
                            spif.is_wlan = iface.is_wlan
                            spif.wlan_info = getattr (iface, 'wlan_info', None)
                        if self.verbose :
                            pyk.fprint ("=" * 60)
                            pyk.fprint (iface)
                            pyk.fprint (spif)
                            pyk.fprint ("-" * 60)
                            pyk.fprint (dev.verbose_repr ())
                            pyk.fprint ("=" * 60)
                        iface = spif
                    self.spider_devs  [i4] = dev
                    self.spider_iface [i4] = iface
                    iface.device = dev
            if ip not in self.spider_devs :
                pyk.fprint ("WARN: ip %s not in dev" % ip)
                if self.verbose :
                    pyk.fprint ("=" * 60)
                    pyk.fprint (dev.verbose_repr ())
                    pyk.fprint ("=" * 60)
                name = 'unknown'
                assert name not in dev.interfaces
                iface = Interface (4711, name)
                iface.done = False
                dev.interfaces [name] = iface
                iface.device = dev
                iface.append_inet4 (Inet4 (ip, None, None, iface = name))
                self.spider_iface [ip] = iface
                self.spider_devs  [ip] = dev

        self.scope          = scope
        self.ffm            = self.scope.FFM
        self.pap            = self.scope.GTW.OMP.PAP
        self.mentor         = {}
        self.rsrvd_nets     = {}
        self.ffm_node_by_id = {}
        self.node_by_id     = {}
        self.ip_by_ip       = {}
        self.email_ids      = {}
        self.phone_ids      = {}
        self.person_by_id   = {}
        self.member_by_id   = {}
        self.dev_by_node    = {}
        self.cons_dev       = {}

        self.parser         = SQL_Parser \
            (verbose = False, fix_double_encode = True)
        self.parser.parse (f)
        self.contents       = self.parser.contents
        self.tables         = self.parser.tables
Esempio n. 9
0
    def __init__(self, cmd, scope, debug=False):
        self.debug = debug
        self.verbose = cmd.verbose
        self.anonymize = cmd.anonymize
        if len(cmd.argv) > 0:
            f = open(cmd.argv[0])
        else:
            f = sys.stdin
        self.ip4nets = {}
        self.ip6nets = {}
        if cmd.network:
            for n in cmd.network:
                ip, comment = n.split(';', 1)
                if ':' in ip:
                    ip = IP6_Address(ip)
                    self.ip6nets[ip] = comment
                else:
                    ip = IP4_Address(ip)
                    self.ip4nets[ip] = comment
        olsr = get_olsr_container(cmd.olsr_file)
        self.olsr_nodes = {}
        for t in olsr.topo.forward.iterkeys():
            self.olsr_nodes[t] = True
        for t in olsr.topo.reverse.iterkeys():
            self.olsr_nodes[t] = True
        self.olsr_mid = olsr.mid.by_ip
        self.olsr_hna = olsr.hna
        self.rev_mid = {}
        for k, v in self.olsr_mid.iteritems():
            if k not in self.olsr_nodes:
                pyk.fprint("WARN: MIB %s: not in OLSR Topology" % k)
            #assert k in self.olsr_nodes
            for mid in v:
                assert mid not in self.rev_mid
                self.rev_mid[mid] = True
        self.spider_info = pickle.load(open(cmd.spider_dump, 'rb'))
        self.spider_devs = {}
        self.spider_iface = {}
        for ip, dev in self.spider_info.iteritems():
            if self.verbose:
                pyk.fprint("IP:", ip)
            # ignore spider errors
            if not isinstance(dev, Guess):
                continue
            dev.mainip = ip
            dev.done = False
            for iface in dev.interfaces.itervalues():
                iface.done = False
                for ip4 in iface.inet4:
                    i4 = ip4.ip
                    # ignore rfc1918, link local, localnet
                    if unroutable(i4):
                        continue
                    if (i4 in self.spider_devs
                            and self.spider_devs[i4] != dev):
                        pyk.fprint("WARN: Device %s/%s not equal:" % (ip, i4))
                        pyk.fprint("=" * 60)
                        pyk.fprint(dev.verbose_repr())
                        pyk.fprint("-" * 60)
                        pyk.fprint(self.spider_devs[i4].verbose_repr())
                        pyk.fprint("=" * 60)
                    elif (i4 in self.spider_iface
                          and self.spider_iface[i4] != iface):
                        assert dev == self.spider_devs[i4]
                        spif = self.spider_iface[i4]
                        pyk.fprint \
                            ( "WARN: Interfaces %s/%s of dev-ip %s share ip %s"
                            % (iface.name, spif.name, ip, i4)
                            )
                        spif.names.append(iface.name)
                        if iface.is_wlan:
                            spif.is_wlan = iface.is_wlan
                            spif.wlan_info = getattr(iface, 'wlan_info', None)
                        if self.verbose:
                            pyk.fprint("=" * 60)
                            pyk.fprint(iface)
                            pyk.fprint(spif)
                            pyk.fprint("-" * 60)
                            pyk.fprint(dev.verbose_repr())
                            pyk.fprint("=" * 60)
                        iface = spif
                    self.spider_devs[i4] = dev
                    self.spider_iface[i4] = iface
                    iface.device = dev
            if ip not in self.spider_devs:
                pyk.fprint("WARN: ip %s not in dev" % ip)
                if self.verbose:
                    pyk.fprint("=" * 60)
                    pyk.fprint(dev.verbose_repr())
                    pyk.fprint("=" * 60)
                name = 'unknown'
                assert name not in dev.interfaces
                iface = Interface(4711, name)
                iface.done = False
                dev.interfaces[name] = iface
                iface.device = dev
                iface.append_inet4(Inet4(ip, None, None, iface=name))
                self.spider_iface[ip] = iface
                self.spider_devs[ip] = dev

        self.scope = scope
        self.ffm = self.scope.FFM
        self.pap = self.scope.GTW.OMP.PAP
        self.mentor = {}
        self.rsrvd_nets = {}
        self.ffm_node_by_id = {}
        self.node_by_id = {}
        self.ip_by_ip = {}
        self.email_ids = {}
        self.phone_ids = {}
        self.person_by_id = {}
        self.member_by_id = {}
        self.dev_by_node = {}
        self.cons_dev = {}

        self.parser         = SQL_Parser \
            (verbose = False, fix_double_encode = True)
        self.parser.parse(f)
        self.contents = self.parser.contents
        self.tables = self.parser.tables
Esempio n. 10
0
    def build_device_structure(self):
        for n in self.contents['nodes']:
            self.node_by_id[n.id] = n
        for d in self.contents['devices']:
            if d.id_nodes not in self.dev_by_node:
                self.dev_by_node[d.id_nodes] = []
            self.dev_by_node[d.id_nodes].append(d)
            self.cons_dev[d.id] = Consolidated_Device(self, d)
        for ip in self.contents['ips']:
            self.ip_by_ip[IP4_Address(ip.ip)] = ip
            if ip.id_devices:
                did = ip.id_devices
                self.cons_dev[did].add_redeemer_ip(ip)
            net = IP4_Address(ip.ip, ip.cidr)
            if net not in self.ip4nets:
                pyk.fprint("WARN: Adding network reservation: %s" % net)
                self.ip4nets[net] = True
        # consistency check of olsr data against redeemer db
        # check nodes from topology
        for ip4 in self.olsr_nodes:
            if ip4 not in self.ip_by_ip:
                pyk.fprint("WARN: ip %s from olsr topo not in ips" % ip4)
                del self.olsr_nodes[ip4]
        # check mid table
        midkey = []
        midtbl = {}
        for ip4, aliases in self.olsr_mid.iteritems():
            if ip4 not in self.ip_by_ip:
                pyk.fprint("WARN: key ip %s from olsr mid not in ips" % ip4)
                midkey.append(ip4)
            for a in aliases:
                if a not in self.ip_by_ip:
                    pyk.fprint("WARN: ip %s from olsr mid not in ips" % a)
                    if ip4 not in midtbl:
                        midtbl[ip4] = []
                    midtbl[ip4].append(a)
        assert not midkey
        for k, v in midtbl.iteritems():
            x = dict.fromkeys(self.olsr_mid[k])
            for ip4 in v:
                del x[ip4]
            self.olsr_mid[k] = x.keys()
        # consolidate devices using information from spider data
        node_by_sdev = {}
        for mainip, sdev in sorted(self.spider_devs.iteritems()):
            if sdev.done:
                continue
            sdev.done = True
            seen_ip = {}
            nodeid = None
            for sif in sorted(sdev.interfaces.itervalues()):
                assert not sif.done
                sif.done = True
                for in4 in sorted(sif.inet4):
                    if unroutable(in4.ip):
                        continue
                    seen_ip[in4.ip] = 1
                    i4 = IP4_Address(in4.ip)
                    ip = self.ip_by_ip.get(i4)
                    if not ip:
                        pyk.fprint \
                            ("WARN: ip %s from spider not in redeemer" % i4)
                        continue
                    if not ip.id_devices:
                        pyk.fprint("ERR: ip %s from spider has no device" % i4)
                        continue
                    d = self.cons_dev[ip.id_devices]
                    if sdev not in node_by_sdev:
                        node_by_sdev[sdev] = {}
                    if d.id_nodes not in node_by_sdev[sdev]:
                        node_by_sdev[sdev][d.id_nodes] = {}
                    if d.id not in node_by_sdev[sdev][d.id_nodes]:
                        node_by_sdev[sdev][d.id_nodes][d.id] = {}
                    node_by_sdev[sdev][d.id_nodes][d.id][in4.ip] = True
            assert mainip in seen_ip
        for sdev, nodes in sorted(node_by_sdev.iteritems()):
            if len(nodes) > 1:
                pyk.fprint \
                    ( "WARN: spider device %s expands to %s nodes: %s"
                    % ( sdev.mainip
                      , len (nodes)
                      , ', '.join
                        (self.node_by_id [n].name for n in nodes.iterkeys ())
                      )
                    )
            for n, devs in sorted(nodes.iteritems()):
                sdevs = {}
                sifs = {}
                dev1 = None
                err = False
                for devid, ips in sorted(devs.iteritems()):
                    d = self.cons_dev[devid]
                    if d.merged:
                        pyk.fprint \
                            ("ERR: %s already merged to %s" % (d, d.merged))
                        err = True
                        continue
                    if dev1 and d.id != dev1.id:
                        if self.verbose:
                            pyk.fprint \
                                ( "Spider %-15s: Merging device %s.%s to %s.%s"
                                % ( sdev.mainip
                                  , d.node.name
                                  , d.name
                                  , dev1.node.name
                                  , dev1.name
                                  )
                                )
                        assert dev1 != d
                        assert not dev1.merged
                        dev1.merge(d)
                    else:
                        dev1 = d
                    for ip in sorted(ips.iterkeys()):
                        sdevs[self.spider_devs[ip]] = True
                        if self.spider_iface[ip] not in sifs:
                            sifs[self.spider_iface[ip]] = {}
                        sifs[self.spider_iface[ip]][ip] = True

                if not err:
                    assert len(sdevs) == 1
                    if sdev not in sdevs:
                        pyk.fprint("ERR:  Merged interface differ:")
                        pyk.fprint("------------------------------")
                        pyk.fprint(sdevs.keys()[0].verbose_repr())
                        pyk.fprint("------------------------------")
                        pyk.fprint(sdev.verbose_repr())
                        pyk.fprint("------------------------------")
                    assert len(sifs) >= 1
                    assert dev1
                for sif, ips in sorted(sifs.iteritems()):
                    l = len(ips)
                    assert l >= 1
                    ifaces = {}
                    for ip in ips:
                        ifaces[ip] = dev1.interfaces[ip]
                    assert len(ifaces) == len(ips)
                    if1 = ip1 = None
                    for ip, ifc in sorted(ifaces.iteritems()):
                        if if1:
                            pyk.fprint \
                                ( "Spider %-15s: "
                                  "Merging iface %s.%s:%s to %s.%s:%s"
                                % ( sdev.mainip
                                  , d.node.name
                                  , d.name
                                  , ip
                                  , dev1.node.name
                                  , dev1.name
                                  , ip1
                                  )
                                )
                            if1.merge(ifc)
                        else:
                            if1 = ifc
                            ip1 = ip
                            if sif.is_wlan:
                                if1.is_wlan = True
                                if1.wlan_info = getattr(sif, 'wlan_info', None)
                            if1.names = sif.names
                            if1.spider_ip = sif.device.mainip
        # compound devices from mid table
        # We index nodes by mid-table entry (by the mid key-ip address)
        # for each mid entry there can be several nodes (config bug)
        for ip4, aliases in sorted(self.olsr_mid.iteritems()):
            nodes = {}
            ip = self.ip_by_ip[ip4]
            if ip.id_devices:
                d = self.cons_dev[ip.id_devices]
                d.mid_ip = ip4
                nodes[d.id_nodes] = d
            else:
                pyk.fprint("ERR:  key %s from mid has no device" % ip4)
            for a in sorted(aliases):
                ip = self.ip_by_ip[a]
                if not ip.id_devices:
                    pyk.fprint("ERR:  %s from mid %s has no device" % (a, ip4))
                    continue
                d = self.cons_dev[ip.id_devices]
                d.mid_ip = ip4
                if d.id_nodes not in nodes:
                    nodes[d.id_nodes] = d
                elif d != nodes[d.id_nodes]:
                    if d.merged:
                        if d.merged != nodes[d.id_nodes]:
                            pyk.fprint \
                                ( "ERR: %s already merged to %s "
                                  "not merging to %s"
                                % (d, d.merged, nodes [d.id_nodes])
                                )
                        continue
                    assert not nodes[d.id_nodes].merged
                    nodes[d.id_nodes].merge(d)
            if len(nodes) > 1:
                pyk.fprint \
                    ("WARN: mid %s expands to %s nodes" % (ip4, len (nodes)))