Python & SNMP

Tänkte fortsätta på samma tema med SNMP och kombinera detta med lite enklare script i Python. Är långt ifrån någon programmerare så detta är nog inte direkt någon vacker lösning, men det fungerar åtminstone. 🙂

För att göra SNMP-querys kan vi använda exempelvis biblioteken subprocess eller netsnmp enligt följande:

Subprocess

#!/usr/bin/env python
import subprocess
checkarg = sys.argv[1:]
#Checks arguments and saves to variables
if len(checkarg) == 2:
    cCommunity = checkarg[0]
    cIP = checkarg[1]
#Modelname
#Gets the Model-ID, returns numeric
cModelInt = subprocess.Popen([r"snmpwalk","-v2c","-Oqv","-c",cCommunity,cIP,"sysObjectID"],stdout=subprocess.PIPE).communicate()[0]

Alternativt netsnmp:

#!/usr/bin/env python
import subprocess
checkarg = sys.argv[1:]
#Checks arguments and saves to variables
if len(checkarg) == 2:
    cCommunity = checkarg[0]
    cIP = checkarg[1]
oid = netsnmp.Varbind('sysName.0')
cName = netsnmp.snmpget(oid, Version = 2, DestHost = cIP, Community = cCommunity)

Vi testar sedan scriptet med “./script.py community ip-adress”.

Här ett exempel där jag hämtar hem lite grundläggande information från en cisco router/switch:

#!/usr/bin/env python
import netsnmp
import subprocess
import ipaddr
import sys
import prettytable
from prettytable import PrettyTable

checkarg = sys.argv[1:]
#Checks arguments and saves to variables
if len(checkarg) == 2:
    cCommunity = checkarg[0]
    cIP = checkarg[1]
if isinstance(cCommunity, str):
    try:
        #Checks for valid IPv4-address
        ccIP = ipaddr.IPv4Address(cIP)

        try:
            #Modelname
            #Gets the Model-ID, returns numeric
            cModelInt = subprocess.Popen([r"snmpwalk","-v2c","-Oqv","-c",cCommunity,cIP,"sysObjectID"],stdout=subprocess.PIPE).communicate()[0]
            cModelSplit = cModelInt.split("::")
            cModelSplit = cModelSplit[1].rstrip()
            #Translate numeric Model-ID to string
            cModel = subprocess.Popen([r"snmptranslate","-m","CISCO-PRODUCTS-MIB","-IR",cModelSplit],stdout=subprocess.PIPE).communicate()[0]
            cModel = cModel.split("::") 

            #Name
            oid = netsnmp.Varbind('sysName.0')
            cName = netsnmp.snmpget(oid, Version = 2, DestHost = cIP, Community = cCommunity)

            #Description
            oid = netsnmp.Varbind('sysDescr.0')
            cDesc = netsnmp.snmpget(oid, Version = 2, DestHost = cIP, Community = cCommunity)
            #Output
            print ""
            print "Device info:"
            print "" 
            print "Host:", ccIP
            print "Model:", cModel[1].rstrip()
            print "Name:", cName[0]
            print cDesc[0]
	    x = PrettyTable(["Interface", "IP", "Subnet", "MAC"])
            x.align["Interface"] = "l"

	    #Index of all the interfaces
	    oid = netsnmp.Varbind("ifIndex")
	    cIndex = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)

	    #Index of all the interfaces with IP
	    oid = netsnmp.Varbind("ipAdEntIfIndex")
	    cIndexIP = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)

	    #IP-Adress list
	    oid = netsnmp.Varbind("ipAdEntAddr")    
	    ipAdd = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)

	    #MAC for all interfaces
	    oid = netsnmp.Varbind("ifPhysAddress")
	    cMAC = netsnmp.snmpwalk(oid, Version = 2, DestHost = sys.argv[2], Community = sys.argv[1])

	    #Subnetmask for all IP interfaces
	    oid = netsnmp.Varbind("ipAdEntNetMask")
	    cNetmask = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)

	    looped = 0

	    #Prints out interface-details
	    for i in cIndex:

	        #Name of every interface
	        oid = netsnmp.Varbind("ifDescr."+i)
	        cInterfacename = netsnmp.snmpget(oid, Version = 2, DestHost = cIP, Community = cCommunity)

	        try:
	            #Matches interface-list with interface+IP-list       
	            IPindex = cIndexIP.index(i)

	            try:
	                #Hex to readable
	                mac = cMAC[looped]
	                mac = ":".join( [ '%x'%(ord(c)) for c in mac ] )

	                #Prints row
	                x.addrow(cInterfacename[0],ipAdd[IPindex],cNetmask[IPindex],mac)

	            except:
		        pass
		    looped += 1

	        except:
	            try:
	                #Hex to readable
	                mac = cMAC[looped]
	                mac = ":".join( [ '%x'%(ord(c)) for c in mac ] )
	                #Prints row w/o IP
	                x.addrow(cInterfacename[0],mac)

	            except:

	                #Prints row w/o MAC & IP
	                x.addrow(cInterfacename[0])

	            looped += 1

		 except:
		     print "SNMP-polling failed"

	     except: 
                 print "Invalid IP given:", cIP
     else:
         print "Invalid Community given (must be string)"
else:
    print "Error - you must set both Community and IP (ex ./3a.py public localhost):"

Programmering/scripting kan vara väldigt skoj har jag märkt! Kan verkligen rekommendera exempelvis https://www.khanacademy.org/science/computer-science-subject/computer-science för att få en liten introduktion till programmering i just python. Till nästa inlägg tänkte jag komplettera scriptet med att spara ner informationen i en MySQL-databas eller fil istället för att endast skriva ut på skärmen.

1 reaktion på ”Python & SNMP

Lämna ett svar

Din e-postadress kommer inte publiceras.