--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dce/lsdb_read.py Fri Nov 12 10:53:29 2010 +0900
@@ -0,0 +1,183 @@
+#
+#
+
+import ns3
+import ospfwalk
+import networkx
+import pygraphviz
+import iplib
+#import visualizer
+
+def PingRtt (context, rtt):
+ print "Received Response with RTT = " + rtt;
+ ns3.Simulator.Destroy ()
+
+
+def main(argv):
+ rlsas = []
+ rlsas_dic = {}
+ nlsas = []
+ nlsas_dic = {}
+ routers = []
+ nets = []
+ csma_dic = {}
+ p2p_dic = {}
+ num_links = 0
+ nodes = ns3.NodeContainer();
+
+ # Parse LSDB
+# ospfwalk.parse_show_ip_ospf_database_router(open("./show_ospf_db_r.txt", "r").read(), rlsas, rlsas_dic)
+# ospfwalk.parse_show_ip_ospf_database_network(open("./show_ospf_db_n.txt", "r").read(), nlsas, nlsas_dic)
+ ospfwalk.parse_show_ip_ospf_database_router(open("./show_ospf_db_r_wide.txt", "r").read(), rlsas, rlsas_dic)
+ ospfwalk.parse_show_ip_ospf_database_network(open("./show_ospf_db_n_wide.txt", "r").read(), nlsas, nlsas_dic)
+
+ G = networkx.Graph()
+ A = pygraphviz.AGraph(directed=False, strict=True)
+ ospfwalk.conv_lsas_to_graph(rlsas, rlsas_dic, nlsas, nlsas_dic, {}, {}, G, A)
+
+ # prepare for transit link
+ csma = ns3.CsmaHelper();
+ csma.SetChannelAttribute("DataRate", ns3.DataRateValue(ns3.DataRate("5Mbps")));
+ csma.SetChannelAttribute("Delay", ns3.TimeValue(ns3.MilliSeconds(2)));
+
+ p2p = ns3.PointToPointHelper();
+ p2p.SetDeviceAttribute("DataRate", ns3.StringValue ("5Mbps"));
+ p2p.SetChannelAttribute("Delay", ns3.TimeValue(ns3.MilliSeconds(2)));
+
+ internet = ns3.InternetStackHelper();
+
+ for node in G.nodes_iter():
+# print "node " + node
+ if node.find('/') != -1:
+ nets.append(node)
+ else:
+ routers.append(node)
+
+ for router in routers:
+ n = ns3.Node();
+ internet.Install(n);
+ nodes.Add(n);
+
+# print "router " + router
+ try:
+ rlsas = rlsas_dic[router]
+ except KeyError:
+ print "Warning: LSAs do not contain interface information about " + router + ". Ignoring."
+
+ for rlsal in rlsas.links:
+ if rlsal.type == "transit" :
+ intaddr = rlsal.linkdata
+ cost = rlsal.metric
+# print "IF: " + str(intaddr) + " cost:" + str(cost)
+
+ try:
+ nlsa = nlsas_dic[rlsal.linkid]
+ except KeyError:
+ print "Couldn't find Network LSA"
+ continue;
+
+ net = iplib.CIDR(rlsal.linkdata + nlsa.netmask)
+ netaddr = str(net.get_network_ip())
+ netmask = str(net.get_netmask())
+
+ try:
+ chan = csma_dic[netaddr+"/"+netmask]
+ dev = csma.Install(n,chan)
+# csma.EnablePcap("lsdb-read", dev, False)
+# print "Reuse existing channel " + netaddr+"/"+netmask + " IF: " + intaddr
+ except KeyError:
+# print "Added new chan"
+ dev = csma.Install(n)
+# csma.EnablePcap("lsdb-read", dev, False)
+ csma_dic[netaddr+"/"+netmask] = dev.Get(0).GetChannel()
+
+ ipv4 = n.GetObject(ns3.Ipv4.GetTypeId())
+ idx = ipv4.AddInterface(dev.Get(0))
+# print "add if " + str(idx) + " node " + str(n.GetId()) + " if " + intaddr
+ ipv4.AddAddress(idx,
+ ns3.Ipv4InterfaceAddress(ns3.Ipv4Address(intaddr), ns3.Ipv4Mask(netmask)))
+ ipv4.SetUp (idx)
+ num_links += 1
+ elif rlsal.type == "stub":
+# print "Stub, skipped"
+ continue
+ # PtP
+ else:
+ try:
+ pnode = p2p_dic[rlsal.linkid]
+ dev = p2p.Install(n,pnode)
+
+ prlsas = rlsas_dic[rlsal.linkid]
+ for prlsal in prlsas.links:
+ if prlsal.type != "ptp" :
+ continue
+ if prlsal.linkid == router:
+ pintaddr = prlsal.linkdata
+ break
+
+ # edge[0]
+ ipv4 = n.GetObject(ns3.Ipv4.GetTypeId())
+ idx = ipv4.AddInterface(dev.Get(0))
+# print "add if p0 " + str(idx) + " node " + str(n.GetId()) + " if " + rlsal.linkdata
+ ipv4.AddAddress(idx,
+ ns3.Ipv4InterfaceAddress(ns3.Ipv4Address(rlsal.linkdata), ns3.Ipv4Mask("255.255.255.255")))
+ ipv4.SetUp (idx)
+
+ # edge[1]
+ ipv4 = pnode.GetObject(ns3.Ipv4.GetTypeId())
+ idx = ipv4.AddInterface(dev.Get(1))
+# print "add if p1 " + str(idx) + " node " + str(pnode.GetId()) + " if " + pintaddr
+# print "Install = " + str(dev.Get(1).GetIfIndex()) + " ifidx1 " + str(idx)
+ ipv4.AddAddress(idx,
+ ns3.Ipv4InterfaceAddress(ns3.Ipv4Address(pintaddr), ns3.Ipv4Mask("255.255.255.255")))
+ ipv4.SetUp (idx)
+ num_links += 1
+ except KeyError:
+# print "INFO: Stores for p2p link " + router + ". "
+ p2p_dic[router] = n
+
+
+ cmd = ns3.CommandLine();
+ cmd.useViz = True
+ cmd.AddValue("useViz", "Use visualizer (default=false")
+ cmd.Parse(argv);
+
+
+ print "#Nodes " + str(nodes.GetN()) + " #Links " + str(num_links) + " #Chans " + str(len(csma_dic))
+
+ # Create OSPF
+ processManager = ns3.ProcessManagerHelper()
+ processManager.Install (nodes)
+ quagga = ns3.QuaggaHelper();
+ quagga.EnableOspf (nodes);
+ quagga.Install (nodes);
+
+ # Ping from Node 0 to Node N
+ v4ping = ns3.V4Ping ()
+ v4ping.SetAttribute ("Verbose", ns3.BooleanValue (True))
+ # To idx=1 of Node(N)
+ ipv4 = nodes.Get (0).GetObject(ns3.Ipv4.GetTypeId())
+ print "Src: " + str(ipv4.GetAddress (1, 0).GetLocal ())
+ ipv4 = nodes.Get (25).GetObject(ns3.Ipv4.GetTypeId())
+ ipv4 = nodes.Get (nodes.GetN () - 1).GetObject(ns3.Ipv4.GetTypeId())
+ print "Dst: " + str(ipv4.GetAddress (1, 0).GetLocal ())
+ v4ping.SetAttribute ("Remote", ns3.Ipv4AddressValue (ipv4.GetAddress (1, 0).GetLocal ()))
+ nodes.Get (0).AddApplication (v4ping)
+ v4ping.SetStartTime (ns3.Seconds (1.0))
+
+ ns3.Names.Add ("v4ping", v4ping);
+# ns3.Config.Connect ("/Names/v4ping/Rtt", generate_callback_classes (PingRtt));
+
+# ns3.Ipv4GlobalRoutingHelper.PopulateRoutingTables ()
+
+ # Run Simulation
+# visualizer.start ()
+ ns3.Simulator.Stop(ns3.Seconds(1800.0))
+ ns3.Simulator.Run()
+
+ ns3.Simulator.Destroy()
+
+if __name__ == '__main__':
+ import sys
+ main(sys.argv)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dce/ospfwalk.py Fri Nov 12 10:53:29 2010 +0900
@@ -0,0 +1,770 @@
+#!/usr/bin/python
+#!/usr/local/bin/python
+#!/opt/local/bin/python2.5
+# -*- coding: utf-8 -*-
+#
+# required external libs: iplib, networkx-1.0, matplotlib, pygraphviz
+#
+
+import os
+import sys
+import getpass
+import getopt
+import telnetlib
+import StringIO
+import datetime
+import re
+import networkx
+import pygraphviz
+import iplib
+
+debug = True
+useELSA = False # to avoid BUG
+
+class RouterLSA:
+ def __init__(self):
+ self.lsid = ""
+ self.links = []
+
+class RouterLSALink:
+ def __init__(self):
+ self.type = ""
+ self.linkid = ""
+ self.linkdata = ""
+ self.metric = 1
+
+class NetworkLSA:
+ def __init__(self):
+ self.lsid = ""
+ self.netmask = ""
+ self.rtrs = []
+
+class ExternalLSA:
+ def __init__(self):
+ self.lsid = ""
+ self.advrouter = ""
+ self.netmask = ""
+ self.metric = 1
+
+
+# convert 10.1/16 -> 10.1.0.0/16
+def add_dot_zero(str):
+ if str.find("/") != -1:
+ # in case of 10.1/16
+ l = str.split("/")
+ for i in range(3 - str.count(".")):
+ l[0] = l[0] + ".0"
+ return "/".join(l)
+ else:
+ # in case of 10.1
+ l = str
+ for i in range(3 - str.count(".")):
+ l = l + ".0"
+ return l
+
+def do_telnet_quagga(host, user, passw):
+ tn = telnetlib.Telnet(host)
+
+ tn.read_until("sername: ")
+ tn.write(user + "\n")
+
+ tn.read_until("assword: ")
+ tn.write(passw + "\n")
+
+ tn.read_until("#")
+ tn.write("terminal length 0\n")
+ tn.read_until("#")
+ tn.write("show ip ospf database router\n")
+ str_r = tn.read_until("#")
+ tn.write("show ip ospf database network\n")
+ str_n = tn.read_until("#")
+ tn.write("show ip ospf database external\n")
+ str_e = tn.read_until("#")
+ str_ne = ""
+ tn.write("exit\n")
+
+ if debug:
+ print "---------- show ip ospf database router ----------"
+ print str_r
+ print "---------- show ip ospf database network ----------"
+ print str_n
+ print "---------- show ip ospf database external ----------"
+ print str_e
+ print "---------- show ip ospf database nssa-external ----------"
+ print str_ne
+
+ return str_r, str_n, str_e, str_ne
+
+def do_telnet_cisco(host, user, passw):
+ tn = telnetlib.Telnet(host)
+
+ tn.read_until("sername: ")
+ tn.write(user + "\n")
+
+ tn.read_until("assword: ")
+ tn.write(passw + "\n")
+
+ tn.read_until("#")
+ tn.write("terminal length 0\n")
+ tn.read_until("#")
+ tn.write("show ip ospf database router\n")
+ str_r = tn.read_until("#")
+ tn.write("show ip ospf database network\n")
+ str_n = tn.read_until("#")
+ tn.write("show ip ospf database external\n")
+ str_e = tn.read_until("#")
+ tn.write("show ip ospf database nssa-external\n")
+ str_ne = tn.read_until("#")
+ tn.write("exit\n")
+
+ if debug:
+ print "---------- show ip ospf database router ----------"
+ print str_r
+ print "---------- show ip ospf database network ----------"
+ print str_n
+ print "---------- show ip ospf database external ----------"
+ print str_e
+ print "---------- show ip ospf database nssa-external ----------"
+ print str_ne
+
+ return str_r, str_n, str_e, str_ne
+
+def do_telnet_cisco_crs(host, user, passw):
+ tn = telnetlib.Telnet(host)
+
+ tn.read_until("sername: ")
+ tn.write(user + "\n")
+
+ tn.read_until("assword: ")
+ tn.write(passw + "\n")
+
+ tn.read_until("#")
+ tn.write("terminal length 0\n")
+ tn.read_until("#")
+ tn.write("show ospf database router\n")
+ str_r = tn.read_until("#")
+ tn.write("show ospf database network\n")
+ str_n = tn.read_until("#")
+ tn.write("show ospf database external\n")
+ str_e = tn.read_until("#")
+ tn.write("show ospf database nssa-external\n")
+ str_ne = tn.read_until("#")
+ tn.write("exit\n")
+
+ if debug:
+ print "---------- show ip ospf database router ----------"
+ print str_r
+ print "---------- show ip ospf database network ----------"
+ print str_n
+ print "---------- show ip ospf database external ----------"
+ print str_e
+ print "---------- show ip ospf database nssa-external ----------"
+ print str_ne
+
+ return str_r, str_n, str_e, str_ne
+
+def do_telnet_ax(host, user, passw):
+ tn = telnetlib.Telnet(host)
+
+ tn.read_until("ogin: ")
+ tn.write(user + "\n")
+
+ tn.read_until("assword:")
+ tn.write(passw + "\n")
+
+ tn.read_until(">")
+ tn.write("enable\n")
+ tn.read_until("#")
+ tn.write("set terminal pager disable\n")
+ tn.read_until("#")
+ tn.write("show ip ospf vrf all database router\n")
+ str_r = tn.read_until("#")
+ tn.write("show ip ospf vrf all database network\n")
+ str_n = tn.read_until("#")
+ tn.write("show ip ospf vrf all database external\n")
+ str_e = tn.read_until("#")
+ tn.write("show ip ospf vrf all database nssa-external\n")
+ str_ne = tn.read_until("#")
+ tn.write("exit\n")
+
+ if debug:
+ print "---------- show ip ospf database router ----------"
+ print str_r
+ print "---------- show ip ospf database network ----------"
+ print str_n
+ print "---------- show ip ospf database external ----------"
+ print str_e
+ print "---------- show ip ospf database nssa-external ----------"
+ print str_ne
+
+ return str_r, str_n, str_e, str_ne
+
+def parse_show_ip_ospf_database_router(str_r, rlsas, rlsas_dic):
+ # parse show ip ospf database router
+ rlsa = RouterLSA()
+ rlsal = None
+ for l in StringIO.StringIO(str_r):
+ # find "Link State ID: "
+ m = re.search('Link State ID: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ if debug:
+ print "LSID = " + m.group(1)
+ rlsa = RouterLSA()
+ rlsa.lsid = m.group(1)
+ rlsas.append(rlsa)
+ rlsas_dic[rlsa.lsid] = rlsa
+ continue
+ # find "Link connected to: "
+ m = re.search('Link connected to: (.+)', l)
+ if m:
+ typestr = m.group(1)
+ if debug:
+ print ' Type = ' + typestr
+ rlsal = RouterLSALink()
+ if typestr.find("Stub") != -1:
+ rlsal.type = "stub"
+ continue
+ if typestr.find("Transit") != -1:
+ rlsal.type = "transit"
+ continue
+ if typestr.find("another Router") != -1:
+ rlsal.type = "ptp"
+ continue
+ print "Unknown link type: " + typestr
+ continue
+
+ # find "Link ID: "
+ m = re.search('\(Link ID\).+: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ linkid = m.group(1)
+ if debug:
+ print ' Link ID = ' + linkid
+ rlsal.linkid = linkid
+ continue
+ # find "Link Data: "
+ m = re.search('\(Link Data\).+: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ linkdata = m.group(1)
+ if debug:
+ print ' Link Data = ' + linkdata
+ rlsal.linkdata = linkdata
+ continue
+ # find "TOS 0 Metrics: "
+ m = re.search('TOS 0 Metric.*: (\d+)', l)
+ if m:
+ metric = m.group(1)
+ if debug:
+ print ' Metrics = ' + metric
+ rlsal.metric = int(metric)
+ if rlsal.metric < 1:
+ print ' Warning: Found 0 metric. Use 1 instead of 0.'
+ rlsal.metric = 1
+ rlsa.links.append(rlsal)
+ continue
+
+def parse_show_ip_ospf_database_network(str_n, nlsas, nlsas_dic):
+ # parse show ip ospf database network
+ for l in StringIO.StringIO(str_n):
+ # find "Link State ID: xxx.yyy.zzz.www"
+ m = re.search('Link State ID: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ nlsa = NetworkLSA()
+ if debug:
+ print "LSID = " + m.group(1)
+ nlsa.lsid = m.group(1)
+ continue
+ # find "Network Mask: "
+ m = re.search(' Network Mask: (\S+)', l)
+ if m:
+ netmask = m.group(1)
+ if debug:
+ print ' Netmask = ' + netmask
+ nlsa.netmask = netmask
+ nlsas.append(nlsa)
+ nlsas_dic[nlsa.lsid] = nlsa
+ continue
+
+def parse_show_ip_ospf_database_external(str_e, elsas, elsas_dic):
+ # parse show ip ospf database external
+ for l in StringIO.StringIO(str_e):
+ # find "Link State ID: xxx.yyy.zzz.www"
+ m = re.search('Link State ID: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ elsa = ExternalLSA()
+ if debug:
+ print "ELSA LSID = " + m.group(1)
+ elsa.lsid = m.group(1)
+ continue
+ # find "Network Mask: "
+ m = re.search('Advertising Router: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ advrouter = m.group(1)
+ if debug:
+ print ' Advrouter = ' + advrouter
+ elsa.advrouter = advrouter
+ continue
+ # find "Network Mask: "
+ m = re.search(' Network Mask: (\S+)', l)
+ if m:
+ netmask = m.group(1)
+ if debug:
+ print ' Netmask = ' + netmask
+ elsa.netmask = netmask
+ continue
+ # find "Metric: "
+ m = re.search('Metric: (\d+)', l)
+ if m:
+ metric = m.group(1)
+ if debug:
+ print ' Metric = ' + metric
+ elsa.metric = int(metric)
+ if elsa.metric < 1:
+ print ' Warning: Found 0 metric. Use 1 instead of 0.'
+ elsa.metric = 1
+ #if elsa.lsid == '0.0.0.0':
+ # don't append default route (ad-hoc hack)
+ # continue
+ elsas.append(elsa)
+ elsas_dic[elsa.lsid] = elsa
+ continue
+
+def parse_show_ip_ospf_database_router_ax(str_r, rlsas, rlsas_dic):
+ # parse show ip ospf database router
+ rlsa = RouterLSA()
+ rlsal = None
+ for l in StringIO.StringIO(str_r):
+ # find "Link State ID: "
+ m = re.search('LSID: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ if debug:
+ print "LSID = " + m.group(1)
+ rlsa = RouterLSA()
+ rlsa.lsid = m.group(1)
+ rlsas.append(rlsa)
+ rlsas_dic[rlsa.lsid] = rlsa
+ continue
+ # find "Link connected to: "
+ m = re.search(' ->(.+Net),', l)
+ if m:
+ typestr = m.group(1)
+ if debug:
+ print ' Type = ' + typestr
+ rlsal = RouterLSALink()
+ if typestr.find("StubNet") != -1:
+ rlsal.type = "stub"
+ m2 = re.search('Network Address: (\d+\S+/\d+), Cost: (\d+)', l)
+ if m2:
+ netaddr = add_dot_zero(m2.group(1))
+ cidr = iplib.CIDR(netaddr)
+ rlsal.linkid = str(cidr.address)
+ if debug:
+ print ' Link ID = ' + rlsal.linkid
+ rlsal.linkdata = str(cidr.netmask)
+ if debug:
+ print ' Link Data = ' + rlsal.linkdata
+ metric = m2.group(2)
+ rlsal.metric = int(metric)
+ if rlsal.metric < 1:
+ print ' Warning: Found 0 metric. Use 1 instead of 0.'
+ rlsal.metric = 1
+ if debug:
+ print ' Metrics = ' + metric
+ rlsa.links.append(rlsal)
+ continue
+ if typestr.find("TransNet") != -1:
+ rlsal.type = "transit"
+ m2 = re.search('DR Address: (\S+),', l)
+ if m2:
+ linkid = m2.group(1)
+ print ' Link ID = ' + linkid
+ rlsal.linkid = linkid
+
+ continue
+ print "Unknown link type: " + typestr
+ continue
+
+ # find "Router Interface Address: " in case of TransNet
+ m = re.search('Router Interface Address: (\d+\.\d+\.\d+\.\d+), Cost: (\d+)', l)
+ if m:
+ linkdata = m.group(1)
+ if debug:
+ print ' Link Data = ' + linkdata
+ rlsal.linkdata = linkdata
+ metric = m.group(2)
+ if debug:
+ print ' Metrics = ' + metric
+ rlsal.metric = int(metric)
+ if rlsal.metric < 1:
+ print ' Warning: Found 0 metric. Use 1 instead of 0.'
+ rlsal.metric = 1
+ rlsa.links.append(rlsal)
+ continue
+
+def parse_show_ip_ospf_database_network_ax(str_n, nlsas, nlsas_dic):
+ # parse show ip ospf database network
+ for l in StringIO.StringIO(str_n):
+ # find "DR Interface Address: xxx.yyy.zzz.www"
+ m = re.search('DR Interface Address: (\d+\.\d+\.\d+\.\d+)(/\d+),', l)
+ if m:
+ nlsa = NetworkLSA()
+ addr = m.group(1)
+ if debug:
+ print "LSID = " + addr
+ nlsa.lsid = addr
+ netmask = m.group(2)
+ if debug:
+ print ' Netmask = ' + netmask
+ nlsa.netmask = netmask
+ nlsas.append(nlsa)
+ nlsas_dic[nlsa.lsid] = nlsa
+ continue
+
+def parse_show_ip_ospf_database_external_ax(str_e, elsas, elsas_dic):
+ # parse show ip ospf database external
+ for l in StringIO.StringIO(str_e):
+ # find "Network Address: xxx.yyy.zzz.www"
+ m = re.search('Network Address: (\S+)(/\d+)\s*, .+Router: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ elsa = ExternalLSA()
+ netaddr = add_dot_zero(m.group(1))
+ if debug:
+ print "ELSA LSID = " + netaddr
+ elsa.lsid = netaddr
+ advrouter = m.group(3)
+ if debug:
+ print ' Advrouter = ' + advrouter
+ elsa.advrouter = advrouter
+ netmask = m.group(2)
+ if debug:
+ print ' Netmask = ' + netmask
+ elsa.netmask = netmask
+ continue
+ # find "Metric: "
+ m = re.search('Metric: (\d+)', l)
+ if m:
+ metric = m.group(1)
+ if debug:
+ print ' Metric = ' + metric
+ elsa.metric = int(metric)
+ if elsa.metric < 1:
+ print ' Warning: Found 0 metric. Use 1 instead of 0.'
+ elsa.metric = 1
+ #if elsa.lsid == '0.0.0.0':
+ # don't append default route (ad-hoc hack) from ax6600s
+ # continue
+ elsas.append(elsa)
+ elsas_dic[elsa.lsid] = elsa
+ continue
+
+def parse_show_ip_ospf_database_nssa_external_ax(str_e, elsas, elsas_dic):
+ # parse show ip ospf database external
+ for l in StringIO.StringIO(str_e):
+ # find "Network Address: xxx.yyy.zzz.www"
+ m = re.search('Network Address: (\S+)(/\d+)\s*, .+Router: (\d+\.\d+\.\d+\.\d+)', l)
+ if m:
+ elsa = ExternalLSA()
+ netaddr = add_dot_zero(m.group(1))
+ if debug:
+ print "NSSA-ELSA LSID = " + netaddr
+ elsa.lsid = netaddr
+ advrouter = m.group(3)
+ if debug:
+ print ' Advrouter = ' + advrouter
+ elsa.advrouter = advrouter
+ netmask = m.group(2)
+ if debug:
+ print ' Netmask = ' + netmask
+ elsa.netmask = netmask
+ continue
+ # find "Metric: "
+ m = re.search('Metric: (\d+)', l)
+ if m:
+ metric = m.group(1)
+ if debug:
+ print ' Metric = ' + metric
+ elsa.metric = int(metric)
+ if elsa.metric < 1:
+ print ' Warning: Found 0 metric. Use 1 instead of 0.'
+ elsa.metric = 1
+ #if elsa.lsid == '0.0.0.0':
+ # don't append default route (ad-hoc hack) obtained from nssa-external
+ # continue
+ elsas.append(elsa)
+ elsas_dic[elsa.lsid] = elsa
+ continue
+
+def conv_lsas_to_graph(rlsas, rlsas_dic, nlsas, nlsas_dic, elsas, elsas_dic, G, A):
+ for rlsa in rlsas:
+ G.add_node(rlsa.lsid)
+ A.add_node(rlsa.lsid, shape='box')
+ for link in rlsa.links:
+ netaddr = None
+ netmask = None
+ if link.type == "stub":
+ netaddr = link.linkid
+ netmask = '/' + iplib.convert_nm(link.linkdata, "bits")
+ #if debug:
+ # print "stub, netaddr = " + netaddr + ", netmask = " + netmask
+ G.add_node(netaddr + netmask)
+ A.add_node(netaddr + netmask, shape='ellipse', color='red')
+ elif link.type == "transit":
+ try:
+ nlsa = nlsas_dic[link.linkid]
+ except KeyError:
+ print "Key: " + link.linkid + " does not exist. Ignoring. (transit)"
+ continue
+ cidr = iplib.CIDR(link.linkdata + nlsa.netmask)
+ netaddr = str(cidr.get_network_ip())
+ netmask = nlsa.netmask
+ #if debug:
+ # print "transit, netaddr = " + netaddr + ", netmask = " + netmask
+ G.add_node(netaddr + netmask)
+ G.add_path([rlsa.lsid, netaddr + netmask])
+ A.add_node(netaddr + netmask, shape='ellipse', color='orange')
+ elif link.type == "ptp":
+ netaddr = link.linkid
+ netmask = ""
+ G.add_node(netaddr + netmask)
+ G.add_path([link.linkid, netaddr + netmask])
+ A.add_node(netaddr + netmask, shape='box')
+ else:
+ print "Unknown link type: " + link.type
+ print "Add edge: " + rlsa.lsid + " - " + netaddr + netmask + " metric " + str(link.metric)
+ G.add_edge(rlsa.lsid, netaddr + netmask, weight=link.metric)
+ A.add_edge(rlsa.lsid, netaddr + netmask, None, label=str(link.metric))
+ for elsa in elsas:
+ # extract the default router only and add it to the graph
+ #if elsa.lsid == '0.0.0.0' and elsa.netmask == '/0':
+ if True:
+ G.add_node(elsa.lsid + elsa.netmask)
+ A.add_node(elsa.lsid + elsa.netmask, shape='ellipse', color='blue')
+ G.add_edge(elsa.advrouter, elsa.lsid + elsa.netmask, weight=elsa.metric)
+ A.add_edge(elsa.advrouter, elsa.lsid + elsa.netmask, None, label=str(elsa.metric))
+ print "Add edge(ELSA): " + elsa.advrouter + " - " + elsa.lsid + elsa.netmask + " metric " + str(elsa.metric)
+
+def make_routing_hop_table(G):
+ nets = []
+ str = ""
+ # extract networks from all nodes
+ for node in G.nodes_iter():
+ if node.find('/') != -1:
+ nets.append(node)
+
+ for src_net in nets:
+ path = networkx.single_source_dijkstra_path(G, src_net)
+ for dst_net in nets:
+ path_str = ""
+ try:
+ for node in path[dst_net]:
+ if node.find('/') == -1:
+ path_str += "," + node
+
+ str += src_net + "," + dst_net + path_str + "\n"
+ except KeyError:
+ print "Key: " + node + " does not exist. Ignoring. (make_routing_hop_table())"
+ continue
+
+ #print len(nets)
+ return str
+
+def make_anybed_topology_file(G, rlsas_dic):
+ routers = []
+ nets = []
+ astr = ""
+ ptpnets = {}
+ ptpnetnum = 0
+ for node in G.nodes_iter():
+ if node.find('/') != -1:
+ nets.append(node)
+ else:
+ routers.append(node)
+
+ astr += "<nodes>\n"
+ for router in routers:
+ astr += ' <node name="' + router + '">' + "\n"
+ astr += " <interfaces>\n"
+ for edge in G.edges_iter([router], True):
+ if edge[1].find('/') != -1:
+ intname = "Node" + router + "-Int" + edge[1].replace('/','.')
+ netname = "Net" + edge[1].replace('/', '.')
+ net = iplib.CIDR(edge[1])
+ #netaddr, netmask = edge[1].split('/')
+ netaddr = str(net.get_network_ip())
+ if netaddr == "None":
+ # When the subnetmask == /32, substitute interface address for netaddr.
+ netaddr = edge[1].split('/')[0]
+ netmask = str(net.get_netmask())
+ #if debug:
+ # print "net = " + str(net)
+ if netaddr == "0.0.0.0" and netmask == "0.0.0.0":
+ # don't use defaultroute for address assign
+ print "Warning: Found default route at " + router + ". Ignoring."
+ else:
+ intaddr = None
+ try:
+ rlsas = rlsas_dic[router]
+ except KeyError:
+ print "Warning: LSAs do not contain interface information about " + router + ". Ignoring."
+ for rlsal in rlsas.links:
+ if rlsal.type == "transit" and net.is_valid_ip(rlsal.linkdata) == 1:
+ intaddr = rlsal.linkdata
+ if intaddr == None:
+ intaddr = str(net.get_first_ip())
+ cost = edge[2]['weight']
+ astr += ' <interface name="' + intname + '" interfaceaddress="' + intaddr + '" netmask="' + netmask + '" ospfcost="' + str(cost) + '">' + "\n"
+ astr += ' <network name="' + netname + '" networkaddress="' + netaddr + '" netmask="' + netmask + '"/>' + "\n"
+ astr += ' </interface>' + "\n"
+ else: #point-to-point link
+ print "Warning: " + router + " directly connects to " + edge[1] + ". PtP link?"
+ oprt = edge[1]
+ intname = "Node" + router + "-PtPInt-to-" + oprt
+ if ptpnets.has_key(oprt + "-" + router):
+ netname = ptpnets[oprt + "-" + router]
+ else:
+ netname = "PtpNet-" + router + "-" + oprt
+ ptpnets[router + "-" + oprt] = netname
+
+ #cost = edge[2]['weight']
+ astr += ' <interface name="' + intname + '" ospfcost="' + str(cost) + '">' + "\n"
+ astr += ' <network name="' + netname + '"/>' + "\n"
+ astr += ' </interface>' + "\n"
+
+ astr += " </interfaces>\n"
+ astr += " <function>\n"
+ astr += ' <ospf routerid="' + router + '">\n'
+ astr += " </ospf>\n"
+ astr += " </function>\n"
+ astr += " </node>\n"
+ astr += "</nodes>\n"
+
+ return astr
+
+
+def usage():
+ sys.stderr.write(sys.argv[0] + " [-h] [-g] [-H a_telnet_hostname] [-u a_telnet_username] [-r a_file_containing_show_ip_ospf_router] [-n a_file_containing_show_ip_ospf_network] [-e a_file_containing_show_ip_ospf_external] [-s a_file_containing_show_ip_ospf_nssa-external]\n-h: show help\n-g: draw a topology with GraphViz\n")
+
+
+#---------- main
+#
+host = None
+user = "sample"
+router_type = "quagga"
+draw_topology = False
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], "hgH:u:p:r:n:e:s:t:")
+except getopt.GetoptError:
+ usage()
+ sys.exit(2)
+
+str_r = None
+str_n = None
+str_e = None
+str_ne = None
+
+for opt, arg in opts:
+ if opt == "-h":
+ usage()
+ sys.exit()
+ elif opt == "-g":
+ draw_topology = True
+ elif opt == "-H":
+ host = arg
+ elif opt == "-u":
+ user = arg
+ elif opt == "-r":
+ str_r = open(arg, "r").read()
+ elif opt == "-n":
+ str_n = open(arg, "r").read()
+ elif opt == "-e":
+ str_e = open(arg, "r").read()
+ elif opt == "-s":
+ str_ne = open(arg, "r").read()
+ elif opt == "-t":
+ router_type = arg
+
+
+#outdir_fig = "/usr/local/www/data/ospfwalk/fig_nat/"
+outdir_fig = "./"
+#outdir_route = "/nicter/route/"
+#outdir_route = "route/"
+outdir_route = "./"
+
+# telnet a router to get raw topology data
+#str_r: the result of show ip ospf database router
+#str_n: the result of show ip ospf database network
+#str_e: the result of show ip ospf database external
+#str_ne: the result of show ip ospf database nssa-external
+if host != None:
+ if router_type == "cisco":
+ passw = getpass.getpass()
+ str_r, str_n, str_e, str_ne = do_telnet_cisco(host, user, passw)
+ if router_type == "cisco-crs":
+ passw = getpass.getpass()
+ str_r, str_n, str_e, str_ne = do_telnet_cisco_crs(host, user, passw)
+ elif router_type == "ax":
+ passw = getpass.getpass()
+ str_r, str_n, str_e, str_ne = do_telnet_ax(host, user, passw)
+ elif router_type == "quagga": # without str_ne
+ passw = getpass.getpass()
+ str_r, str_n, str_e, str_ne = do_telnet_quagga(host, user, passw)
+
+# BUG: due to a bug on dealing with external LSAs, currently ignoring the external LSAs. Only use router LSAs and network LSAs.
+if useELSA != True:
+ str_e = None
+ str_ne = None
+
+# parse raw topology data
+rlsas = []
+rlsas_dic = {}
+src_nets = []
+nlsas = []
+nlsas_dic = {}
+elsas = []
+elsas_dic = {}
+
+if router_type == "ax": #alaxala
+ parse_show_ip_ospf_database_router_ax(str_r, rlsas, rlsas_dic)
+ parse_show_ip_ospf_database_network_ax(str_n, nlsas, nlsas_dic)
+ parse_show_ip_ospf_database_external_ax(str_e, elsas, elsas_dic)
+ parse_show_ip_ospf_database_nssa_external_ax(str_ne, elsas, elsas_dic)
+else: # cisco or quagga
+ parse_show_ip_ospf_database_router(str_r, rlsas, rlsas_dic)
+ parse_show_ip_ospf_database_network(str_n, nlsas, nlsas_dic)
+ parse_show_ip_ospf_database_external(str_e, elsas, elsas_dic)
+
+# making a graph structure
+d = datetime.datetime.now()
+datestr = d.strftime("%Y%m%d-%H%M%S")
+G = networkx.Graph()
+A = pygraphviz.AGraph(directed=False, strict=True)
+conv_lsas_to_graph(rlsas, rlsas_dic, nlsas, nlsas_dic, elsas, elsas_dic, G, A)
+
+
+# visualizing
+if draw_topology == True:
+ print "Drawing a graph...",
+ graphfn = datestr + ".png"
+ graphfnpath = outdir_fig + graphfn
+ dotfnpath = outdir_fig + datestr + ".dot"
+ A.draw(graphfnpath, prog='fdp', args='-Gmaxiter=5000')
+ A.write(dotfnpath)
+ #os.system("cd " + outdir_fig + "; /bin/ln -sf " + graphfn + " current.png")
+ print "done"
+
+# calculate shortest paths
+#str = make_routing_hop_table(G)
+#f = open(outdir_route + "hop.cnf", "w")
+#f.write(str)
+#f.close()
+
+# write a file by GraphML
+#networkx.write_graphml(G, "graph.gml")
+
+# write a AnyBed topology file
+print "Writing a AnyBed topology file...",
+astr = make_anybed_topology_file(G, rlsas_dic)
+f = open("ospftopology.xml", "w")
+f.write(astr)
+f.close()
+print "done"