Page 1 of 1
SNMP WinAPI Example (Need help)
Posted: Sun Feb 02, 2020 11:41 am
by tatanas
Hi, Hi !
For a long time i'm looking for a way to use internal functions (not external app like net-snmp) to make a SNMP wrapper for questioning network devices.
I found nothing in PB so I searched in C++ and I found this code :
https://github.com/microsoft/Windows-cl ... Helper.Cpp
https://github.com/microsoft/Windows-cl ... mpUtil.Cpp
https://github.com/microsoft/Windows-cl ... SnmpUtil.h
Header with all the constants/structures :
http://www.naic.edu/~phil/hardware/vert ... /winsnmp.h
Here is my attempt to translate it in PureBasic :
http://s000.tinyupload.com/?file_id=028 ... 9679928152
Archive files : conversionSNMP.pb, conversionSNMP_DEF.pbi and the 3 required libraries mgmtapi.lib, snmpapi.lib, wsnmp32.lib
EDIT : Archive reuploaded : Ive got response from device agent (a printer). The Get request works (at least under Wireshark). However the program still hangs at SnmpRecvMsg() function.
EDIT2 : I receive the message and the only thing to finish is the format of output result : PrintOidValue()
EDIT3 : Archive updated. Before the print of the result I will have to understand the smiOCTETS and smiOID structure to handle more than one result.
EDIT4 : Archive updated again. And it works pretty well !!!
I will greatly appreciate some help.
Thanks.
P.S : I'm using Windows 7 64bits and Purebasic 64bits compiler.
Re: SNMP WinAPI Example (Need help)
Posted: Sun Feb 02, 2020 4:06 pm
by infratec
You didn't searched enough:
viewtopic.php?f=13&t=17512&hilit=snmp
I also did snmp stuff in PB, but I think it's only v1.
I don't know the original source, but I think Michael Vogel was also involved.
But it is at work and not at home.
I'll publish the code tommorow.
Re: SNMP WinAPI Example (Need help)
Posted: Sun Feb 02, 2020 6:06 pm
by tatanas
Thanks for the link but I already tested this code and it doesn't work for me (I verify with Snmpb in parallel).
EDIT : got some results with the C++ conversion code :
Wireshark tells me that the message is send to the agent but there is no OID bind to it... Let's dig deeper
EDIT 2 : OID ok and response from a Get request without error. Program still hangs and crashes at SnmpRecvMsg() function... - RESOLVED : POINTER PROBLEM
EDIT 3 : There is an error with SetWindowLongPtr_(*pSession\hWnd, 0, *pSession). It returns 0 and getlasterror too. So I don't know if it's the source of the problem. However the *pSession pointer is passed correctly to the NotificationWndProc callback function. - SEEMS NORMAL
Re: SNMP WinAPI Example (Need help)
Posted: Tue Feb 04, 2020 1:07 pm
by tatanas
It's almost working ! (archive updated)
EDIT : More important, how should I declare the 'ptr' variable of smiOCTETS and smiOID structures ?
EDIT2 : Change this procedure to get a partially working 'WALK'
Code: Select all
Procedure CreatePduSendRequest(*pSession.SNMP_MGR_SESSION, *pValue.smiVALUE)
; check For the validity of the Structure
If *pSession = #Null
ProcedureReturn #False
EndIf
; set the pdu type
Select gVars\operation
Case "GET"
*pSession\nPduType = #SNMP_PDU_GET
Case "GET_NEXT"
*pSession\nPduType = #SNMP_PDU_GETNEXT
Case "WALK"
*pSession\nPduType = #SNMP_PDU_GETNEXT
Case "SET"
*pSession\nPduType = #SNMP_PDU_SET
Case "SUB_TREE"
*pSession\nPduType = #SNMP_PDU_GETNEXT
Case "GET_BULK"
*pSession\nPduType = #SNMP_PDU_GETBULK
EndSelect
; first time around, walk: always use the first oid
If (gVars\nRequestId = 1) And (gVars\operation = "WALK" Or gVars\operation = "SUB_TREE") ; Or ( gVars\operation = #GET_BULK ) ) )
If SnmpStrToOid(gVars\pszOid[0], @gVars\oid) = #SNMPAPI_FAILURE
If SnmpMgrStrToOid(gVars\pszOid[0], @gVars\oid) = #False
Debug "snmputil: Failed in SnmpStrToOid( ) or SnmpMgrStrToOid( ) function"
ProcedureReturn #False
EndIf
Else
; copy the var bind
gVars\startOid = gVars\oid
EndIf
EndIf
; create the appropriate Varbind lists depending on the operation.
If gVars\operation = "WALK" Or gVars\operation = "SUB_TREE"
If CreateVbl(*pSession, @gVars\oid, #Null) = #False
ProcedureReturn #False
EndIf
ElseIf gVars\operation = "GET_NEXT" Or gVars\operation = "GET"
If SnmpStrToOid(gVars\pszOid[gVars\nRequestId - 1], gVars\oid) = #SNMPAPI_FAILURE
Debug "SnmpStrToOid failed : " + SnmpGetLastError(#Null) ; 9 = Invalid OID parameter, The string parameter is invalid
If SnmpMgrStrToOid(gVars\pszOid[gVars\nRequestId - 1], gVars\oid) = #False
Debug "SnmpMgrStrToOid failed"
ProcedureReturn #False
EndIf
EndIf
If CreateVbl(*pSession, @gVars\oid, #Null ) = #False
ProcedureReturn #False
EndIf
ElseIf gVars\operation = "SET"
*pSession\hVbl = SnmpCreateVbl(*pSession\hSnmpSession, @gVars\oid, *pValue)
ElseIf gVars\operation = "GET_BULK"
; CreateVbl first then add OIDs To the Vbl
*pSession\hVbl = SnmpCreateVbl(*pSession\hSnmpSession, ; handle To the WinSNMP session
#Null, ; pointer To the variable name
#Null) ; pointer To the value To associate With the variable
If *pSession\hVbl = #SNMPAPI_FAILURE
ProcedureReturn #False
EndIf
For i = 0 To gVars\oidCount - 1
; the very last gVars.oid in the loop will be freed later
If i > 0
SnmpFreeDescriptor(#SNMP_SYNTAX_OID, @gVars\oid)
EndIf
If SnmpStrToOid(gVars\pszOid[i], @gVars\oid) = #SNMPAPI_FAILURE
If SnmpMgrStrToOid(gVars\pszOid[i], @gVars\oid) = #False
Debug "snmputil: Failed in SnmpStrToOid( ) or SnmpMgrStrToOid( ) function"
ProcedureReturn #False
EndIf
EndIf
; append vb To Vbl
If SnmpSetVb(*pSession\hVbl, 0, @gVars\oid, #Null) = #SNMPAPI_FAILURE
Debug "snmputil: Failed in SnmpSetVb( ) function"
ProcedureReturn #False
EndIf
Next
EndIf
gVars\nRequestId = gVars\nRequestId + 1
*pSession\nRequestId = gVars\nRequestId
If gVars\operation = "GET_BULK"
error_status = gVars\non_repeaters
error_index = gVars\max_repetitions
Else
error_status = #Null
error_index = #Null
EndIf
; create a pdu using the parameters in pSession Structure
*pSession\hPdu = SnmpCreatePdu(*pSession\hSnmpSession, *pSession\nPduType, *pSession\nRequestId, error_status, error_index, *pSession\hVbl)
If *pSession\hPdu = #SNMPAPI_FAILURE
Debug "snmputil: Failed in creating PDU"
ProcedureReturn #False
EndIf
; send the message To the agent
*pSession\nError = SnmpSendMsg(*pSession\hSnmpSession, *pSession\hManagerEntity, *pSession\hAgentEntity, *pSession\hViewContext, *pSession\hPdu)
If gVars\operation <> "SUB_TREE"
SnmpFreeDescriptor(#SNMP_SYNTAX_OID, @gVars\oid)
EndIf
; check error status And Return
If *pSession\nError = #SNMPAPI_FAILURE
*pSession\nError = SnmpGetLastError(*pSession\hSnmpSession)
Debug "snmputil: Failed in send message, Last Error " + *pSession\nError
FreeVblandPdu(*pSession)
ProcedureReturn #False
Else
FreeVblandPdu(*pSession)
ProcedureReturn ProcessAgentResponse(*pSession)
EndIf
EndProcedure
The problem is still the smiOCTETS and smiVALUE structures...
Re: SNMP WinAPI Example (Need help)
Posted: Wed Feb 05, 2020 10:38 am
by tatanas
Archive updated.
GET, WALK and SUB_TREE requests work !
Got some problem with COUNTER64 Base Type because the smiCNTR64 structure should host high part and low part of this value. It didn't and I don't know why. I have to do it manually.