public void ProcessOSPFDatabase() { #region Query, parse and store LSAs string ospfOverView = _router.Session.ExecCommand("show ip ospf"); string ospfAreaRouters = _router.Session.ExecCommand("show ip ospf database"); string[] lines = ospfAreaRouters.SplitByLine(); OSPFArea currentArea = null; string currentLSATypeName = ""; List <OSPFLSA> LSAs = new List <OSPFLSA>(); Dictionary <string, List <OSPFLSA> > OSPFLSAs = new Dictionary <string, List <OSPFLSA> >(); foreach (string line in lines.Where(l => l != "").Select(l => l.Trim())) { try { if (line.ToLowerInvariant().Contains("link states (area ")) { string AreaName = Regex.Match(line, @"(?<=\().*?(?=\))")?.Value; string thisAreaID = Regex.Match(AreaName, @"(?<=Area )[\d.]{0,99}")?.Value; string thisLSATypeName = Regex.Match(line.ToLowerInvariant(), @"^.*(?=(link))")?.Value; // line is like : Router Link States (Area 172.20.0.0) if (currentArea == null) { currentArea = new OSPFArea(); currentArea.AreaID = thisAreaID.Trim(); currentArea.AreaType = GetAreaType(currentArea.AreaID); } else if (thisAreaID != currentArea.AreaID) { // area ID is changing this._ospfAreaLSAs[currentArea] = OSPFLSAs; OSPFLSAs = new Dictionary <string, List <OSPFLSA> >(); currentArea = new OSPFArea(); currentArea.AreaID = thisAreaID.Trim(); currentArea.AreaType = GetAreaType(currentArea.AreaID); } //-- if (currentLSATypeName == "") { currentLSATypeName = thisLSATypeName.Trim(); } else if (currentLSATypeName != thisLSATypeName) { // LSA Type is changing OSPFLSAs.Add(currentLSATypeName, LSAs); LSAs = new List <OSPFLSA>(); currentLSATypeName = thisLSATypeName.Trim(); } } else if (line.ToLowerInvariant().Contains("link states")) { // line is like : Type-5 AS External Link States // area is not changing, only the LSA Type string thisLSATypeName = Regex.Match(line.ToLowerInvariant(), @"^.*(?=(link))")?.Value; if (currentLSATypeName != "" && currentLSATypeName != thisLSATypeName) { // LSA Type is changing OSPFLSAs.Add(currentLSATypeName, LSAs); currentLSATypeName = thisLSATypeName; } LSAs = new List <OSPFLSA>(); } else { string[] r = line.ToLowerInvariant().SplitBySpace(); string firstWord = r[0].Trim(); //if first word is ip address, then this is an LSA entry if (IPAddress.TryParse(firstWord, out IPAddress testIP)) { // header : Link ID ADV Router Age Seq# Checksum Link count // line is like :100.65.0.46 100.65.0.46 238 0x8000EBC3 0x00D97D 1 string LSAID = firstWord; // The Adv Router should be the second word in thisLine string AdvRouter = r[1].Trim(); OSPFLSA thisLSA = new OSPFLSA() { LSAType = currentLSATypeName, LSAID = LSAID, AdvRouter = AdvRouter }; LSAs.Add(thisLSA); } } } catch (Exception Ex) { DebugEx.WriteLine("Cisco IOS OSPF Protocol Parser : unable to parse OSPF database line :" + line, DebugLevel.Warning); } } // add the last area router ID-s if (currentArea != null) { this._ospfAreaLSAs[currentArea] = OSPFLSAs; } #endregion #region Local functions OSPFAreaType GetAreaType(string AreaID) { try { if (AreaID == "0.0.0.0") { return(OSPFAreaType.Backbone); } bool scanningAreaBlock = false; List <string> areaBlok = new List <string>(); foreach (string line in ospfOverView.SplitByLine().Select(l => l.ToLowerInvariant().Trim())) { if (line.StartsWith(string.Format("area {0}", AreaID))) { if (scanningAreaBlock) { break; } scanningAreaBlock = true; continue; } if (scanningAreaBlock) { areaBlok.Add(line); } } if (areaBlok.Any(l => l.Contains("nssa"))) { return(OSPFAreaType.NSSA); } if (areaBlok.Any(l => l.Contains("stub"))) { return(OSPFAreaType.Stub); } if (areaBlok.Any(l => l.Contains("totally"))) { return(OSPFAreaType.TotallyStub); } return(OSPFAreaType.Normal); } catch (Exception Ex) { DebugEx.WriteLine("Cisco_IOS_OSPFParser.ProcessOSPFDatabase.GetAreaType() : unexpected error : " + Ex.Message); return(OSPFAreaType.Unknown); } } #endregion }
public void ProcessOSPFDatabase() { if (_router?.Session == null || !_router.Session.IsConnected()) { throw new ArgumentException("Unable to parse OSPF. Either thisRouter or Session parameter is invalid"); } #region Query, parse and store LSAs string ospfOverView = _router.Session.ExecCommand("show ospf overview"); string ospfAreaRouters = _router.Session.ExecCommand("show ospf database"); string[] lines = ospfAreaRouters.SplitByLine(); OSPFArea currentArea = null; string currentLSATypaName = ""; List <OSPFLSA> LSAs = new List <OSPFLSA>(); Dictionary <string, List <OSPFLSA> > OSPFLSAs = new Dictionary <string, List <OSPFLSA> >(); foreach (string line in lines.Select(l => l.Trim())) { // header : Type ID Adv Rtr Seq Age Opt Cksum Len // line is like :Router 10.93.1.200 10.93.1.200 0x800005af 1113 0x8 0x6280 60 try { if (line.StartsWith("{master:")) { continue; } if (line.ToLowerInvariant().StartsWith("ospf database")) { // line is like : OSPF database, Area 10.72.0.0 string[] o = line.SplitByComma(); string[] a = o[1].SplitBySpace(); string thisAreaID = a[1]; if (currentArea == null) { currentArea = new OSPFArea(); currentArea.AreaID = thisAreaID.Trim(); currentArea.AreaType = GetAreaType(currentArea.AreaID); } else if (thisAreaID != currentArea.AreaID) { // area ID is changing this._ospfAreaLSAs[currentArea] = OSPFLSAs; OSPFLSAs = new Dictionary <string, List <OSPFLSA> >(); LSAs = new List <OSPFLSA>(); currentArea = new OSPFArea(); currentArea.AreaID = thisAreaID.Trim(); currentArea.AreaType = GetAreaType(currentArea.AreaID); } } else { // The LSA Type should be the first word in thisLine string[] r = line.ToLowerInvariant().SplitBySpace(); string LSATypeName = r[0]; if (LSATypeName != "type") { if (LSATypeName != currentLSATypaName) { // LSAType is changing if (currentLSATypaName != "") { OSPFLSAs[currentLSATypaName] = LSAs; LSAs = new List <OSPFLSA>(); } currentLSATypaName = LSATypeName; } string LSAID = r[1].TrimStart('*'); string AdvRouter = r[1].Trim(); OSPFLSA thisLSA = new OSPFLSA() { LSAType = currentLSATypaName, LSAID = LSAID, AdvRouter = AdvRouter }; LSAs.Add(thisLSA); } } } catch (Exception Ex) { DebugEx.WriteLine("JunOS IRouter : unable to parse OSPF database line :" + line); } } // add the last area router ID-s if (currentArea != null) { this._ospfAreaLSAs[currentArea] = OSPFLSAs; } #endregion #region Local functions OSPFAreaType GetAreaType(string AreaID) { try { // parsing as per https://www.juniper.net/documentation/en_US/junos/topics/reference/command-summary/show-ospf-ospf3-overview.html if (AreaID == "0.0.0.0") { return(OSPFAreaType.Backbone); } bool inDesiredAreaSection = false; foreach (string line in ospfOverView.SplitByLine().Select(l => l.ToLowerInvariant().Trim())) { if (line.StartsWith(string.Format("area: {0}", AreaID))) { if (inDesiredAreaSection) { break; } inDesiredAreaSection = true; } if (inDesiredAreaSection) { if (line.StartsWith("stub type:")) { string[] typeDesc = line.Split(':'); if (typeDesc[1].Contains("normal stub")) { return(OSPFAreaType.Stub); } if (typeDesc[1].Contains("not stub")) { return(OSPFAreaType.Normal); } if (typeDesc[1].Contains("not so stubby") || typeDesc[1].Contains("nssa")) { return(OSPFAreaType.NSSA); } } } } return(OSPFAreaType.Unknown); } catch (Exception Ex) { DebugEx.WriteLine("JUNOS_OSPFParser.ProcessOSPFDatabase.GetAreaType() : unexpected error : " + Ex.Message); return(OSPFAreaType.Unknown); } #endregion } }