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
     }
 }