summaryrefslogtreecommitdiff
path: root/examples/v1arch/asyncore/manager/cmdgen/getnext-pull-whole-mib.py
blob: 20be7ca2b0038fcf38c99a087b84a6f1690ed9b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""Command Generator Application (GETNEXT)"""
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram.udp import UdpSocketTransport
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto import api
from time import time

# Protocol version to use
pMod = api.protoModules[api.protoVersion1]

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

# Build PDU
reqPDU =  pMod.GetNextRequestPDU()
pMod.apiPDU.setDefaults(reqPDU)
pMod.apiPDU.setVarBinds(
    reqPDU, map(lambda x, pMod=pMod: (x, pMod.Null()), headVars)
    )

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

startedAt = time()

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

def cbRecvFun(tspDsp, transportDomain, transportAddress, wholeMsg,
              reqPDU=reqPDU, headVars=headVars):
    while wholeMsg:
        rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
#        print rspMsg.prettyPrinter()        
        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 and errorStatus != 2:
                raise errorStatus
            # Build SNMP table from response
            tableIndices = pMod.apiPDU.getTableIndices(
                reqPDU, rspPDU, headVars
                )
            # Report SNMP table
            varBindList = pMod.apiPDU.getVarBindList(rspPDU)
            for rowIndices in tableIndices:
                for cellIdx in filter(lambda x: x!=-1, rowIndices):
                    print transportAddress,
                    print pMod.apiVarBind.getOIDVal(varBindList[cellIdx])

            # Remove completed SNMP table columns
            map(lambda idx, headVars=headVars: headVars.__delitem__(idx), \
                filter(lambda x: x==-1, tableIndices[-1]))
            if not headVars:
                raise "EOM"

            # Generate request for next row
            lastRow = []
            for cellIdx in filter(lambda x: x!=-1, tableIndices[-1]):
                lastRow.append(
                    (pMod.apiVarBind.getOIDVal(varBindList[cellIdx])[0],
                     pMod.Null())
                    )
            pMod.apiPDU.setVarBinds(reqPDU, lastRow)
            pMod.apiPDU.setRequestID(reqPDU, pMod.getNextRequestID())
            tspDsp.sendMessage(
                encoder.encode(reqMsg), transportDomain, transportAddress
                )
            global startedAt
            if time() - startedAt > 3:
                raise 'Request timed out'
            startedAt = time()
    return wholeMsg

dsp = AsynsockDispatcher(udp=UdpSocketTransport().openClientMode())
dsp.registerRecvCbFun(cbRecvFun)
dsp.registerTimerCbFun(cbTimerFun)
#dsp.sendMessage(req.berEncode(), 'udp', ('localhost', 1161)) # 161
dsp.sendMessage(encoder.encode(reqMsg), 'udp', ('ts29.moscow.net.rol.ru', 161))

try:
    msgAndPduDsp.transportDispatcher.runDispatcher()
except "EOM":
    pass

#def f():
#    dsp.runDispatcher(liveForever=1)
#f()
#import profile
#profile.run('f()')