Cynagen Posted April 11, 2009 Share Posted April 11, 2009 (edited) Ok, well this whole SNMP thing has been interesting me for some time, simply for the fact that I have a router with SNMP enabled on it and I can get information like the memory, and cpu usage, and the inbound/outbound traffic information, which is very nice. However, i'm using a patch between right now, where I have to run the program STG (Site Traffic Graph) and have it log to a .CSV, then have an AutoIt script send that to my database for all my number crunching and a live online graph. I noticed some samples posted here in this thread, but the MIB reader doesn't work for me under Vista, I might have disabled whatever service/function that it relies on, so that's my problem. However, the fact that we don't have a working request client, and response reader, did irk me. So i've spent the better part of this week working on one, and here's the basic of it. It still needs LOTS of work, and right now, the walker works fine, so you actually CAN get results from something, I'll just need to extend the recognition to more than just COUNTER. Either way, enjoy.expandcollapse popup#include <string.au3> ; Rebuild of ptrex's toner status reader, now general purpose! ; Original code by ptrex, additions are credited where found. Dim $Broadcast $debug = 0 $Broadcast = "192.168.1.1" ; Detination Address $Port = 161 ; UDP 161 = SNMP port UDPStartUp() $Start = 1 $Socket = UDPopen($Broadcast, $Port) ConsoleWrite($Socket[1] & "|" & $Socket[2] & "|" & $Socket[3] & @LF & @LF) $_Version = 0 ; SNMPInteger(Version) $_Community = "public" ; SNMPString(Community) $_RequestID = 1 ; Try 57005 for some extra fun when you read the console output... ; SNMPInteger(RequestID) $_Error = 0 ; SNMPInteger(Error) $_Index = 0 ; SNMPInteger(Index) $_ObjectID = "6.1.2.1.2.2.1.10.4" ; SNMPObjectID(ObjectID) -- This will read the Inbound data count on a DD-WRT router ; when sending the object ID the first 2 digits don't need to be sent (1.3) - Also exclude the periods ; IF YOU DON'T HAVE AN SNMP DEVICE TO PLAY WITH, YOU CAN USE THIS OUTPUT FROM MY ROUTER TO SATISFY YOUR CURIOSITY ; _SNMPWalk(0x302C02010004067075626C6963A21F02010102010002010030143012060A2B060102010202010A0441023288) ;-------------------------------- Func _SysObjIDToHexString($Input) ; Courtesy of Rogdog ------------ ;-------------------------------- Local $Output If StringLeft($Input,4) = "1.3." then $Input = StringTrimLeft($Input,4) $aInput = stringsplit($Input,".") for $x = 1 to $aInput[0] $Output &= hex(Number($aInput[$x]),2) ; This step might be incorrect based on the fact that we're cutting ; the hex output to 2 max, basically an artificial cap of 255 (0xFF) Next Return $Output EndFunc ;------------------------------------------------ Func _BuildSNMPItem($_type, $_data, $_binary = 0) ; All $_data must be HEX minus ObjectIDs and ---- ; strings. NOTE that output from this is HEX ---- ; produced by Stringtobinary, which is how I ---- ; learned how to construct before stringing it -- ; and handing it to UDPSend, since binary in ---- ; the UDPSend was sent as a raw string, so it --- ; would fail to be understood by the SNMP ------- ; device EVERY TIME ----------------------------- ;------------------------------------------------ Local $oid, $out if stringleft($_data,2) = "0x" then $_data = stringtrimleft($_data,2) if $_type = "int" then ; Integer type item if $_data > 255 Then $_data = hex($_data) while stringleft($_data,2) = "00" $_data = StringTrimLeft($_data,2) wend $out = stringtobinary(chr(2) & chr(stringlen($_data) / 2)) & $_data Else $out = stringtobinary(chr(2) & chr(stringlen($_data)) & chr($_data)) EndIf elseif $_type = "str" then ; String $out = stringtobinary(chr(4) & chr(stringlen($_data)) & $_data) elseif $_type = "nul" then ; Null item $out = stringtobinary(chr(5) & chr(0)) elseif $_type = "oid" then ; Object ID $oid = "2B" & _SysObjIDToHexString($_data) $out = stringtobinary(chr(6) & chr(stringlen($oid) / 2)) & $oid elseif $_type = "seq" then ; Sequence (wrapper) $out = stringtobinary(chr(48) & chr(stringlen($_data) / 2)) & $_data elseif $_type = "get" then ; GetRequest (we want info from the device!) $out = stringtobinary(chr(160) & chr(stringlen($_data) / 2)) & $_data else return EndIf if $_binary then return $out else return StringTrimLeft($out,2) EndIf EndFunc ;---------------------- Func _ReadSNMP($_input) ; This is my hand- ---- ; written SNMP packet - ; reader. It has a ---- ; nifty chop output --- ; which is the rest --- ; of the packet after - ; what's just been ---- ; read, so it's easy -- ; to walk through a --- ; packet. ;-D --------- ; Example walk below -- ;---------------------- local $chopped, $choplen, $tnum, $data $chopped = "" $choplen = 0 $data = "" if isbinary($_input) then $_input = stringtrimleft($_input,2) ; Trim off the 0x $tnum = dec(stringleft($_input,2)) $len = dec(stringmid($_input, 3, 2)) if $tnum = 2 Then ; We found an integer! $type = "INTEGER" ElseIf $tnum = 4 then ; We found a string! $type = "STRING" $data = binarytostring("0x" & stringmid($_input,5,$len*2)) $choplen = ($len*2) + 4 elseif $tnum = 5 then ; We found a NULL $type = "NULL" $data = 0 $choplen = 4 ElseIf $tnum = 6 then ; We found an Object Identifier! Oh joy! $type = "OBJECTID" $objID = stringmid($_input, 5, $len*2) while stringleft($objID,2) $data = $data & "." & dec(stringleft($objID,2)) $objID = stringtrimleft($objID,2) wend $data = "1.3." & stringtrimleft($data,4) $choplen = ($len*2) + 4 ElseIf $tnum = 48 then ; We found a sequence! $type = "SEQUENCE" $data = stringright($_input, $len*2) $choplen = 4 ElseIf $tnum = 65 then ; We found a counter! $type = "COUNTER" $data = asc(stringmid($_input, 5, $len*2)) $choplen = ($len*2) + 4 elseif $tnum = 162 then ; We found a Response! $type = "RESPONSE" $choplen = 4 else msgbox(0,"_ReadSNMP", "UNKNOWN TYPE: " & $tnum) endif if $data = "" then $data = stringmid($_input, 5, $len*2) if $choplen = 0 then $choplen = stringlen($data) + 4 $chopped = stringtrimleft($_input,$choplen) return stringsplit($type & chr(255) & $data & chr(255) & $chopped,chr(255)) EndFunc func _SNMPWalk($_input) msgbox(0,"Starting...", "Starting example SNMP packet walk") $snmp=_ReadSNMP($_input) while $snmp[0] msgbox(0,"SNMP","Type: " & $snmp[1] & @CRLF & "Value: " & $snmp[2] & @CRLF & @CRLF & "Remaining: " & $snmp[3]) $snmp=_ReadSNMP($snmp[3]) WEnd EndFunc $_Version = _BuildSNMPItem("int", $_Version) ;old StringToBinary(Chr(02) & Chr(StringLen($_Version)) & Chr($_Version)) $_Community = _BuildSNMPItem("str", $_Community) ;old StringToBinary(Chr(04) & Chr(stringlen($_Community)) & $_Community) $_Request = _BuildSNMPItem("int", $_RequestID) ;old StringToBinary(Chr(02) & Chr(Stringlen($_RequestID)) & chr($_RequestID)) $_Error = _BuildSNMPItem("int", $_Error) ;old StringToBinary(chr(02) & Chr(stringlen($_Error)) & chr($_Error)) $_Index = _BuildSNMPItem("int", $_Index) ;old StringToBinary(chr(02) & Chr(stringlen($_Index)) & chr($_Index)) $_Value = _BuildSNMPItem("nul",0) ;old stringtobinary(chr(05) & chr(00)) $_ObjectID = _BuildSNMPItem("oid", $_ObjectID) ;$_ObjectID = StringSplit($_ObjectID,".") ;$_ID = chr(43) ;for $o = 1 to $_ObjectID[0] ; $_ID &= chr($_ObjectID[$o]) ;next ;$_ObjectID = stringtobinary(chr(06) & chr(stringlen($_ID)) & $_ID) $_Varbind = _BuildSNMPItem("seq", $_ObjectID & $_Value) ;old StringtoBinary(chr(48) & chr(stringlen(binarytostring($_Object)))) & $_Object $_VarbindList = _BuildSNMPItem("seq", $_Varbind) ;old StringToBinary(chr(48) & chr(stringlen(binarytostring($_Varbind)))) & $_Varbind $_PDU = _BuildSNMPItem("get", $_Request & $_Error & $_Index & $_VarbindList) ;old $_PDU = StringToBinary(chr(160) & chr(stringlen(binarytostring($_PDU)))) & $_PDU $_MSG = _BuildSNMPItem("seq", $_Version & $_Community & $_PDU, 1) ;old $_MSG = StringToBinary(chr(48) & chr(stringlen(binarytostring($_MSG)))) & $_MSG if $debug = 1 then msgbox(0,"Version",$_Version) msgbox(0,"Community",$_Community) msgbox(0,"Request",$_Request) msgbox(0,"Error",$_Error) msgbox(0,"Index",$_Index) msgbox(0,"ObjectID",$_ObjectID) msgbox(0,"Varbind",$_Varbind) msgbox(0,"Varbind List",$_VarbindList) msgbox(0,"SNMP PDU",$_PDU) msgbox(0,"SNMP MESSAGE",$_MSG) EndIf ConsoleWrite($_MSG & @LF& @LF) UDPSend($Socket, BinaryToString($_MSG)) _StartListener() sleep (200) Func _StartListener() If $Start = 1 Then $i = 0 While 1 $srcv = UDPRecv($Socket, 2048) If $srcv <> "" Then ConsoleWrite("Received Response" & @CR) ConsoleWrite(stringleft($srcv,2) & @CR) if stringleft(binarytostring($srcv),1) = 0 then ConsoleWrite($srcv & @CR) msgbox(0,"Starting...", "Starting example SNMP packet walk") _SNMPWalk($srcv) Exit EndIf ;ConsoleWrite(BinaryToString($srcv) & @CR) EndIf sleep(100) WEnd EndIf EndFunc Func OnAutoItExit() UDPCloseSocket($Socket) UDPShutdown() EndFuncAgain, this is just a working example, and needs a LOT of work, a LOT to become a functional replacement for third party SNMP applications.I'm an idiot, but i'll leave this posted here for anyone else to look at.Found an SNMP UDF here: http://www.autoitscript.com/forum/index.php?showtopic=81687 Edited April 11, 2009 by Cynagen Blah, blah, blah... lip service... lip service.Working on a number of projects right now, just waiting for my time to post them here on AutoIt forums. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now