Exemplo n.º 1
2
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
Exemplo n.º 2
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 = {}
Exemplo n.º 3
0
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( )
Exemplo n.º 4
0
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()
Exemplo n.º 5
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 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)
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
 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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
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 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)
Exemplo n.º 10
0
def Test1():
    print "Testing creation and deletion of one snmp object"
    s = SNMP("public", "192.168.1.2")
    del s
    dump_garbage()
Exemplo n.º 11
0
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
Exemplo n.º 12
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