2015-03-25 5 views
0

Я пытаюсь выполнить сканирование устройства в своей сети с помощью PySNMP и хочу провести обширную прогулку по дереву MIB и посмотреть, что я могу найти. Для этого я написал сценарий, который работает довольно хорошо, но он не выполняет задачу.Выполнение полного сканирования nextCmd с помощью PySNMP

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 entrys, последняя запись имеет кортеж 1,3,6,1,2,1,2,2,1,2,21. Теперь, когда я использую этот последний кортеж как исходный кортеж, он все еще находит больше. Либо я что-то не понял, либо не так, как предполагалось.

UPDATE:

Я изменил код немного, и теперь он работает почти как это предполагается. Единственная проблема заключается в том, что я не могу оставить параметр «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) 

ответ

1

Чтение documentation of the example you are following, переменная maxRows торчит релевантными. В примере задается значение 100, которое, как вы говорите, равно количеству возвращаемых строк. (Я бы ожидал, что это будет именно тот номер.)

Итак, попробуйте увеличить maxRows!

Обычно SNMP Walk не ограничивается определенным количеством строк. Вместо этого правильные критерии завершения будут «я получил OID ответа, который не является дочерним элементом OID, с которого я начал». Мне непонятно, закончится ли эта утилита в этот момент. В худшем случае он будет ходить по всему MIB-дереву, если вы его разрешите.

+0

Чтобы пройти весь агент SNMP, вы должны полностью удалить параметр maxRows. В противном случае он может перестать получать данные преждевременно. –

+0

О, ну, это довольно просто. Я не знаю, как я этого не видел. Спасибо. Теперь это работает. Единственное, что я не понимаю, это то, что я получаю файл с 200 строками, хотя я ввел 100 строк. Он всегда дает мне удвоить количество строк, которые я хотел - и значение половины строк - это только последняя цифра OID. – vicco

Смежные вопросы