ptrex

Reading toner status from SNMP device

21 posts in this topic

#1 ·  Posted (edited)

Using SNMP - MIB protocol

In the support forum someone was asking if there was a possibility to readout the printer toner status using SNMP.

For those who don't know what SNMP is :

The Simple Network Management Protocol (SNMP) forms part of the internet protocol suite as defined by the Internet Engineering Task Force (IETF). SNMP is used in network management systems to monitor network-attached devices for conditions that warrant administrative attention. It consists of a set of standards for network management, including an Application Layer protocol, a database schema, and a set of data objects.[1]

Source : http://en.wikipedia.org/wiki/Simple_Networ...gement_Protocol

In order to retrieve data from an SNMP device you need to read the MIB database structure.

For those who want to know more about MIB's :

A management information base (MIB) stems from the OSI/ISO Network management model and is a type of database used to manage the devices in a communications network. It comprises a collection of objects in a (virtual) database used to manage entities (such as routers and switches) in a network.

Objects in the MIB are defined using a subset of Abstract Syntax Notation One (ASN.1) called "Structure of Management Information Version 2 (SMIv2)" RFC 2578.The software that performs the parsing is a MIB compiler.

Source : http://en.wikipedia.org/wiki/Management_information_base

So the key to the lock is :

1. have the SNMP protocol communication = UDP 161

2. Read the MIB for the info you want to retrieve

The first thing is simple in AU3, create a UDF socket.

The second thing takes more time to dig.

Microsoft supplies by default some MIB file in your windows. Look in C:\Windows\System32\ for *.MIB files

Reading them is easy. Just open them in Notepad :) and read.

It contains a structure of hierarchy information which was defined occording to the RFC1213 and others.

So now what ?

You can query the some MIB object using WMI.

$strTargetSnmpDevice = "10.0.0.x" ; Device IP Address

$objWmiLocator = ObjCreate("WbemScripting.SWbemLocator")
$objWmiServices = $objWmiLocator.ConnectServer("", "rootsnmplocalhost")

$objWmiNamedValueSet = ObjCreate("WbemScripting.SWbemNamedValueSet")
$objWmiNamedValueSet.Add ("AgentAddress", $strTargetSnmpDevice)
$objWmiNamedValueSet.Add ("AgentReadCommunityName", "public")

$colIfTable = $objWmiServices.InstancesOf("SNMP_RFC1213_MIB_ifTable",Default , $objWmiNamedValueSet)

For $objInterface In $colIfTable
ConsoleWrite ("ifIndex [Key]: " & $objInterface.ifIndex & @CRLF & _
" ifAdminStatus: " & $objInterface.ifAdminStatus & @CRLF & _
" ifDescr: " & $objInterface.ifDescr & @CRLF & _
" ifInDiscards: " & $objInterface.ifInDiscards & @CRLF & _
" ifInErrors: " & $objInterface.ifInErrors & @CRLF & _
" ifInNUcastPkts: " & $objInterface.ifInNUcastPkts & @CRLF & _
" ifInOctets: " & $objInterface.ifInOctets & @CRLF & _
" ifInUcastPkts: " & $objInterface.ifInUcastPkts & @CRLF & _
" ifInUnknownProtos: " & $objInterface.ifInUnknownProtos & @CRLF & _
" ifLastChange: " & $objInterface.ifLastChange & @CRLF & _
" ifMtu: " & $objInterface.ifMtu & @CRLF & _
" ifOperStatus: " & $objInterface.ifOperStatus & @CRLF & _
" ifOutDiscards: " & $objInterface.ifOutDiscards & @CRLF & _
" ifOutErrors: " & $objInterface.ifOutErrors & @CRLF & _
" ifOutNUcastPkts: " & $objInterface.ifOutNUcastPkts & @CRLF & _
" ifOutOctets: " & $objInterface.ifOutOctets & @CRLF & _
" ifOutQLen: " & $objInterface.ifOutQLen & @CRLF & _
" ifOutUcastPkts: " & $objInterface.ifOutUcastPkts & @CRLF & _
" ifPhysAddress: " & $objInterface.ifPhysAddress & @CRLF & _
" ifSpecific: " & $objInterface.ifSpecific & @CRLF & _
" ifSpeed: " & $objInterface.ifSpeed & @CRLF & _
" ifType: " & $objInterface.ifType & @CRLF)
Next

Enjoy !!

regards

ptrex

Edited by ptrex

Share this post


Link to post
Share on other sites



@all

Some other usefull information :

This the packet structure if you want to get started yourself.

SNMP packet structure

Best is also to download a good MIB browser from the net that suits your needs.

Type MIB browser in google and you'll see miltiple appear.

regards

ptrex

Share this post


Link to post
Share on other sites

Thanks allot Ptrex its perfect !:)

How can I thank you ?

Best Regards

Boodo

Share this post


Link to post
Share on other sites

Give me Your Adress and I Will send you german beer :)

But the time it takes to you it will be warm :(

The script has only one bug. The sequence wich is generated is to short so it doesen`t work. But with the explain of you i`am on the right way.

Share this post


Link to post
Share on other sites

@boodo

I have tested this on a HP 4005 Color Laserprinter,and it got a hit.

Ofcourse my example is not for generic use as you know by now.

You first need to get the correct MIB file for you device or vendor. Than investigate what the OjectID is you are looking for.

Adjust the script accordingly and that's it.

PS : Wat the beer concerns. I'llck it up when I am in the neighbourhood.

regards,

ptrex

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

The Mib is not the Problem The Translation to binary seems to be wrong.....

When i Comment the this line:

$cmd = "0x302B02010004067075626C6963A01E0202014402010002010030123010_060C2B060104010B0204030102000500"

The Sequence seems to be wrong....

The string wich its createt looks: 0x315075626C69633130303631343131313234333132300

When i test the $_ObhectID i became: 0x363134313131323433313230

But it should be: 060C2B060104010B0204030102000500

Edited by boodo

Share this post


Link to post
Share on other sites

Hello,

In order to give nice ideas to others, here is my -crap- code (Thanks to PTREX for his help) to manage toner

capacity on XEROX Phaser 4510

CODE

#include <string.au3>

Dim $IP_ADDRESS

$IP_ADDRESS = "10.33.134.84"

$PORT = "161"

$TONER_MAX = "0x302B02010004067075626C6963A01E0202014402010002010030123010060C2B060102012B0B01010801010500"

$TONER_MAX_RESULT_LENGHT = 4

$TONER_CURRENT = "0x302B02010004067075626C6963A01E0202014402010002010030123010060C2B060102012B0B01010901010500"

$TONER_CURRENT_RESULT_LENGHT = 4

$result_max_toner=getsnmp($IP_ADDRESS,$TONER_MAX,$TONER_MAX_RESULT_LENGHT)

$result_current_toner=getsnmp($IP_ADDRESS,$TONER_CURRENT,$TONER_CURRENT_RESULT_LENGHT)

$CAPACITY_PER_CENT = Round((($result_current_toner * 100) / $result_max_toner),2)

MsgBox(1,"IP Address : " &$IP_ADDRESS,"Max Capacity: " & $result_max_toner & @CRLF & "Current Capacity : " & $result_current_toner & @CRLF & "Per cent: " & $CAPACITY_PER_CENT & "%")

Func getsnmp($IP_ADDRESS,$CMD,$MAXRESULT)

UDPStartUp()

$Start = 1

$Socket = UDPopen($IP_ADDRESS, $Port)

UDPSend($Socket, $CMD)

While (1)

$srcv = UDPRecv($Socket, 2048)

If ($srcv <> "") Then

$result_getsnmp=Dec(stringright($srcv,$MAXRESULT))

Return $result_getsnmp

ExitLoop

EndIf

sleep(100)

WEnd

UDPCloseSocket($Socket)

UDPShutdown()

EndFunc

Enjoy :)

Share this post


Link to post
Share on other sites

Hi Ptrex

Can you explain

$cmd = "0x302B02010004067075626C6963A01E0202014402010002010030123010060C2B060104010B0204030102000500"

Because when I try to adapt the script with

$_Version = StringToBinary("1") ; SNMPInteger(Version)

$_Community = StringToBinary("public") ; SNMPString(Community)

$_RequestID = StringToBinary("1") ; 0x30549f5c ; SNMPInteger(RequestID)

$_Error = StringToBinary("0") ; SNMPInteger(Error)

$_Index = StringToBinary("0") ; SNMPInteger(Index)

$_ObjectID = StringToBinary("6141967913122010")

I get a strange $cmd which don't work.

What is this part ...302B0201000406...

this one 7075626C6963 suppose to be "public".

But after I don't understand.

Thank for your help

Regards

Share this post


Link to post
Share on other sites

@starship616

You can ignore that part. This was trial and error.

$_Version = StringToBinary("1") ; SNMPInteger(Version)
$_Community = StringToBinary("public") ; SNMPString(Community) 
$_RequestID = StringToBinary("1") ; 0x30549f5c ; SNMPInteger(RequestID) 
$_Error = StringToBinary("0") ; SNMPInteger(Error) 
$_Index = StringToBinary("0") ; SNMPInteger(Index) 
$_ObjectID = StringToBinary("6141967913122010")oÝ÷ Ù8b²+-è(¡Ü(®H§Éjëh×6$cmd = "0x302B02010004067075626C6963A01E0202014402010002010030123010060C2B060104010B0204030102000500"

regards

ptrex

Share this post


Link to post
Share on other sites

@starship616

You can ignore that part. This was trial and error.

$_Version = StringToBinary("1") ; SNMPInteger(Version)
$_Community = StringToBinary("public") ; SNMPString(Community) 
$_RequestID = StringToBinary("1") ; 0x30549f5c ; SNMPInteger(RequestID) 
$_Error = StringToBinary("0") ; SNMPInteger(Error) 
$_Index = StringToBinary("0") ; SNMPInteger(Index) 
$_ObjectID = StringToBinary("6141967913122010")oÝ÷ Ù8b²+-è(¡Ü(®H§Éjëh×6$cmd = "0x302B02010004067075626C6963A01E0202014402010002010030123010060C2B060104010B0204030102000500"

regards

ptrex

@PTREX

Thanks for your answer,

In fact I'm trying to send and get answer for this OID '1.3.6.1.4.1.9679.1.31.2.406.0', but I don't understand how to change the $cmd to insert this OID.

Regards

Share this post


Link to post
Share on other sites

@PTREX

Thanks for your answer,

In fact I'm trying to send and get answer for this OID '1.3.6.1.4.1.9679.1.31.2.406.0', but I don't understand how to change the $cmd to insert this OID.

Regards

I fund a way to get and send the right hex string

Thanks for your help

Share this post


Link to post
Share on other sites

@starship616

Please share how you managed to get the correct hex string for the OID.

Thanks!

Share this post


Link to post
Share on other sites

@starship616

Please share how you managed to get the correct hex string for the OID.

Thanks!

You could try my bit of code here

CODE

;--------------------------------

Func _SysObjIDToHexString($Input)

;--------------------------------

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)

Next

Return $Output

EndFunc


My Scripts[topic="73325"]_ReverseDNS()[/topic]Favourite scripts by other members[topic="81687"]SNMP udf[/topic][topic="70759"]Using SNMP - MIB protocol[/topic][topic="39050"]_SplitMon:Section off your monitor!, split your monitor into sections for easy management[/topic][topic="73425"]ZIP.au3 UDF in pure AutoIt[/topic][topic="10534"]WMI ScriptOMatic tool for AutoIt[/topic][topic="51103"]Resources UDF embed/use any data/files into/from AutoIt compiled EXE files[/topic]

Share this post


Link to post
Share on other sites

Thx rogdog I appreciate your input. I tried the code and I managed to covert the OID, so far so good. The only problem left is that I seem to be a SNMP dummy :) now I have to figure out how to automaticly create the part before the OID as well.

Share this post


Link to post
Share on other sites

you are not the only dummy.

I have several printers to monitor and this post sound very usefull. (HP, Xerox, Brother and Cannon printers

once I learn how the communication works, I plan on making an app that monitors these printers for tonerstatus and other maintainance (drum, fuser etz)

brunal's code for the xerox return some values for my xerox (phaser 6360n) which is colour istead of black. (nut sure for what but proberbly black toner)

So I start working on deciffering the cmd block of code.

Where did you all get those blocks of codes????

So far I understand that:

the 1st byte is 0x30

and the whole thing is terminated by a 0x0500 (null)

and that the OID string is put just before the termination(null)

this page helped me a bit to understand whats going on, maybe some of you can "deciffer" some more information, and teach the rest of us.

http://www.henrys.de/daniel/index.php?cmd=...insock/SNMP.HTM

Regarding MIB:

I used ireasoning MIB browser (you can load MIBS into it)

- I downloaded a MIB from xerox and loaded it into the browser

- it lets you do a walk to (makes all the querys in the mib to the device)

it didn't tell me there to find the remaining toner for a specific colour yet, but then again I don't even know how to make that query yet either.

hopefully some of us will get some thing out of all this..

best regards MiMo


Best Regards Mimo

Share this post


Link to post
Share on other sites

Hi all,

@Mimo, the OID values used works for black & white printers (HP & Xerox as far as it uses standard RFC mibs for printers)

the thing on color printers (we've got 8560N) is that the printer tests if there is any toner in.

The first drawing given py PTREX is very useful, link : http://www.rane.com/swf/n161fig5.swf

other advice I can give you is using ireasonning (free mib browser), wireshark (free network monitor to understand clearly how the SNMP frame is built)

I think that the main problem for most of people here is calculating different checksums of SNMP frame.

Holidays are coming and I hope not to be so busy and try to make a small tut' for that.

For my part, I didn't understand very well how to get the exact length of response :) will work on it later.

Have fun

Share this post


Link to post
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