class ThreecomSwitch(Switch): """\brief Subclass for any 3com switch in the testbed This subclass implements methods to retrieve and set information from a switch using SNMP version 1 that is proprietary to 3com (vlans, etc). """ functions = [] def __init__( self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID, ): """\brief Initializes the class \param switchNode (\c SwitchNode) The SwitchNode object to obtain information from to initialize the class with \param minimumVLANInternalID (\c int) The minimum number for a vlan's internal id \param maximumVLANInternalID (\c int) The maximum number for a vlan's internal id \param minimumInterfaceInternalID (\c int) The minimum number for an interface's internal id \param maximumInterfaceInternalID (\c int) The maximum number for an interface's internal id """ Switch.__init__( self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID, ) self.snmp = SNMP(self.getCommunity(), self.getIPAddress(), SNMP.SNMPv1) def getVLANNames(self): """\brief Gets the names of the vlans on the switch, returning a dictionary whose keys are the objects' internal ids and whose values are the actual vlan names (see getSNMPResultTable for more info) \return (\c dictionary) A dictionary with the names of the vlans """ vlans = {} threecomVlanStaticNameTable = self.snmp.walk(OID.threecomVlanStaticName) for threecomVlanStaticNameTableRow in threecomVlanStaticNameTable: vlans[ threecomVlanStaticNameTableRow[0][0][len(threecomVlanStaticNameTableRow[0][0]) - 1] ] = threecomVlanStaticNameTableRow[0][1] return vlans def getVlanInfo(self): vlans = {} dot1qVlanStaticNameTable = self.snmp.walk(OID.threecomVlanStaticName) dot1qVlanFdbIdTable = self.snmp.walk(OID.threecomVlanStaticExternalID) for dot1qVlanStaticNameTableRow in dot1qVlanStaticNameTable: for dot1qVlanFdbIdTableRow in dot1qVlanFdbIdTable: if ( dot1qVlanStaticNameTableRow[0][0][len(dot1qVlanStaticNameTableRow[0][0]) - 1] == dot1qVlanFdbIdTableRow[0][0][len(dot1qVlanFdbIdTableRow[0][0]) - 1] ): vlans[dot1qVlanStaticNameTableRow[0][1]] = ( dot1qVlanFdbIdTableRow[0][1], dot1qVlanStaticNameTableRow[0][0][len(dot1qVlanStaticNameTableRow[0][0]) - 1], ) return vlans def getFullVLANInfo(self, theVLANName=None): """\brief Returns a list of VLAN objects consisting of all of the vlans in the switch. If the theVLANName parameter is set, the function returns a single VLAN object corresponding to the requested vlan \param theVLANName (\c string) The name of the VLAN to retrieve \return (\c list of VLAN objects) A list of VLAN objects with the requested information or a VLAN object if a vlan name is specified """ vlans = [] vlan_names = self.getVLANNames() port_ids = self.getPortIDs() # If only wanting information about one vlan, only get that information. if theVLANName != None: vn = {} for v in vlan_names: if vlan_names[v] == theVLANName: vn[v] = theVLANName vlan_names = vn for v in vlan_names: externalID = (self.snmp.get(OID.threecomVlanStaticExternalID + (v,)))[0][1] if self.snmp.getErrorStatus(): print "unable to get external id of vlan internal ID " + v vlans.append(VLAN(vlan_names[v], {}, None, v)) else: vlans.append(VLAN(vlan_names[v], {}, externalID, v, externalID)) for vlan in vlans: epl = [] upl = [] switches = {} ports = [] remove = [] table2 = table = self.getVLANToInterfacesTable() for t in table: if t == vlan.getInternalID(): for tt in table[t]: for pi in port_ids: if pi[0][1] == rfc1902.Integer32(tt): ports.append(Port(pi[0][0][len(pi[0][0]) - 1], False, tt)) remove.append(tt) # remove found ports from the list for r in remove: table[t].remove(r) # ports left in table[t] at this point are tagged vlans for vt in table[t]: for ids in table2: if vt == ids: for pi in port_ids: if pi[0][1] == rfc1902.Integer32(table2[ids][0]): ports.append(Port(pi[0][0][len(pi[0][0]) - 1], True, table2[ids][0])) # vlan.setTaggedID(vt) # vlan.setID(vt) switches[self.getSwitchName()] = ports vlan.setSwitches(switches) # print vlan return vlans def createVLAN(self, vlan): """\brief Creates a vlan as specified by a vlan object. See addPorts for rules on how ports are added. The function returns the following error codes: -1: if a vlan with the same external id already exists on the switch -2: if a vlan with the same name already exists on the switch -3: if there was an error creating the vlan using the retrieved index -4: if the vlan id is invalid (not in the range 2-4094) or is already assigned to another vlan -5: if the vlan name is invalid or couldn't be set -6: if the vlan couldn't be activated -7: if the operation to create and association an 802.1Q interface with the vlan failed -8: if any of the operations to add ports to the vlan failed 0: if the operation succeeds \param (\c VLAN) A VLAN object representing the vlan to be added \return (\c int) 0 if the operation is sucessful, negative otherwise """ # Now make sure that there isn't a vlan with the same name already on the switch log.debug("STUFF") vlanName = vlan.getName() vlanNames = self.getVLANNames() for name in vlanNames.values(): if str(name) == str(vlanName): return -1 # First we need to get the next available index to use as the vlan's internal id vlan.setInternalID(int(self.snmp.get(OID.threecomVlanNextAvailableIndex)[0][1])) if self.snmp.getErrorStatus(): print "Error with getting next static vlan id" print self.snmp return -2 else: print "Correctly got next static vlan id" # Now create the vlan using the retrieved available index # Table filling snmp_set_cmd_list = [] snmp_set_cmd_list.append((OID.threecomVlanStaticRowStatus + (vlan.getInternalID(),), rfc1902.Integer(5))) snmp_set_cmd_list.append( (OID.threecomVlanStaticExternalID + (vlan.getInternalID(),), rfc1902.Integer(vlan.getID())) ) snmp_set_cmd_list.append( (OID.threecomVlanStaticName + (vlan.getInternalID(),), rfc1902.OctetString(vlan.getName())) ) snmp_set_cmd_list.append((OID.threecomVlanStaticRowStatus + (vlan.getInternalID(),), rfc1902.Integer(1))) self.snmp.complex_set(snmp_set_cmd_list) if self.snmp.getErrorStatus(): print "Error creating static vlan " + str(snmp_set_cmd_list[int(self.snmp.getErrorIndex()) - 1]) # print self.snmp return -3 else: print "Correctly created static vlan" # Create the vlan's 802.1Q interface # First we need to get the next available index to use as the interface's internal id vlan.setTaggedID(int(self.snmp.get(OID.threecomVlanNextAvailableIndex)[0][1])) print "next available vlan id " + str(vlan.getTaggedID()) if self.snmp.getErrorStatus(): # print "Error with getting next available vlan 8021Q id" log.critical("Error with getting next available vlan 8021Q id") # print self.snmp return -1 else: print "Correctly got next available vlan 8021Q id" self.snmp.set(OID.threecomVlanTaggedRowStatus + (vlan.getTaggedID(),), rfc1902.Integer(5)) if self.snmp.getErrorStatus(): print "Error doing create and wait on tagged row creation" # print self.snmp return -1 else: print "Correctly did create and wait on tagged row creation" snmp_set_cmd_list = [] snmp_set_cmd_list.append((OID.threecomVlanTaggedType + (vlan.getTaggedID(),), rfc1902.Integer(2))) snmp_set_cmd_list.append((OID.threecomVlanTaggedTag + (vlan.getTaggedID(),), rfc1902.Integer(vlan.getID()))) snmp_set_cmd_list.append((OID.threecomVlanTaggedRowStatus + (vlan.getTaggedID(),), rfc1902.Integer(4))) self.snmp.complex_set(snmp_set_cmd_list) if self.snmp.getErrorStatus(): print "Error with creating 8021Q interface " + str(snmp_set_cmd_list[int(self.snmp.getErrorIndex()) - 1]) print self.snmp return -7 else: print "correctly created 8021Q interface" # Create an interface associated with the vlan using create and go (4) self.snmp.set(OID.ifStackStatus + (vlan.getInternalID(), vlan.getTaggedID()), rfc1902.Integer(4)) if self.snmp.getErrorStatus(): print "Error setting up ifStackStatus" print self.snmp return -1 else: print "Correctly setup ifStackStatus" # Now add the ports to the vlan if self.addPorts(vlan.getName(), vlan.getPortsOnSwitch(self.getSwitchName())) < 0: return -8 return 0 def addPorts(self, vlanName, ports): return self.modifyPorts(vlanName, ports, True) def deletePorts(self, vlanName, ports): return self.modifyPorts(vlanName, ports, False) def modifyPorts(self, vlanName, ports, addPorts): if ports == None or len(ports) == 0: return 0 vlan = None try: vlan = self.getFullVLANInfo(vlanName)[0] except Exception, e: print e for p in ports: # get correct internal id print p p.setInternalID(self.getPortInternalID(p.getPortNumber())) if p.getTagged(): # tagged if addPorts: self.snmp.set(OID.ifStackStatus + (vlan.getTaggedID(), p.getInternalID()), rfc1902.Integer(4)) else: print vlan.getTaggedID() print p.getInternalID() self.snmp.set(OID.ifStackStatus + (vlan.getTaggedID(), p.getInternalID()), rfc1902.Integer(6)) if self.snmp.getErrorStatus(): print "Error with adding/removing port to tagged vlan" print self.snmp return -1 else: # untagged if addPorts: self.snmp.set(OID.ifStackStatus + (vlan.getInternalID(), p.getInternalID()), rfc1902.Integer(4)) else: print vlan print vlan.getTaggedID() print p print p.getInternalID() self.snmp.set(OID.ifStackStatus + (vlan.getInternalID(), p.getInternalID()), rfc1902.Integer(6)) if self.snmp.getErrorStatus(): print "Error with adding/removing port to untagged vlan" print self.snmp return -1 return 0
def __init__(self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID): """\brief Initializes the class \param switchNode (\c SwitchNode) The SwitchNode object to obtain information from to initialize the class with \param macIDLength (\c int) The length of the id of an snmp result coming from a mac address query. The id is anything to the left of the equal sign, and its length is the number of dot-separated terms. """ if (switchNode.getInfrastructure() == "yes"): self.__ipAddress = switchNode.getInterfaces("infrastructure")[0].getIP() else: self.__ipAddress = switchNode.getInterfaces("management")[0].getIP() self.__switchName = switchNode.getNodeID() self.snmp = SNMP(switchNode.getSNMPwriteCommunity(),self.__ipAddress) # cache of static tables self.__refresh = True # reload self.__dot1dBasePortIfIndex = None self.__ifDescr = None self.__ifName = None self.__dot1qVlanStaticUntaggedPorts = None self.__dot1qVlanStaticEgressPorts = None self.__dot1qPvid = None self.__dot1qTpFdbPort = None self.__dot1qTpFdbStatus = None self.__dot1qVlanFdbId = None self.__dot1qVlanStaticName = None # ports self.__ports = {} self.refreshPortInfo() # vlans self.__vlans = {}
def Test2(): print "Testing getting temperature reading" s = SNMP("private","192.168.1.9") res = s.get(SNMP.extremeCurrentTemperature) del s del res dump_garbage( )
def Test2(): print "Testing getting temperature reading" s = SNMP("private", "192.168.1.9") res = s.get(SNMP.extremeCurrentTemperature) del s del res dump_garbage()
def __init__(self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID): """\brief Initializes the class \param switchNode (\c SwitchNode) The SwitchNode object to obtain information from to initialize the class with \param minimumVLANInternalID (\c int) The minimum number for a vlan's internal id \param maximumVLANInternalID (\c int) The maximum number for a vlan's internal id \param minimumInterfaceInternalID (\c int) The minimum number for an interface's internal id \param maximumInterfaceInternalID (\c int) The maximum number for an interface's internal id """ Switch.__init__(self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID) self.snmp = SNMP(self.getCommunity(), self.getIPAddress(), SNMP.SNMPv1)
def setCommunity(self, c): """\brief Sets the community and updates the snmp commands accordingly \param c (\c string) The community """ self.__community = c del self.snmp self.snmp = SNMP(self.__community, self.__ipAddress, SNMP.SNMPv1)
def __init__(self, sensorNode): """\brief Initializes the class \param serialNode (\c SensorNode) A SensorNode object containing information to instantiate the class with """ self.__sensorNode = sensorNode self.__ipAddress = sensorNode.getInterfaces("infrastructure")[0].getIP() self.snmp = SNMP("private",self.__ipAddress,SNMP.SNMPv1)
def __init__(self, powerswitchNode): """\brief Initializes the class \param powerswitchNode (\c PowerswitchNode) A PowerswitchNode object containing information to instantiate the class with """ self.__powerswitchNode = powerswitchNode self.__community = powerswitchNode.getSNMPwriteCommunity() self.__powerswitchNodeID = powerswitchNode.getNodeID() self.__ipAddress = powerswitchNode.getInterfaces( "infrastructure")[0].getIP() self.__username = None self.__password = None if (powerswitchNode.getUsers() != None): self.__username = powerswitchNode.getUsers()[0].getUsername() self.__password = powerswitchNode.getUsers()[0].getPassword() self.snmp = SNMP(self.__community, self.__ipAddress, SNMP.SNMPv1)
def __init__( self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID, ): """\brief Initializes the class \param switchNode (\c SwitchNode) The SwitchNode object to obtain information from to initialize the class with \param minimumVLANInternalID (\c int) The minimum number for a vlan's internal id \param maximumVLANInternalID (\c int) The maximum number for a vlan's internal id \param minimumInterfaceInternalID (\c int) The minimum number for an interface's internal id \param maximumInterfaceInternalID (\c int) The maximum number for an interface's internal id """ Switch.__init__( self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID, ) self.snmp = SNMP(self.getCommunity(), self.getIPAddress(), SNMP.SNMPv1)
def Test1(): print "Testing creation and deletion of one snmp object" s = SNMP("public", "192.168.1.2") del s dump_garbage()
class ThreecomSwitch(Switch): """\brief Subclass for any 3com switch in the testbed This subclass implements methods to retrieve and set information from a switch using SNMP version 1 that is proprietary to 3com (vlans, etc). """ functions = [] def __init__(self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID): """\brief Initializes the class \param switchNode (\c SwitchNode) The SwitchNode object to obtain information from to initialize the class with \param minimumVLANInternalID (\c int) The minimum number for a vlan's internal id \param maximumVLANInternalID (\c int) The maximum number for a vlan's internal id \param minimumInterfaceInternalID (\c int) The minimum number for an interface's internal id \param maximumInterfaceInternalID (\c int) The maximum number for an interface's internal id """ Switch.__init__(self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID) self.snmp = SNMP(self.getCommunity(), self.getIPAddress(), SNMP.SNMPv1) def getVLANNames(self): """\brief Gets the names of the vlans on the switch, returning a dictionary whose keys are the objects' internal ids and whose values are the actual vlan names (see getSNMPResultTable for more info) \return (\c dictionary) A dictionary with the names of the vlans """ vlans = {} threecomVlanStaticNameTable = self.snmp.walk( OID.threecomVlanStaticName) for threecomVlanStaticNameTableRow in threecomVlanStaticNameTable: vlans[threecomVlanStaticNameTableRow[0][0] [len(threecomVlanStaticNameTableRow[0][0]) - 1]] = threecomVlanStaticNameTableRow[0][1] return vlans def getVlanInfo(self): vlans = {} dot1qVlanStaticNameTable = self.snmp.walk(OID.threecomVlanStaticName) dot1qVlanFdbIdTable = self.snmp.walk(OID.threecomVlanStaticExternalID) for dot1qVlanStaticNameTableRow in dot1qVlanStaticNameTable: for dot1qVlanFdbIdTableRow in dot1qVlanFdbIdTable: if dot1qVlanStaticNameTableRow[0][0][ len(dot1qVlanStaticNameTableRow[0][0]) - 1] == dot1qVlanFdbIdTableRow[0][0][ len(dot1qVlanFdbIdTableRow[0][0]) - 1]: vlans[dot1qVlanStaticNameTableRow[0][1]] = ( dot1qVlanFdbIdTableRow[0][1], dot1qVlanStaticNameTableRow[0][0][ len(dot1qVlanStaticNameTableRow[0][0]) - 1]) return vlans def getFullVLANInfo(self, theVLANName=None): """\brief Returns a list of VLAN objects consisting of all of the vlans in the switch. If the theVLANName parameter is set, the function returns a single VLAN object corresponding to the requested vlan \param theVLANName (\c string) The name of the VLAN to retrieve \return (\c list of VLAN objects) A list of VLAN objects with the requested information or a VLAN object if a vlan name is specified """ vlans = [] vlan_names = self.getVLANNames() port_ids = self.getPortIDs() # If only wanting information about one vlan, only get that information. if theVLANName != None: vn = {} for v in vlan_names: if vlan_names[v] == theVLANName: vn[v] = theVLANName vlan_names = vn for v in vlan_names: externalID = (self.snmp.get(OID.threecomVlanStaticExternalID + (v, )))[0][1] if self.snmp.getErrorStatus(): print "unable to get external id of vlan internal ID " + v vlans.append(VLAN(vlan_names[v], {}, None, v)) else: vlans.append(VLAN(vlan_names[v], {}, externalID, v, externalID)) for vlan in vlans: epl = [] upl = [] switches = {} ports = [] remove = [] table2 = table = self.getVLANToInterfacesTable() for t in table: if t == vlan.getInternalID(): for tt in table[t]: for pi in port_ids: if pi[0][1] == rfc1902.Integer32(tt): ports.append( Port(pi[0][0][len(pi[0][0]) - 1], False, tt)) remove.append(tt) # remove found ports from the list for r in remove: table[t].remove(r) # ports left in table[t] at this point are tagged vlans for vt in table[t]: for ids in table2: if vt == ids: for pi in port_ids: if pi[0][1] == rfc1902.Integer32( table2[ids][0]): ports.append( Port(pi[0][0][len(pi[0][0]) - 1], True, table2[ids][0])) #vlan.setTaggedID(vt) #vlan.setID(vt) switches[self.getSwitchName()] = ports vlan.setSwitches(switches) # print vlan return vlans def createVLAN(self, vlan): """\brief Creates a vlan as specified by a vlan object. See addPorts for rules on how ports are added. The function returns the following error codes: -1: if a vlan with the same external id already exists on the switch -2: if a vlan with the same name already exists on the switch -3: if there was an error creating the vlan using the retrieved index -4: if the vlan id is invalid (not in the range 2-4094) or is already assigned to another vlan -5: if the vlan name is invalid or couldn't be set -6: if the vlan couldn't be activated -7: if the operation to create and association an 802.1Q interface with the vlan failed -8: if any of the operations to add ports to the vlan failed 0: if the operation succeeds \param (\c VLAN) A VLAN object representing the vlan to be added \return (\c int) 0 if the operation is sucessful, negative otherwise """ # Now make sure that there isn't a vlan with the same name already on the switch log.debug("STUFF") vlanName = vlan.getName() vlanNames = self.getVLANNames() for name in vlanNames.values(): if (str(name) == str(vlanName)): return -1 # First we need to get the next available index to use as the vlan's internal id vlan.setInternalID( int(self.snmp.get(OID.threecomVlanNextAvailableIndex)[0][1])) if self.snmp.getErrorStatus(): print "Error with getting next static vlan id" print self.snmp return -2 else: print "Correctly got next static vlan id" # Now create the vlan using the retrieved available index # Table filling snmp_set_cmd_list = [] snmp_set_cmd_list.append( (OID.threecomVlanStaticRowStatus + (vlan.getInternalID(), ), rfc1902.Integer(5))) snmp_set_cmd_list.append( (OID.threecomVlanStaticExternalID + (vlan.getInternalID(), ), rfc1902.Integer(vlan.getID()))) snmp_set_cmd_list.append( (OID.threecomVlanStaticName + (vlan.getInternalID(), ), rfc1902.OctetString(vlan.getName()))) snmp_set_cmd_list.append( (OID.threecomVlanStaticRowStatus + (vlan.getInternalID(), ), rfc1902.Integer(1))) self.snmp.complex_set(snmp_set_cmd_list) if self.snmp.getErrorStatus(): print "Error creating static vlan " + str( snmp_set_cmd_list[int(self.snmp.getErrorIndex()) - 1]) #print self.snmp return -3 else: print "Correctly created static vlan" # Create the vlan's 802.1Q interface # First we need to get the next available index to use as the interface's internal id vlan.setTaggedID( int(self.snmp.get(OID.threecomVlanNextAvailableIndex)[0][1])) print "next available vlan id " + str(vlan.getTaggedID()) if self.snmp.getErrorStatus(): #print "Error with getting next available vlan 8021Q id" log.critical("Error with getting next available vlan 8021Q id") #print self.snmp return -1 else: print "Correctly got next available vlan 8021Q id" self.snmp.set(OID.threecomVlanTaggedRowStatus + (vlan.getTaggedID(), ), rfc1902.Integer(5)) if self.snmp.getErrorStatus(): print "Error doing create and wait on tagged row creation" #print self.snmp return -1 else: print "Correctly did create and wait on tagged row creation" snmp_set_cmd_list = [] snmp_set_cmd_list.append( (OID.threecomVlanTaggedType + (vlan.getTaggedID(), ), rfc1902.Integer(2))) snmp_set_cmd_list.append( (OID.threecomVlanTaggedTag + (vlan.getTaggedID(), ), rfc1902.Integer(vlan.getID()))) snmp_set_cmd_list.append( (OID.threecomVlanTaggedRowStatus + (vlan.getTaggedID(), ), rfc1902.Integer(4))) self.snmp.complex_set(snmp_set_cmd_list) if self.snmp.getErrorStatus(): print "Error with creating 8021Q interface " + str( snmp_set_cmd_list[int(self.snmp.getErrorIndex()) - 1]) print self.snmp return -7 else: print "correctly created 8021Q interface" # Create an interface associated with the vlan using create and go (4) self.snmp.set( OID.ifStackStatus + (vlan.getInternalID(), vlan.getTaggedID()), rfc1902.Integer(4)) if self.snmp.getErrorStatus(): print "Error setting up ifStackStatus" print self.snmp return -1 else: print "Correctly setup ifStackStatus" # Now add the ports to the vlan if (self.addPorts(vlan.getName(), vlan.getPortsOnSwitch(self.getSwitchName())) < 0): return -8 return 0 def addPorts(self, vlanName, ports): return self.modifyPorts(vlanName, ports, True) def deletePorts(self, vlanName, ports): return self.modifyPorts(vlanName, ports, False) def modifyPorts(self, vlanName, ports, addPorts): if (ports == None or len(ports) == 0): return 0 vlan = None try: vlan = self.getFullVLANInfo(vlanName)[0] except Exception, e: print e for p in ports: #get correct internal id print p p.setInternalID(self.getPortInternalID(p.getPortNumber())) if p.getTagged(): # tagged if addPorts: self.snmp.set( OID.ifStackStatus + (vlan.getTaggedID(), p.getInternalID()), rfc1902.Integer(4)) else: print vlan.getTaggedID() print p.getInternalID() self.snmp.set( OID.ifStackStatus + (vlan.getTaggedID(), p.getInternalID()), rfc1902.Integer(6)) if self.snmp.getErrorStatus(): print "Error with adding/removing port to tagged vlan" print self.snmp return -1 else: # untagged if addPorts: self.snmp.set( OID.ifStackStatus + (vlan.getInternalID(), p.getInternalID()), rfc1902.Integer(4)) else: print vlan print vlan.getTaggedID() print p print p.getInternalID() self.snmp.set( OID.ifStackStatus + (vlan.getInternalID(), p.getInternalID()), rfc1902.Integer(6)) if self.snmp.getErrorStatus(): print "Error with adding/removing port to untagged vlan" print self.snmp return -1 return 0
class Switch(Device): """\brief Superclass for any switch in the testbed This class implements methods to retrieve information from a switch using SNMP version 1. In addition, it acts as a super class for all types of switches in the testbed """ functions = [] mask = [128,64,32,16,8,4,2,1,0] inv_mask = [127,191,223,239,247,251,254,255] def __init__(self, switchNode, minimumVLANInternalID, maximumVLANInternalID, minimumInterfaceInternalID, maximumInterfaceInternalID): """\brief Initializes the class \param switchNode (\c SwitchNode) The SwitchNode object to obtain information from to initialize the class with \param macIDLength (\c int) The length of the id of an snmp result coming from a mac address query. The id is anything to the left of the equal sign, and its length is the number of dot-separated terms. """ if (switchNode.getInfrastructure() == "yes"): self.__ipAddress = switchNode.getInterfaces("infrastructure")[0].getIP() else: self.__ipAddress = switchNode.getInterfaces("management")[0].getIP() self.__switchName = switchNode.getNodeID() self.snmp = SNMP(switchNode.getSNMPwriteCommunity(),self.__ipAddress) # cache of static tables self.__refresh = True # reload self.__dot1dBasePortIfIndex = None self.__ifDescr = None self.__ifName = None self.__dot1qVlanStaticUntaggedPorts = None self.__dot1qVlanStaticEgressPorts = None self.__dot1qPvid = None self.__dot1qTpFdbPort = None self.__dot1qTpFdbStatus = None self.__dot1qVlanFdbId = None self.__dot1qVlanStaticName = None # ports self.__ports = {} self.refreshPortInfo() # vlans self.__vlans = {} # Informational commands def getSwitchName(self,use_snmp=False): """\brief Retrieves the switch's name \param use_snmp (\c boolean) if True read value from switch. \return (\c string) The switch's name """ if use_snmp: return self.snmp.get(OID.sysName)[0][1] else: return self.__switchName def setSwitchName(self,name,commit=False): """\brief Sets the switch's name, and commits to the hardware if commit is True \param name (\c string) The switch's name \param commit (\c boolean) If True apply to hardware \return (\c int) Returns 0 if successful, -1 if unsuccessful """ self.__switchName = name if commit: self.snmp.set(OID.sysName,rfc1902.OctetString(name)) return self.snmp.getErrorStatus() return def getPorts(self): return self.__ports def getPort(self,local_id): return self.__ports[local_id] def getPortByName(self,i): for port in self.__ports: if str(self.__ports[port].getName()) == str(i): return self.__ports[port] return None def addPort(self,port): self.__ports[port.getId()] = port def clearPorts(self): self.__ports = {} def resetPortsVlanInfo(self): for port in self.__ports: self.__ports[port].setUntagged((None,None)) self.__ports[port].setPvid((None,None)) self.__ports[port].setTagged([]) def resetPortsMacInfo(self): for port in self.__ports: self.__ports[port].setMacs([]) def getPortsVlanMode(self): return None def getPortVlanMode(self,pid): return 0 def setPortVlanMode(self,pid,mode): return 0 def refreshPortInfo(self): """\brief Refreshes the port list for the switch` """ self.clearPorts() #log.debug("Creating ports") ifname_table = self.getPortNames() iftype_table = self.snmp.walk(OID.ifType) portsvlanmode_table = self.getPortsVlanMode() ethernet_ports = [] for iftype in iftype_table: if str(iftype[0][1]) == "6": ethernet_ports.append(iftype[0][0][-1]) for ifname in ifname_table: if int(ifname[0][0][-1]) in ethernet_ports: sp = SimplePort(ifname[0][1],ifname[0][0][-1],self.getNodeID()) self.addPort(sp) if portsvlanmode_table != None: for portmode in portsvlanmode_table: sp = self.getPort(portmode[0][0][-1]) sp.setVlanMode(int(portmode[0][1])) def getVlans(self): return self.__vlans def getVlan(self,ident): return self.__vlans[ident] def getVlanByName(self,name): for v_id in self.__vlans: if str(self.__vlans[v_id].getName()) == name: log.debug("Vlan name "+str(name)+" id "+str(v_id)+" "+str(self.__vlans[v_id])) return self.__vlans[v_id] return None def addVlan(self,vlan): self.__vlans[vlan.getLocalId()] = vlan def clearVlans(self): self.__vlans = {} def getNodeID(self): return self.__switchName def setIPAddress(self, i): """\brief Sets the ip address of the switch's management interface and updates the snmp command accordingly \param i (\c string) The ip address of the switch's management interface """ self.__ipAddress = i self.snmp.setIpAddress(i) def getIPAddress(self): """\brief Gets the ip address of the switch's management interface \return (\c string) The ip address of the switch's management interface """ return self.__ipAddress def getNumberofPorts(self): """\brief Retrieves the number of ports on the switch \return (\c string) The number of ports on the switch """ return self.snmp.get(OID.dot1dBaseNumPorts)[0][1] def getSwitchDescription(self): """\brief Retrieves the switch's description \return (\c string) The switch's description """ return self.snmp.get(OID.sysDescr)[0][1] def setSwitchDescription(self,s): """\brief Retrieves the switch's description \return (\c int) Returns 0 if successful, -1 if unsuccessful """ self.snmp.set(OID.sysDescr,rfc1902.OctetString(s)) return self.snmp.getErrorStatus() def getSwitchUptime(self): """\brief Retrieves the switch's uptime \return (\c string) The switch's uptime """ return str(self.snmp.get(OID.sysUpTimeInstance)[0][1]) def getSwitchContact(self): """\brief Retrieves the switch's contact \return (\c string) The switch's contact """ return self.snmp.get(OID.sysContact)[0][1] def setSwitchContact(self,s): """\brief Retrieves the switch's contact \param s (\c string) The switch's contact \return (\c int) Returns 0 if successful, -1 if unsuccessful """ self.snmp.set(OID.sysContact,rfc1902.OctetString(s)) return self.snmp.getErrorStatus() def getSwitchLocation(self): """\brief Retrieves the switch's location \return (\c string) The switch's location """ return self.snmp.get(OID.sysLocation)[0][1] def setSwitchLocation(self,s): """\brief Retrieves the switch's location \param s (\c string) The switch's location \return (\c int) Returns 0 if successful, -1 if unsuccessful """ self.snmp.set(OID.sysLocation,rfc1902.OctetString(s)) return self.snmp.getErrorStatus() def getSerialNumber(self): """\brief returns the serial number of the device \return A string of the serial number """ return "" # operational commands ## Ports def enablePort(self, portNumber): """\brief Enables a port. Returns 0 upon success, -1 otherwise \param portNumber (\c string) The port to enable \return (\c int) 0 if succesful, -1 otherwise """ internalID = int(self.getPortInternalID(portNumber)) self.snmp.set(OID.ifAdminStatus+(internalID,),rfc1902.Integer(1)) return self.snmp.getErrorStatus() def getPortStatus(self, portNumber): """\brief Gets the operational status of a port: up (1), down (2) \param portNumber (\c string) The port whose status is to be retrieved \return (\c string) The port status """ internalID = int(self.getPortInternalID(portNumber)) return self.snmp.get(OID.ifOperStatus+(internalID,))[0][1] def getPortAdminStatus(self, portNumber): """\brief Gets the status of a port: up (1), down (2) or testing (3) \param portNumber (\c string) The port whose status is to be retrieved \return (\c string) The port status """ internalID = int(self.getPortInternalID(portNumber)) return self.snmp.get(OID.ifAdminStatus+(internalID,))[0][1] def disablePort(self, portNumber): """\brief Disables a port. Returns 0 upon success, -1 otherwise \param portNumber (\c string) The port to disable \return (\c int) 0 if succesful, -1 otherwise """ internalID = int(self.getPortInternalID(portNumber)) self.snmp.set(OID.ifAdminStatus+(internalID,),rfc1902.Integer(2)) return self.snmp.getErrorStatus() def getPortIDs(self): """\brief Gets the internal ids for each of the ports on the switch. This function returns a dictionary with the results \return (\c dictionary) A dictionary with the results (see getSNMPResultTable for more information) """ return self.getDot1dBasePortIfIndex() def getPortNames(self): if self.__ifName == None: self.__ifName = self.snmp.walk(OID.ifName) return self.__ifName def getDot1dBasePortIfIndex(self): if self.__dot1dBasePortIfIndex == None: self.__dot1dBasePortIfIndex = self.snmp.walk(OID.dot1dBasePortIfIndex) return self.__dot1dBasePortIfIndex def getIfDescr(self): if self.__ifDescr == None: self.__ifDescr = self.snmp.walk(OID.ifDescr) return self.__ifDescr def getPortInternalID(self, portNumber): """\brief Given a port's external number, this function returns its internal number. If the port is not found -1 is returned \param portNumber (\c string) The port number whose internal port is to be searched \return (\c string) The port's internal id, or -1 if unsuccessful """ varBindTable = self.getPortIDs() for tableRow in varBindTable: for name, val in tableRow: #print name,val if name is None: continue if name[len(name)-1] == rfc1902.Integer32(portNumber): return val return -1 def getFullMACTable(self): """\brief Gets the full learned mac table from the switch, returning a list of MACTableEntry objects. \return (\c list) A list of MACTableEntry objects with the results. """ portsTable = self.snmp.walk(OID.dot1dTpFdbPort) learnedTypeTable = self.snmp.walk(OID.dot1dTpFdbStatus) result = [] for learnedTypeTableRow in learnedTypeTable: for learnedname, learnedval in learnedTypeTableRow: if learnedval == rfc1902.Integer32('3'): learnedname = rfc1902.ObjectName((learnedname.prettyPrint()).replace(OID.dot1dTpFdbStatus.prettyPrint(),OID.dot1dTpFdbPort.prettyPrint())) for portTableRow in portsTable: for portname, portval in portTableRow: if learnedname == portname: result.append(MACTableEntry(("%02x:%02x:%02x:%02x:%02x:%02x" % (int(learnedname[11]),int(learnedname[12]),int(learnedname[13]),int(learnedname[14]),int(learnedname[15]),int(learnedname[16]))).replace("0x","").upper(),portval,'3',self.__switchName)) return result for key in learnedTypeTable.keys(): if (learnedTypeTable[key] == str(3)): mac = MACTableEntry((macAddressesTable[key]).replace(' ',':',5).upper(),portsTable[key],learnedTypeTable[key]) mac.setSwitch(self.getSwitchID()) result.append(mac) #print mac def getInterfaceDescriptionTable(self): """\brief Gets the table of interface descriptions \return (\c dictionary) A dictionary with the results (see getSNMPResultTable for more information) """ result = {} interfaceTable = self.getIfDescr() for interfaceTableRow in interfaceTable: for name, val in interfaceTableRow: result[name[len(name)-1]] = val return result def setCommunity(self, c): """\brief Sets the community and updates the snmp commands accordingly \param c (\c string) The community """ self.snmp.setCommunity(c) def getCommunity(self): """\brief Gets the community \return (\c string) The community """ return self.snmp.getCommunity() ## VLANS def getVLANToInterfacesTable(self): """\brief Gets the mappings between VLANS and interfaces (ports) \return (\c dictionary) A dictionary with the results (see getSNMPResultVLANTable for more information) """ table = {} ifStackStatusTable = self.snmp.walk(OID.ifStackStatus) for ifStackStatusTableRow in ifStackStatusTable: if (table.has_key(ifStackStatusTableRow[0][0][len(ifStackStatusTableRow[0][0])-2]) == False): table[ifStackStatusTableRow[0][0][len(ifStackStatusTableRow[0][0])-2]] = [] table[ifStackStatusTableRow[0][0][len(ifStackStatusTableRow[0][0])-2]].append(ifStackStatusTableRow[0][0][len(ifStackStatusTableRow[0][0])-1]) return table def getVlanInfo(self): vlans = {} dot1qVlanStaticNameTable = self.snmp.walk(OID.dot1qVlanStaticName) dot1qVlanFdbIdTable = self.snmp.walk(OID.dot1qVlanFdbId) for dot1qVlanStaticNameTableRow in dot1qVlanStaticNameTable: for dot1qVlanFdbIdTableRow in dot1qVlanFdbIdTable: if dot1qVlanStaticNameTableRow[0][0][len(dot1qVlanStaticNameTableRow[0][0])-1] == dot1qVlanFdbIdTableRow[0][0][len(dot1qVlanFdbIdTableRow[0][0])-1] : vlans[dot1qVlanStaticNameTableRow[0][1]] = (int(dot1qVlanFdbIdTableRow[0][1]),dot1qVlanStaticNameTableRow[0][0][len(dot1qVlanStaticNameTableRow[0][0])-1]) return vlans def setMinimumVLANInternalID(self, m): print "not implemented" def getMinimumVLANInternalID(self): print "not implemented" def setMaximumVLANInternalID(self, m): print "not implemented" def getMaximumVLANInternalID(self): print "not implemented" def getVLANNames(self): print "not implemented" def getFullVLANInfo(self, theVLANName=None): print "not implemented" def createVLAN(self, vlan): print "not implemented" def addPorts(self, vlanName, ports): print "not implemented" def deletePorts(self, vlanName, ports): print "not implemented" def deleteVLAN(self, vlanName): print "not implemented" def populateVLAN(self, vlanName): print "not implemented" def getEmptyBitMap(self,num_ports=None): s = "" if num_ports == None: num_ports = int(self.snmp.get(OID.dot1dBaseNumPorts)[0][1]) for i in range(0,divmod(num_ports,8)[0]): s = s + pack('B',0) return s def printPortMap(self, portList, Tagged=False): bitfield = array('B') for i in range(0,len(portList)): bitfield.extend(unpack('B',portList[i])) s = "u" if Tagged: s = "t" for port in bitfield: for slot in range(0,8): if slot == 0: s = s + " " if (port & Switch.mask[slot] == Switch.mask[slot]): s = s + "1" else: s = s + "0" return s def getPortTdr(self, port_str): return (False,"TDR testing not supported") #### # Caching code #### def getDot1qVlanStaticUntaggedPorts(self,run=False): if self.__dot1qVlanStaticUntaggedPorts == None or self.__refresh or run: self.__dot1qVlanStaticUntaggedPorts = self.snmp.walk(OID.dot1qVlanStaticUntaggedPorts) return self.__dot1qVlanStaticUntaggedPorts def getDot1qVlanStaticEgressPorts(self,run=False): if self.__dot1qVlanStaticEgressPorts == None or self.__refresh or run: self.__dot1qVlanStaticEgressPorts = self.snmp.walk(OID.dot1qVlanStaticEgressPorts) return self.__dot1qVlanStaticEgressPorts def getDot1qPvid(self,run=False): if self.__dot1qPvid == None or self.__refresh or run: self.__dot1qPvid = self.snmp.walk(OID.dot1qPvid) return self.__dot1qPvid def getDot1qTpFdbPort(self,run=False): if self.__dot1qTpFdbPort == None or self.__refresh or run: self.__dot1qTpFdbPort = self.snmp.walk(OID.dot1qTpFdbPort) return self.__dot1qTpFdbPort def getDot1qTpFdbStatus(self,run=False): if self.__dot1qTpFdbStatus == None or self.__refresh or run: self.__dot1qTpFdbStatus = self.snmp.walk(OID.dot1qTpFdbStatus) return self.__dot1qTpFdbStatus def getDot1qVlanStaticName(self,run=False): if self.__dot1qVlanStaticName == None or self.__refresh or run: self.__dot1qVlanStaticName = self.snmp.walk(OID.dot1qVlanStaticName) return self.__dot1qVlanStaticName def getDot1qVlanFdbId(self,run=False): if self.__dot1qVlanFdbId == None or self.__refresh or run: self.__dot1qVlanFdbId = self.snmp.walk(OID.dot1qVlanFdbId) return self.__dot1qVlanFdbId