Jump to content

Reading toner status from SNMP device


ptrex
 Share

Recommended Posts

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.

#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()
EndFunc

Again, 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 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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...