public RouterInterface GetInterfaceByName(string InterfaceName) { RouterInterface result = null; if (string.IsNullOrEmpty(InterfaceName)) { throw new ArgumentException("Invalid interface name"); } try { if (_interfaces.ContainsKey(InterfaceName)) { result = _interfaces[InterfaceName]; } else { result = new RouterInterface() { Name = InterfaceName.Trim() }; GetInterfaceConfiguration(result); } } catch (Exception Ex) { string msg = string.Format("JunOS IRouter : error requesting interface configuration for {0} : {1}", result.Name, Ex.Message); DebugEx.WriteLine(msg); } return(result); }
public string GetInterfaceNameByIPAddress(string Address) { if (string.IsNullOrEmpty(Address)) { throw new ArgumentException("Invalid interface address. GetInterfaceNameByIPAddress requires a valid ip address to query."); } string ifName = ""; try { var foundIfName = _interfaces.Values.Where(c => c.Address == Address)?.Select(c => c.Name).FirstOrDefault(); if (foundIfName == null) { string ifInfo = _session.ExecCommand(string.Format("show interfaces terse | match {0}", Address)); // ifInfo should look like : "ge-0/0/9.0 up up inet 172.16.2.30/28 " string[] a = ifInfo.SplitBySpace(); ifName = a[0]; } else { ifName = foundIfName; } } catch (Exception Ex) { string msg = string.Format("JunOS IRouter : error finding interface name for ip address {0} : {1}", Address, Ex.Message); DebugEx.WriteLine(msg); } return(ifName); }
public void Initialize(IScriptExecutorBase Executor) { DebugEx.WriteLine("Initializing PGTNetworkDiscovery CustomActionHandler... ", DebugLevel.Informational); _terminated = false; local_dataset = new CDPDataSet(); local_dataset.Clear(); ScriptSettings = SettingsManager.GetCurrentScriptSettings(); Guid engineID = Executor.EngineID; // search an existing inventory file and load. used later for checking domain boundary InventoryFileName = string.Format("{0}{1}{2}.xml", Helper.GetWorkingDirectory(), Options.Default.InventoryDBDirectory, engineID.ToString()); DebugEx.WriteLine(string.Format("Checking for pre-existing inventory file {0}... ", InventoryFileName), DebugLevel.Informational); if (File.Exists(InventoryFileName)) { try { local_dataset.ReadXml(InventoryFileName); InventoryPreProvisioned = true; AllowRecursion = local_dataset.Parameters.First()?.AllowRecursion ?? Options.Default.MRUActiveDiscovery; DebugEx.WriteLine(string.Format("Inventory file loaded successfully. Active discovery is {0}.", AllowRecursion ? "enabled" : "disabled"), DebugLevel.Informational); } catch (Exception Ex) { DebugEx.WriteLine(string.Format("Error loading inventory file : {0}", Ex.InnerExceptionsMessage())); } } else { AllowRecursion = Options.Default.MRUActiveDiscovery; DebugEx.WriteLine(string.Format("File {0} does not exist. Active discovery is {1}.", InventoryFileName, AllowRecursion ? "enabled" : "disabled"), DebugLevel.Informational); } }
private void _ScriptManager_OnScriptAborted(object sender, Common.ScriptEventArgs e) { DebugEx.WriteLine("COnfigurationManager : OnScriptAborted - " + e.Reason, DebugLevel.Informational); SNGScriptManager thisManager = null; if (sender is ScriptExecutor) { thisManager = ScriptingFormManager.GetScriptManager(sender as ScriptExecutor); } else if (sender is ScriptingForm) { thisManager = (sender as ScriptingForm).ScriptManager; } if (ScriptManagers.Contains(thisManager)) { lock (_lckObject) // locking is required to synchronize potential parallel calls { Invoke(new MethodInvoker(delegate { if (pbPullProgress.Value < pbPullProgress.Maximum) { pbPullProgress.Value += 1; } if (ScriptManagers.Count == 0) { EnableControls(); btnPullConfig.Enabled = true; lblOperationInProgress.Text = "Operation completed"; RefreshScriptManagers(); } btnCancelPull.Visible = !btnPullConfig.Enabled; })); } } }
/// <summary> /// Terminates a script specified by its ScriptManager /// </summary> /// <param name="thisManager"></param> private void TerminateScript(SNGScriptManager thisManager) { bool stopped = false; try { int waitTime = (int)SettingsManager.GetCurrentScriptSettings(this.SNGDataSet).ConnectTimeout.TotalMilliseconds; DebugEx.WriteLine(string.Format("Stopping script {0}...", thisManager.GetScriptName()), DebugLevel.Informational); stopped = thisManager.StopScript(waitTime); thisManager.SetScriptSaved(); DebugEx.WriteLine(string.Format("Closing form for script {0}...", thisManager.GetScriptName()), DebugLevel.Informational); this.Invoke(new MethodInvoker(delegate() { thisManager.CloseForm(); })); } catch (Exception Ex) { DebugEx.WriteLine(string.Format("CancelPullOperation : error while closing Form for <{0}> : {1}", thisManager.GetScriptName() + Ex.Message)); } if (!stopped) { Invoke(new MethodInvoker(delegate { if (pbPullProgress.Value < pbPullProgress.Maximum) { pbPullProgress.Value += 1; } })); } }
public void CreateShape(Visio.Application VApp, Visio.IVDocument drawingDocument) { Visio_shape = VisioInterface.CreateVisioShape(VApp, drawingDocument, X_coord, Y_coord, stencilName, masterNameU); if (Visio_shape == null) { DebugEx.WriteLine(string.Format("Error creating Visio shape for {0}", FullName)); } }
private void _ScriptManager_OnScriptFinished(object sender, Common.ScriptEventArgs e) { DebugEx.WriteLine("ConfigurationManager : OnScriptFinished - " + e.Reason.ToString(), DebugLevel.Informational); SNGScriptManager thisManager = null; if (sender is ScriptExecutor) { thisManager = ScriptingFormManager.GetScriptManager(sender as ScriptExecutor); } else if (sender is ScriptingForm) { thisManager = (sender as ScriptingForm).ScriptManager; } if (ScriptManagers.Contains(thisManager)) { lock (_lckObject) // locking is required to synchronize potential parallel calls { ScriptManagers.Remove(thisManager); if (e.Reason != ScriptEventReason.UserAborted) { Invoke(new MethodInvoker(delegate() { if (pbPullProgress.Value < pbPullProgress.Maximum) { pbPullProgress.Value += 1; } DialogResult saveConfig = DialogResult.Yes; if (cbAutoSave.Checked || (saveConfig = MessageBox.Show(String.Format("Script <{0}> finished. Do you want to auto-save script results to database ?", thisManager.GetScriptName()), "Auto-save", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) == System.Windows.Forms.DialogResult.Yes) { SaveScriptResults(thisManager); } if (saveConfig == DialogResult.Yes) { thisManager.CloseForm(); } if (ScriptManagers.Count == 0) { EnableControls(); btnPullConfig.Enabled = true; lblOperationInProgress.Text = "Operation completed"; RefreshScriptManagers(); } btnCancelPull.Visible = !btnPullConfig.Enabled; })); } else { Invoke(new MethodInvoker(delegate() { if (!IsDisposed && pbPullProgress.Value < pbPullProgress.Maximum) { pbPullProgress.Value += 1; } })); } } } }
public void Parse(INeighborRegistry registry, CancellationToken token) { if (_router?.Session == null || registry == null || !_router.Session.IsConnected()) { throw new ArgumentException("Unable to parse STATIC routes, invalid parameters."); } try { _OperationStatusLabel = "Querying static routes..."; string routes = _router.Session.ExecCommand("show route protocol static"); token.ThrowIfCancellationRequested(); MatchCollection knownNetworks = Regex.Matches(routes, @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b\/\d{1,2}", RegexOptions.Compiled); if (knownNetworks.Count > 0) { _OperationStatusLabel = "Processing static routes..."; // insert actual routes for (int i = 0; i < knownNetworks.Count; i++) { string thisNetwork = knownNetworks[i].Value; int routeBlockStart = knownNetworks[i].Index; int routeBlockEnd = i == knownNetworks.Count - 1 ? routes.Length : knownNetworks[i + 1].Index; string thisRouteBlock = routes.Substring(routeBlockStart, routeBlockEnd - routeBlockStart); bool isBestRoute = thisRouteBlock.IndexOf("*[") > 0; MatchCollection protocolBlocksHeaders = Regex.Matches(thisRouteBlock, @"\[(.*?)\]", RegexOptions.Compiled); for (int j = 0; j < protocolBlocksHeaders.Count; j++) { try { string thisProtocolBlockHeader = protocolBlocksHeaders[j].Value; int protocolBlockStart = protocolBlocksHeaders[j].Index; int protocolBlockEnd = j == protocolBlocksHeaders.Count - 1 ? thisRouteBlock.Length : protocolBlocksHeaders[j + 1].Index; string thisProtocolBlock = thisRouteBlock.Substring(protocolBlockStart, protocolBlockEnd - protocolBlockStart); string thisProtocolName = Regex.Match(thisProtocolBlockHeader, @"[a-zA-Z]+", RegexOptions.Compiled)?.Value; string nextHopAddress = Regex.Match(thisProtocolBlock, @"(?<=to )[\d\.]{0,99}", RegexOptions.Compiled)?.Value; string nextHopViaInterfaceName = Regex.Match(thisProtocolBlock, @"(?<=via ).*", RegexOptions.Compiled)?.Value?.Trim('\r'); _OperationStatusLabel = string.Format("Querying router interface {0}...", nextHopViaInterfaceName); RouterInterface ri = _router.GetInterfaceByName(nextHopViaInterfaceName); _OperationStatusLabel = string.Format("Registering STATIC neighbor {0}...", nextHopAddress); registry.RegisterSTATICNeighbor(_router, thisNetwork, nextHopAddress, ri.Address, ri); } catch (Exception Ex) { DebugEx.WriteLine("Jumos_STATICParser error : " + Ex.Message); } } } } _OperationStatusLabel = "JunOS STATIC route parser completed."; } catch (Exception Ex) { _OperationStatusLabel = "JunOS STATIC route parser failed with error : " + Ex.Message; } }
private void LoadConfigurationFromFile(string FileName = "") { try { openFileDialog.Filter = "TXT files|*.txt|All files|*.*"; if (FileName != "" || openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if ((tbConfigurationLines.Text.Length == 0 & !targetConfigurationChanged) || MessageBox.Show("Overwrite configuration from file ?", "Open file", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { tbConfigurationLines.Text = ""; tbConfigurationLines.Lines = File.ReadAllLines(FileName != "" ? FileName : openFileDialog.FileName); DebugEx.WriteLine("ConfigManager read configuration from file " + FileName, DebugLevel.Informational); } } } catch (Exception Ex) { MessageBox.Show("Unfortunately an error occurred : " + Ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public bool GetInterfaceConfiguration(RouterInterface checkInterface) { bool result = false; try { if (string.IsNullOrEmpty(checkInterface?.Name)) { throw new ArgumentException("Interface parameter and/or interface name must not be null"); } if (_interfaces.ContainsKey(checkInterface.Name)) { checkInterface.Configuration = _interfaces[checkInterface.Name].Configuration; } else { checkInterface.Configuration = _session.ExecCommand(string.Format("show configuration interfaces {0}", checkInterface.Name)); string desc = Regex.Match(checkInterface.Configuration, @"(?<=description ).*", RegexOptions.Compiled)?.Value; checkInterface.Description = desc.TrimEnd('\r'); var ifIP = Regex.Match(checkInterface.Configuration, @"(?<=address )[\/\d.]{0,99}", RegexOptions.Compiled); if (ifIP.Success) { string[] addressAndMask = ifIP.Value.Split('/'); checkInterface.Address = addressAndMask[0]; checkInterface.MaskLength = addressAndMask.Length >= 2 ? addressAndMask[1] : ""; } _interfaces.Add(checkInterface.Name, checkInterface); } result = true; } catch (Exception Ex) { string msg = string.Format("JunOS IRouter : error requesting interface configuration for {0} : {1}", checkInterface.Name, Ex.Message); DebugEx.WriteLine(msg); } return(result); }
/// <summary> /// Checks database and creates it if missing and also creates required DB objects /// </summary> /// <param name="ServerName">The SQL Server name to connect to</param> /// <param name="DatabaseName">The name of the database to check or create</param> /// <param name="intSecurity">If integrated security to be used for connection</param> /// <param name="sqlUserName">SQL Username for connection</param> /// <param name="sqlPassword">SQL Password for connection</param> /// <param name="animation">A Backgoundworker to stop before displaying any dialog boxes. Optional</param> /// <returns></returns> public static bool RegisterDatabase(string ServerName, string DatabaseName, bool intSecurity, string sqlUserName, string sqlPassword, WorkInProgress animation = null) { bool runResult = true; bool DBExists = false; bool DBCreated = false; bool DBObjectsCreated = false; try { #region Create Database if not exists string MasterConnectionString = intSecurity ? string.Format("Data Source={0};Initial Catalog=master;Integrated Security=True", ServerName) : string.Format("Data Source={0};Initial Catalog=master;Persist Security Info=True;User ID={1};Password={2}", ServerName, sqlUserName, sqlPassword); DebugEx.WriteLine(string.Format("Connecting to master db using : {0}", MasterConnectionString), DebugLevel.Informational); using (SqlConnection conn = new SqlConnection(MasterConnectionString)) { try { conn.Open(); #region Test database existence try { DebugEx.WriteLine(string.Format("Checking database : {0}", DatabaseName), DebugLevel.Informational); SqlCommand scmd = conn.CreateCommand(); scmd.CommandText = string.Format("SELECT name FROM master.sys.databases WHERE name = N'{0}'", DatabaseName); object o = new object(); o = scmd.ExecuteScalar(); DBExists = o != null; if (!DBExists) { DebugEx.WriteLine("database doesn't exist", DebugLevel.Informational); animation?.Cancel(); runResult = MessageBox.Show(string.Format("Database {0} does not exists. Do you want to create it now?", DatabaseName), "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes; if (runResult) { animation?.Run(); } } else { DebugEx.WriteLine("database exists", DebugLevel.Informational); } } catch (SqlException Ex) { DebugEx.WriteLine("Unexpected error 1"); animation?.Cancel(); MessageBox.Show(string.Format("Unexpected error while checking database {0} : {1} ", DatabaseName, Ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); runResult = false; } #endregion if (runResult & !DBExists) { #region Create database try { DebugEx.WriteLine(string.Format("Creating database : {0}", DatabaseName), DebugLevel.Informational); SqlCommand scmd = conn.CreateCommand(); scmd.CommandText = "CREATE DATABASE " + DatabaseName; scmd.ExecuteNonQuery(); scmd.CommandText = string.Format("ALTER DATABASE {0} SET AUTO_SHRINK ON", DatabaseName); scmd.ExecuteNonQuery(); DBCreated = true; DebugEx.WriteLine("database created successfully", DebugLevel.Informational); } catch (SqlException Ex) { if (((SqlException)Ex).Number == 1801) { DebugEx.WriteLine("database already exists", DebugLevel.Informational); } else { DebugEx.WriteLine("Unexpected error 2"); animation?.Cancel(); MessageBox.Show(string.Format("Unexpected error while creating database {0} : {1} ", DatabaseName, Ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); runResult = false; } } #endregion } } catch (SqlException Ex) { DebugEx.WriteLine("Unexpected error 3"); animation?.Cancel(); MessageBox.Show(string.Format("Unexpected error while opening connection : {0} ", Ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); runResult = false; } } #endregion if (runResult) { #region Connect to database and create database objects if missing string InstallerConnectionString = intSecurity ? string.Format("Data Source={0};Initial Catalog={1};Integrated Security=True", ServerName, DatabaseName) : string.Format("Data Source={0};Initial Catalog={1};Persist Security Info=True;User ID={1};Password={2}", ServerName, DatabaseName, sqlUserName, sqlPassword); DebugEx.WriteLine(string.Format("Connecting using : {0}", InstallerConnectionString), DebugLevel.Informational); using (SqlConnection conn = new SqlConnection(InstallerConnectionString)) { conn.Open(); SqlCommand scmd; try { try { #region Check if require objects exist DebugEx.WriteLine("Checking database objects", DebugLevel.Informational); bool RequiredObjectsExist = false; // This is to try whether required database objects exist or not scmd = new SqlCommand("SELECT COUNT (*) FROM CONFIGTARGETS", conn); try { object o = new object(); o = scmd.ExecuteScalar(); RequiredObjectsExist = true; } catch (SqlException Ex) { // Error number 208 is normal, meaning that there is no Params table yet if (((SqlException)Ex).Number == 208) { DebugEx.WriteLine("Error 208 : there is no CONFIGTARGETS table yet"); } else { // other exceptions are unexpected and unhandled errors animation?.Cancel(); MessageBox.Show(string.Format("Unexpected error while creating database {0} : {1} ", DatabaseName, Ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); runResult = false; throw Ex; } } #endregion #region Run DDL script if required objects do not exist if (!RequiredObjectsExist) { // this is a new empty database DebugEx.WriteLine("this is a new empty database, running DDL script", DebugLevel.Informational); try { string SqlScript = Resource1.CreateConfigManagerObjects_20151007_v1; SqlScript = SqlScript.Replace("GO", "^"); string[] SqlCommands = SqlScript.Split("^".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string command in SqlCommands) { DebugEx.WriteLine(scmd.CommandText); scmd = new SqlCommand(command, conn); scmd.ExecuteNonQuery(); } DBObjectsCreated = true; DebugEx.WriteLine("DB objects created sucessfully", DebugLevel.Informational); } catch (Exception Ex) { animation?.Cancel(); MessageBox.Show(string.Format("Unexpected error while creating database objects : {0} ", Ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); runResult = false; } } #endregion } finally { conn.Close(); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Sorry, I am unable to register database. Please view debug logs for more details.", MessageBoxButtons.OK, MessageBoxIcon.Error); runResult = false; } } #endregion } } catch (Exception ex) { animation?.Cancel(); MessageBox.Show("Sorry, I am unable to register database. Please view debug logs for more details. Error : " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); runResult = false; } if (DBCreated | DBObjectsCreated) { animation?.Cancel(); string s = DBCreated ? "Database created sucessfully." : ""; if (DBObjectsCreated) { s += " Required database objects created sucessfully."; } MessageBox.Show(s, "SQL Operation success", MessageBoxButtons.OK, MessageBoxIcon.Information); } return(runResult); }
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 } }
private void WriteToLog(string message) { DebugEx.WriteLine(message); }
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 Terminate() { DebugEx.WriteLine("Terminating PGTNetworkDiscovery CustomActionHandler and saving Inventory information", DebugLevel.Informational); bool RetryWrite = true; while (RetryWrite) { try { if (!Directory.Exists(Path.GetDirectoryName(InventoryFileName))) { Directory.CreateDirectory(Path.GetDirectoryName(InventoryFileName)); } var LockedBy = PGT.Common.FileUtil.WhoIsLocking(InventoryFileName); if (LockedBy.Count > 0) { string ProcessList = string.Join(";", LockedBy.Select(p => p.ProcessName)); RetryWrite = MessageBox.Show(string.Format("The file {0} is being used by processes : {1}. Do you want to retry ?", InventoryFileName, ProcessList), "Could not create inventory file", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes; } else { local_dataset.WriteXml(InventoryFileName); RetryWrite = false; if (!InventoryPreProvisioned && MessageBox.Show("Do you want to save the inventory to a specific file ?\r\nIf you choose No, the temporary inventory file will be retained.", "Save As", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "CDP Inventory database|*.xml|All Files|*.*"; if (sfd.ShowDialog() == DialogResult.OK) { try { local_dataset.WriteXml(sfd.FileName); MessageBox.Show("Inventory saved successfully", "Operation completed", MessageBoxButtons.OK, MessageBoxIcon.Information); try { // as the inventory file was not pre-provisioned and hence the CDP2Visio handler will not be searching for it // we can safely delete the file File.Delete(InventoryFileName); } catch (Exception Ex) { string msg = string.Format("Error while removing temporary inventory file : {0}", InventoryFileName, Ex.Message); DebugEx.WriteLine(Ex.InnerExceptionsMessage()); } } catch (Exception Ex) { string msg = string.Format("Unfortunately an unexpected error occurred while saving inventory to file {0}. Error is : {1}", sfd.FileName, Ex.InnerExceptionsMessage()); DebugEx.WriteLine(msg); MessageBox.Show(msg, "Could not create inventory file", MessageBoxButtons.YesNo, MessageBoxIcon.Error); } } } } } catch (Exception Ex) { string msg = string.Format("Unfortunately an unexpected error occurred while writing inventory to file {0}. Error is : {1}. Do you want to retry ?", InventoryFileName, Ex.InnerExceptionsMessage()); DebugEx.WriteLine(msg); RetryWrite = MessageBox.Show(msg, "Could not create inventory file", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes; } } _terminated = true; }
public bool DoCustomAction(IScriptExecutorBase Executor, DeviceConnectionInfo ConnectionInfo, out dynamic ActionResult, out bool ConnectionDropped, out bool BreakExecution) { bool result = false; ActionResult = "Custom action not implemented"; ConnectionDropped = false; BreakExecution = false; IScriptableSession st = (IScriptableSession)Executor.Session; int DeviceID = 0; if (ConnectionInfo.CustomActionID == "PGTNetworkDiscovery") { if (ConnectionInfo.VendorName.ToLowerInvariant() == "cisco") { #region Cisco ActionResult = "Error processing PGTNetworkDiscovery for Cisco"; string show_ver = string.Empty; string device_type = "router"; string actual_hostname = string.Empty; string show_inventory = string.Empty; string system_serial = string.Empty; #region SHOW VER, Virtual switch, Stacked switch Executor.ShowActivity("Retrieving device information..."); show_ver = st.ExecCommand("sh ver"); actual_hostname = st.GetHostName(); string virtualswitch = st.ExecCommand("sh switch virtual"); bool isVSS = false; try { isVSS = virtualswitch.SplitByLine().First().Split(':')[1].ToLowerInvariant().Trim() == "virtual switch"; } catch (Exception Ex) { DebugEx.WriteLine(String.Format("CDP2VISIO : error parsing \"sh virtual switch\" output : {0}", Ex.InnerExceptionsMessage()), DebugLevel.Debug); } int stackCount = 0; string stackedswitches = st.ExecCommand("sh switch"); try { if (stackedswitches.ToLowerInvariant().StartsWith("switch/stack")) { stackCount = stackedswitches.SplitByLine().Count(l => l.SplitBySpace()[0].Trim('*').IsInt()); } } catch (Exception Ex) { DebugEx.WriteLine(String.Format("CDP2VISIO : error parsing \"sh switch\" output : {0}", Ex.InnerExceptionsMessage()), DebugLevel.Debug); } #endregion try { #region Identify device show_inventory = st.ExecCommand("show inventory"); // Indicates that we are connected to an ASA, using later for VLAN discovery bool isASA = show_inventory.IndexOf("Adaptive Security Appliance") >= 0; // some switches doe no support the "show inventory" command bool exec_error = show_inventory.ToLowerInvariant().Contains("invalid input detected") || ScriptSettings.FailedCommandPattern.SplitBySemicolon().Any(w => show_inventory.IndexOf(w) >= 0); if (exec_error) { DebugEx.WriteLine(String.Format("CDP2VISIO : switch does not support \"sh inventory\" command, parsing version information"), DebugLevel.Debug); // try to parse sh_version to get system serial numbers try { system_serial = string.Join(",", show_ver.SplitByLine().Where(l => l.StartsWith("System serial number")).Select(l => l.Split(':')[1].Trim())); } catch (Exception Ex) { DebugEx.WriteLine(String.Format("CDP2VISIO : error searching serial number in \"sh version\" output : {0}", Ex.InnerExceptionsMessage()), DebugLevel.Debug); } } else { // This should return system serial most of the time try { if (stackCount > 0) { // if stackCount > 0 the switch supported the "show switch" command. Probably also understands "show module" string modules = st.ExecCommand("show module"); // some switches who support the "show switch" command may still do not understand "show modules" exec_error = modules.ToLowerInvariant().Contains("invalid input detected") || ScriptSettings.FailedCommandPattern.SplitBySemicolon().Any(w => modules.IndexOf(w) >= 0); if (exec_error) { DebugEx.WriteLine(String.Format("CDP2VISIO : switch does not support \"sh module\" command, parsing version information"), DebugLevel.Debug); // try to parse sh_version to get system serial numbers system_serial = string.Join(",", show_ver.SplitByLine().Where(l => l.StartsWith("System serial number")).Select(l => l.Split(':')[1].Trim())); } else { // select lines starting with a number. These are assumed the be the switches in stack var switchList = modules.SplitByLine().Where(l => l.SplitBySpace()[0].Trim('*').IsInt()); // each line contains the serial number in th 4th column system_serial = string.Join(",", switchList.Select(m => m.SplitBySpace()[3])); } } else { system_serial = show_inventory.SplitByLine().First(l => l.StartsWith("PID:")).Split(',')[2].Split(':')[1].Trim(); } } catch (Exception Ex) { system_serial = "parsing error"; DebugEx.WriteLine(string.Format("Error parsing serial number : {0}", Ex.InnerExceptionsMessage()), DebugLevel.Error); } } #endregion #region Add New Device to DB with inlist // Two devices considered identical if : // - have the same hostname, or // - have the same IPAddress CDPDataSet.DevicesRow device_row = local_dataset.Devices.FirstOrDefault(d => d.IP_Address.SplitBySemicolon().Any(thisIP => thisIP == ConnectionInfo.DeviceIP) || d.Name.SplitBySemicolon().Any(thisName => DottedNameSpace.CompateTLD(thisName, ConnectionInfo.HostName)) ); if (device_row == null) //If NOT found in the DB have to ADD as new { device_row = local_dataset.Devices.NewDevicesRow(); device_row.SystemSerial = system_serial; device_row.IP_Address = ConnectionInfo.DeviceIP; device_row.Name = actual_hostname; device_row.VersionInfo = show_ver; device_row.Type = isASA ? "ASA" : isVSS ? "VSS" : stackCount > 1 ? string.Format("Stack{0}", stackCount) : device_type; device_row.Inventory = show_inventory; local_dataset.Devices.AddDevicesRow(device_row); DeviceID = device_row.ID; } else //IF found in the existing DB have to update! { device_row.VersionInfo = show_ver; device_row.Inventory = show_inventory; device_row.SystemSerial = system_serial; if (isASA) { device_row.Type = "ASA"; } else if (isVSS) { device_row.Type = "VSS"; } else if (stackCount > 1) { device_row.Type = string.Format("Stack{0}", stackCount); } } #endregion #region SHOW CDP NEIGHBOUR if (!isASA) { Executor.ShowActivity("Checking for CDP neighbors..."); string cdpResult = st.ExecCommand("sh cdp neighbors detail"); CDPParser thisParser; if (show_ver.IndexOf("NX-OS") >= 0) { thisParser = new NXOS_CDPParser(Executor, ConnectionInfo, AllowRecursion); thisParser.ProcessCDPResult(cdpResult, device_row, local_dataset); } else { thisParser = new IOS_CDPParser(Executor, ConnectionInfo, AllowRecursion); thisParser.ProcessCDPResult(cdpResult, device_row, local_dataset); } } #endregion #region Collect interface configuration details for CDP connected interfaces Executor.ShowActivity("Collecting CDP connected interface information..."); var query_local_interfaces = from device in local_dataset.Devices where (device.ID == device_row.ID) join neigh in local_dataset.Neighbours on device.ID equals neigh.Parent_ID select new { local_int = neigh.Local_Interface, ID = device.ID, }; foreach (var thisInterface in query_local_interfaces) { CDP2VISIO.CDPDataSet.InterfacesRow interface_row = null; interface_row = local_dataset.Interfaces.NewInterfacesRow(); string command = "sh run interface " + thisInterface.local_int; string commandResult = st.ExecCommand(command); commandResult = commandResult.ToLower(); string[] lines_in_commandresult = commandResult.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); string interface_config = string.Empty; bool addtoconfig = false; foreach (var line in lines_in_commandresult) { if (line.IndexOf(RevConvInt(thisInterface.local_int)) >= 0) { addtoconfig = true; } if (addtoconfig) { interface_config = interface_config + line + "\r\n"; } } interface_row.ID = thisInterface.ID; interface_row.Name = thisInterface.local_int; interface_row.Running_config = interface_config; local_dataset.Interfaces.AddInterfacesRow(interface_row); } #endregion #region Collect overall interface status information if (Options.Default.DisplayConnected && !isASA) { Executor.ShowActivity("Checking interface status..."); string[] ifDesc = st.ExecCommand("show interface description").SplitByLine(); foreach (string thisIfDescription in ifDesc.SkipWhile((string s, int i) => i < 1)) { string[] ifDescrWords = thisIfDescription.SplitBySpace(); string IFName = Common.ConvInt(ifDescrWords[0]); if (!IFName.StartsWith("vl")) // Don't care vlan interfaces here { string IFStatus = string.Format("{0}/{1}", ifDescrWords[1], ifDescrWords[2]); string IFDescription = string.Join(" ", ifDescrWords.SkipWhile((string s, int i) => i < 3)); var foundIF = from thisIF in local_dataset.Interfaces where thisIF.ID == device_row.ID && thisIF.Name == IFName select thisIF; if (foundIF.Count() == 1) { // Update existing IF data foundIF.ElementAt(0).Status = IFStatus; foundIF.ElementAt(0).Description = IFDescription; } else { // Add as new IF CDPDataSet.InterfacesRow thisIF = local_dataset.Interfaces.NewInterfacesRow(); thisIF.ID = device_row.ID; thisIF.Name = IFName; thisIF.Status = IFStatus; thisIF.Description = IFDescription; local_dataset.Interfaces.AddInterfacesRow(thisIF); } } } } #endregion #region Collect VLAN interface information if (isASA) { Executor.ShowActivity("Gathering VLAN information..."); // Contains the L3 information : interface names, interface ip, network, mask List <string> VLANInfo = new List <string>(); string asaIFs = st.ExecCommand("sh int ip brief"); device_row.L3InterfaceInformation = asaIFs; foreach (string thisInterface in asaIFs.SplitByLine().SkipWhile(l => l.StartsWith("Interface"))) { string[] ifWords = thisInterface.SplitBySpace(); string asaIFName = ifWords[0]; string nameIF = ""; string secLevel = ""; string vlanIPAddr = ""; string vlanNetMask = ""; string netaddress = ""; int maskLength = 0; int vlanID = 0; string thisIFConfig = st.ExecCommand(string.Format("sh run int {0}", asaIFName)); foreach (string thisConfigLine in thisIFConfig.SplitByLine().Select(s => s.Trim())) { if (thisConfigLine.StartsWith("vlan")) { int.TryParse(thisConfigLine.SplitBySpace()[1], out vlanID); } else if (thisConfigLine.StartsWith("nameif")) { nameIF = thisConfigLine.SplitBySpace()[1]; } else if (thisConfigLine.StartsWith("security-level")) { secLevel = thisConfigLine.SplitBySpace()[1]; } else if (thisConfigLine.StartsWith("ip address")) { string[] lineWords = thisConfigLine.SplitBySpace(); vlanIPAddr = lineWords[2]; vlanNetMask = lineWords[3]; maskLength = IPOperations.GetMaskLength(vlanNetMask); netaddress = IPOperations.GetNetworkAddress(vlanIPAddr, maskLength); } } string networkAddressPrint = ""; if (maskLength > 0) { networkAddressPrint = string.Format("{0}/{1}", netaddress, maskLength); } string reportedIFName = string.Format("{0} name: {1} security-level: {2}", asaIFName, nameIF, secLevel); VLANInfo.Add(string.Join(";", new string[] { vlanID == 0 ? "routed" : vlanID.ToString(), reportedIFName, vlanIPAddr, vlanNetMask, networkAddressPrint })); #region Add ASA interface to inventory database string IFStatus = "n/a"; if (ifWords.Length == 6) { IFStatus = string.Format("{0}/{1}", ifWords[4], ifWords[5]); } else if (ifWords.Length == 7) { IFStatus = string.Format("{0} {1}/{2}", ifWords[4], ifWords[5], ifWords[6]); } var foundIF = from thisIF in local_dataset.Interfaces where thisIF.ID == device_row.ID && thisIF.Name == asaIFName select thisIF; if (foundIF.Count() == 1) { // Update existing IF data foundIF.ElementAt(0).Status = IFStatus; foundIF.ElementAt(0).Description = reportedIFName; } else { // Add as new IF CDPDataSet.InterfacesRow thisIF = local_dataset.Interfaces.NewInterfacesRow(); thisIF.ID = device_row.ID; thisIF.Name = asaIFName; thisIF.Status = IFStatus; thisIF.Description = reportedIFName; local_dataset.Interfaces.AddInterfacesRow(thisIF); } #endregion } device_row.VLANInformation = string.Join(Environment.NewLine, VLANInfo); } else { Executor.ShowActivity("Gathering VLAN interface information..."); // TODO : for routers, also include "sh ip int brief" string vlanIFs = st.ExecCommand("sh ip int brief | i [Vv]lan"); device_row.L3InterfaceInformation = vlanIFs; #region Collect network details for VLANs // Contains the list of VLAN interface names List <string> VLANInterfaces = Regex.Matches(vlanIFs, "^Vlan(\\d+)", RegexOptions.Multiline).Cast <Match>().Select(m => m.Value.ToLowerInvariant()).ToList(); // Contains the L3 information : interface names, interface ip, network, mask List <string> VLANInfo = new List <string>(); string vlans = st.ExecCommand("sh vlan"); bool addLineToOutput = false; foreach (string line in vlans.SplitByLine()) { if (line.StartsWith("---")) { addLineToOutput = !addLineToOutput; if (!addLineToOutput) { break; } } else if (addLineToOutput) { string[] words = line.SplitBySpace(); int vlanID = -1; if (int.TryParse(words[0], out vlanID)) { string vlanName = words[1]; string vlanIPAddr = ""; string vlanNetMask = ""; string netaddress = ""; int maskLength = 0; // Check if current VLAN has a corresponding VLAN interface definition if (VLANInterfaces.Contains(string.Format("vlan{0}", vlanID))) { string vlanIntConfig = st.ExecCommand(string.Format("sh run int vlan{0}", vlanID)); string ipAddressLine = vlanIntConfig.SplitByLine().FirstOrDefault(l => l.Trim().StartsWith("ip address")); if (ipAddressLine != null) { string[] addr = ipAddressLine.SplitBySpace(); vlanIPAddr = addr[2]; vlanNetMask = addr[3]; maskLength = IPOperations.GetMaskLength(vlanNetMask); netaddress = IPOperations.GetNetworkAddress(vlanIPAddr, maskLength); } else { ipAddressLine = vlanIntConfig.SplitByLine().FirstOrDefault(l => l.Trim().StartsWith("no ip address")); if (ipAddressLine != null) { vlanIPAddr = "no ip address"; } } } string networkAddressPrint = ""; if (maskLength > 0) { networkAddressPrint = string.Format("{0}/{1}", netaddress, maskLength); } VLANInfo.Add(string.Join(";", new string[] { vlanID.ToString(), vlanName, vlanIPAddr, vlanNetMask, networkAddressPrint })); } } } device_row.VLANInformation = string.Join(Environment.NewLine, VLANInfo); #endregion } #endregion result = true; ActionResult = "Discovery information processing finished successfully."; if (system_serial == "") { ActionResult += "Warning : Could not identify system serial number."; } } catch (Exception Ex) { ActionResult = string.Format("Unexpected processing error : {0} {1}", Ex.Message, Ex.InnerException?.Message); } #endregion } else if (ConnectionInfo.VendorName.ToLowerInvariant() == "junos") { #region JunOS // // http://www.juniper.net/documentation/en_US/junos11.1/topics/task/configuration/802-1x-lldp-cli.html // ActionResult = "Error processing PGTNetworkDiscovery for JunOS"; string show_ver = string.Empty; string device_type = "router"; string actual_hostname = string.Empty; string show_inventory = string.Empty; string system_serial = string.Empty; int stackCount = 0; #region Identify device show_inventory = st.ExecCommand("show chassis hardware"); // Indicates that we are connected to an ASA, using later for VLAN discovery bool isASA = show_inventory.IndexOf("Adaptive Security Appliance") >= 0; // some switches doe no support the "show inventory" command bool exec_error = show_inventory.ToLowerInvariant().Contains("invalid input detected") || ScriptSettings.FailedCommandPattern.SplitBySemicolon().Any(w => show_inventory.IndexOf(w) >= 0); if (exec_error) { DebugEx.WriteLine(String.Format("CDP2VISIO : switch does not support \"sh inventory\" command, parsing version information"), DebugLevel.Debug); // try to parse sh_version to get system serial numbers try { system_serial = string.Join(",", show_ver.SplitByLine().Where(l => l.StartsWith("System serial number")).Select(l => l.Split(':')[1].Trim())); } catch (Exception Ex) { DebugEx.WriteLine(String.Format("CDP2VISIO : error searching serial number in \"sh version\" output : {0}", Ex.InnerExceptionsMessage()), DebugLevel.Debug); } } else { // This should return system serial most of the time try { if (stackCount > 0) { // if stackCount > 0 the switch supported the "show switch" command. Probably also understands "show module" string modules = st.ExecCommand("show module"); // some switches who support the "show switch" command may still do not understand "show modules" exec_error = modules.ToLowerInvariant().Contains("invalid input detected") || ScriptSettings.FailedCommandPattern.SplitBySemicolon().Any(w => modules.IndexOf(w) >= 0); if (exec_error) { DebugEx.WriteLine(String.Format("CDP2VISIO : switch does not support \"sh module\" command, parsing version information"), DebugLevel.Debug); // try to parse sh_version to get system serial numbers system_serial = string.Join(",", show_ver.SplitByLine().Where(l => l.StartsWith("System serial number")).Select(l => l.Split(':')[1].Trim())); } else { // select lines starting with a number. These are assumed the be the switches in stack var switchList = modules.SplitByLine().Where(l => l.SplitBySpace()[0].Trim('*').IsInt()); // each line contains the serial number in th 4th column system_serial = string.Join(",", switchList.Select(m => m.SplitBySpace()[3])); } } else { system_serial = show_inventory.SplitByLine().First(l => l.StartsWith("PID:")).Split(',')[2].Split(':')[1].Trim(); } } catch (Exception Ex) { system_serial = "parsing error"; DebugEx.WriteLine(string.Format("Error parsing serial number : {0}", Ex.InnerExceptionsMessage()), DebugLevel.Error); } } #endregion #endregion } } return(result); }
public void Parse(INeighborRegistry registry, CancellationToken token) { if (_router?.Session == null || !_router.Session.IsConnected()) { throw new ArgumentException("Unable to parse OSPF. Either thisRouter or Session parameter is invalid"); } try { _OperationStatusLabel = "Querying OSPF neighbors..."; string TextToParse = _router.Session.ExecCommand("show ospf neighbor"); _OperationStatusLabel = "Querying OSPF interfaces..."; string ospfInterfaces = _router.Session.ExecCommand("show ospf interface"); _OperationStatusLabel = "Processing OSPF data..."; token.ThrowIfCancellationRequested(); string[] ospf_lines = TextToParse.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); string neighborRouterID = ""; string neighborState = ""; string remoteNeighboringIP = ""; string description = ""; foreach (string line in ospf_lines.Select(l => l.Trim())) { neighborRouterID = ""; neighborState = ""; remoteNeighboringIP = ""; description = ""; DebugEx.WriteLine(String.Format("JUNOS_OSPF_PARSER : parsing OSPF neighbor row [ {0} ]", line), DebugLevel.Full); token.ThrowIfCancellationRequested(); try { string[] words = line.SplitBySpace(); if (words.Length < 4) { continue; // this line is something else } // Words should be: // Address,Interface,State,ID,Pri,Dead // 10.0.0.241,ae0.0,Full,10.0.0.254,128,34 neighborState = words[2]; IPAddress nIP; IPAddress nID; if (System.Net.IPAddress.TryParse(words[0], out nIP) && System.Net.IPAddress.TryParse(words[3], out nID)) { // This is a new peer, initialize variables _OperationStatusLabel = string.Format("Querying router interface {0}...", words[1]); RouterInterface ri = _router.GetInterfaceByName(words[1]); if (ri != null) { // add OSPF Area info to RouterInterface if (ospfInterfaces != "") { string ospfIntfLine = ospfInterfaces.SplitByLine().FirstOrDefault(l => l.Trim().StartsWith(ri.Name)); if (!string.IsNullOrEmpty(ospfIntfLine)) { string[] w = ospfIntfLine.SplitBySpace(); // words array header : Interface,State,Area,DR ID,BDR ID,Nbrs // words should be like: lo0.0,DRother,0.0.0.0,0.0.0.0,0.0.0.0,0 ri.OSPFArea = w[2]; } } neighborRouterID = nID.ToString(); remoteNeighboringIP = nIP.ToString(); description = ""; _OperationStatusLabel = string.Format("Registering OSPF neighbor {0}...", neighborRouterID); registry.RegisterNeighbor(_router, RoutingProtocol.OSPF, neighborRouterID, "", description, remoteNeighboringIP, ri, neighborState); } } } catch (OperationCanceledException) { throw; } catch (Exception Ex) { string msg = String.Format("OSPFarser : Error while parsing ospf output line [{0}]. Error is : {1}", line, Ex.InnerExceptionsMessage()); DebugEx.WriteLine(msg); _OperationStatusLabel = msg; } } _OperationStatusLabel = "JunOS OSPF route parser completed."; } catch (Exception Ex) { _OperationStatusLabel = "JunOS OSPF parser failed with error : " + Ex.Message; } }
public virtual void ProcessCDPResult(string command_result, CDPDataSet.DevicesRow parent_device, CDPDataSet ds) { if (command_result.IndexOf("CDP is not enabled") >= 0) { parent_device.CDP_status = false; } else { string[] cdp_lines = command_result.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); CDPDataSet.DevicesRow current_device = null; // As going through the CDP output lines, this is the actual neighbor string currentDeviceName = ""; string currentDeviceIP = ""; CDPDataSet.NeighboursRow new_neigbor = null; // This is the neighbor created for current_device as a neighbor of parent_device PGTDataSet.ScriptSettingRow ScriptSettings = SettingsManager.GetCurrentScriptSettings(); // As the ip address must be unique for each device, adding a device with ip address of nocdpip constant would fail for the second time // To overcome this issue, we do indexing for devices with no ip address (such as VMware ESX hosts) int nocdpip_index = 0; foreach (string line in cdp_lines) { DebugEx.WriteLine(String.Format("CDP2VISIO : parsing cdp neighbor row [ {0} ]", line), DebugLevel.Full); try { bool isVMWareESX = false; #region Check for DeviceID line and set currentDeviceName accordingly if (line.IndexOf(DeviceID()) >= 0) { try { if (new_neigbor != null) { ds.Neighbours.AddNeighboursRow(new_neigbor); } } catch (Exception Ex) { // Depending on discovery list, under special circumstances it can happen that we try to add a new neighbor row // with the same connection parameters (same parent, neighbor and interfaces) that will violate unique key constraint DebugEx.WriteLine(String.Format("CDP2VISIO : Error storing neighbor row : {0}", Ex.InnerExceptionsMessage()), DebugLevel.Warning); } new_neigbor = null; string[] words = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); currentDeviceName = words[2].Trim();; currentDeviceIP = ""; DebugEx.WriteLine(String.Format("CDP2VISIO : CDPParser found a new neighbor : {0}", currentDeviceName), DebugLevel.Informational); } #endregion if (currentDeviceName == "") { continue; } #region Check for IPAddress line and set currentDeviceIP accordingly if (line.IndexOf(IPAddress()) >= 0) { string[] words_in_line = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); currentDeviceIP = words_in_line[2].Trim(); if (currentDeviceIP == "") { DebugEx.WriteLine(String.Format("CDP2VISIO : cdp is not reporting ip address for neighbor {0}", currentDeviceName), DebugLevel.Debug); currentDeviceIP = string.Format("{0}_{1}", nocdpip, nocdpip_index); nocdpip_index++; } } #endregion #region Check whether the Platform is VMware ESX if (line.Trim().StartsWith("Platform:")) { string[] words = line.SplitByComma(); // words[0] should be PlatForm, words[1] is Capabilities isVMWareESX = words[0].ToLowerInvariant().IndexOf("vmware esx") >= 0; if (isVMWareESX) { DebugEx.WriteLine(String.Format("CDP2VISIO : neighbor {0} is an ESX host", currentDeviceName), DebugLevel.Debug); currentDeviceIP = string.Format("{0}_{1}", nocdpip, nocdpip_index); nocdpip_index++; } } #endregion if (currentDeviceIP == "") { continue; } #region Add current device as new device or select existing device from Devices table // At this point we can identify the current device(cdp neighbor) by name and ip. This is also a new neighbor // Two devices considered identical if : // - have the same hostname, or // - have the same IPAddress string currentDeviceHostName = DottedNameSpace.TLD(currentDeviceName); current_device = ds.Devices.FirstOrDefault(d => currentDeviceIP != nocdpip && d.IP_Address.SplitBySemicolon().Any(thisIP => thisIP == currentDeviceIP) || d.Name.SplitBySemicolon().Any(thisName => DottedNameSpace.CompateTLD(thisName, currentDeviceHostName)) ); if (current_device == null) { DebugEx.WriteLine(String.Format("CDP2VISIO : neighbor {0} is a new device, adding to devices data table", currentDeviceName), DebugLevel.Informational); // This device is not yet known. Add to device list and also to list of devices in script current_device = ds.Devices.NewDevicesRow(); //if (current_device.Name != currentDeviceName) current_device.Name += ";" + currentDeviceName; //else current_device.Name = currentDeviceName; if (current_device.IsIP_AddressNull() || current_device.IP_Address == "") { current_device.IP_Address = currentDeviceIP; } else if (current_device.IP_Address != currentDeviceIP) { current_device.IP_Address += ";" + currentDeviceIP; } ds.Devices.AddDevicesRow(current_device); // Add a new entry for discovered device if has a valid neighbor ip, Recursion is allowed // and this ip is not defined as discovery boundary if (_AllowRecursion && !currentDeviceIP.StartsWith(nocdpip)) { var includedAddresses = (from addressdefinition in ds.DomainBoundary where addressdefinition.Action == BoundaryAddressAction.Include.ToString() select addressdefinition.IP_Address)?.ToList(); var excludedAddresses = (from addressdefinition in ds.DomainBoundary where addressdefinition.Action == BoundaryAddressAction.Exclude.ToString() select addressdefinition.IP_Address)?.ToList(); if (IPOperations.IsIPAddressInNetworks(currentDeviceIP, includedAddresses, true) && !IPOperations.IsIPAddressInNetworks(currentDeviceIP, excludedAddresses, false)) { string[] newScriptLine = _ConnectionInfo.ScriptLine.Split(ScriptSettings.CSVSeparator.ToCharArray()); newScriptLine[2] = currentDeviceIP; newScriptLine[3] = currentDeviceName; _Executor.AddScriptEntry(string.Join(ScriptSettings.CSVSeparator, newScriptLine)); string msg = string.Format("Added device <{0}> to discovery list.", currentDeviceIP); DebugEx.WriteLine(msg, DebugLevel.Informational); _Executor.ShowActivity(msg); } else { string msg = string.Format("Not adding device <{0}> to discovery list because it is either explicitly excluded or not included in discovery domain", currentDeviceIP); DebugEx.WriteLine(msg, DebugLevel.Full); _Executor.ShowActivity(msg); } } else { string msg = "Not adding device a new neighbor to discovery list because Active Discovery is not allowed or the neighbor does not have a valid ip address detected."; DebugEx.WriteLine(msg, DebugLevel.Full); } } else { DebugEx.WriteLine(String.Format("CDP2VISIO : neighbor {0} is already a known device", currentDeviceName), DebugLevel.Full); } #endregion if (current_device == null) { continue; } #region Create Neighbor for parent_device <-> current_device if (new_neigbor == null) { new_neigbor = ds.Neighbours.NewNeighboursRow(); new_neigbor.Neighbor_ID = current_device.ID; new_neigbor.Parent_ID = parent_device.ID; new_neigbor.Name = current_device.Name; DebugEx.WriteLine(String.Format("CDP2VISIO : new neighbor {0} added for device {1}", currentDeviceName, parent_device.Name), DebugLevel.Full); } #endregion #region Get Platform/Interfaces info and update the neighbor if (line.Trim().StartsWith("Platform") && new_neigbor != null) { string[] words = line.SplitByComma(); // words[0] should be PlatForm, words[1] is Capabilities string[] platformWords = words[0].SplitBySpace(); string[] capabilities = words[1].SplitBySpace(); current_device.Platform = string.Join(" ", platformWords.SkipWhile((string l, int i) => i < 1)); if (current_device.Type != "VSS" && current_device.Type != "ASA" && !current_device.Type.StartsWith("Stack")) { current_device.Type = string.Join(";", capabilities.SkipWhile((s, i) => i < 1)); } DebugEx.WriteLine(String.Format("CDP2VISIO : Platform of neighbor {0} identified as {1}. Device type was set to {2}", currentDeviceName, current_device.Platform, current_device.Type), DebugLevel.Full); } if (line.IndexOf("Interface") >= 0 && new_neigbor != null) { string[] words_in_line = line.SplitBySpace(); int words_length = words_in_line.Length; string neighbour_interfaces = words_in_line[words_length - 1]; neighbour_interfaces = Common.ConvInt(neighbour_interfaces); string local_interfaces = words_in_line[1].Replace(",", ""); local_interfaces = Common.ConvInt(local_interfaces); new_neigbor.Neighbour_Interface = neighbour_interfaces; new_neigbor.Local_Interface = local_interfaces; DebugEx.WriteLine(String.Format("CDP2VISIO : connected interface added {0}::{1} connects to {2}::{3}", currentDeviceName, local_interfaces, parent_device.Name, neighbour_interfaces), DebugLevel.Full); } #endregion } catch (Exception Ex) { DebugEx.WriteLine(String.Format("CDP2VISIO : Error while parsing cdp output line [{0}]. Error is : {1}", line, Ex.InnerExceptionsMessage())); } } if (new_neigbor != null) { ds.Neighbours.AddNeighboursRow(new_neigbor); } } }
public void RegisterNHRP(INeighborRegistry registry) { try { string vrrpSummary = _session.ExecCommand("show vrrp summary"); string[] vrrpSummaryLines = vrrpSummary.SplitByLine(); // // Sample input for parsing // //Interface State Group VR state VR Mode Type Address //irb.2100 up 210 master Active lcl 10.37.24.2 // vip 10.37.24.1 //irb.2200 up 220 master Active lcl 10.37.26.2 // vip 10.37.26.1 string VIPAddress = ""; string GroupID = ""; string PeerAddress = ""; bool isActive = false; RouterInterface ri = null; foreach (string thisLine in vrrpSummaryLines) { if (thisLine.IndentLevel() == 0) { // interface definition is changing if (GroupID != "" && VIPAddress != "") { registry.RegisterNHRPPeer(this, ri, NHRPProtocol.VRRP, isActive, VIPAddress, GroupID, PeerAddress); VIPAddress = ""; GroupID = ""; PeerAddress = ""; ri = null; } // string[] words = thisLine.SplitBySpace(); string ifName = words[0]; isActive = thisLine.ToLowerInvariant().Contains("master"); ri = GetInterfaceByName(ifName); GroupID = words[2]; continue; } if (ri != null) { string[] words = thisLine.SplitBySpace(); if (words.Length == 2) { switch (words[0]) { case "lcl": break; case "mas": PeerAddress = words[1]; break; case "vip": VIPAddress = words[1]; break; } } } } // register the last one if (ri != null && VIPAddress != "" && GroupID != "") { registry.RegisterNHRPPeer(this, ri, NHRPProtocol.VRRP, isActive, VIPAddress, GroupID, PeerAddress); } } catch (Exception Ex) { string msg = string.Format("CiscoIOSRouter says : error processing NHRP interfaces : {0}", Ex.Message); DebugEx.WriteLine(msg); } }
public void Parse(INeighborRegistry registry, CancellationToken token) { if (_router?.Session == null || !_router.Session.IsConnected()) { throw new ArgumentException("Unable to parse OSPF. Either thisRouter or Session parameter is invalid"); } try { _OperationStatusLabel = "Querying OSPF neighbors..."; string TextToParse = _router.Session.ExecCommand("show ip ospf neighbor"); _OperationStatusLabel = "Querying OSPF interfaces..."; string ospfInterfaces = _router.Session.ExecCommand("show ip ospf interface brief"); _OperationStatusLabel = "Processing OSPF data..."; token.ThrowIfCancellationRequested(); string[] ospf_lines = TextToParse.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); string neighborRouterID = ""; string neighborState = ""; string remoteNeighboringIP = ""; string description = ""; foreach (string line in ospf_lines.Select(l => l.Trim())) { neighborRouterID = ""; neighborState = ""; remoteNeighboringIP = ""; description = ""; DebugEx.WriteLine(String.Format("CISCO_IOS_OSPF_PARSER : parsing OSPF neighbor row [ {0} ]", line), DebugLevel.Full); token.ThrowIfCancellationRequested(); try { string[] words = line.SplitBySpace(); if (words.Length < 4) { continue; } // Words should look like: // Neighbor ID,Pri,State,Dead Time,Address,Interface // 172.20.0.255,128,FULL/BDR,00:00:34,172.20.0.14,TenGigabitEthernet0/1/0 var MatchedIPs = Regex.Matches(line, @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"); // we expect two ip addresses in the line, first is the Neighbor router ID, second is Neighboring IP address if (MatchedIPs.Count == 2 && System.Net.IPAddress.TryParse(MatchedIPs[0].Value, out IPAddress nID) && System.Net.IPAddress.TryParse(MatchedIPs[1].Value, out IPAddress nIP)) { // This is a new peer, initialize variables string ifName = words[words.Length - 1]; // last work is the interface name _OperationStatusLabel = string.Format("Querying router interface {0}...", ifName); RouterInterface ri = _router.GetInterfaceByName(ifName); if (ri != null) { // add OSPF Area info to RouterInterface if (ospfInterfaces != "") { string ospfIntfLine = ospfInterfaces.SplitByLine().FirstOrDefault(l => l.Trim().StartsWith(ri.Name)); if (!string.IsNullOrEmpty(ospfIntfLine)) { string[] w = ospfIntfLine.SplitBySpace(); //Interface PID Area IP Address/Mask Cost State Nbrs F/C //Te0/1/0 100 172.20.0.0 172.20.0.1/28 1 DR 1/1 ri.OSPFArea = w[2]; } } neighborRouterID = nID.ToString(); remoteNeighboringIP = nIP.ToString(); neighborState = words[2]; description = ""; _OperationStatusLabel = string.Format("Registering OSPF neighbor {0}...", neighborRouterID); registry.RegisterNeighbor(_router, RoutingProtocol.OSPF, neighborRouterID, "", description, remoteNeighboringIP, ri, neighborState); } } } catch (OperationCanceledException) { throw; } catch (Exception Ex) { string msg = String.Format("Cisco IOS OSPF Protocol Parser : Error while parsing ospf output line [{0}]. Error is : {1}", line, Ex.InnerExceptionsMessage()); DebugEx.WriteLine(msg); _OperationStatusLabel = msg; } } _OperationStatusLabel = "Cisco IOS OSPF Protocol Parser completed."; } catch (Exception Ex) { _OperationStatusLabel = "Cisco IOS OSPF Protocol Parser failed with error : " + Ex.Message; } }
private void CalculateSystemSerial() { // some switches does not support the "show inventory" command bool exec_error = Inventory.ToLowerInvariant().Contains("invalid input detected") || ScriptSettings.FailedCommandPattern.SplitBySemicolon().Any(w => Inventory.IndexOf(w) >= 0); if (exec_error) { DebugEx.WriteLine(String.Format("JunOS IRouter : switch does not support \"show chassis hardware\" command, parsing version information"), DebugLevel.Debug); // try to parse sh_version to get system serial numbers try { _systemSerial = string.Join(",", _versionInfo.SplitByLine().Where(l => l.StartsWith("System serial number")).Select(l => l.Split(':')[1].Trim())); } catch (Exception Ex) { DebugEx.WriteLine(String.Format("JunOS IRouter : error searching serial number in \"sh version\" output : {0}", Ex.InnerExceptionsMessage()), DebugLevel.Debug); } } else { switch (Type) { case "Switch": { // Assuming an EX / QFX series switch var FPCs = Regex.Matches(Inventory, @"FPC \d.*"); foreach (Match thisFPC in FPCs) { string[] fpcLineWords = thisFPC.Value.SplitBySpace(); // words should look like:FPC,0,REV,19,650-044931,PE3716200032,EX4300-48T // serial number should be words[5] _systemSerial += (";" + fpcLineWords[5]); _modelNumber += (";" + fpcLineWords[6]); } _systemSerial = _systemSerial?.TrimStart(';'); _modelNumber = _modelNumber?.TrimStart(';'); break; } case "Firewall": { // Assuming SRX firewall var FPCs = Regex.Matches(Inventory, @"\bChassis.*\b"); foreach (Match thisFPC in FPCs) { string[] chassisLineWords = thisFPC.Value.SplitBySpace(); // expecting chassisLineWords as : Chassis,BU4913AK0887,SRX240H2 _systemSerial += (";" + chassisLineWords[1]); _modelNumber += (";" + chassisLineWords[2]); } _systemSerial = _systemSerial?.TrimStart(';'); _modelNumber = _modelNumber?.TrimStart(';'); break; } case "Router": { // not yet implemented _systemSerial = "?"; _modelNumber = "?"; break; } } } }
public static void ConnectWithDynamicGlueAndConnector(int DeviceNumber, Visio.IVShape shapeFrom, Visio.IVShape shapeTo, string EdgeText, string EdgeIntConfigs, string Edgecolor, string EdgeWeight, int TextSize, string RouteType) { if (shapeFrom == null || shapeTo == null) { DebugEx.WriteLine("Can't connect a null shape !"); return; } const string BASIC_FLOWCHART_STENCIL = "Basic Flowchart Shapes (US units).vss"; const string DYNAMIC_CONNECTOR_MASTER = "Dynamic Connector"; const string MESSAGE_NOT_SAME_PAGE = "Both the shapes are not on the same page."; Visio.Application visioApplication; Visio.IVDocument stencil; Visio.IVMaster masterInStencil; Visio.IVShape connector; Visio.IVCell beginX; Visio.IVCell endX; // Get the Application object from the shape. visioApplication = (Visio.Application)shapeFrom.Application; try { // Verify that the shapes are on the same page if (shapeFrom.ContainingPage != null && shapeTo.ContainingPage != null && shapeFrom.ContainingPage == shapeTo.ContainingPage) { #region Set ConnectorShapeProperties #region InitiateConnector // Access the Basic Flowchart Shapes stencil from the // Documents collection of the application. stencil = visioApplication.Documents.OpenEx(BASIC_FLOWCHART_STENCIL, (short)VisOpenSaveArgs.visOpenDocked); // Get the dynamic connector master on the stencil by its // universal name. masterInStencil = stencil.Masters.get_ItemU(DYNAMIC_CONNECTOR_MASTER); // Drop the dynamic connector on the active page. connector = visioApplication.ActivePage.Drop(masterInStencil, 0, 0); #endregion #region SetconnectorToSraightLine //Set dynamic cable is a straight line, the key is to know FormulaU this property 16 shows a straight line // Straight Line : 16 // Right Angle : 1 string rType = "16"; if (RouteType == "Right Angle") { rType = "1"; } else if (RouteType == "Straight Lines") { rType = "16"; } // https://msdn.microsoft.com/en-us/library/office/aa221304(v=office.11).aspx connector.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowShapeLayout, (short)VisCellIndices.visSLORouteStyle).FormulaU = rType; #endregion #region SetConnector_Tiptext string connector_Tiptex = string.Empty; connector_Tiptex = EdgeIntConfigs; //Set the Tiptext connector.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowMisc, (short)VisCellIndices.visComment).FormulaU = "\"" + connector_Tiptex.Replace("\"", "") + "\""; #endregion #region SetConnectorText connector.Text = string.Empty; connector.Text = EdgeText; Visio.IVCharacters shapeText; shapeText = connector.Characters; shapeText.set_CharProps((short)VisCellIndices.visCharacterSize, (short)TextSize); #endregion #region SetConnectorColor try { //Set the connection line to "RED" color Visio.IVCell thisCell = connector.CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLine, (short)VisCellIndices.visLineColor); if (thisCell != null) { thisCell.Formula = Edgecolor; } else { DebugEx.WriteLine("CDP2VISIO : Couldn't set connector color, Cell is null", DebugLevel.Warning); } } catch (Exception Ex) { DebugEx.WriteLine(string.Format("CDP2VISIO : Couldn't set connector color : {0} {1}", Ex.InnerExceptionsMessage(), Ex.InnerException?.Message), DebugLevel.Warning); } #endregion #region SetConnectorWeight try { Visio.IVCell thisCell = connector.get_CellsU("LineWeight"); if (thisCell != null) { thisCell.FormulaU = EdgeWeight; } else { DebugEx.WriteLine("CDP2VISIO : Couldn't set connector weight, Cell is null", DebugLevel.Warning); } } catch (Exception Ex) { DebugEx.WriteLine("CDP2VISIO : Couldn't set connector weight : " + Ex.InnerExceptionsMessage(), DebugLevel.Warning); } #endregion #region SetConnectorSource&TargetShape try { // Connect the begin point of the dynamic connector to the // PinX cell of the first 2-D shape. beginX = connector.CellsSRC( (short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowXForm1D, (short)VisCellIndices.vis1DBeginX); if (beginX != null) { beginX.GlueTo(shapeFrom.get_CellsSRC( (short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowXFormOut, (short)VisCellIndices.visXFormPinX)); } else { DebugEx.WriteLine("CDP2VISIO : Couldn't glue connector origin", DebugLevel.Warning); } // Connect the end point of the dynamic connector to the // PinX cell of the second 2-D shape. endX = connector.get_CellsSRC( (short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowXForm1D, (short)VisCellIndices.vis1DEndX); if (endX != null) { endX.GlueTo(shapeTo.get_CellsSRC( (short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowXFormOut, (short)VisCellIndices.visXFormPinX)); DebugEx.WriteLine(string.Format("Glued {0} to {1}", shapeFrom.Name, shapeTo.Name), DebugLevel.Informational); } else { DebugEx.WriteLine("CDP2VISIO : Couldn't glue connector end", DebugLevel.Warning); } } catch (Exception Ex) { DebugEx.WriteLine("CDP2VISIO : Couldn't glue connector : " + Ex.InnerExceptionsMessage(), DebugLevel.Warning); } #endregion #endregion } else { // Processing cannot continue because the shapes are not on // the same page. System.Diagnostics.DebugEx.WriteLine(MESSAGE_NOT_SAME_PAGE); } } catch (Exception Ex) { System.Diagnostics.DebugEx.WriteLine(Ex.InnerExceptionsMessage()); throw; } }
public void Parse(INeighborRegistry registry, CancellationToken token) { if (_router?.Session == null || !_router.Session.IsConnected()) { throw new ArgumentException("Unable to parse BGP. Either thisRouter or Session parameter is invalid"); } else { try { _OperationStatusLabel = "Querying bgp neighbors..."; string bgpNeighbors = _router.Session.ExecCommand("show bgp neighbor"); token.ThrowIfCancellationRequested(); string[] bgp_lines = bgpNeighbors.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); string peerRouterID = ""; string localNeighboringIP = ""; string remoteNeighboringIP = ""; string remoteAS = ""; string description = ""; string neighborState = ""; bool sessionEstablished = true; bool skipRestOfLines = false; string localInterfaceName = ""; BGPType _bgpType = BGPType.undetermined; foreach (string line in bgp_lines.Select(l => l.Trim())) { DebugEx.WriteLine(String.Format("BGPParser : parsing BGP neighbor row [ {0} ]", line), DebugLevel.Full); token.ThrowIfCancellationRequested(); try { #region Get description if (line.StartsWith("Description:")) { string[] words = line.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); description = words[1]; continue; } #endregion #region Check for Peer line if (line.StartsWith("Peer:")) { // This is a new peer, initialize variables peerRouterID = ""; localNeighboringIP = ""; remoteNeighboringIP = ""; remoteAS = ""; description = ""; neighborState = ""; sessionEstablished = true; skipRestOfLines = false; localInterfaceName = ""; // Get local address Match m = Regex.Match(line, @"(?<=Local: )[\d.]{0,99}", RegexOptions.Compiled); if (m.Success) { localNeighboringIP = m.Value; } // Get peer address m = Regex.Match(line, @"(?<=Peer: )[\d.]{0,99}", RegexOptions.Compiled); if (m.Success) { remoteNeighboringIP = m.Value; } // Get AS Numbers var ASes = Regex.Matches(line, @"(?<=AS )[\d.]{0,99}", RegexOptions.Compiled); if (ASes.Count != 2) { throw new InvalidOperationException("Cannot parse BGP output : unable to retrieve local and remote AS numbers."); } remoteAS = ASes[0].Value; _OperationStatusLabel = string.Format("Processing neighbor {0} for AS {1}...", remoteNeighboringIP, remoteAS); continue; } #endregion if (skipRestOfLines) { continue; } #region Check for state if (line.StartsWith("Type:") && line.Contains("State:")) { Match m = Regex.Match(line, @"(?<=State: )\w+", RegexOptions.Compiled); if (m.Success) { neighborState = m.Value; } sessionEstablished = neighborState.ToLowerInvariant() == "established"; m = Regex.Match(line, @"(?<=Type: )\w+", RegexOptions.Compiled); if (m.Success) { _bgpType = m.Value.ToLowerInvariant() == "internal" ? BGPType.iBGP : BGPType.eBGP; } } #endregion if (sessionEstablished) { #region Parse Remote router ID if (line.StartsWith("Peer ID:")) { // Get remote router ID Match m = Regex.Match(line, @"(?<=Peer ID: )[\d.]{0,99}", RegexOptions.Compiled); if (!m.Success) { throw new InvalidOperationException("Cannot parse BGP output : unable to retrieve peer router ID."); } peerRouterID = m.Value; DebugEx.WriteLine(String.Format("JunOSBGPParser : found a neighbor {0}AS{1} <-> {2}AS{3}", _router.RouterID(RoutingProtocol.BGP), _router.BGPAutonomousSystem, peerRouterID, remoteAS), DebugLevel.Informational); continue; } #endregion #region Get local interface if (localInterfaceName == "") { switch (_bgpType) { case BGPType.eBGP: { if (line.StartsWith("Local Interface:")) { string[] words = line.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); localInterfaceName = words[1]; continue; } break; } case BGPType.iBGP: { // since JunOS does not show Local Interface for iBGP, we need to query it, if we know the local ip if (localNeighboringIP != "") { localInterfaceName = _router.GetInterfaceNameByIPAddress(localNeighboringIP); } break; } } } #endregion } if (sessionEstablished && (localInterfaceName == "" || peerRouterID == "" || remoteAS == "" || localNeighboringIP == "" || remoteNeighboringIP == "")) { continue; } // when the BGP session is not established we can't know the neighbor router ID, so name it after peering ip which should be unique anyway // We also won't know the localInterface at this point, so we need to query it by ip address if (!sessionEstablished) { peerRouterID = remoteNeighboringIP; if (localNeighboringIP != "") { localInterfaceName = _router.GetInterfaceNameByIPAddress(localNeighboringIP); } } // search database for peer router, select it or add new neighbor _OperationStatusLabel = string.Format("Querying router interface {0}...", localInterfaceName); RouterInterface ri = _router.GetInterfaceByName(localInterfaceName); _OperationStatusLabel = string.Format("Registering BGP neighbor {0}...", peerRouterID); registry.RegisterNeighbor(_router, RoutingProtocol.BGP, peerRouterID, remoteAS, description, remoteNeighboringIP, ri, neighborState); // now all is done for this peer, skip lines until next peer is found skipRestOfLines = true; } catch (OperationCanceledException) { throw; } catch (InvalidOperationException) { throw; } catch (Exception Ex) { string msg = String.Format("JunOSBGPParser : Error while parsing bgp output line [{0}]. Error is : {1}", line, Ex.InnerExceptionsMessage()); DebugEx.WriteLine(msg); _OperationStatusLabel = msg; } } _OperationStatusLabel = "JunOS BGP route parser completed."; } catch (Exception Ex) { _OperationStatusLabel = "JunoS BGP parser failed with error : " + Ex.Message; } } }