使用 PySNMP 进行完整的 nextCmd 扫描

Doing a complete nextCmd scan with PySNMP

我正在尝试使用 PySNMP 扫描我网络中的设备,并希望广泛遍历 MIB 树并查看我能找到什么。 为此我写了一个脚本,效果很好,但是没有完成任务。

from pysnmp.entity.rfc3413.oneliner import cmdgen
from os.path import exists
import sys


    # Create command generator
    cmdGen = cmdgen.CommandGenerator()

    # Function definition
    def snmp_get_next(OID, target_IP, target_port, target):

        if exists(target):
            sys.exit("The file '%s' already exists!" % target)
        else: 
            target_file = open(target, 'w+')

        # Getting values
        errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
            cmdgen.CommunityData('public'),
            cmdgen.UdpTransportTarget((target_IP, target_port)),
            OID,
            cmdgen.MibVariable('IF-MIB', '').loadMibs(),
            lexicographicMode=True, maxRows=100,
            ignoreNonIncreasingOid=True
        )

        # Printing errors and OID_name to file
        if errorIndication:
            print(errorIndication)
        else:
            if errorStatus:
                print('%s at %s' % (
                    errorStatus.prettyPrint(),
                    errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
                    )
                )
            else:
                for varBindTableRow in varBindTable:
                    for name, val in varBindTableRow:
                        target_file.write('- %s:\t OID: %s and value = %s\n' 
                                      % (OID, name.prettyPrint(), val.prettyPrint())
                                      )
        target_file.close()
        print('Writing successful!')


        sys.exit(0)

    # Execution of function
    snmp_get_next(
                  tuple(map(int,raw_input('OID Tuple:\t').split(','))), 
                  raw_input('Target IP:\t'), 
                  raw_input('Target Port:\t'), 
                  raw_input('Target File:\t')
                 )

所以,当我以起始元组 1,3,6,1,2,1,2,2,1,3 执行脚本时,我得到一个包含大约 100 个条目的文件,最后一个条目有元组 1, 3,6,1,2,1,2,2,1,2,21。现在,当我使用最后一个元组作为起始元组时,它仍然会找到更多。 要么我误解了什么,要么它不符合预期。

更新:

我稍微更改了我的代码,现在它几乎可以正常工作了。唯一的问题是,我不能省略 "maxRows" 参数,否则我会收到超时错误消息。

from pysnmp.entity.rfc3413.oneliner import cmdgen
from os.path import exists
import sys

# Turn on debugging
#debug.setLogger(debug.Debug('msgproc', 'secmod'))

# Enter parameters
target_IP           = raw_input('Target IP (192.168.13.100): ') or '192.168.13.100'
target_port         = raw_input('Target port (161): ') or 161
target_file_name    = raw_input('Target filename (.txt is added): ') + '.txt' 

# Check for already existing file
if exists(target_file_name):
    sys.exit("The file '%s' already exists!" % target_file_name)
else: 
    target_file = open(target_file_name, 'w+')

# Initialize counter to zero
counter = 0

# Create command generator
cmdGen = cmdgen.CommandGenerator()

# Get data

errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
    cmdgen.CommunityData('public'),
    cmdgen.UdpTransportTarget((target_IP, target_port)),
    '1.3', # <---- Does not seem perfect to me, but it works
    lexicographicMode=True, 
    maxRows=5000, #  <---- Can't be left out, but I want to
    ignoreNonIncreasingOid=True,
    lookupNames=True, 
    lookupValues=True
)

# Print errors and values to file
if errorIndication:
    print(errorIndication)
else:
    # Print error messages

    if errorStatus:
        print('%s at %s' % (
            errorStatus.prettyPrint(),
            errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
            )
        )
    else:
        # Print values
        for varBindTableRow in varBindTable:
            for name, val in varBindTableRow:
                counter += 1
                target_file.write("(%s)\t start_OID: %s\tvalue =\t%s\n" % (counter, name.prettyPrint(), val.prettyPrint()))

        # Finish the operation                
        target_file.close()
        print('Writing to %s successful. %d lines have been written' % (target_file_name, counter))
        sys.exit(0)

阅读 documentation of the example you are following,变量 maxRows 突出显示为相关。 该示例将其设置为 100,您说的大致是返回的行数。 (我希望它正好是那个数字。)

所以,尝试增加 maxRows

通常情况下,SNMP Walk 不会将自己限制在特定的行数。相反,正确的终止标准应该是 "have I received a response OID which is not a child of the OID I started at"。我不清楚该实用程序是否会在此时终止。最坏的情况下,如果你愿意,它会遍历整个 MIB 树。