Exemple #1
0
def cbRecvFun(transportDispatcher,
              transportDomain,
              transportAddress,
              wholeMsg,
              reqPDU=reqPDU):

    while wholeMsg:
        rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
        rspPDU = pMod.apiMessage.getPDU(rspMsg)

        # Match response to request
        if pMod.apiPDU.getRequestID(reqPDU) == pMod.apiPDU.getRequestID(
                rspPDU):

            # Check for SNMP errors reported
            errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
            if errorStatus:
                print(errorStatus.prettyPrint())

            else:
                print('INFORM message delivered, response var-binds follow')

                for oid, val in pMod.apiPDU.getVarBinds(rspPDU):
                    print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))

            transportDispatcher.jobFinished(1)

    return wholeMsg
Exemple #2
0
    def cbRecvFun(
        transportDispatcher,
        transportDomain,
        transportAddress,
        wholeMsg,
        reqPDU=reqPDU,
        headVars=headVars,
    ):
        while wholeMsg:
            rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message())
            rspPDU = v2c.apiMessage.getPDU(rspMsg)

            # Match response to request
            if v2c.apiBulkPDU.getRequestID(
                    reqPDU) == v2c.apiBulkPDU.getRequestID(rspPDU):
                # Format var-binds table
                varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, rspPDU)

                # Check for SNMP errors reported
                errorStatus = v2c.apiBulkPDU.getErrorStatus(rspPDU)
                if errorStatus and errorStatus != 2:
                    errorIndex = v2c.apiBulkPDU.getErrorIndex(rspPDU)
                    print("%s at %s" % (
                        errorStatus.prettyPrint(),
                        errorIndex and varBindTable[int(errorIndex) - 1]
                        or "?",
                    ))
                    transportDispatcher.jobFinished(1)
                    break

                # Report SNMP table
                for tableRow in varBindTable:
                    for name, val in tableRow:
                        # print mib data
                        print("from: %s, %s = %s" %
                              (transportAddress, name.prettyPrint(),
                               val.prettyPrint()))
                        output_list.append(
                            "from: %s, %s = %s\n" %
                            (transportAddress, name.prettyPrint(),
                             val.prettyPrint()))

                # Stop on EOM
                for _oid, val in varBindTable[-1]:
                    if not isinstance(val, v2c.Null):
                        break
                    else:
                        transportDispatcher.jobFinished(1)

                # Generate request for next row
                v2c.apiBulkPDU.setVarBinds(reqPDU,
                                           [(x, v2c.null)
                                            for x, y in varBindTable[-1]])
                v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID())
                transportDispatcher.sendMessage(encoder.encode(reqMsg),
                                                transportDomain,
                                                transportAddress)
        return wholeMsg
def cbRecvFun(transportDispatcher,
              transportDomain,
              transportAddress,
              wholeMsg,
              reqPDU=reqPDU,
              headVars=headVars):

    while wholeMsg:
        rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message())

        rspPDU = v2c.apiMessage.getPDU(rspMsg)

        # Match response to request
        if v2c.apiBulkPDU.getRequestID(reqPDU) == v2c.apiBulkPDU.getRequestID(
                rspPDU):
            # Format var-binds table
            varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, rspPDU)

            # Check for SNMP errors reported
            errorStatus = v2c.apiBulkPDU.getErrorStatus(rspPDU)
            if errorStatus and errorStatus != 2:
                errorIndex = v2c.apiBulkPDU.getErrorIndex(rspPDU)
                print(
                    '%s at %s' %
                    (errorStatus.prettyPrint(),
                     errorIndex and varBindTable[int(errorIndex) - 1] or '?'))
                transportDispatcher.jobFinished(1)
                break

            # Report SNMP table
            for tableRow in varBindTable:
                for name, val in tableRow:
                    print('from: %s, %s = %s' %
                          (transportAddress, name.prettyPrint(),
                           val.prettyPrint()))

            # Stop on EOM
            for oid, val in varBindTable[-1]:
                if not isinstance(val, v2c.Null):
                    break
            else:
                transportDispatcher.jobFinished(1)
                continue

            # Generate request for next row
            v2c.apiBulkPDU.setVarBinds(reqPDU, [(x, v2c.null)
                                                for x, y in varBindTable[-1]])
            v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID())
            transportDispatcher.sendMessage(encoder.encode(reqMsg),
                                            transportDomain, transportAddress)
            global startedAt
            if time() - startedAt > 3:
                raise Exception('Request timed out')
            startedAt = time()

    return wholeMsg
    def _trap_receiver_cb(transport, domain, sock, msg):
        if decodeMessageVersion(msg) != protoVersion2c:
            raise RuntimeError('Only SNMP v2c traps are supported.')

        req, msg = decoder.decode(msg, asn1Spec=v2c.Message())
        pdu = v2c.apiMessage.getPDU(req)

        # ignore any non trap PDUs
        if not pdu.isSameTypeWith(v2c.TrapPDU()):
            return

        # Stop the receiver if the trap we are looking for was received.
        if trap_filter(domain, sock, pdu):
            transport.jobFinished(1)
| $ snmpinform -v2c -c public udp:demo.snmplabs.com 0 1.3.6.1.6.3.1.1.5.1
| $ snmpinform -v2c -c public udp6:[::1] 0 1.3.6.1.6.3.1.1.5.1

"""#
from time import time
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto.api import v2c as pMod

# Build PDU
reqPDU = pMod.InformRequestPDU()
pMod.apiTrapPDU.setDefaults(reqPDU)

# Build message
trapMsg = pMod.Message()
pMod.apiMessage.setDefaults(trapMsg)
pMod.apiMessage.setCommunity(trapMsg, 'public')
pMod.apiMessage.setPDU(trapMsg, reqPDU)

startedAt = time()


def cbTimerFun(timeNow):
    if timeNow - startedAt > 3:
        raise Exception("Request timed out")


# noinspection PyUnusedLocal,PyUnusedLocal
def cbRecvFun(transportDispatcher,
              transportDomain,
Exemple #6
0
class SnmpV2cMessageProcessingModel(SnmpV1MessageProcessingModel):
    messageProcessingModelID = 1 # SNMPv2c
    _snmpMsgSpec = v2c.Message()
Exemple #7
0
def SnmpwalkAsync(target_IP=None,
                  oid=None,
                  community='public',
                  walk_timeout=10,
                  mode='ipv4'):
    """Script to run in the remote device for snmp mib walk.

       This script can be copied to the remote device eg:wan
       and can be executed directly using python for snmp mib walk
       The walk can done for both ipv6 and ipv4

    :param target_IP: device IP for mib query
    :type target_IP: string
    :param oid: mib query OID
    :type oid: string
    :param community: community string for mib query, defaults to public
    :type community: string, optional
    :param walk_timeout: snmp walk timeout, defaults to 10
    :type walk_timeout: integer, optional
    :param mode: mib query mode, defaults to ipv4
    :type mode: string, optional
    :return: mib query output
    :rtype: string
    """
    # SNMP table header
    headVars = [v2c.ObjectIdentifier((oid))]

    # Build PDU
    reqPDU = v2c.GetBulkRequestPDU()
    v2c.apiBulkPDU.setDefaults(reqPDU)
    v2c.apiBulkPDU.setNonRepeaters(reqPDU, 0)
    v2c.apiBulkPDU.setMaxRepetitions(reqPDU, 25)
    v2c.apiBulkPDU.setVarBinds(reqPDU, [(x, v2c.null) for x in headVars])

    # Build message
    reqMsg = v2c.Message()
    v2c.apiMessage.setDefaults(reqMsg)
    v2c.apiMessage.setCommunity(reqMsg, community)
    v2c.apiMessage.setPDU(reqMsg, reqPDU)

    startedAt = time.time()
    output_list = []

    def cbTimerFun(timeNow):
        # Duration
        if timeNow - startedAt > walk_timeout:
            if walk_timeout != 0:
                raise Exception("Request timed out")
            else:
                if timeNow - startedAt > 30:
                    transportDispatcher.jobFinished(1)

    # noinspection PyUnusedLocal
    def cbRecvFun(transportDispatcher,
                  transportDomain,
                  transportAddress,
                  wholeMsg,
                  reqPDU=reqPDU,
                  headVars=headVars):
        while wholeMsg:
            rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message())
            rspPDU = v2c.apiMessage.getPDU(rspMsg)

            # Match response to request
            if v2c.apiBulkPDU.getRequestID(
                    reqPDU) == v2c.apiBulkPDU.getRequestID(rspPDU):
                # Format var-binds table
                varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, rspPDU)

                # Check for SNMP errors reported
                errorStatus = v2c.apiBulkPDU.getErrorStatus(rspPDU)
                if errorStatus and errorStatus != 2:
                    errorIndex = v2c.apiBulkPDU.getErrorIndex(rspPDU)
                    print('%s at %s' %
                          (errorStatus.prettyPrint(), errorIndex
                           and varBindTable[int(errorIndex) - 1] or '?'))
                    transportDispatcher.jobFinished(1)
                    break

                # Report SNMP table
                for tableRow in varBindTable:
                    for name, val in tableRow:
                        # print mib data
                        print('from: %s, %s = %s' %
                              (transportAddress, name.prettyPrint(),
                               val.prettyPrint()))
                        output_list.append(
                            'from: %s, %s = %s\n' %
                            (transportAddress, name.prettyPrint(),
                             val.prettyPrint()))

                # Stop on EOM
                for oid, val in varBindTable[-1]:
                    if not isinstance(val, v2c.Null):
                        break
                    else:
                        transportDispatcher.jobFinished(1)

                # Generate request for next row
                v2c.apiBulkPDU.setVarBinds(reqPDU,
                                           [(x, v2c.null)
                                            for x, y in varBindTable[-1]])
                v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID())
                transportDispatcher.sendMessage(encoder.encode(reqMsg),
                                                transportDomain,
                                                transportAddress)
        return wholeMsg

    transportDispatcher = AsyncoreDispatcher()
    transportDispatcher.registerRecvCbFun(cbRecvFun)
    transportDispatcher.registerTimerCbFun(cbTimerFun)
    if mode == 'ipv4':
        transportDispatcher.registerTransport(
            udp.domainName,
            udp.UdpSocketTransport().openClientMode())
        transportDispatcher.sendMessage(encoder.encode(reqMsg), udp.domainName,
                                        (target_IP, 161))
    else:
        transportDispatcher.registerTransport(
            udp6.domainName,
            udp6.Udp6SocketTransport().openClientMode())
        transportDispatcher.sendMessage(encoder.encode(reqMsg),
                                        udp6.domainName, (target_IP, 161))
    transportDispatcher.jobStarted(1)
    # Dispatcher will finish as job#1 counter reaches zero
    transportDispatcher.runDispatcher()
    transportDispatcher.closeDispatcher()

    if output_list != []:
        return output_list
    else:
        return
Exemple #8
0
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto.api import v2c
from time import time

# SNMP table header
headVars = [v2c.ObjectIdentifier((1, 3, 6))]

# Build PDU
reqPDU = v2c.GetBulkRequestPDU()
v2c.apiBulkPDU.setDefaults(reqPDU)
v2c.apiBulkPDU.setNonRepeaters(reqPDU, 0)
v2c.apiBulkPDU.setMaxRepetitions(reqPDU, 25)
v2c.apiBulkPDU.setVarBinds(reqPDU, [(x, v2c.null) for x in headVars])

# Build message
reqMsg = v2c.Message()
v2c.apiMessage.setDefaults(reqMsg)
v2c.apiMessage.setCommunity(reqMsg, 'public')
v2c.apiMessage.setPDU(reqMsg, reqPDU)

startedAt = time()


def cbTimerFun(timeNow):
    if timeNow - startedAt > 3:
        raise Exception("Request timed out")


# noinspection PyUnusedLocal
def cbRecvFun(transportDispatcher,
              transportDomain,
Exemple #9
0
    def callback(self, transportDispatcher, transportDomain, transportAddress,
                 wholeMsg, reqPDU=None, headVars=None):
        """ Callback function called when SNMP answer arrives """
        aBP = v2c.apiBulkPDU
        # Get PDU
        if reqPDU:
            self.reqPDU = reqPDU
        # Get headVars (OID list)
        if headVars:
            self.headVars = headVars

        while wholeMsg:
            # Do some stuff to read SNMP anser
            self.rspMsg, wholeMsg = decoder.decode(wholeMsg,
                                                   asn1Spec=v2c.Message())
            self.rspPDU = v2c.apiMessage.getPDU(self.rspMsg)
            if aBP.getRequestID(self.reqPDU) == aBP.getRequestID(self.rspPDU):
                # Check for SNMP errors reported
                errorStatus = aBP.getErrorStatus(self.rspPDU)
                if errorStatus and errorStatus != 2:
                    logger.error('[SnmpBooster] SNMP Request error 2: %s' % str(errorStatus))
                    self.set_exit("SNMP Request error 2: " + str(errorStatus), rc=3)
                    return wholeMsg
                # Format var-binds table
                varBindTable = aBP.getVarBindTable(self.reqPDU, self.rspPDU)
                # Initialize mapping_instance dict
                mapping_instance = {}
                # Read datas from the anser
                for tableRow in varBindTable:
                    # TODO: MAYBE: Check if the current 'tableRow' is in the list of the
                    # need tables. If NOT, maybe we can jump the current 'tableRow' ?? (continue)

                    # Read all oid in the 'tableRow'
                    for oid, val in tableRow:
                        # Clean the oid
                        oid = "." + oid.prettyPrint()

                        # Check what kind of datas we have
                        if oid in self.oids_waiting_values:
                            # Standard datas
                            # Get value and save it in the result dict
                            self.results_oid_dict[oid] = str(val)
                        elif any([oid.startswith(m_oid + ".") for m_oid in self.mapping_oids]):
                            # Mapping datas
                            # TODO: Need more detail
                            for m_oid in self.mapping_oids:
                                if oid.startswith(m_oid + "."):
                                    instance = oid.replace(m_oid + ".", "")
                                    val = re.sub("[,:/ ]", "_", str(val))
                                    mapping_instance[val] = instance
                        elif oid in self.limit_oids:
                            # get limits => What is a limit ????????????
                            try:
                                self.results_limits_dict[oid] = float(val)
                            except ValueError:
                                logger.error('[SnmpBooster] Bad limit for '
                                             'oid: %s - Skipping' % str(oid))
                        else:
                            # The current oid is not needed
                            pass

                # IF the mapping is done, we can look for OID values
                if self.mapping_done:
                    # Get all OIDS that we want datas
                    oids = set(self.oids_waiting_values.keys() + self.limit_oids.keys())
                    # Get all OIDS that we have datas
                    results_oids = set(self.results_oid_dict.keys() +
                                       self.results_limits_dict.keys())
                    # Get all OIDS which have not datas YET
                    self.remaining_oids = oids - results_oids


                    # We have to determinate which OIDs we need to ask,
                    # to get the datas for our wanted OIDs...
                    tableRow = []
                    for oid in self.remaining_oids:
                        # For all current OIDs, we need to get the previous OID
                        # But if in the current OID is last number is 0
                        # We get the parent table
                        if int(oid.rsplit(".", 1)[1]) - 1 >= 0:
                            # Get previous oid here
                            tableRow.append(oid[1:].rsplit(".", 1)[0] +
                                            "." +
                                            str(int(oid[1:].rsplit(".", 1)[1]) - 1))
                        else:
                            # Get parent table here
                            tableRow.append(oid[1:].rsplit(".", 1)[0])

                    # We need to get more OIDs (the request ask more than 100 oids)
                    # - From the __init__ function
                    #   => We didn't query all needed oids YET
                    # - From "oids != results_oids"
                    #   => Some OIDs doesn't have value, so probably the table
                    #      that we queried is long (more than 100 children)
                    if len(self.remaining_tablerow) > 0:
                        # SNMP BULK is limited to 100 OIDs in same request
                        if len(self.remaining_tablerow) >= 100:
                            oids_to_check = [self.remaining_tablerow.pop() for x in xrange(99)]
                        else:
                            oids_to_check = self.remaining_tablerow
                            self.remaining_tablerow = set()
                        # Prepare request to get nest OIDs
                        aBP.setVarBinds(self.reqPDU,
                                        [(x, v2c.null) for x in oids_to_check])
                        aBP.setRequestID(self.reqPDU, v2c.getNextRequestID())
                        transportDispatcher.sendMessage(encoder.encode(self.reqMsg),
                                                        transportDomain,
                                                        transportAddress)
                        # Count the number of requests done for one host/frequency couple
                        self.nb_next_requests = self.nb_next_requests + 1
                        return wholeMsg

                    # Some oids doesn't have any value (oids != results_oids)
                    # We make a new request to get this values
                    if oids != results_oids and self.nb_next_requests < 5:
                        # SNMP BULK is limited to 100 OIDs in same request
                        if len(tableRow) >= 100:
                            # Add missing oid to self.remaining_tablerow
                            # This oids will be checked in a few requests
                            # Here : "if len(self.remaining_tablerow) > 0:"
                            self.remaining_tablerow.update(set(tableRow[99:]))
                            tableRow = tableRow[:99]

                        aBP.setVarBinds(self.reqPDU,
                                        [(v2c.ObjectIdentifier(x), v2c.null) for x in tableRow])
                        aBP.setRequestID(self.reqPDU, v2c.getNextRequestID())
                        transportDispatcher.sendMessage(encoder.encode(self.reqMsg),
                                                        transportDomain,
                                                        transportAddress)
                        self.nb_next_requests = self.nb_next_requests + 1
                        return wholeMsg

                # LOCKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
                try:
                    # Get OID from memcache
                    self.obj = self.memcached.get(self.obj_key)
                except ValueError, e:
                    logger.error('[SnmpBooster] Memcached error while getting: `%s' % self.obj_key)
                    self.set_exit("Memcached error: `%s'"
                                  % self.memcached.get(self.obj_key),
                                  3, transportDispatcher)
                    return wholeMsg

                self.obj.frequences[self.check_interval].old_check_time = copy.copy(self.obj.frequences[self.check_interval].check_time)
                self.obj.frequences[self.check_interval].check_time = self.start_time

                # We have to do the mapping instance
                if not self.mapping_done:
                    # TODO: need more documentation
                    self.obj.instances = mapping_instance

                    self.obj.map_instances(self.check_interval)
                    s = self.obj.frequences[self.check_interval].services[self.serv_key]

                    self.obj.frequences[self.check_interval].checking = False
                    self.memcached.set(self.obj_key, self.obj, time=604800)
                    if s.instance.startswith("map("):
                        result_oids_mapping = set([".%s" % str(o).rsplit(".", 1)[0]
                                                   for t in varBindTable for o, _ in t])
                        if not result_oids_mapping.intersection(set(self.mapping_oids.keys())):
                            s.instance = "NOTFOUND"
                            self.obj.frequences[self.check_interval].checking = False
                            self.memcached.set(self.obj_key, self.obj, time=604800)
                            logger.info("[SnmpBooster] - Instance mapping not found. "
                                        "Please check your config")
                            self.set_exit("%s: Instance mapping not found. "
                                          "Please check your config" % s.instance_name,
                                          3,
                                          transportDispatcher)
                            # Stop if oid not in mappping oidS
                            return

                        # Mapping not finished
                        aBP.setVarBinds(self.reqPDU,
                                        [(x, v2c.null) for x, y in varBindTable[-1]])
                        aBP.setRequestID(self.reqPDU, v2c.getNextRequestID())
                        transportDispatcher.sendMessage(encoder.encode(self.reqMsg),
                                                        transportDomain,
                                                        transportAddress)
                        return wholeMsg

                    logger.info("[SnmpBooster] - Instance mapping completed. "
                                "Expect results at next check")
                    self.set_exit("Instance mapping completed. "
                                  "Expect results at next check",
                                  3,
                                  transportDispatcher)
                    return

                # set Limits
                if not self.limits_done:
                    self.obj.set_limits(self.check_interval,
                                        self.results_limits_dict)
                    self.memcached.set(self.obj_key,
                                       self.obj,
                                       time=604800)

                # Save values
                self.oids_to_check = self.obj.get_oids_by_frequence(self.check_interval)
                for oid, value in self.results_oid_dict.items():
                    if value != None:
                        self.oids_to_check[oid].raw_value = str(value)
                    else:
                        self.oids_to_check[oid].raw_value = None

                # save data
                self.obj.frequences[self.check_interval].checking = False
                self.memcached.set(self.obj_key, self.obj, time=604800)

                # UNLOCKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK

                if time.time() - self.snmp_request_start_time > self.timeout:
                    self.set_exit("SNMP Request timed out",
                                  3,
                                  transportDispatcher)
                #return wholeMsg

                self.snmp_request_start_time = time.time()
Exemple #10
0
        self.reqPDU = v2c.GetBulkRequestPDU()
        v2c.apiBulkPDU.setDefaults(self.reqPDU)
        v2c.apiBulkPDU.setNonRepeaters(self.reqPDU, 0)
        v2c.apiBulkPDU.setMaxRepetitions(self.reqPDU, self.max_repetitions)

        # Cut SNMP request if it is too long
        if len(self.headVars) >= 100:
            self.remaining_tablerow = set(self.headVars[99:])
            self.headVars = self.headVars[:99]

        v2c.apiBulkPDU.setVarBinds(self.reqPDU,
                                   [(v2c.ObjectIdentifier(tuple(int(i) for i in x.split("."))), v2c.null)
                                    for x in sorted(self.headVars)])

        # Build message
        self.reqMsg = v2c.Message()
        v2c.apiMessage.setDefaults(self.reqMsg)
        v2c.apiMessage.setCommunity(self.reqMsg, self.community)
        v2c.apiMessage.setPDU(self.reqMsg, self.reqPDU)
        # Save the time when snmp request start
        self.snmp_request_start_time = time.time()

        # Prepare SNMP Request
        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerTransport(udp.domainName,
                                              udp.UdpSocketTransport().openClientMode())

        transportDispatcher.registerRecvCbFun(self.callback)
        transportDispatcher.registerTimerCbFun(self.callback_timer)
        transportDispatcher.sendMessage(encoder.encode(self.reqMsg),
                                        udp.domainName,