def ParseInterfaceConfigurations(self):
        """Gets router running configurtion to collect interface configurations"""
        # Get running configuration to parse
        if not self._running_config:
            self._running_config = Session.ExecCommand("show running-config")

        self._interfaceConfigurations = {}
        currentIntfName = ""
        currentIntfConfig = []
        intfConfigBlock = False
        for thisLine in self._running_config.splitlines():
            try:
                words = filter(None, thisLine.split(" "))
                rep_IntfLine = r"(?<=^interface)\s+(\d+\/\d+)"
                m_intfLine = re.findall(rep_IntfLine, thisLine, re.IGNORECASE)
                if len(m_intfLine):
                    # This should be a new interface definition
                    currentIntfConfig = []
                    currentIntfName = m_intfLine[0].strip()
                    intfConfigBlock = True
                elif intfConfigBlock:
                    sline = thisLine.strip()
                    if sline and sline != "exit":
                        currentIntfConfig.append(sline)
                    if sline == "exit" and currentIntfName:
                        # add the interface config
                        self._interfaceConfigurations[
                            currentIntfName] = "\r\n".join(currentIntfConfig)
                        intfConfigBlock = False
            except Exception as Ex:
                message = "Hirschmann.InterfaceParser.ParseInterfaceConfigurations() : could not parse an interface configuration for line <{0}>. Error is : {1} ".format(
                    thisLine, str(Ex))
                DebugEx.WriteLine(message)
Example #2
0
    def ParseInterfaceConfigurations(self):
        """Gets router running configurtion to collect interface configurations"""
        # Get running configuration to parse
        if not self._running_config:
            self._running_config = Session.ExecCommand(
                "show running-config interface")
            if len(
                    self._running_config
            ) < 100 and "Command authorization failed" in self._running_config:
                # some systems may not allow running "show run" but still allow "show tech", let's give a try :-)
                tech_support_ipc = Session.ExecCommand("show tech-support")
                temp_running_config = []
                riBlock = False
                for line in tech_support_ipc.splitlines():
                    if riBlock:
                        if line.find("--- show") > 0:
                            # end of running configuration block
                            break
                        temp_running_config.append(line)
                    else:
                        if line.find("--- show running-config ---") > 0:
                            # start of running configuration block
                            riBlock = True
                self._running_config = "\r\n".join(temp_running_config)

        self._interfaceConfigurations = {}
        self._ifNames = {}
        self._nameIfs = {}
        currentIntfName = ""
        currentIntfConfig = []
        for thisLine in self._running_config.splitlines():
            try:
                words = thisLine.split(" ")
                if thisLine.startswith("interface") and len(words) == 2:
                    # This should be a new interface definition
                    if currentIntfName != "":
                        # add previous interface
                        self._interfaceConfigurations[
                            currentIntfName] = "\r\n".join(currentIntfConfig)
                    # Clear current configuration
                    currentIntfConfig = []
                    currentIntfName = words[1]
                else:
                    sline = thisLine.strip(' ')
                    if sline != "!":
                        currentIntfConfig.append(sline)
                        # region memorize ASA nameif properties
                        m = re.findall(r"(?<=nameif ).*", sline)
                        if len(m) == 1:
                            nameif = m[0].strip()
                            self._ifNames[currentIntfName] = nameif
                            self._nameIfs[nameif] = currentIntfName

            except Exception as Ex:
                message = "CiscoASA.InterfaceParser.ParseInterfaceConfigurations() : could not parse an interface configuration for line <{0}>. Error is : {1} ".format(
                    thisLine, str(Ex))
                DebugEx.WriteLine(message)
 def GetSystemMAC(self, instance):
     """Returns the MAC addresses associated with the local system for the given routing instance"""
     systemMAC = ""
     v = self.GetVersion()
     rep_BackplaneMAC = r"^Base MAC Address(?:.+\.)\s(.*)"
     try:
         systemMAC = GetRegexGroupMatches(rep_BackplaneMAC, v, 1)[0].strip()
     except Exception as Ex:
         DebugEx.WriteLine(
             "HirschmannMACH.GetSystemMAC() : unexpected error : {0}".
             format(str(Ex)))
     return systemMAC
 def GetManagementIP(self):
     """Returns the management ip address as a string"""
     sysIP = ConnectionInfo.DeviceIP
     v = self.GetVersion()
     rep_SystemIP = r"system ip address\.+(.*)"
     try:
         sysIP = GetRegexGroupMatches(rep_SystemIP, v, 1)[0].strip()
     except Exception as Ex:
         DebugEx.WriteLine(
             "HirschmannMACH.GetManagementIP() : unexpected error : {0}".
             format(str(Ex)))
     return sysIP
 def GetHostName(self):
     """ Returns the host bane as a string"""
     if not self._hostName:
         v = self.GetVersion()
         rep_SystemName = r"^System Name\.+(.*)"
         try:
             self._hostName = GetRegexGroupMatches(rep_SystemName, v,
                                                   1)[0].strip()
         except Exception as Ex:
             DebugEx.WriteLine(
                 "HirschmannMACH.GetHostName() : unexpected error : {0}".
                 format(str(Ex)))
     return self._hostName
 def GetInventory(self):
     """Returns the device inventory string"""
     if self.SwitchType == HirshmannSwitchType.MachSwitch:
         # regex group 1 : Power Supply Information
         rep_PSInfo = r"power supply information:([\s\S]+(?=media module information))"
         # regex group 1 : Media Module Information
         rep_MMInfo = r"media module information:([\s\S]+(?=sfp information))"
         # regex group 1 : Media Module Information
         rep_SFPInfo = r"sfp information[\w\s\S]+:([\s\S]+(?=^CPU))"
         v = self.GetVersion()
         inventoryText = "unknown"
         try:
             PSInfo = GetRegexGroupMatches(rep_PSInfo, v, 1)[0]
             MMInfo = GetRegexGroupMatches(rep_MMInfo, v, 1)[0]
             SFPInfo = GetRegexGroupMatches(rep_SFPInfo, v, 1)[0]
             inventoryText = "\r\n".join([PSInfo, MMInfo, SFPInfo])
         except Exception as Ex:
             DebugEx.WriteLine(
                 "HirschmannMACH.GetInventory() : unexpected error : {0}".
                 format(str(Ex)))
         return inventoryText
     elif self.SwitchType == HirshmannSwitchType.RailSwitch:
         # regex group 1 : Power Supply Information
         rep_PSInfo = r"power supply.*"
         # regex group 1 : Media Module Information
         rep_MMInfo = r"media module information.*"
         v = self.GetVersion()
         inventoryText = "unknown"
         try:
             PSInfo = "\r\n".join(re.findall(rep_PSInfo, v, re.IGNORECASE))
             MMInfo = "\r\n".join(re.findall(rep_MMInfo, v, re.IGNORECASE))
             inventoryText = "\r\n".join([PSInfo, MMInfo])
         except Exception as Ex:
             DebugEx.WriteLine(
                 "HirschmannMACH.GetInventory() : unexpected error : {0}".
                 format(str(Ex)))
         return inventoryText
 def GetSystemSerial(self):
   """Returns System serial numbers as a string, calculated from Inventory"""
   if not self._SystemSerial :
     ss = ""
     # first try to check inventory for serial numbers
     inv = self.GetInventory()
     failwords = self.ScriptSettings.FailedCommandPattern.split(";")
     if any(fw in inv for fw in failwords) or "invalid input" in inv.lower():
       # show inventory did not work, try to parse version information for system serial number
       DebugEx.WriteLine("CiscoIOSRouter : router does not support \"show inventory\" command, parsing version information", DebugLevel.Debug)
       r_serial = re.findall(r"(?<=System serial number : ).*", self.GetVersion(), re.IGNORECASE)
       if len(r_serial) > 0:
         self._SystemSerial = r_serial[0]
       
     else:
       if self.GetStackCount() > 0 :
         modules = Session.ExecCommand("show module")
         if any(fw in modules for fw in failwords) or "invalid input" in modules.lower():
           # show module did not work, try to parse version information to get system serial numbers
           DebugEx.WriteLine("CiscoIOSRouter : router does not support \"sh module\" command, parsing version information", DebugLevel.Debug)
           r_serial = re.findall(r"(?<=System serial number : ).*", self.GetVersion(), re.IGNORECASE)
           if len(r_serial) > 0:
             self._SystemSerial = r_serial[0]
         else:
           # try to parse sh_version to get system serial numbers
           # TODO : missing command output sample to process
           pass  
       else:
         SNs = re.finditer(r"(?<=SN: ).*", inv, re.MULTILINE)
         self._SystemSerial = ",".join([SN.group() for matchNum, SN in enumerate(SNs, start=1)])
     FPCs = re.findall(r"FPC \d.*", inv)
     for thisFPC in FPCs :
       words = filter(None, thisFPC.split(" "))
       ss += (";" + words[5])
     self._SystemSerial = ss.strip(";")
   return self._SystemSerial
 def GetSystemSerial(self):
     """Returns System serial numbers as a string, calculated from Inventory"""
     if not self._SystemSerial:
         v = self.GetVersion()
         if self.SwitchType == HirshmannSwitchType.MachSwitch:
             rep_BackplaneSerial = r"^Serial Number \(Backplane\)\.+(.*)"
         elif self.SwitchType == HirshmannSwitchType.RailSwitch:
             rep_BackplaneSerial = r"^Serial Number\.+(.*)"
         try:
             self._SystemSerial = GetRegexGroupMatches(
                 rep_BackplaneSerial, v, 1)[0].strip()
         except Exception as Ex:
             DebugEx.WriteLine(
                 "HirschmannMACH.GetSystemSerial() : unexpected error : {0}"
                 .format(str(Ex)))
     return self._SystemSerial
 def GetModelNumber(self):
     """Returns Model number as a string, calculated from Inventory"""
     if not self._ModelNumber:
         v = self.GetVersion()
         if self.SwitchType == HirshmannSwitchType.MachSwitch:
             rep_Backplane = r"Backplane Hardware Description\.+(.*)"
         elif self.SwitchType == HirshmannSwitchType.RailSwitch:
             rep_Backplane = r"Hardware Description\.+(.*)"
         try:
             self._ModelNumber = GetRegexGroupMatches(rep_Backplane, v,
                                                      1)[0].strip()
         except Exception as Ex:
             DebugEx.WriteLine(
                 "HirschmannMACH.GetModelNumber() : unexpected error : {0}".
                 format(str(Ex)))
     return self._ModelNumber
Example #10
0
    def GetSystemMAC(self, instance):
        """Returns the CSV list of MAC addresses associated with the local system for the given routing instance"""
        # For ASA, we skip the instance. Cotexts are not yet supported by this parser
        systemMACs = []
        v = self.GetVersion()
        rep_systemMACs = r"(?!0000)[a-f,0-9]{4}\.[a-f,0-9]{4}\.[a-f,0-9]{4}"
        try:
            ri_systemMACs = re.finditer(rep_systemMACs, v,
                                        re.MULTILINE | re.IGNORECASE)
            for index, match in enumerate(ri_systemMACs):
                systemMACs.append(match.group())

        except Exception as Ex:
            DebugEx.WriteLine(
                "CiscoASA.GetSystemMAC() : unexpected error : {0}".format(
                    str(Ex)))
        return ",".join(systemMACs)
 def ResolveObjectSubnet(self, objectName):
     """Returns a dictionary of network address and mask for the given object name like {Subnet:"1.0.0.0", Mask:"255.0.0.0"}"""
     if not objectName:
         return None
     try:
         result = Session.ExecCommand(
             "show run object id {0}".format(objectName))
         rep_SubnetAddressAndMask = r"\s+subnet\s(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)\s(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)"
         subnetAddress = GetRegexGroupMatches(rep_SubnetAddressAndMask,
                                              result, 1)[0]
         subnetMask = GetRegexGroupMatches(rep_SubnetAddressAndMask, result,
                                           2)[0]
         return {"Subnet": subnetAddress, "Mask": subnetMask}
     except Exception as Ex:
         message = "CiscoASA Static route parser : could not resolve object name : {0}  due to error : {1}".format(
             objectName, str(Ex))
         DebugEx.WriteLine(message)
         return None
Example #12
0
 def Parse(self, nRegistry, cToken, instance):
     """Collects information about active tunnels and registers them with Network Discovery Engine"""
     # The neighbor registry object is received as parameter
     # This must be used to register a new neighbor for further discovery.
     # --
     # A CancellationToken is also passed as parameter. The token should be checked repetitively whether cancellation was requested
     # by user and if yes, stop further processing.
     # --
     # The RoutingInstance object to work with is also passed as a parameter
     instanceName = "default"
     if instance: instanceName = instance.Name.lower()
     OperationStatusLabel = "Collecting ip routes..."
     cToken.ThrowIfCancellationRequested()
     routes = Session.ExecCommand("show ip route static")
     cToken.ThrowIfCancellationRequested()
     OperationStatusLabel = "Processing STATIC route entries..."
     # regex groups => 1 : network, 2 : subnet mask, 3 : preference, 4 : next-hop, 5: status, 6 : out interface
     rep_StaticWithAddressOnly = r"^(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s+(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s+(\d+)\s+(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s+([^\s]+)\s+([^\s]+)"
     # Enumerate static routes containing addresses only
     static_with_address = re.finditer(rep_StaticWithAddressOnly, routes,
                                       re.MULTILINE)
     for matchnum, match in enumerate(static_with_address):
         try:
             # Group 1 : destination network, Group 2 : metric, Group 3 : dst. network mask, Group 4: next-hop, Group5 : outgoing interface
             networkAddress = match.group(1).strip()
             networkAddressMask = match.group(2).strip()
             maskLength = IPOperations.GetMaskLength(networkAddressMask)
             routeForNetwork = "{0}/{1}".format(networkAddress, maskLength)
             metric = match.group(3).strip()
             nexthop = match.group(4).strip()
             routeStatus = match.group(5).strip()
             outInterfaceName = match.group(6).strip()
             ri = self.Router.GetInterfaceByName(outInterfaceName, instance)
             if ri != None:
                 OperationStatusLabel = "Registering static neighbor {0}...".format(
                     ri.Address)
                 nRegistry.RegisterSTATICNeighbor(self.Router, instance,
                                                  routeForNetwork, nexthop,
                                                  ri.Address, ri)
         except Exception as Ex:
             message = "Hirschmann Static route parser: could not parse a static route entry because : {0} ".format(
                 str(Ex))
             DebugEx.WriteLine(message)
 def RouteTableSize(self, instance):
   """Returns the size of the route table for the requested routing instance"""
   instanceName = self._defaultRoutingInstanceName
   if instance : instanceName = instance.Name
   routeTableSize = -1
   try :
     cmd = "show ip route summary"
     if instanceName != self._defaultRoutingInstanceName:
       cmd = "show ip route vrf {0} summary".format(instanceName)   
           
     routeSummary = Session.ExecCommand(cmd)   
     routeTotals = filter(lambda s: s.startswith("Total"), routeSummary.splitlines())
     
     if len(routeTotals) > 0:
       # return the last number in Total line
       words = filter(None, routeTotals[0].split(' '))
       routeTableSize = int(words[2])
   except Exception as Ex :
     DebugEx.WriteLine("CiscoIOSRouter : error calculating route table size : {0}".format(str(Ex)))
   
   return routeTableSize
    def Parse(self, nRegistry, cToken, instance):
        """Collects information about active tunnels and registers them with Network Discovery Engine"""
        # The neighbor registry object is received as parameter
        # This must be used to register a new neighbor for further discovery.
        # --
        # A CancellationToken is also passed as parameter. The token should be checked repetitively whether cancellation was requested
        # by user and if yes, stop further processing.
        # --
        # The RoutingInstance object to work with is also passed as a parameter
        instanceName = "default"
        if instance: instanceName = instance.Name.lower()
        OperationStatusLabel = "Identifying router..."
        #--
        cToken.ThrowIfCancellationRequested()
        #
        # Compiled regex search patters
        rep_ConnectionIndex = r"^Index\s+:\s(\d+)"
        rep_ConnectionAddress = r"^Connection\s+:\s(.*)"
        rep_Encryption = r"^Encryption\s+:\s(.*)"
        rep_Hashing = r"^Hashing\s+:\s(.*)"
        rep_EncHash = r"^Encryption\s+:\s(.+)Hashing\s+:\s(.+)"
        # rep_IPSecBlocks = r"IPsec:.*\s*(?:(?:(?!^IPsec:)[\s\S])*)"
        rep_LocalAddr = r"Local Addr\s+:\s((?:\d{1,3}.){3}\d{1,3}/(?:\d{1,3}.){3}\d{1,3})"
        rep_RemoteAddr = r"Remote Addr\s+:\s((?:\d{1,3}.){3}\d{1,3}/(?:\d{1,3}.){3}\d{1,3})"
        # get vpn session details for l2l tunnels
        l2lTunnels = Session.ExecCommand("show vpn-sessiondb detail l2l")
        # extract connection indexes, get match iterator
        connectionIndexes = GetRegexGroupMatches(rep_ConnectionIndex,
                                                 l2lTunnels, 1)
        try:
            for thisConnectionIndex in connectionIndexes:
                try:
                    # get detail for this connection index
                    thisConnectionDetails = Session.ExecCommand(
                        "show vpn-sessiondb detail index {0}".format(
                            thisConnectionIndex))
                    # extract remote ip address from thisConnectionDetails, get match iterator
                    thisConnectionRemoteAddresses = GetRegexGroupMatches(
                        rep_ConnectionAddress, thisConnectionDetails, 1)
                    for tunnel_RemoteAddress in thisConnectionRemoteAddresses:
                        # get local address for this remote address
                        thisConnectionIPSEC = Session.ExecCommand(
                            "sh crypto ipsec sa | i remote crypto endpt.: {0}".
                            format(tunnel_RemoteAddress)).splitlines()[0]
                        # extract the first ip address from result, that will be the local address
                        tunnel_LocalAddress = GetIndexedIPAddressFromLine(
                            thisConnectionIPSEC, 1)
                        if tunnel_LocalAddress:
                            cipherAlgs = GetRegexGroupMatches(
                                rep_EncHash, thisConnectionDetails, 1)
                            if len(cipherAlgs) > 0: cipherAlg = cipherAlgs[0]
                            else: cipherAlg = "n/a"
                            hashAlgs = GetRegexGroupMatches(
                                rep_EncHash, thisConnectionDetails, 2)
                            if len(hashAlgs) > 0: hashAlg = hashAlgs[0]
                            else: hashAlg = "n/a"
                            # get local / remote networks for each ipsec tunnel
                            localProxies = GetRegexGroupMatches(
                                rep_LocalAddr, thisConnectionDetails, 1)
                            remoteProxies = GetRegexGroupMatches(
                                rep_RemoteAddr, thisConnectionDetails, 1)
                            s_localProxies = "\r\n".join(localProxies)
                            s_remoteProxies = "\r\n".join(remoteProxies)
                            #
                            # RegisterTunnel parameters in order :
                            #/// <param name="router">The IRouter requesting registration</param>
                            #/// <param name="instance">The routing instance the tunnel is terminating on</param>
                            #/// <param name="tunnelProtocol">The protocol used to establish the tunnel</param>
                            #/// <param name="tunnelType">The link-type over the tunnel</param>
                            #/// <param name="tunnelName">Optional : tunnel name or description</param>
                            #/// <param name="tunnelState">Tunnel connection state</param>
                            #/// <param name="externalLocalAddress">Tunnel external, local address</param>
                            #/// <param name="externalRemoteAddress">Tunnel external, remote address</param>
                            #/// <param name="tunnelSourceAddress">Optional : Tunnel internal source address</param>
                            #/// <param name="tunnelDestinationAddress">Optional : Tunnel internal destination address</param>
                            #/// <param name="localProxy">Optional : the local networks the tunnel is forwarding for. If not empty, must contain valid ipv4 network prefixes per line</param>
                            #/// <param name="remoteProxy">Optional : the remote networks the tunnel is forwarding for. If not empty, must contain valid ipv4 network prefixes per line</param>
                            #/// <param name="cipher">Optional : the cipher algorithm used by the tunnel</param>
                            #/// <param name="hash">Optional : the hashing algorithm used by the tunnel</param>
                            #/// <param name="tag">Optional : any data to include. Max length is 1024 characters</param>
                            nRegistry.RegisterTunnel(
                                self.Router, instance,
                                L3Discovery.NeighborProtocol.IPSEC,
                                L3Discovery.LinkType.P2P, None,
                                L3Discovery.NeighborState.Established,
                                tunnel_LocalAddress.strip(),
                                tunnel_RemoteAddress.strip(), None, None,
                                s_localProxies, s_remoteProxies, cipherAlg,
                                hashAlg, None)
                except Exception as Ex:
                    pass

        except Exception as Ex:
            message = "CiscoASA Router Module Error : could not parse vpn-sessiondb information because : {1} ".format(
                str(Ex))
            DebugEx.WriteLine(message)
 def ParseInterfaces(self, instance) :
   """Collects interface details for all interfaces of specified routing instance, but do not collect interface configuration """
   # Get the interfaces configurations
   if len(self._interfaceConfigurations) == 0 : self.ParseInterfaceConfigurations()
   # Init interface dictionary for instance
   instanceName = self.Router._defaultRoutingInstanceName
   if instance : instanceName = instance.Name
   if self.Interfaces.get(instanceName, None) == None:
     self.Interfaces[instanceName] = [] 
   # Query the device interfaces
   interfaces = Session.ExecCommand("show ip interface").splitlines()
   # Parse the result and fill up self.Interfaces list
   ri = L3Discovery.RouterInterface()
   lineCount = len(interfaces)
   currentLineIndex = 1
   for line in interfaces:
     try:  
       indentLevel = len(line) - len(line.lstrip(' '))
       if indentLevel == 0 or currentLineIndex == lineCount :
         # this is either a new interface block, or the end of the interface list
         if ri and ri.Name :
           # Add actual interface if vrf name matches instanceName
           if not ri.VRFName and instanceName == self.Router._defaultRoutingInstanceName or ri.VRFName == instanceName:
             ri.Configuration = self.GetInterfaceConfiguration(ri.Name)
             if ri.Configuration.find("encapsulation dot1q") >= 0 : 
               ri.PortMode = L3Discovery.RouterInterfacePortMode.L3Subinterface
               subinterfaceDefinition = next((cline for cline in ri.Configuration.splitlines() if cline.startswith("encapsulation dot1q")), "")
               ri.VLANS = subinterfaceDefinition.split(' ')[-1]
             elif ri.Address : ri.PortMode = L3Discovery.RouterInterfacePortMode.Routed
             elif ri.Configuration.find("switchport mode trunk") >= 0 : 
               ri.PortMode = L3Discovery.RouterInterfacePortMode.Trunk
               # get allowed vlans
               cmd = "show interfaces {0} trunk".format(ri.Name)                
               cmdResult = Session.ExecCommand(cmd)
               #Port        Mode         Encapsulation  Status        Native vlan
               #Fa0/2       on           802.1q         trunking      1
               #
               #Port     Vlans allowed on trunk
               #Fa0/2    1-4,7,11,13-4094
               #
               #Port        Vlans allowed and active in management domain
               #Fa0/2       1
               #
               #Port        Vlans in spanning tree forwarding state and not pruned
               #Fa0/2       1                
               vlanBlock = False
               for vLine in cmdResult.splitlines():
                 if "Vlans allowed on trunk" in vLine:
                   vlanBlock = True
                   continue
                 if vlanBlock and vLine.strip() == "" :
                   break;
                 elif vlanBlock:
                   words = filter(None, vLine.split(' '))
                   if len(words) == 2:
                     vlanList = words[0]
                     ri.VLANS = re.sub(r",", "|", vlanList)
             elif ri.Configuration.find("switchport mode access") >= 0 : 
               ri.PortMode = L3Discovery.RouterInterfacePortMode.Access
               accessVlan = next((cline for cline in ri.Configuration.splitlines() if cline.startswith("switchport access vlan")), "")
               ri.VLANS = accessVlan.split(' ')[-1]
             else : ri.PortMode = L3Discovery.RouterInterfacePortMode.Unknown
             ri.Description = next((cline for cline in ri.Configuration.splitlines() if cline.startswith("description")), "")
             self.Interfaces[instanceName].Add(ri)  
           if currentLineIndex == lineCount :
             break
         # Create new interface    
         ri = L3Discovery.RouterInterface()
         words = filter(None, line.split(' '))  
         # words should look like : GigabitEthernet0/0/0,is,up,line,protocol,is,up 
         ri.LogicalSystemName = "Default"    
         ri.Name = words[0]
         status = [i.strip(',') for i in words if "up" in i.lower() or "down" in i.lower()]
         ri.Status = ",".join(status)
       else:
         # this line belongs to an iterface information block
         sline = line.strip().lower()
         if sline.startswith("internet address"):
           addressAndMask = GetIPAddressAndMaskFromLine(sline).split('/')
           ri.Address = addressAndMask[0]
           ri.MaskLength = addressAndMask[1]
         
         elif sline.startswith("vpn routing/forwarding"):  
           words = filter(None, line.split(' '))   
           ri.VRFName = words[-1].strip('"')
       
       # PortMode and VLANS will be processed later in a second pass
     except Exception as Ex:
       DebugEx.WriteLine("CiscoIOSRouter.InterfaceParser.ParseInterfaces() : error parsing text {0}. Error is {1}".format(line, str(Ex)))
     
     currentLineIndex += 1
  def CalculateRouterIDAndASNumber(self, instance):
    """Parse the RouterID and AS number for the requested RoutingInstance"""  
    instanceName = self.Router._defaultRoutingInstanceName
    if instance : instanceName = instance.Name
    if self.RouterID.get(instanceName, None) == None: self.RouterID[instanceName] = {}
    
    # Determine default router ID
    globalRouterID = ConnectionInfo.DeviceIP
    l3interfaces = Session.ExecCommand("sh ip interface brief")
    if l3interfaces:
      try :
        loopbacks = [intf.lower() for intf in l3interfaces.splitlines() if intf.lower().startswith("loopback") and GetIPAddressFromLine(intf)]
        if len(loopbacks) > 0 :
          # find the loopback with lowest number
          lowestLoopback = sorted(loopbacks, key=lambda i: int(i[8:10]))[0]
          if lowestLoopback:
            globalRouterID = lowestLoopback.split()[1]
        else:
          # no loopbacks, find the interface with highest ip address
          highestIPLine = (sorted(l3interfaces.splitlines(), key=lambda i: IP2Int(GetIPAddressFromLine(i)))[-1]).strip()
          if highestIPLine:
            globalRouterID = GetIPAddressFromLine(highestIPLine)
      except Exception as Ex :
        DebugEx.WriteLine("CiscoIOSRouter.CalculateRouterIDAndASNumber() : error while parsing interface information : " + str(Ex))
    
   
    # get the running routing protocols for this routing instance
    runnintRoutingProtocols = self.Router.ActiveProtocols(instance)
    for thisProtocol in runnintRoutingProtocols:  
      if thisProtocol == L3Discovery.NeighborProtocol.BGP:
        # construct CLI command
        if instanceName == self.Router._defaultRoutingInstanceName :
          cmd = "show ip bgp summary"
        else:
          cmd = "show ip bgp vpnv4 vrf {0} summary".format(instanceName)
        
        bgpSummary = Session.ExecCommand(cmd)
        match = re.findall(r"(?<=BGP router identifier )[\d.]{0,99}", bgpSummary, re.IGNORECASE)
        if len(match) == 1 :
          self.RouterID[instanceName][str(thisProtocol)] = match[0]
          if globalRouterID == ConnectionInfo.DeviceIP : globalRouterID = match[0]
        
        # get also the BGP AS number
        match = re.findall(r"(?<=local AS number )[\d.]{0,99}", bgpSummary, re.IGNORECASE) 
        if len(match) == 1 :
          self.BGPASNumber[instanceName] = match[0]
        
      elif thisProtocol == L3Discovery.NeighborProtocol.OSPF:
        cmd = "show ip ospf | i ID"
        ospfGeneral = Session.ExecCommand(cmd)
        # expecting output like this:
			  # Routing Process "ospf 200" with ID 10.9.254.251
				# Routing Process "ospf 100" with ID 192.168.1.1
        #
        # WARNING if more than one EIGRP process is running, generate error
        #        
        if len(ospfGeneral.splitlines()) == 1 :
          match = re.findall(r"(?<=ID )[\d.]{0,99}", ospfGeneral, re.IGNORECASE)
          if len(match) == 1 :
            self.RouterID[instanceName][str(thisProtocol)] = match[0]
            if globalRouterID == ConnectionInfo.DeviceIP : globalRouterID = match[0]
        else:
          raise ValueError("Parsing more than one OSPF process is not supported by parser")
     
      elif thisProtocol == L3Discovery.NeighborProtocol.EIGRP :
        cmd = "show ip eigrp topology | i ID"
        eigrpGeneral = Session.ExecCommand(cmd)
        # expecting output like this:
        # IP - EIGRP Topology Table for AS(10) / ID(10.9.240.1)
        # IP - EIGRP Topology Table for AS(20) / ID(10.9.240.1)
        #
        # TODO :
        # WARNING if more than one EIGRP process is running, generate error
        #        
        if len(eigrpGeneral.splitlines()) == 1 :
          match = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", eigrpGeneral, re.IGNORECASE)
          if len(match) == 1 :
            self.RouterID[instanceName][str(thisProtocol)] = match[0]
            if globalRouterID == ConnectionInfo.DeviceIP : globalRouterID = match[0]
        else:
          raise ValueError("Parsing more than one EIGRP process is not supportedby parser")        
                
      elif thisProtocol == L3Discovery.NeighborProtocol.CDP:
        # only for default (global) routing instance
        if instanceName == self.Router._defaultRoutingInstanceName :
          self.RouterID[instanceName][str(thisProtocol)] = self.Router.GetHostName()
          
      elif thisProtocol == L3Discovery.NeighborProtocol.RIP:
        # always use global router-id
        # TODO : this may require tuning
        self.RouterID[instanceName][str(thisProtocol)] = globalRouterID       
        
      elif thisProtocol == L3Discovery.NeighborProtocol.STATIC:  
        # always use global router-id
        self.RouterID[instanceName][str(thisProtocol)] = globalRouterID 
        
      else :
        self.RouterID[instanceName][str(thisProtocol)] = globalRouterID   
 def RoutingTable(self, instance):
   """Returns the list of RouteTableEntry objects for requested RoutingInstance"""
   parsedRoutes = []
   try:
     if instance : 
       instanceName = instance.Name
     # get route table size
     routeTableSize = self.RouteTableSize(instance)
     if routeTableSize > self._maxRouteTableEntries :
       # query only default route 
       if instance.IsDefaultRoutingInstance() :
         cmd = "show ip route 0.0.0.0"
       else :
         cmd = "show ip route vrf {0} 0.0.0.0".format(instanceName)
     else:
       # query inet.0 route table for the requested instance
       if instance.IsDefaultRoutingInstance() :
         cmd = "show ip route"
       else:
         cmd = "show ip route vrf {0}".format(instanceName)
     routes = Session.ExecCommand(cmd)
     v = self.GetVersion()
     if "ios-xe software" in v.lower():
       thisProtocol = NeighborProtocol.UNKNOWN
       expectingNextHop = False
       prefix = ""
       maskLength = -1
       subnettedPrefix = ""
       subnettedMaskLength = -1
       nextHop = ""
       adminDistance = ""
       routeMetric = ""
       parserSuccess = False
       outInterface = ""
       for rLine in [line.strip() for line in routes.splitlines()]:
         if "subnetted" in rLine:
           # lets check if we find an ipAddress/MaskLength combination in the line
           m = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b\/\d{1,2}", rLine)
           if len(m) == 1 :
             prefixAndMask = m[0].split('/')
             if len(prefixAndMask) == 2 :
               subnettedPrefix = prefixAndMask[0]
           # proceed to next rLine
           continue
         if rLine.startswith("B") :
           thisProtocol = NeighborProtocol.BGP
           expectingNextHop = False
         elif rLine.startswith("O") or rLine.startswith("IA") or rLine.startswith("N1") or rLine.startswith("N2") or rLine.startswith("E1") or rLine.startswith("E2") :
           thisProtocol = NeighborProtocol.OSPF
           expectingNextHop = False
         elif rLine.startswith("D") or rLine.startswith("EX") :
           thisProtocol = NeighborProtocol.EIGRP;
           expectingNextHop = False;
         elif rLine.startswith("R") :
           thisProtocol = NeighborProtocol.RIP
           expectingNextHop = False
         elif rLine.startswith("L") :
           thisProtocol = NeighborProtocol.LOCAL
           expectingNextHop = False
         elif rLine.startswith("C") :
           thisProtocol = NeighborProtocol.CONNECTED
           expectingNextHop = False
         elif rLine.startswith("S") :
           thisProtocol = NeighborProtocol.STATIC
           expectingNextHop = False
         elif rLine.startswith("[") and expectingNextHop : pass
         else :
           thisProtocol = NeighborProtocol.UNKNOWN
           expectingNextHop = False
         # reset variables if current line is not a continuation
         if not expectingNextHop :
           prefix = ""
           maskLength = -1
           nextHop = ""
           adminDistance = ""
           routeMetric = ""
           parserSuccess = False
           outInterface = ""
         
         if thisProtocol != NeighborProtocol.UNKNOWN :
           if thisProtocol == NeighborProtocol.LOCAL or thisProtocol == NeighborProtocol.CONNECTED :
             # we expect only one ip addresses in these lines which is the prefix
             m = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b\/\d{1,2}", rLine)
             if len(m) == 1 :
               s = m[0]
               prefixAndMask = filter(None, s.split('/'))
               prefix = prefixAndMask[0]
               maskLength = int(prefixAndMask[1])
               expectingNextHop = True
               # this line should also contain the out interface as the last word
               words = filter(None, rLine.split(','))
               outInterface = words[-1]
               expectingNextHop = False
               parserSuccess = True
           else:
             if not expectingNextHop:
               # we expect two ip addresses in these lines, first is the prefix and second is next-hop check for the prefix first 
               m = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b\/\d{1,2}", rLine)
               if len(m) == 1 :
                 s = m[0]
                 prefixAndMask = filter(None, s.split('/'))
                 prefix = prefixAndMask[0]
                 maskLength = int(prefixAndMask[1])
                 expectingNextHop = True
               else:
                 # check if we find an ip address in line and if it was a subnet of last prefix
                 # unfortunately logic seems to be broken in cas of some IOS-XE, like below route table entry is totally crap :
                 #     159.63.0.0 / 27 is subnetted, 2 subnets
                 # S        159.63.248.32[1 / 0] via 212.162.30.89
                 # S        159.63.248.96[1 / 0] via 212.162.30.89               
                 m = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", rLine)
                 # Due to above issue , below check does not work and we need to trust the subnettedPrefix value anyhow
                 # if (m.Success && IPOperations.IsIPAddressInNetwork(m.Value, subnettedPrefix, subnettedMaskLength))    
                 if len(m) == 1:
                   # the maskLength is still valid for this prefix
                   prefix = m[0]
                   maskLength = subnettedMaskLength
                   expectingNextHop = True                      
                 
             if expectingNextHop:
               # get next-hop
               m = re.findall(R"(?<=via )\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", rLine)
               if len(m) == 1 :
                 expectingNextHop = False
                 parserSuccess = True
                 nextHop = m[0]
                 # get preference
                 m = re.findall(r"\[(.*?)\]", rLine)
                 if len(m) == 1 :
                   preferences = filter(None, m[0].split('/'))
                   adminDistance = preferences[0].strip('[')
                   routeMetric = preferences[1].strip(']')
                 # this line should also contain the out interface
                 words = rLine.split(',')
                 if len(words) > 1 :
                   outInterface = words[-1]
                   # discard outInterface if not a real interface name, like matches date pattern
                   m =  re.findall(r"(\d{1,2}w\d{1,2}d)|(\d{1,2}d\d{1,2}h)", outInterface)
                   if len(m) == 1:
                     outInterface = "";
               else:
                 # only for debugging
                 expectingNextHop = True               
               
         if parserSuccess:
           try:
             rte = L3Discovery.RouteTableEntry()
             rte.RouterID = self.RouterID(thisProtocol, instance)
             rte.Prefix = prefix
             rte.MaskLength = maskLength
             rte.Protocol = str(thisProtocol)
             rte.AD = adminDistance
             rte.Metric = routeMetric
             rte.NextHop = nextHop
             rte.OutInterface = outInterface
             rte.Best = True # the show ip route output only lists best routes :-(
             rte.Tag = ""
             parsedRoutes.Add(rte)
           except Exception as Ex :
             msg = "CiscoIOSRouter.RoutingTable() : error processing route table : {0}".format(str(Ex))
             DebugEx.WriteLine(msg)
           
     else:
       # Not an ios-xe
       thisProtocol = NeighborProtocol.UNKNOWN
       expectingNextHop = False
       prefix = ""
       maskLength = -1
       subnettedPrefix = ""
       subnettedMaskLength = -1
       nextHop = ""
       adminDistance = ""
       routeMetric = ""
       parserSuccess = False
       outInterface = ""
       for rLine in [line.strip() for line in routes.splitlines()]:
         words = filter(None, rLine.split(' '))
         # lets check if we find an ipAddress/MaskLength combination in the line
         prefixFound = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b\/\d{1,2}", rLine)
         # or just an ipAddress
         addressFound = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", rLine)
         # if the line contains the expression "subnetted" then we will learn the subnet mask for upcoming route entries and continue the loop
         if "subnetted" in rLine and len(prefixFound) == 1 :
           addressAndMask = prefixFound[0].split('/')
           if len(addressAndMask) == 2:
             try:
               maskLength = int(addressAndMask[1])
             except:
               pass
           # proceed to next rLine
           continue
         if len(prefixFound) == 1:
           addressAndMask = prefixFound[0].split('/')
           if len(addressAndMask) == 2:
             prefix = addressAndMask[0]
             try:
               maskLength = int(addressAndMask[1])
             except:
               pass
         elif len(addressFound) == 1:
           prefix = addressFound[0]
         else: 
           continue
           
         if prefix:
           parserSuccess = True
           if prefix == "0.0.0.0" : 
             maskLength = 0
           # get next-hop
           nexthopFound = re.findall(r"(?<=via )\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", rLine)
           if len(nexthopFound) == 1:
             nextHop = nexthopFound[0]
           # get preference
           routeDetails = re.findall(r"\[(.*?)\]", rLine)
           if len(routeDetails) == 1:
             preferences = routeDetails[0].split('/')
             adminDistance = preferences[0].strip('[')
             routeMetric = preferences[1].strip(']')
           # this line should also contain the out interface
           outInterface = words[-1]
         else:
           # no ip address in this line, proceed to next
           continue
         # here we already know a mask length and the actual routed prefix, so check the protocol  
         if rLine.startswith("B") :
           thisProtocol = NeighborProtocol.BGP
         elif rLine.startswith("O") or rLine.startswith("IA") or rLine.startswith("N1") or rLine.startswith("N2") or rLine.startswith("E1") or rLine.startswith("E2") :
           thisProtocol = NeighborProtocol.OSPF
         elif rLine.startswith("D") or rLine.startswith("EX") :
           thisProtocol = NeighborProtocol.EIGRP;
         elif rLine.startswith("R") :
           thisProtocol = NeighborProtocol.RIP
         elif rLine.startswith("L") :
           thisProtocol = NeighborProtocol.LOCAL
         elif rLine.startswith("C") :
           thisProtocol = NeighborProtocol.CONNECTED
         elif rLine.startswith("S") :
           thisProtocol = NeighborProtocol.STATIC
         else :
           thisProtocol = NeighborProtocol.UNKNOWN
         
         if thisProtocol != NeighborProtocol.UNKNOWN:
           if parserSuccess:
             try :
               rte = RouteTableEntry()
               rte.RouterID = self.RouterID(thisProtocol, instance)
               rte.Prefix = prefix
               rte.MaskLength = maskLength
               rte.Protocol = str(thisProtocol)
               rte.AD = adminDistance
               rte.Metric = routeMetric
               rte.NextHop = nextHop
               rte.OutInterface = outInterface
               rte.Best = True # the show ip route output only lists best routes :-(
               rte.Tag = ""
               parsedRoutes.Add(rte)
             except Exception as Ex :
               msg = "CiscoIOSRouter.RoutingTable() : error processing route table : {0}".format(str(Ex))
               DebugEx.WriteLine(msg)
         
           
   except Exception as Ex:
     msg = "CiscoIOSRouter.RoutingTable() :unexpected error while processing route table : {0}".format(str(Ex))
     DebugEx.WriteLine(msg)
     raise Exception(msg)
   
   return parsedRoutes
 def RegisterNHRP(self, neighborRegistry, instance):
   """Performs NHRP database registration"""
   # neighborRegistry :The NetworkRegistry object
   # instance :The Routing instance reference
   # 
   # Sample input for parsing
   #
   #GigabitEthernet0/0/1 - Group 44
   #  State is Active
   #	  5 state changes, last state change 4w4d
   #  Virtual IP address is 10.81.0.1
   #  Active virtual MAC address is 0000.0c07.ac2c(MAC In Use)
   #	  Local virtual MAC address is 0000.0c07.ac2c(v1 default)
   #  Hello time 1 sec, hold time 3 sec
   #	  Next hello sent in 0.256 secs
   #  Authentication text, string "ROWVA252"
   #  Preemption enabled, delay min 60 secs
   #  Active router is local
   #  Standby router is 10.81.0.3, priority 100 (expires in 3.040 sec)
   #  Priority 105 (configured 105)
   #			Track object 1 state Up decrement 10
   #  Group name is "hsrp-Gi0/0/1-44" (default)
   VIPAddress = ""
   GroupID = ""
   PeerAddress = ""
   isActive = False
   ri = None
   hsrpSummary = Session.ExecCommand("show standby")
   for thisLine in hsrpSummary.splitlines():
     try:
       indentLevel = len(thisLine) - len(thisLine.lstrip(' '))
       if indentLevel == 0:
         # interface definition is changing
         if GroupID  and VIPAddress :
           neighborRegistry.RegisterNHRPPeer(self, instance, ri, L3Discovery.NHRPProtocol.HSRP, isActive, VIPAddress, GroupID, PeerAddress)
           VIPAddress = ""
           GroupID = ""
           PeerAddress = ""
           ri = None
         # -- 
         words = filter(None, thisLine.split(" "))
         if len(words) >= 3 :
           ifName = words[0]
           ri = self.GetInterfaceByName(ifName, instance)
           match = re.findall(r"(?<=Group )\d{0,99}", thisLine, re.IGNORECASE)
           if len(match) == 1 :  GroupID = words[2]
         continue
       if ri :
         l = thisLine.lower().lstrip()
         if l.startswith("virtual ip address is") :
           match = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", l, re.IGNORECASE)
           if len(match) == 1 : VIPAddress = match[0]
           continue
         if l.startswith("active router is local") :
           isActive = True
           continue
         if l.startswith("standby router is") :
           match = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", l, re.IGNORECASE)
           if len(match) == 1 : PeerAddress = match[0]
           continue
     except Exception as Ex:
       message = "JunOS Router Module Error : could not parse NHRP information <{0}> because : {1} ".format(thisLine, str(Ex))
       DebugEx.WriteLine(message)
       
   # -- register the last one
   if ri and VIPAddress and GroupID :
     neighborRegistry.RegisterNHRPPeer(self, instance, ri, L3Discovery.NHRPProtocol.HSRP, isActive, VIPAddress, GroupID, PeerAddress)    
Example #19
0
    def ParseInterfaces(self, instance):
        """Collects interface details for all interfaces of specified routing instance, but do not collect interface configuration """
        # Get the interfaces configurations
        if len(self._interfaceConfigurations) == 0:
            self.ParseInterfaceConfigurations()
        # Init interface dictionary for instance
        instanceName = self.Router._defaultRoutingInstanceName
        if instance: instanceName = instance.Name
        if self.Interfaces.get(instanceName, None) == None:
            self.Interfaces[instanceName] = []
        # Query the device interfaces
        interfaces = Session.ExecCommand("show interface summary").splitlines()
        # Add a dummy line at the end, required for below processing only
        interfaces.append("--end--")
        # Parse the result and fill up self.Interfaces list
        ri = L3Discovery.RouterInterface()
        lineCount = len(interfaces)
        currentLineIndex = 1
        rep_MAC = r"(?!0000)[a-f,0-9]{4}\.[a-f,0-9]{4}\.[a-f,0-9]{4}"
        for line in interfaces:
            try:
                if line.lower().startswith(
                        "interface") or currentLineIndex == lineCount:
                    # this is either a new interface block, or the end of the interface list
                    if ri and ri.Name:
                        # Add actual interface if vrf name matches instanceName
                        if not ri.VRFName and instanceName == self.Router._defaultRoutingInstanceName or ri.VRFName == instanceName:
                            ri.Configuration = self.GetInterfaceConfiguration(
                                ri.Name)
                            if ri.Configuration.find("vlan ") >= 0:
                                ri.PortMode = L3Discovery.RouterInterfacePortMode.L3Subinterface
                                subinterfaceDefinition = next((
                                    cline
                                    for cline in ri.Configuration.splitlines()
                                    if cline.startswith("vlan ")), "")
                                ri.VLANS = subinterfaceDefinition.split(
                                    ' ')[-1]
                            elif ri.Address:
                                ri.PortMode = L3Discovery.RouterInterfacePortMode.Routed
                            else:
                                ri.PortMode = L3Discovery.RouterInterfacePortMode.Unknown
                            ri.Description = next(
                                (cline
                                 for cline in ri.Configuration.splitlines()
                                 if cline.startswith("description")), "")
                            self.Interfaces[instanceName].Add(ri)
                        if currentLineIndex == lineCount:
                            break
                    words = filter(None, line.split(' '))
                    interfaceName = words[1]
                    if self.IsInterrestingInterface(interfaceName):
                        # Create new interface
                        ri = L3Discovery.RouterInterface()
                        # words should look like : Interface,GigabitEthernet0/0,"outside",is,up,line,protocol,is,up
                        ri.LogicalSystemName = "Default"
                        ri.Name = interfaceName
                        status = [
                            i.strip(',') for i in words
                            if "up" in i.lower() or "down" in i.lower()
                        ]
                        ri.Status = ",".join(status)
                    else:
                        ri = None
                else:
                    if ri:
                        # this line belongs to an iterface information block
                        sline = line.strip().lower()
                        if sline.startswith("ip address"):
                            addressAndMask = GetIPAddressAndSubnetMaskFromLine(
                                sline)
                            if len(addressAndMask) == 2:
                                ri.Address = addressAndMask[0]
                                ri.MaskLength = str(
                                    IPOperations.GetMaskLength(
                                        addressAndMask[1]))
                        if sline.startswith("mac address"):
                            mac = re.findall(rep_MAC, sline)
                            if len(mac) == 1:
                                ri.MAC = mac[0]
                        if "member of port-channel" in sline:
                            lagID = re.findall(r"\d+$", sline)
                            if len(lagID) == 1:
                                ri.AggregateID = lagID[0]

                # PortMode and VLANS will be processed later in a second pass
            except Exception as Ex:
                DebugEx.WriteLine(
                    "CiscoASA.InterfaceParser.ParseInterfaces() : error parsing text {0}. Error is {1}"
                    .format(line, str(Ex)))

            currentLineIndex += 1
    def ActiveProtocols(self, instance):
        """Returns the list of NeighborProtocols running on the requested routing instance """
        # no routing instances supported here
        instanceName = self._defaultRoutingInstanceName
        if instance: instanceName = instance.Name
        if self._runningRoutingProtocols.get(instanceName, None) == None:
            self._runningRoutingProtocols[instanceName] = []
        if len(self._runningRoutingProtocols[instanceName]) == 0:
            # OSPF
            cmd = "show ip ospf"
            response = Session.ExecCommand(cmd)
            rep_ospfEnabled = r"^OSPF Admin Mode\.+(.*)"
            try:
                ospfStatus = GetRegexGroupMatches(rep_ospfEnabled, response,
                                                  1)[0].strip().lower()
                if not ("disable" in ospfStatus):
                    self._runningRoutingProtocols[instanceName].Add(
                        L3Discovery.NeighborProtocol.OSPF)
            except Exception as Ex:
                DebugEx.WriteLine(
                    "HirschmannMACH.ActiveProtocols() : unexpected error parsing OSPF protocol information : {0}"
                    .format(str(Ex)))
            # RIP
            cmd = "show ip rip"
            response = Session.ExecCommand(cmd)
            rep_ripEnabled = r"^RIP Admin Mode\.+(.*)"
            try:
                ripStatus = GetRegexGroupMatches(rep_ripEnabled, response,
                                                 1)[0].strip().lower()
                if not ("disable" in ripStatus):
                    self._runningRoutingProtocols[instanceName].Add(
                        L3Discovery.NeighborProtocol.RIP)
            except Exception as Ex:
                DebugEx.WriteLine(
                    "HirschmannMACH.ActiveProtocols() : unexpected error parsing RIP protocol information : {0}"
                    .format(str(Ex)))
            # STATIC
            cmd = "show ip route static"
            response = Session.ExecCommand(cmd)
            rep_ipAddress = r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
            try:
                foundAddresses = re.findall(rep_ipAddress, response)
                # TODO : this may be too simple
                if len(foundAddresses) > 0:
                    self._runningRoutingProtocols[instanceName].Add(
                        L3Discovery.NeighborProtocol.STATIC)
            except Exception as Ex:
                DebugEx.WriteLine(
                    "HirschmannMACH.ActiveProtocols() : unexpected error parsing STATIC routing information : {0}"
                    .format(str(Ex)))

            # LLDP - only for default instance
            cmd = "show lldp config chassis admin-state"
            response = Session.ExecCommand(cmd)
            rep_lldpEnabled = r"^LLDP Config. Chassis,\s+Admin State\.+(.*)"
            try:
                lldpStatus = GetRegexGroupMatches(rep_lldpEnabled, response,
                                                  1)[0].strip().lower()
                if "on" in lldpStatus:
                    self._runningRoutingProtocols[instanceName].Add(
                        L3Discovery.NeighborProtocol.LLDP)
            except Exception as Ex:
                DebugEx.WriteLine(
                    "HirschmannMACH.ActiveProtocols() : unexpected error parsing LLDP protocol information : {0}"
                    .format(str(Ex)))
        result = self._runningRoutingProtocols[instanceName]
        return result
Example #21
0
    def RoutingTable(self, instance):
        """Returns the list of RouteTableEntry objects for requested RoutingInstance"""
        parsedRoutes = []
        try:
            if instance:
                instanceName = instance.Name
            # get route table size
            routeTableSize = self.RouteTableSize(instance)
            if routeTableSize > self._maxRouteTableEntries:
                # query only default route
                cmd = "show route 0.0.0.0"
            else:
                # query inet.0 route table for the requested instance
                cmd = "show route"
            routes = Session.ExecCommand(cmd)

            thisProtocol = NeighborProtocol.UNKNOWN
            expectingNextHop = False
            prefix = ""
            maskLength = -1
            subnettedPrefix = ""
            subnettedMaskLength = -1
            nextHop = ""
            adminDistance = ""
            routeMetric = ""
            parserSuccess = False
            outInterface = ""
            for rLine in [line.strip() for line in routes.splitlines()]:
                if "subnetted" in rLine:
                    # lets check if we find an ipAddress subnetMask combination in the line
                    m = re.findall(
                        r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b\/\d{1,2}",
                        rLine)
                    if len(m) == 1:
                        prefixAndMask = m[0].split('/')
                        if len(prefixAndMask) == 2:
                            subnettedPrefix = prefixAndMask[0]
                    # proceed to next rLine
                    continue
                if rLine.startswith("B"):
                    thisProtocol = NeighborProtocol.BGP
                    expectingNextHop = False
                elif rLine.startswith("O") or rLine.startswith(
                        "IA") or rLine.startswith("N1") or rLine.startswith(
                            "N2") or rLine.startswith(
                                "E1") or rLine.startswith("E2"):
                    thisProtocol = NeighborProtocol.OSPF
                    expectingNextHop = False
                elif rLine.startswith("D") or rLine.startswith("EX"):
                    thisProtocol = NeighborProtocol.EIGRP
                    expectingNextHop = False
                elif rLine.startswith("R"):
                    thisProtocol = NeighborProtocol.RIP
                    expectingNextHop = False
                elif rLine.startswith("L"):
                    thisProtocol = NeighborProtocol.LOCAL
                    expectingNextHop = False
                elif rLine.startswith("C"):
                    thisProtocol = NeighborProtocol.CONNECTED
                    expectingNextHop = False
                elif rLine.startswith("S"):
                    thisProtocol = NeighborProtocol.STATIC
                    expectingNextHop = False
                elif rLine.startswith("[") and expectingNextHop:
                    pass
                else:
                    thisProtocol = NeighborProtocol.UNKNOWN
                    expectingNextHop = False
                # reset variables if current line is not a continuation
                if not expectingNextHop:
                    prefix = ""
                    maskLength = -1
                    nextHop = ""
                    adminDistance = ""
                    routeMetric = ""
                    parserSuccess = False
                    outInterface = ""

                if thisProtocol != NeighborProtocol.UNKNOWN:
                    if thisProtocol == NeighborProtocol.LOCAL or thisProtocol == NeighborProtocol.CONNECTED:
                        # we expect an ip addresses-subnet mask pair in these lines
                        prefixAndMask = GetIPAddressAndSubnetMaskFromLine(
                            rLine)
                        if prefixAndMask:
                            prefix = prefixAndMask[0]
                            maskLength = IPOperations.GetMaskLength(
                                prefixAndMask[1])
                            # this line should also contain the out interface as the last word
                            words = filter(None, rLine.split(','))
                            asaNameif = words[-1]
                            oif = self._interfaceParser.GetInterfaceByASANameIf(
                                asaNameif, instance)
                            if oif: outInterface = oif.Name
                            else: outInterface = asaNameif
                            expectingNextHop = False
                            parserSuccess = True
                    else:
                        if not expectingNextHop:
                            #  we expect an ip addresses-subnet mask pair in these lines, and also a next-hop
                            prefixAndMask = GetIPAddressAndSubnetMaskFromLine(
                                rLine)
                            if prefixAndMask:
                                prefix = prefixAndMask[0]
                                maskLength = IPOperations.GetMaskLength(
                                    prefixAndMask[1])
                                expectingNextHop = True

                        if expectingNextHop:
                            # get next-hop
                            m = re.findall(
                                R"(?<=via )\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}",
                                rLine)
                            if len(m) == 1:
                                expectingNextHop = False
                                parserSuccess = True
                                nextHop = m[0]
                                # get preference
                                m = re.findall(r"\[(.*?)\]", rLine)
                                if len(m) == 1:
                                    preferences = filter(None, m[0].split('/'))
                                    adminDistance = preferences[0].strip('[')
                                    routeMetric = preferences[1].strip(']')
                                # this line should also contain the out interface
                                words = rLine.split(',')
                                if len(words) > 1:
                                    asaNameif = words[-1]
                                    oif = self._interfaceParser.GetInterfaceByASANameIf(
                                        asaNameif, instance)
                                    if oif: outInterface = oif.Name
                                    else: outInterface = asaNameif
                            else:
                                # only for debugging
                                expectingNextHop = True

                if parserSuccess:
                    try:
                        rte = L3Discovery.RouteTableEntry()
                        rte.RouterID = self.RouterID(thisProtocol, instance)
                        rte.Prefix = prefix
                        rte.MaskLength = maskLength
                        rte.Protocol = str(thisProtocol)
                        rte.AD = adminDistance
                        rte.Metric = routeMetric
                        rte.NextHop = nextHop
                        rte.OutInterface = outInterface
                        rte.Best = True  # the show ip route output only lists best routes :-(
                        rte.Tag = ""
                        parsedRoutes.Add(rte)
                    except Exception as Ex:
                        msg = "CiscoASA.RoutingTable() : error processing route table : {0}".format(
                            str(Ex))
                        DebugEx.WriteLine(msg)

        except Exception as Ex:
            msg = "CiscoASA.RoutingTable() :unexpected error while processing route table : {0}".format(
                str(Ex))
            DebugEx.WriteLine(msg)
            raise Exception(msg)

        return parsedRoutes
    def ParseInterfaces(self, instance):
        """Collects interface details for all interfaces of specified routing instance, but do not collect interface configuration """
        from Scriptngo.Common import IPOperations
        try:
            # First parse the VLAN database if missing
            if len(self._vlanIDs) == 0: self.ParseVLANDatabase()
            # Then collect the interfaces configurations if not yet done
            if len(self._interfaceConfigurations) == 0:
                self.ParseInterfaceConfigurations()
            # Init interface dictionary for current routing instance
            instanceName = self.Router._defaultRoutingInstanceName
            if instance: instanceName = instance.Name
            if self.Interfaces.get(instanceName, None) == None:
                self.Interfaces[instanceName] = []
            if self.Router.SwitchType == HirshmannSwitchType.MachSwitch:
                # get vlan-ip data
                vlanRoutedInterfaces = Session.ExecCommand(
                    "show ip vlan").splitlines()
                # expected output for vlanRoutedInterfaces :
                #           Logical
                #VLAN ID   Interface     IP Address       Subnet Mask        MAC Address
                #-------  -----------  ---------------  ---------------  -----------------
                #1        9/7          10.0.40.254      255.255.255.0    EC:74:BA:50:0B:49
                #2        9/1          10.0.41.254      255.255.255.0    EC:74:BA:50:0B:43
                #3        9/2          10.0.39.254      255.255.255.0    EC:74:BA:50:0B:44
                #4        9/3          10.0.43.254      255.255.255.0    EC:74:BA:50:0B:45
                #5        9/4          10.0.38.254      255.255.255.0    EC:74:BA:50:0B:46
                vlanIPHeaderLine = next(
                    (l for l in vlanRoutedInterfaces if l.startswith("----")),
                    None)
                # vlanHeaderSection will contain column start-end positions
                vlanIPHeaderSection = []
                if vlanIPHeaderLine:
                    matches = re.finditer(r"-  -", vlanIPHeaderLine)
                    for index, match in enumerate(matches):
                        frompos = match.regs[0][0]
                        topos = match.regs[0][1]
                        #print "{0}:{1}".format(frompos, topos)
                        if index == 0:
                            vlanIPHeaderSection.append([0, frompos + 1])
                        else:
                            vlanIPHeaderSection[index][1] = topos - 2
                        vlanIPHeaderSection.append([topos - 1, -1])
                    if len(vlanIPHeaderSection) > 0:
                        vlanIPHeaderSection[-1][1] = len(vlanIPHeaderLine)

            # get all interface data
            responseLines = Session.ExecCommand("show port all").splitlines()
            # expected output responseLines :
            #               Admin   Physical   Physical   Link   Link   Cable-Cross   Flow   Device  VLAN
            # Intf   Type    Mode    Mode       Status   Status  Trap   PhysMode Fix  Mode   status  Prio
            #------ ------ ------- ---------- ---------- ------ ------- ------------ ------- ------- ----
            #6/1           Enable  Auto       1000 Full  Up     Enable  Unsupported  Enable  Ignore     0
            #6/2           Enable  Auto       1000 Full  Up     Enable  Unsupported  Enable  Ignore     0
            #
            interfaceLines = [
                l.strip() for l in responseLines
                if len(re.findall(r"^\d+\/\d+\s+", l)) > 0
            ]
            headerLine = next(
                (l for l in responseLines if l.startswith("----")), None)
            # headerSection will contain column start-end positions
            headerSections = []
            matches = re.finditer(r"- -", headerLine)
            for index, match in enumerate(matches):
                frompos = match.regs[0][0]
                topos = match.regs[0][1]
                #print "{0}:{1}".format(frompos, topos)
                if index == 0:
                    headerSections.append([0, frompos + 1])
                else:
                    headerSections[index][1] = topos - 2
                headerSections.append([topos - 1, -1])
            headerSections[-1][1] = len(headerLine)
            # --
            for line in interfaceLines:
                try:
                    ri = L3Discovery.RouterInterface()
                    ri.Name = line[
                        headerSections[0][0]:headerSections[0][1]].strip()
                    adminMode = line[headerSections[2][0]:headerSections[2]
                                     [1]].strip().lower()
                    if adminMode == "enable": adminMode = "up"
                    else: adminMode = "down"
                    linkState = line[headerSections[5][0]:headerSections[5]
                                     [1]].strip().lower()
                    ri.Status = "{0}/{1}".format(linkState, adminMode)
                    ri.PortMode = L3Discovery.RouterInterfacePortMode.Access
                    ri.Configuration = self._interfaceConfigurations.get(
                        ri.Name, "")
                    ri.Address = ""
                    if "ip address" in ri.Configuration:
                        addressline = next(
                            (l for l in ri.Configuration.splitlines()
                             if l.startswith("ip address")), "")
                        if addressline:
                            prefixAndMask = GetIPAddressAndSubnetMaskFromLine(
                                addressline)
                            if prefixAndMask:
                                prefix = prefixAndMask[0]
                                ri.Address = prefix
                                maskLength = str(
                                    IPOperations.GetMaskLength(
                                        prefixAndMask[1]))
                                ri.MaskLength = maskLength
                                ri.PortMode = L3Discovery.RouterInterfacePortMode.Routed
                                # try to get which VLAN this interface belongs to, if any
                                for vlanLine in vlanRoutedInterfaces:
                                    vlanIntfName = vlanLine[
                                        vlanIPHeaderSection[1][0]:
                                        vlanIPHeaderSection[1][1]].strip()
                                    if vlanIntfName == ri.Name:
                                        thisIntfVlanID = vlanLine[
                                            vlanIPHeaderSection[0][0]:
                                            vlanIPHeaderSection[0][1]].strip()
                                        if thisIntfVlanID.isdigit():
                                            intfVLANinfo = ""
                                            vname = self._vlanNames.get(
                                                thisIntfVlanID, "")
                                            if vname:
                                                intfVLANinfo = "{0}|{1}".format(
                                                    vname, thisIntfVlanID)
                                            else:
                                                intfVLANinfo = thisIntfVlanID
                                            ri.VLANS = intfVLANinfo

                    # process interface vlan membership
                    if ri.PortMode != L3Discovery.RouterInterfacePortMode.Routed and ri.Configuration:
                        try:
                            pvid = ""
                            rep_pvid = r"vlan pvid (\d+)"
                            ri_pvid = re.finditer(rep_pvid, ri.Configuration,
                                                  re.MULTILINE | re.IGNORECASE)
                            for i, m in enumerate(ri_pvid):
                                pvid = m.group(1)
                            taggedVLANs = []
                            rep_taggedVLANs = r"vlan tagging (\d+)"
                            ri_taggedVLANs = re.finditer(
                                rep_taggedVLANs, ri.Configuration,
                                re.MULTILINE | re.IGNORECASE)
                            for i, m in enumerate(ri_taggedVLANs):
                                vid = m.group(1)
                                vname = self._vlanNames.get(vid, "")
                                if vname:
                                    taggedVLANs.append("{0}|{1}".format(
                                        vname, vid))
                                else:
                                    taggedVLANs.append(vid)
                            if len(taggedVLANs) > 0:
                                ri.PortMode = L3Discovery.RouterInterfacePortMode.Trunk
                            interfaceVLANInfo = ",".join(taggedVLANs)
                            if pvid:
                                pvidname = self._vlanNames.get(pvid, "")
                                if pvidname:
                                    interfaceVLANInfo += ",{0}|{1}".format(
                                        pvidname, pvid)
                                else:
                                    interfaceVLANInfo += ",{0}".format(pvid)
                            ri.VLANS = interfaceVLANInfo.strip(',')
                        except Exception as Ex:
                            DebugEx.WriteLine(
                                "HirschmannMACH.InterfaceParser.ParseInterfaces() : unexpected error procesing VLAN data for interface: {0}. Error is : {1}"
                                .format(ri.Name, str(Ex)))
                    self.Interfaces[instanceName].Add(ri)
                except Exception as Ex:
                    DebugEx.WriteLine(
                        "HirschmannMACH.InterfaceParser.ParseInterfaces() : unexpected error procesing interface data: {0}"
                        .format(str(Ex)))
        except Exception as Ex:
            DebugEx.WriteLine(
                "HirschmannMACH.InterfaceParser.ParseInterfaces() : unexpected error : {0}"
                .format(str(Ex)))
Example #23
0
    def Parse(self, nRegistry, cToken, instance):
        """ Perform parsing logic on the given text, which should be relevant to the supported protocols and vendors"""
        # The neighbor registry object is received as parameter
        # This must be used to register a new neighbor for further discovery.
        # --
        # A CancellationToken is also passed as parameter. The token should be checked repetitively whether cancellation was requested
        # by user and if yes, stop further processing.
        # --
        # The RoutingInstance onject to work with is also passed as a parameter
        instanceName = L3Discovery.RoutingInstance.DefaultInstanceName(
            self.ParsingForVendor)
        if instance: instanceName = instance.Name
        OperationStatusLabel = "Querying LLDP neighbor data..."
        #--
        cToken.ThrowIfCancellationRequested()
        #
        # regex search patters
        # Split command output to neighbor blocks. WARNING : splitting does not work with line engins \r\n, only if \r removed !
        repNeighborDataBlocks = r"-+\n.*(?:(?:(?!^-+\n)[\s\S])*)"
        repConnectingPort = r"^Local Intf:(.*)"
        repRemoteChassisID = r"^Chassis id:(.*)"
        repRemoteSystemName = r"^System Name:(.*)"
        repNameOfStation = r"^System Description(.*)"
        repRemotePortID = r"^Port id:(.*)"
        repManagementAddress = r"Management Addresses:\s+ip:(.[\d.]+)"

        # Get data from switch
        lldpNeighborData = Session.ExecCommand("show lldp neighbors detail")
        # Must replace \r\n to simply \n
        lldpNeighborData = re.sub(r"\r", "", lldpNeighborData)
        # Parse neighbor data
        neighborDatablocks = re.finditer(repNeighborDataBlocks,
                                         lldpNeighborData,
                                         re.MULTILINE | re.IGNORECASE)
        for index, match in enumerate(neighborDatablocks):
            try:
                thisRemoteData = match.group()
                localIntfName = self.GetRegexGroupMatches(
                    repConnectingPort, thisRemoteData, 1)[0].strip()
                ri = self.Router.GetInterfaceByName(localIntfName, instance)
                if ri:
                    remoteChassisID = self.GetRegexGroupMatches(
                        repRemoteChassisID, thisRemoteData, 1)
                    if remoteChassisID and remoteChassisID[0]:
                        remoteChassisID = remoteChassisID[0].strip()
                    else:
                        remoteChassisID = "Unknown Chassis ID"
                    remoteSystemName = self.GetRegexGroupMatches(
                        repRemoteSystemName, thisRemoteData, 1)
                    if remoteSystemName and remoteSystemName[0]:
                        remoteSystemName = remoteSystemName[0].strip()
                    else:
                        remoteSystemName = self.GetRegexGroupMatches(
                            repNameOfStation, thisRemoteData, 1)
                        if remoteSystemName and remoteSystemName[0]:
                            remoteSystemName = remoteSystemName[0].strip()
                        else:
                            remoteSystemName = "Unknown System Name"

                    remotePortName = self.GetRegexGroupMatches(
                        repRemotePortID, thisRemoteData, 1)
                    remoteIntfName = ""
                    if remotePortName and remotePortName[0]:
                        remotePortName = remotePortName[0].strip()
                        if remotePortName.isdigit():
                            remotePortName = str(int(remotePortName))
                    remoteIntfName = remotePortName
                    remoteNeighboringIP = self.GetRegexGroupMatches(
                        repManagementAddress, thisRemoteData, 1)
                    if remoteNeighboringIP and remoteNeighboringIP[0]:
                        remoteNeighboringIP = remoteNeighboringIP[0].strip()
                    else:
                        # try resolve from ARP if remote PortName is a MAC address and if that can be resolved from ARP cache
                        isremotePortNameMAC = re.findall(
                            r"[a-f0-9]{2}-[a-f0-9]{2}-[a-f0-9]{2}-[a-f0-9]{2}-[a-f0-9]{2}-[a-f0-9]{2}",
                            remotePortName, re.IGNORECASE) > 0
                        if isremotePortNameMAC:
                            arpEntry = Session.ExecCommand(
                                "show arp | i {0}".format(remotePortName))
                            matchedIPs = re.findall(
                                r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b",
                                arpEntry, re.IGNORECASE)
                            if len(matchedIPs) > 0:
                                remoteNeighboringIP = matchedIPs[0].strip()
                            else:
                                remoteNeighboringIP = ""
                        if not remoteNeighboringIP:
                            # try if remote chassi ID is MAC and if that can be resolved from ARP cache
                            isremoteChassisIsMAC = re.findall(
                                r"[a-f0-9]{2}-[a-f0-9]{2}-[a-f0-9]{2}-[a-f0-9]{2}-[a-f0-9]{2}-[a-f0-9]{2}",
                                remoteChassisID, re.IGNORECASE) > 0
                            if isremoteChassisIsMAC:
                                arpEntry = Session.ExecCommand(
                                    "show arp | i {0}".format(remoteChassisID))
                                matchedIPs = re.findall(
                                    r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b",
                                    arpEntry, re.IGNORECASE)
                                if len(matchedIPs) > 0:
                                    remoteNeighboringIP = matchedIPs[0].strip()
                            else:
                                remoteNeighboringIP = ""
                    # Now we have all the data to register the neighbor
                    nRegistry.RegisterNeighbor(
                        self.Router, instance,
                        L3Discovery.NeighborProtocol.LLDP, remoteChassisID, "",
                        remoteSystemName, remoteNeighboringIP, ri, "OK",
                        remoteIntfName)
                else:
                    DebugEx.WriteLine(
                        "CiscoIOS_LLDP.Parse() : Router object failed to provide details for interface < {0} >"
                        .format(localIntfName), DebugLevel.Warning)
            except Exception as Ex:
                DebugEx.WriteLine(
                    "CiscoIOS_LLDP.Parse() : Error while processing block #{0}. Error is: {1}"
                    .format(index, str(Ex)))
    def Parse(self, nRegistry, cToken, instance):
        """ Perform parsing logic on the given text, which should be relevant to the supported protocols and vendors"""
        # The neighbor registry object is received as parameter
        # This must be used to register a new neighbor for further discovery.
        # --
        # A CancellationToken is also passed as parameter. The token should be checked repetitively whether cancellation was requested
        # by user and if yes, stop further processing.
        # --
        # The RoutingInstance onject to work with is also passed as a parameter
        instanceName = L3Discovery.RoutingInstance.DefaultInstanceName(
            self.ParsingForVendor)
        if instance: instanceName = instance.Name
        OperationStatusLabel = "Querying LLDP neighbor data..."
        #--
        cToken.ThrowIfCancellationRequested()
        #
        repMAC = r"[a-f0-9]{2}[:-][a-f0-9]{2}[:-][a-f0-9]{2}[:-][a-f0-9]{2}[:-][a-f0-9]{2}[:-][a-f0-9]{2}"
        repIPv4 = r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"
        if self.Router.PythonRouter._switchType == DLinkSwitchType.DGS3600:
            # regex search patters
            # Split command output to neighbor blocks. WARNING : splitting does not work with line engins \r\n, only if \r removed !
            repNeighborDataBlocks = r"Port ID:.*(?:(?:(?!^Port ID:)[\s\S])*)"
            # Split command output to entity blocks. WARNING : splitting does not work with line engins \r\n, only if \r removed !
            repEntityDataBlocks = r"Entity\s\d+.*(?:(?:(?!^Entity\s\d+)[\s\S])*)"
            repConnectingPort = r"^Port ID:(.*)"
            repRemoteChassisID = r"Chassis ID\s+:(.*)"
            repRemoteSystemName = r"System Name\s+:(.*)"
            repNameOfStation = r"^\s+Name of Station\.+\s(.*)"
            repRemotePortID = r"Port ID\s+:(.*)"
            repManagementAddress = r"Management Address\.+\s([a-f\d:.]+)"
            # Get data from switch
            lldpNeighborData = Session.ExecCommand(
                "show lldp neighbors interface eth1/0/1-1/0/28")
            # Must replace \r\n to simply \n
            lldpNeighborData = re.sub(r"\r", "", lldpNeighborData)
            # Parse neighbor data
            neighborDatablocks = re.finditer(repNeighborDataBlocks,
                                             lldpNeighborData,
                                             re.MULTILINE | re.IGNORECASE)
            for index, match in enumerate(neighborDatablocks):
                try:
                    thisRemoteData = match.group()
                    localIntfName = self.GetRegexGroupMatches(
                        repConnectingPort, thisRemoteData, 1)[0].strip()
                    entityDatablocks = re.finditer(
                        repEntityDataBlocks, thisRemoteData,
                        re.MULTILINE | re.IGNORECASE)
                    for index, match in enumerate(entityDatablocks):
                        thisEntityData = match.group()
                        ri = self.Router.GetInterfaceByName(
                            localIntfName, instance)
                        if ri:
                            remoteChassisID = self.GetRegexGroupMatches(
                                repRemoteChassisID, thisEntityData, 1)
                            if remoteChassisID and remoteChassisID[0]:
                                remoteChassisID = remoteChassisID[0].strip()
                            else:
                                remoteChassisID = "Unknown Chassis ID"
                            remoteSystemName = self.GetRegexGroupMatches(
                                repRemoteSystemName, thisEntityData, 1)
                            if remoteSystemName and remoteSystemName[0]:
                                remoteSystemName = remoteSystemName[0].strip()
                            else:
                                remoteSystemName = self.GetRegexGroupMatches(
                                    repNameOfStation, thisEntityData, 1)
                                if remoteSystemName and remoteSystemName[0]:
                                    remoteSystemName = remoteSystemName[
                                        0].strip()
                                else:
                                    remoteSystemName = "Unknown System Name"

                            remotePortName = self.GetRegexGroupMatches(
                                repRemotePortID, thisEntityData, 1)
                            remoteIntfName = ""
                            if remotePortName and remotePortName[0]:
                                remotePortName = remotePortName[0].strip()
                                if remotePortName.isdigit():
                                    remotePortName = str(int(remotePortName))
                            remoteIntfName = remotePortName
                            remoteNeighboringIP = self.GetRegexGroupMatches(
                                repManagementAddress, thisEntityData, 1)
                            if remoteNeighboringIP and remoteNeighboringIP[0]:
                                remoteNeighboringIP = remoteNeighboringIP[
                                    0].strip()
                            else:
                                remoteNeighboringIP = ""
                                # try resolve from ARP if remote PortName is a MAC address and if that can be resolved from ARP cache
                                isremotePortNameMAC = len(
                                    re.findall(repMAC, remotePortName,
                                               re.IGNORECASE)) > 0
                                if isremotePortNameMAC:
                                    arpEntry = Session.ExecCommand(
                                        "show arp | i {0}".format(
                                            remotePortName))
                                    matchedIPs = re.findall(
                                        repIPv4, arpEntry, re.IGNORECASE)
                                    if len(matchedIPs) > 0:
                                        remoteNeighboringIP = matchedIPs[
                                            0].strip()
                                if not remoteNeighboringIP:
                                    # try if remote chassi ID is MAC and if that can be resolved from ARP cache
                                    isremoteChassisIsMAC = len(
                                        re.findall(repMAC, remoteChassisID,
                                                   re.IGNORECASE)) > 0
                                    if isremoteChassisIsMAC:
                                        arpEntry = Session.ExecCommand(
                                            "show arp | i {0}".format(
                                                remoteChassisID))
                                        matchedIPs = re.findall(
                                            repIPv4, arpEntry, re.IGNORECASE)
                                        if len(matchedIPs) > 0:
                                            remoteNeighboringIP = matchedIPs[
                                                0].strip()

                            # Now we have all the data to register the neighbor
                            nRegistry.RegisterNeighbor(
                                self.Router, instance,
                                L3Discovery.NeighborProtocol.LLDP,
                                remoteChassisID, "", remoteSystemName,
                                remoteNeighboringIP, ri, "OK", remoteIntfName)
                        else:
                            DebugEx.WriteLine(
                                "DLinkSwitch_LLDP.Parse() : Router object failed to provide details for interface < {0} >"
                                .format(localIntfName), DebugLevel.Warning)
                except Exception as Ex:
                    DebugEx.WriteLine(
                        "Error in DLinkSwitch_LLDP parser while processing block #{0}. Error is: {1}"
                        .format(index, str(Ex)))

        elif self.Router.PythonRouter._switchType == DLinkSwitchType.DGS3100:
            # regex search patters
            # Split command output to neighbor blocks. WARNING : splitting does not work with line engins \r\n, only if \r removed !
            repNeighborDataBlocks = r"Port ID\s+:\s\d+:\d+\n-(?:(?:(?!^Port ID\s+:\s\d+:\d+\n-)[\s\S])*)"
            # Split command output to entity blocks. WARNING : splitting does not work with line engins \r\n, only if \r removed !
            repEntityDataBlocks = r"Entity\s\d+.*(?:(?:(?!^Entity\s\d+)[\s\S])*)"
            repConnectingPort = r"^Port ID\s+:\s(.*)\n--"
            repRemoteChassisID = r"Chassis ID\s+:(.*)"
            repRemotePortID = r"^Port ID\s+:\s(.*)\n[^-]"
            repManagementAddress = r"Management Address\.+\s([a-f\d:.]+)"
            # Get data from switch
            lldpNeighborData = Session.ExecCommand("show lldp remote_ports")
            # Must replace \r\n to simply \n
            lldpNeighborData = re.sub(r"\r", "", lldpNeighborData)
            # Parse neighbor data
            neighborDatablocks = re.finditer(repNeighborDataBlocks,
                                             lldpNeighborData,
                                             re.MULTILINE | re.IGNORECASE)
            for index, match in enumerate(neighborDatablocks):
                try:
                    thisRemoteData = match.group()
                    localIntfName = self.GetRegexGroupMatches(
                        repConnectingPort, thisRemoteData, 1)[0].strip()
                    entityDatablocks = re.finditer(
                        repEntityDataBlocks, thisRemoteData,
                        re.MULTILINE | re.IGNORECASE)
                    for index, match in enumerate(entityDatablocks):
                        thisEntityData = match.group()
                        ri = self.Router.GetInterfaceByName(
                            localIntfName, instance)
                        if ri:
                            remoteChassisID = self.GetRegexGroupMatches(
                                repRemoteChassisID, thisEntityData, 1)
                            if remoteChassisID and remoteChassisID[0]:
                                remoteChassisID = remoteChassisID[0].strip()
                            else:
                                remoteChassisID = "Unknown Chassis ID"
                            remoteSystemName = "Unknown System Name"
                            #              remoteSystemName = self.GetRegexGroupMatches(repRemoteSystemName, thisEntityData, 1)
                            #              if remoteSystemName and remoteSystemName[0] :
                            #                remoteSystemName = remoteSystemName[0].strip()
                            #              else :
                            #                remoteSystemName = self.GetRegexGroupMatches(repNameOfStation, thisEntityData, 1)
                            #                if remoteSystemName and remoteSystemName[0] :
                            #                  remoteSystemName = remoteSystemName[0].strip()
                            #                else:

                            remotePortName = self.GetRegexGroupMatches(
                                repRemotePortID, thisEntityData, 1)
                            remoteIntfName = ""
                            if remotePortName and remotePortName[0]:
                                remotePortName = remotePortName[0].strip()
                                if remotePortName.isdigit():
                                    remotePortName = str(int(remotePortName))
                            remoteIntfName = remotePortName
                            remoteNeighboringIP = self.GetRegexGroupMatches(
                                repManagementAddress, thisEntityData, 1)
                            if remoteNeighboringIP and remoteNeighboringIP[0]:
                                remoteNeighboringIP = remoteNeighboringIP[
                                    0].strip()
                            else:
                                remoteNeighboringIP = ""
                                # try resolve from ARP if remote PortName is a MAC address and if that can be resolved from ARP cache
                                isremotePortNameMAC = len(
                                    re.findall(repMAC, remotePortName,
                                               re.IGNORECASE)) > 0
                                if isremotePortNameMAC:
                                    arpEntries = Session.ExecCommand(
                                        "show arpentry")
                                    m_arpEntry = filter(
                                        lambda e: remotePortName in e,
                                        arpEntries.splitlines())
                                    if len(m_arpEntry) > 0:
                                        arpEntry = m_arpEntry[0]
                                    else:
                                        arpEntry = ""
                                    matchedIPs = re.findall(
                                        repIPv4, arpEntry, re.IGNORECASE)
                                    if len(matchedIPs) > 0:
                                        remoteNeighboringIP = matchedIPs[
                                            0].strip()
                                if not remoteNeighboringIP:
                                    # try if remote chassi ID is MAC and if that can be resolved from ARP cache
                                    isremoteChassisIsMAC = len(
                                        re.findall(repMAC, remoteChassisID,
                                                   re.IGNORECASE)) > 0
                                    if isremoteChassisIsMAC:
                                        arpEntries = Session.ExecCommand(
                                            "show arpentry")
                                        m_arpEntry = filter(
                                            lambda e: remoteChassisID in e,
                                            arpEntries.splitlines())
                                        if len(m_arpEntry) > 0:
                                            arpEntry = m_arpEntry[0]
                                        else:
                                            arpEntry = ""
                                        matchedIPs = re.findall(
                                            repIPv4, arpEntry, re.IGNORECASE)
                                        if len(matchedIPs) > 0:
                                            remoteNeighboringIP = matchedIPs[
                                                0].strip()

                            # Now we have all the data to register the neighbor
                            nRegistry.RegisterNeighbor(
                                self.Router, instance,
                                L3Discovery.NeighborProtocol.LLDP,
                                remoteChassisID, "", remoteSystemName,
                                remoteNeighboringIP, ri, "OK", remoteIntfName)
                        else:
                            DebugEx.WriteLine(
                                "DLinkSwitch_LLDP.Parse() : Router object failed to provide details for interface < {0} >"
                                .format(localIntfName), DebugLevel.Warning)
                except Exception as Ex:
                    DebugEx.WriteLine(
                        "Error in DLinkSwitch_LLDP parser while processing block #{0}. Error is: {1}"
                        .format(index, str(Ex)))

        elif self.Router.PythonRouter._switchType == DLinkSwitchType.DGS3400:
            # regex search patters
            # Split command output to neighbor blocks. WARNING : splitting does not work with line engins \r\n, only if \r removed !
            repNeighborDataBlocks = r"Port ID\s+:\s+\d+\s+\n-(?:(?:(?!^Port ID\s+:\s+\d+\s+\n-)[\s\S])*)"
            # Split command output to entity blocks. WARNING : splitting does not work with line endings \r\n, only if \r removed !
            repEntityDataBlocks = r"Entity\s\d+.*(?:(?:(?!^Entity\s\d+)[\s\S])*)"
            repConnectingPort = r"^Port ID\s+:\s(.*)\n--"
            repRemoteSystemName = r"^\s+System Name\s+:(.*)"
            repNameOfStation = r"^\s+System Description\.+\s(.*)"
            repRemoteChassisID = r"Chassis ID\s+:(.*)"
            repRemotePortID = r"Port ID\s+:\s(.*)\n[^-]"
            repManagementAddress = r"Management Address\.+\s([a-f\d:.]+)"
            # Get data from switch
            lldpNeighborData = Session.ExecCommand("show lldp remote_ports")
            # Must replace \r\n to simply \n
            # lldpNeighborData = re.sub(r"\r", "", lldpNeighborData)
            # Parse neighbor data
            neighborDatablocks = re.finditer(repNeighborDataBlocks,
                                             lldpNeighborData,
                                             re.MULTILINE | re.IGNORECASE)
            for index, match in enumerate(neighborDatablocks):
                try:
                    thisRemoteData = match.group()
                    localIntfName = self.GetRegexGroupMatches(
                        repConnectingPort, thisRemoteData, 1)[0].strip()
                    entityDatablocks = re.finditer(
                        repEntityDataBlocks, thisRemoteData,
                        re.MULTILINE | re.IGNORECASE)
                    for index, match in enumerate(entityDatablocks):
                        thisEntityData = match.group()
                        ri = self.Router.GetInterfaceByName(
                            localIntfName, instance)
                        if ri:
                            remoteChassisID = self.GetRegexGroupMatches(
                                repRemoteChassisID, thisEntityData, 1)
                            if remoteChassisID and remoteChassisID[0]:
                                remoteChassisID = remoteChassisID[0].strip()
                            else:
                                remoteChassisID = "Unknown Chassis ID"
                            remoteSystemName = "Unknown System Name"
                            remoteSystemName = self.GetRegexGroupMatches(
                                repRemoteSystemName, thisEntityData, 1)
                            if remoteSystemName and remoteSystemName[0]:
                                remoteSystemName = remoteSystemName[0].strip()
                            else:
                                remoteSystemName = self.GetRegexGroupMatches(
                                    repNameOfStation, thisEntityData, 1)
                                if remoteSystemName and remoteSystemName[0]:
                                    remoteSystemName = remoteSystemName[
                                        0].strip()
                                else:
                                    remoteSystemName = "Unknown System Name"
                            remotePortName = self.GetRegexGroupMatches(
                                repRemotePortID, thisEntityData, 1)
                            remoteIntfName = ""
                            if remotePortName and remotePortName[0]:
                                remotePortName = remotePortName[0].strip()
                                if remotePortName.isdigit():
                                    remotePortName = str(int(remotePortName))
                            remoteIntfName = remotePortName
                            remoteNeighboringIP = self.GetRegexGroupMatches(
                                repManagementAddress, thisEntityData, 1)
                            if remoteNeighboringIP and remoteNeighboringIP[0]:
                                remoteNeighboringIP = remoteNeighboringIP[
                                    0].strip()
                            else:
                                remoteNeighboringIP = ""
                                # try resolve from ARP if remote PortName is a MAC address and if that can be resolved from ARP cache
                                isremotePortNameMAC = len(
                                    re.findall(repMAC, remotePortName,
                                               re.IGNORECASE)) > 0
                                if isremotePortNameMAC:
                                    arpEntries = Session.ExecCommand(
                                        "show arpentry")
                                    m_arpEntry = filter(
                                        lambda e: remotePortName in e,
                                        arpEntries.splitlines())
                                    if len(m_arpEntry) > 0:
                                        arpEntry = m_arpEntry[0]
                                    else:
                                        arpEntry = ""
                                    matchedIPs = re.findall(
                                        repIPv4, arpEntry, re.IGNORECASE)
                                    if len(matchedIPs) > 0:
                                        remoteNeighboringIP = matchedIPs[
                                            0].strip()
                                if not remoteNeighboringIP:
                                    # try if remote chassi ID is MAC and if that can be resolved from ARP cache
                                    isremoteChassisIsMAC = len(
                                        re.findall(repMAC, remoteChassisID,
                                                   re.IGNORECASE)) > 0
                                    if isremoteChassisIsMAC:
                                        arpEntries = Session.ExecCommand(
                                            "show arpentry")
                                        m_arpEntry = filter(
                                            lambda e: remoteChassisID in e,
                                            arpEntries.splitlines())
                                        if len(m_arpEntry) > 0:
                                            arpEntry = m_arpEntry[0]
                                        else:
                                            arpEntry = ""
                                        matchedIPs = re.findall(
                                            repIPv4, arpEntry, re.IGNORECASE)
                                        if len(matchedIPs) > 0:
                                            remoteNeighboringIP = matchedIPs[
                                                0].strip()

                            # Now we have all the data to register the neighbor
                            nRegistry.RegisterNeighbor(
                                self.Router, instance,
                                L3Discovery.NeighborProtocol.LLDP,
                                remoteChassisID, "", remoteSystemName,
                                remoteNeighboringIP, ri, "OK", remoteIntfName)
                        else:
                            DebugEx.WriteLine(
                                "DLinkSwitch_LLDP.Parse() : Router object failed to provide details for interface < {0} >"
                                .format(localIntfName), DebugLevel.Warning)
                except Exception as Ex:
                    DebugEx.WriteLine(
                        "Error in DLinkSwitch_LLDP parser while processing block #{0}. Error is: {1}"
                        .format(index, str(Ex)))
    def Parse(self, nRegistry, cToken, instance):
        """ Perform parsing logic on the given text, which should be relevant to the supported protocols and vendors"""
        # The neighbor registry object is received as parameter
        # This must be used to register a new neighbor for further discovery.
        # --
        # A CancellationToken is also passed as parameter. The token should be checked repetitively whether cancellation was requested
        # by user and if yes, stop further processing.
        # --
        # The RoutingInstance onject to work with is also passed as a parameter
        instanceName = "default"
        if instance: instanceName = instance.Name.lower()
        OperationStatusLabel = "Identifying router..."
        #--
        cToken.ThrowIfCancellationRequested()
        #
        # Compiled regex search patters
        repChassisType = re.compile(r"(Chassis type\s+:)(.*)", re.IGNORECASE)
        repChassisID = re.compile(r"(Chassis ID\s+:)(.*)", re.IGNORECASE)
        repSystemName = re.compile(r"(System name\s+:)(.*)", re.IGNORECASE)
        repLocalPortID = re.compile(r"(Local Port ID\s+:)(.*)", re.IGNORECASE)
        repPortID = re.compile(r"(Port ID\s+:)(.*)", re.IGNORECASE)
        repPortDescription = re.compile(r"(Port description\s+:)(.*)",
                                        re.IGNORECASE)
        repManagementAddress = re.compile(r"(Address\s+:)(.*)", re.IGNORECASE)
        repLLDPNeighborBlock = re.compile(
            r"LLDP Neighbor Information.*\s*((?:(?!^LLDP Neighbor Information)[\s\S])*)",
            re.IGNORECASE | re.MULTILINE)
        repMACAddress = re.compile(
            r"[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}",
            re.IGNORECASE)
        unknownSystemName = "Unknown system"
        unknownChassisType = "Unknown chassis type"
        unknownChassisID = "Unknown chassis id"
        # Query all LLDP neighbors
        lldpNeighbors = Session.ExecCommand("show lldp neighbors")
        # Output is like below:
        # Local Interface    Parent Interface    Chassis Id          Port info          System Name
        # ge-1/0/6           -                   a4:1f:72:cf:bf:04   a4:1f:72:cf:bf:04
        for thisLine in [line.strip() for line in lldpNeighbors.splitlines()]:
            cToken.ThrowIfCancellationRequested()
            try:
                words = filter(None, thisLine.split(" "))
                if len(words) >= 1:
                    localIntfName = words[0]
                    if self.IsInterrestingInterface(localIntfName):
                        # Check if logical unit number is specified in localIntfName
                        # localIntfLUN = re.findall(r"\.\d+$", localIntfName)
                        ri = self.Router.GetInterfaceByName(
                            localIntfName, instance)
                        if ri != None:
                            interfaceLUN = re.findall(r"\.\d+$", localIntfName)
                            # Depending on JunOS version, it sometimes reports logical interfaces for LLDP peering that has no configuration
                            # In this case wil will take the Physical interface that should have the proper port mode (inherit subinterface) set by JunOS router module
                            if ri.PortMode == L3Discovery.RouterInterfacePortMode.Unknown and len(
                                    interfaceLUN) == 1:
                                phIntfName = re.sub(r"\.\d+$", "",
                                                    localIntfName)
                                ri = self.Router.GetInterfaceByName(
                                    phIntfName, instance)
                                if ri == None:
                                    # Could not find physical interface. This is an error we can't handle, let's continue to next LLDP interface
                                    DebugEx.WriteLine(
                                        "JunOS LLDP Parser error : can't find physical interface {0}"
                                        .format(phIntfName),
                                        DebugLevel.Warning)
                                    continue
                                localIntfName = phIntfName
                            # Neighbor registration variables
                            remoteChassisID = ""
                            remoteIntfName = ""
                            remoteSystemName = ""
                            remoteNeighboringIP = ""
                            # Query LLDP details for this interface
                            lldpDetails = Session.ExecCommand(
                                "show lldp neighbors interface {0}".format(
                                    localIntfName))
                            # Break output to bolcks of "LLDP Neighbor Information"
                            neighborBlocks = repLLDPNeighborBlock.findall(
                                lldpDetails)
                            for thisNeighborBlock in neighborBlocks:
                                #-- Local Port ID - The SNMP index of the local interface (used to match remote)
                                x = repLocalPortID.findall(thisNeighborBlock)
                                localPortID = (x[0][1]).strip()
                                ri.SNMPIndex = localPortID
                                # Build NeighborInformationBlock
                                niBlock = False
                                niBlockText = []
                                niText = ""
                                for detailLine in thisNeighborBlock.splitlines(
                                ):
                                    if detailLine.lower().startswith(
                                            "neighbour information"):
                                        niBlock = True
                                        continue
                                    elif niBlock:
                                        # Empty line makrs the end of block
                                        if len(detailLine.strip()) == 0: break
                                        niBlockText.append(detailLine)
                                if len(niBlockText) > 0:
                                    niText = "\r\n".join(niBlockText)
                                # Search for interesting information in niText
                                #-- SystemName - Optional field in LLDP
                                x = repSystemName.findall(niText)
                                if len(x) > 0:
                                    remoteSystemName = (x[0][1]).strip()
                                else:
                                    remoteSystemName = unknownSystemName
                                # -- ChassisID - Mandatory field in LLDP, but VMWare vSwitch does not send this, so be careful
                                x = repChassisID.findall(niText)
                                if len(x) > 0:
                                    remoteChassisID = (x[0][1]).strip()
                                else:
                                    remoteChassisID = unknownChassisID
                                #-- PortID - Mandatory field in LLDP
                                x = repPortID.findall(niText)
                                remoteIntfName = (x[0][1]).strip()
                                #-- ChassisType - Optional field in LLDP
                                x = repChassisType.findall(niText)
                                if len(x) > 0:
                                    chassisType = (x[0][1]).strip()
                                    if remoteSystemName == unknownSystemName and chassisType.lower(
                                    ) == "mac address":
                                        # Use remoteChassisID as a unique ID
                                        if ri.Description:
                                            remoteSystemName = ri.Description
                                        else:
                                            remoteSystemName = remoteChassisID
                                    elif chassisType.lower(
                                    ) == "interface name":
                                        remoteChassisID = remoteSystemName
                                    elif chassisType.lower(
                                    ) == "network address":
                                        remoteChassisID = remoteSystemName

                                else:
                                    chassisType = unknownChassisType
                                # Find management address if present
                                managementBlock = False
                                managementBlockText = []
                                managementText = ""
                                lineIndentLevel = -1
                                for detailLine in thisNeighborBlock.splitlines(
                                ):
                                    if detailLine.lower().startswith(
                                            "management address"):
                                        managementBlock = True
                                        continue
                                    elif managementBlock:
                                        lineIndentLevel = len(
                                            detailLine) - len(
                                                detailLine.strip())
                                        if lineIndentLevel > 0:
                                            managementBlockText.append(
                                                detailLine)
                                        pass
                                    if lineIndentLevel == 0: break

                                if len(managementBlockText) > 0:
                                    managementText = "\r\n".join(
                                        managementBlockText)
                                    foundIP = repManagementAddress.findall(
                                        managementText)
                                    if len(foundIP) == 1:
                                        remoteNeighboringIP = (
                                            foundIP[0][1]).strip()
                                # Now we have all the data to register the neighbor
                                nRegistry.RegisterNeighbor(
                                    self.Router, instance,
                                    L3Discovery.NeighborProtocol.LLDP,
                                    remoteChassisID, "", remoteSystemName,
                                    remoteNeighboringIP, ri, "OK",
                                    remoteIntfName)
                        else:
                            DebugEx.WriteLine(
                                "Router object failed to provide details for interface < {0} >"
                                .format(localIntfName), DebugLevel.Warning)
            except Exception as Ex:
                DebugEx.WriteLine(
                    "Error in JunOS_LLDPParser while parsine line < {0} >. Error is: {1}"
                    .format(thisLine, str(Ex)))
Example #26
0
    def Parse(self, nRegistry, cToken, instance):
        """Collects information about active tunnels and registers them with Network Discovery Engine"""
        # The neighbor registry object is received as parameter
        # This must be used to register a new neighbor for further discovery.
        # --
        # A CancellationToken is also passed as parameter. The token should be checked repetitively whether cancellation was requested
        # by user and if yes, stop further processing.
        # --
        # The RoutingInstance object to work with is also passed as a parameter
        instanceName = "default"
        if instance: instanceName = instance.Name.lower()
        OperationStatusLabel = "Identifying router..."
        #--
        cToken.ThrowIfCancellationRequested()
        #
        # process legacy (not globalprotect) vpn tunnels
        #
        try:
            # Regex search patters
            rep_vpn_State = r"state:\s+(.*)"
            rep_vpn_localIP = r"^\s+local ip:(\s+[\.\d+]+)"
            rep_vpn_peerIP = r"^\s+peer ip:(\s+[\.\d+]+)"
            rep_Encryption = r"^\s+enc\s+algorithm:(.*)"
            rep_Hashing = r"^\s+auth\s+algorithm:(.*)"
            rep_ProxyBlock = r"(?<=proxy-id:)([\s\S]*)(?=anti replay)"
            rep_localProxies = r"(?:\s+local ip:)(\s+[.\d\/]+)"
            rep_remoteProxies = r"(?:\s+remote ip:)(\s+[.\d\/]+)"
            l2lTunnels = Session.ExecCommand("show vpn tunnel").splitlines()
            # rep_IPSecBlocks = r"IPsec:.*\s*(?:(?:(?!^IPsec:)[\s\S])*)"
            # the line starting with TnID is the header
            columnHeader = next(
                (line for line in l2lTunnels if line.startswith("TnID")), None)
            for vpnLine in l2lTunnels:
                tnID = GetColumnValue(vpnLine, columnHeader, "TnID", "  ")
                if not tnID.isdigit():
                    continue
                # --
                thisTunnelID = int(tnID)
                tunnel_Name = GetColumnValue(vpnLine, columnHeader, "Name",
                                             "  ")
                # get detail for this connection index
                thisTunnelDetails = Session.ExecCommand(
                    "show vpn flow tunnel-id {0}".format(thisTunnelID))
                tunnel_StateStr = GetRegexGroupMatches(rep_vpn_State,
                                                       thisTunnelDetails,
                                                       1)[0].strip().lower()
                tunnel_State = L3Discovery.NeighborState.Down
                if "active" in tunnel_StateStr:
                    tunnel_State = L3Discovery.NeighborState.Active
                elif "established" in tunnel_StateStr:
                    tunnel_State = L3Discovery.NeighborState.Established
                # extract local ip address from thisTunnelDetails
                tunnel_LocalAddress = GetRegexGroupMatches(
                    rep_vpn_localIP, thisTunnelDetails, 1)[0].strip()
                # extract remote ip address from thisTunnelDetails
                tunnel_PeerAddress = GetRegexGroupMatches(
                    rep_vpn_peerIP, thisTunnelDetails, 1)[0].strip()
                # get Cipher and Hashing algorithms
                cipherAlg = GetRegexGroupMatches(rep_Encryption,
                                                 thisTunnelDetails,
                                                 1)[0].strip()
                hashAlg = GetRegexGroupMatches(rep_Hashing, thisTunnelDetails,
                                               1)[0].strip()
                # get local / remote networks for each ipsec tunnel
                proxyBlock = GetRegexGroupMatches(rep_ProxyBlock,
                                                  thisTunnelDetails, 1)[0]
                localProxies = GetRegexGroupMatches(rep_localProxies,
                                                    proxyBlock, 1)
                s_localProxies = "\r\n".join([s.strip() for s in localProxies])
                remoteProxies = GetRegexGroupMatches(rep_remoteProxies,
                                                     proxyBlock, 1)
                s_remoteProxies = "\r\n".join(
                    [s.strip() for s in remoteProxies])
                #
                # RegisterTunnel parameters in order :
                #/// <param name="router">The IRouter requesting registration</param>
                #/// <param name="instance">The routing instance the tunnel is terminating on</param>
                #/// <param name="tunnelProtocol">The protocol used to establish the tunnel</param>
                #/// <param name="tunnelType">The link-type over the tunnel</param>
                #/// <param name="tunnelName">Optional : tunnel name or description</param>
                #/// <param name="tunnelState">The connection state</param>
                #/// <param name="externalLocalAddress">Tunnel external, local address</param>
                #/// <param name="externalRemoteAddress">Tunnel external, remote address</param>
                #/// <param name="tunnelSourceAddress">Optional : Tunnel internal source address</param>
                #/// <param name="tunnelDestinationAddress">Optional : Tunnel internal destination address</param>
                #/// <param name="localProxy">Optional : the local networks the tunnel is forwarding for. If not empty, must contain valid ipv4 network prefixes per line</param>
                #/// <param name="remoteProxy">Optional : the remote networks the tunnel is forwarding for. If not empty, must contain valid ipv4 network prefixes per line</param>
                #/// <param name="cipher">Optional : the cipher algorithm used by the tunnel</param>
                #/// <param name="hash">Optional : the hashing algorithm used by the tunnel</param>
                #/// <param name="tag">Optional : any data to include. Max length is 1024 characters</param>
                nRegistry.RegisterTunnel(
                    self.Router, instance, L3Discovery.NeighborProtocol.IPSEC,
                    L3Discovery.LinkType.P2P, tunnel_Name, tunnel_State,
                    tunnel_LocalAddress, tunnel_PeerAddress, None, None,
                    s_localProxies, s_remoteProxies, cipherAlg, hashAlg, None)

        except Exception as Ex:
            message = "PaloAlto VPN parser : error processing legacy vpn tunnel information. Error is : {0} ".format(
                str(Ex))
            DebugEx.WriteLine(message)
        #
        # process globalprotect vpn tunnels
        #
        try:
            gwData = Session.ExecCommand("show global-protect-gateway gateway")
            isLSVPNGateway = "GlobalProtect Gateway" in gwData
            if isLSVPNGateway:
                #
                # Firewall acts as LSVPN Gateway
                #
                rep_gwAddress = r"(?:\s+Local Address\s+\(IPv4\)\s+:)(\s+[.\d\/]+)"
                rep_tunnelEnryption = r"(?:\s+Encryption\s+:)(.*)"
                rep_tunnelAuthentication = r"(?:\s+Authentication\s+:)(.*)"
                rep_tunnelSourceAddress = r"(?:\s+Tunnel Interface IP\s+:)(\s+[.\d\/]+)"
                rep_tunnelDestinationAddress = r"Satellite Tunnel IPs .+:([ .\d]+)"
                # https://stackoverflow.com/questions/52354728/regex-to-split-text-to-blocks
                rep_satelliteBlocks = r"Satellite\s+:.*\s*((?:(?!Satellite\s+:)[\s\S])*)"
                rep_satelliteHostName = r"Satellite Hostname\s+:(.*)"
                rep_satellitePublicIP = r"Public IP .+:([ .\d]+)"
                gateway_Address = GetRegexGroupMatches(rep_gwAddress, gwData,
                                                       1)[0].strip()
                tunnel_SourceAddress = GetRegexGroupMatches(
                    rep_tunnelSourceAddress, gwData, 1)[0].strip()
                tunnel_Encryption = GetRegexGroupMatches(
                    rep_tunnelEnryption, gwData, 1)[0].strip()
                tunnel_Authentication = GetRegexGroupMatches(
                    rep_tunnelAuthentication, gwData, 1)[0].strip()
                # get satellite details
                satelliteData = Session.ExecCommand(
                    "show global-protect-gateway current-satellite")
                satelliteBlocks = GetRegexGroupMatches(rep_satelliteBlocks,
                                                       satelliteData, 1)
                for thisSatelliteBlock in satelliteBlocks:
                    tunnel_Name = GetRegexGroupMatches(rep_satelliteHostName,
                                                       thisSatelliteBlock,
                                                       1)[0].strip()
                    tunnel_PublicAddress = GetRegexGroupMatches(
                        rep_satellitePublicIP, thisSatelliteBlock,
                        1)[0].strip()
                    tunnel_DestinationAddress = GetRegexGroupMatches(
                        rep_tunnelDestinationAddress, thisSatelliteBlock,
                        1)[0].strip()
                    # Only satellites with established tunnel status are enlisted by "show global-protect-gateway current-satellite", so no need to query tunnel status here
                    nRegistry.RegisterTunnel(
                        self.Router, instance,
                        L3Discovery.NeighborProtocol.IPSEC,
                        L3Discovery.LinkType.P2P, tunnel_Name,
                        L3Discovery.NeighborState.Established, gateway_Address,
                        tunnel_PublicAddress, tunnel_SourceAddress,
                        tunnel_DestinationAddress, None, None,
                        tunnel_Encryption, tunnel_Authentication, None)
            else:
                #
                # Firewall is not an LSVPN Gateway, check if a Satellite
                #
                gwData = Session.ExecCommand(
                    "show global-protect-satellite current-gateway")
                isLSVPNSatellite = "GlobalProtect Satellite" in gwData
                if isLSVPNSatellite:
                    #
                    # Firewall is an LSVPN Satellite
                    #
                    rep_tunnelState = r"Status\s+:(.*)"
                    rep_gwAddress = r"GlobalProtect Gateway Address\s+:(.*)"
                    rep_tunnelDestinationAddress = r"Gateway Tunnel IP\s+:(.*)"
                    rep_tunnelName = r"Gateway Tunnel Name\s+:(.*)"
                    rep_tunnelEnryption = r"(?:\s+Encryption\s+:)(.*)"
                    rep_satellitePublicIP = r"(?:\s+Local Address\s+:)(\s+[.\d\/]+)"
                    gateway_Address = GetRegexGroupMatches(
                        rep_gwAddress, gwData, 1)[0].strip()
                    tunnel_StateStr = GetRegexGroupMatches(
                        rep_tunnelState, gwData, 1)[0].strip().lower()
                    tunnel_State = L3Discovery.NeighborState.Down
                    if "active" in tunnel_StateStr:
                        tunnel_State = L3Discovery.NeighborState.Active
                    elif "established" in tunnel_StateStr:
                        tunnel_State = L3Discovery.NeighborState.Established
                    if tunnel_State == L3Discovery.NeighborState.Active or tunnel_State == L3Discovery.NeighborState.Established:
                        tunnel_Encryption = GetRegexGroupMatches(
                            rep_tunnelEnryption, gwData, 1)[0].strip()
                    else:
                        tunnel_Encryption = "unknown"
                    tunnel_DestinationAddress = GetRegexGroupMatches(
                        rep_tunnelDestinationAddress, gwData, 1)[0].strip()
                    tunnel_Name = GetRegexGroupMatches(rep_tunnelName, gwData,
                                                       1)[0].strip()
                    # get satellite details
                    satelliteData = Session.ExecCommand(
                        "show global-protect-satellite satellite")
                    tunnel_PublicAddress = GetRegexGroupMatches(
                        rep_satellitePublicIP, satelliteData, 1)[0].strip()
                    tunnel_SourceAddress = ""  # unknown
                    nRegistry.RegisterTunnel(
                        self.Router, instance,
                        L3Discovery.NeighborProtocol.IPSEC,
                        L3Discovery.LinkType.P2P, tunnel_Name, tunnel_State,
                        tunnel_PublicAddress, gateway_Address,
                        tunnel_SourceAddress, tunnel_DestinationAddress, None,
                        None, tunnel_Encryption, "unknown", None)

        except Exception as Ex:
            message = "PaloAlto VPN parser : error processing legacy vpn tunnel information. Error is : {0} ".format(
                str(Ex))
            DebugEx.WriteLine(message)
Example #27
0
    def Parse(self, nRegistry, cToken, instance):
        """ Perform parsing logic on the given text, which should be relevant to the supported protocols and vendors"""
        # The neighbor registry object is received as parameter
        # This must be used to register a new neighbor for further discovery.
        # --
        # A CancellationToken is also passed as parameter. The token should be checked repetitively whether cancellation was requested
        # by user and if yes, stop further processing.
        # --
        # The RoutingInstance onject to work with is also passed as a parameter
        instanceName = L3Discovery.RoutingInstance.DefaultInstanceName(
            self.ParsingForVendor)
        if instance: instanceName = instance.Name
        OperationStatusLabel = "Querying LLDP neighbor data..."
        #--
        cToken.ThrowIfCancellationRequested()
        #
        # regex search patters
        repRemoteDataBlocks = r"Remote Data.*\s*((?:(?!^Remote Data)[\s\S])*)"
        repConnectingPort = r"^Remote Data,\s(\d+/\d+)"
        repRemoteChassisID = r"Chassis ID [^.]+\.+\s(.*)"
        repRemoteSystemName = r"^\s+System Name\.+\s(.*)"
        repNameOfStation = r"^\s+Name of Station\.+\s(.*)"
        # repLocalPortID : regex group 1 : port number, group2 : module number (optional)GetRegexGroupMatchesGetRegexGroupMatches
        repRemotePortID = r"Port ID [^)]+\)\.+\s(?:port-)?([a-f\d:]+)-?(\d+)?"
        # repRemotePortDescription : regex group 1 : module number, group2 : port number
        repRemotePortDescription = r"Port Description[\.\s]+Module:\s(\d+)\s+Port:\s(\d+)"
        repManagementAddress = r"Management Address\.+\s([a-f\d:.]+)"
        repMACAddress = re.compile(
            r"[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}",
            re.IGNORECASE)
        lldpNeighbors = Session.ExecCommand("show lldp neighbors")
        lldpRemoteData = Session.ExecCommand("show lldp remote-data")
        remoteDatablocks = re.finditer(repRemoteDataBlocks, lldpRemoteData,
                                       re.MULTILINE | re.IGNORECASE)
        for index, match in enumerate(remoteDatablocks):
            try:
                thisRemoteData = match.group()
                localIntfName = self.GetRegexGroupMatches(
                    repConnectingPort, thisRemoteData, 1)[0].strip()
                ri = self.Router.GetInterfaceByName(localIntfName, instance)
                if ri:
                    remoteChassisID = self.GetRegexGroupMatches(
                        repRemoteChassisID, thisRemoteData, 1)
                    if remoteChassisID and remoteChassisID[0]:
                        remoteChassisID = remoteChassisID[0].strip()
                    else:
                        remoteChassisID = "Unknown Chassis ID"
                    remoteSystemName = self.GetRegexGroupMatches(
                        repRemoteSystemName, thisRemoteData, 1)
                    if remoteSystemName and remoteSystemName[0]:
                        remoteSystemName = remoteSystemName[0].strip()
                    else:
                        remoteSystemName = self.GetRegexGroupMatches(
                            repNameOfStation, thisRemoteData, 1)
                        if remoteSystemName and remoteSystemName[0]:
                            remoteSystemName = remoteSystemName[0].strip()
                        else:
                            remoteSystemName = "Unknown System Name"

                    # First try repRemotePortDescription regex
                    remotePortName = self.GetRegexGroupMatches(
                        repRemotePortDescription, thisRemoteData, 2)
                    if remotePortName and remotePortName[0]:
                        remotePortName = remotePortName[0].strip()
                        if remotePortName.isdigit():
                            remotePortName = str(int(remotePortName))
                        remotePortModuleName = self.GetRegexGroupMatches(
                            repRemotePortDescription, thisRemoteData, 1)
                        if remotePortModuleName and remotePortModuleName[0]:
                            remotePortModuleName = remotePortModuleName[
                                0].strip()
                            if remotePortModuleName.isdigit():
                                remotePortModuleName = str(
                                    int(remotePortModuleName))
                            remoteIntfName = "{0}/{1}".format(
                                remotePortModuleName, remotePortName)
                        else:
                            remoteIntfName = remotePortName
                    else:
                        # repRemotePortDescription failed, so let's try repRemotePortID
                        remotePortName = self.GetRegexGroupMatches(
                            repRemotePortID, thisRemoteData, 1)
                        if remotePortName and remotePortName[0]:
                            remotePortName = remotePortName[0].strip()
                            if remotePortName.isdigit():
                                remotePortName = str(int(remotePortName))
                            remotePortModuleName = self.GetRegexGroupMatches(
                                repRemotePortID, thisRemoteData, 2)
                            if remotePortModuleName and remotePortModuleName[0]:
                                remotePortModuleName = remotePortModuleName[
                                    0].strip()
                                if remotePortModuleName.isdigit():
                                    remotePortModuleName = str(
                                        int(remotePortModuleName))
                                remoteIntfName = "{0}/{1}".format(
                                    remotePortModuleName, remotePortName)
                            else:
                                remoteIntfName = remotePortName

                    remoteNeighboringIP = self.GetRegexGroupMatches(
                        repManagementAddress, thisRemoteData, 1)
                    if remoteNeighboringIP and remoteNeighboringIP[0]:
                        remoteNeighboringIP = remoteNeighboringIP[0].strip()
                    else:
                        remoteNeighboringIP = ""

                    # Now we have all the data to register the neighbor
                    nRegistry.RegisterNeighbor(
                        self.Router, instance,
                        L3Discovery.NeighborProtocol.LLDP, remoteChassisID, "",
                        remoteSystemName, remoteNeighboringIP, ri, "OK",
                        remoteIntfName)
                else:
                    DebugEx.WriteLine(
                        "HirschmannSwitch_LLDP.Parse() : Router object failed to provide details for interface < {0} >"
                        .format(localIntfName), DebugLevel.Warning)
            except Exception as Ex:
                DebugEx.WriteLine(
                    "Error in HirschmannSwitch_LLDP parser while processing block #{0}. Error is: {1}"
                    .format(index, str(Ex)))