Bonjour tout le monde !
Je souhaiterais pouvoir requêter des périphériques réseaux en SNMP v2.
J'ai déjà des programmes fonctionnels qui utilisent les exécutables issus de Net-Snmp mais je voudrais le faire sans passer par des applications externes. J'ai repéré quelques scripts en Purebasic où les gens recréent les paquets entièrement mais je n'ai rien trouvé de fonctionnel (ou bien je m'y suis mal pris)
Après quelques recherches, je me suis rendu compte que Windows a une API dédiée (jusqu'au v2c). J'ai fouiné et trouvé un code C++ plutôt bien foutu et pas trop compliqué :
https://github.com/microsoft/Windows-cl ... Helper.Cpp
https://github.com/microsoft/Windows-cl ... mpUtil.Cpp
https://github.com/microsoft/Windows-cl ... SnmpUtil.h
Le header pour toutes les déclarations des constantes et structures : http://www.naic.edu/~phil/hardware/vert ... /winsnmp.h
Et voici le code adapté en PureBasic : http://s000.tinyupload.com/?file_id=028 ... 9679928152
(2 fichiers de code et les 3 librairies indispensables)
Alors normalement vous devriez avoir un plantage au bout de quelques secondes. Plantage qui provient de la fonction SnmpRecvMsg() sur laquelle je coince complètement.
Par contre en utilisant Wireshark ou équivalent, vous verrez que la requête Snmp est bien envoyée et que le retour fonctionne aussi (pour l'instant je n'ai testé qu'un simple GET).
Voilà ! Maintenant j'espère que vous pourrez m'aider à débugger ce programme.
En vous remerciant.
PS : J'utilise PureBasic en 64bits sur un Windows 7, ce sont donc les librairies 64 bits.
Edit : En compilant en 32 bits sous Windows 7 32 bits, j'ai une erreur "Invalid memory access. (write error at address 1)" au même endroit. Mais le tool Variable Viewer m'indique que les pointeurs passés en paramètre de SnmpRecvMsg se sont bien remplis sauf le *pSession\hpdu que je n'arrive pas à vérifier. Il semblerait que le plantage vienne bien de cette variable qui n'arrive pas à être remplie en sortie de la fonction.
Edit2 : c'est bon j'ai trouvé pourquoi ça plantait : une histoire de pointeurs... Il ne reste plus qu'à formater correctement le résultat mais printf() avec des formats est utilisé et là je ne connais pas. Si vous avez une idée...
SNMP WinAPI - Conversion d'un code C++
SNMP WinAPI - Conversion d'un code C++
Dernière modification par tatanas le mer. 05/févr./2020 10:42, modifié 2 fois.
Re: SNMP WinAPI - Conversion d'un code C++
Salut..mais printf() avec des formats est utilisé et là je ne connais pas
J'ai pas bien compris ta phrase.
Tu peux écrire un exemple concret
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Re: SNMP WinAPI - Conversion d'un code C++
Si c'est juste printf(), ça fonctionne exactement comme FormatDate() et FormatNumber() mais avec plus de type de formatstatanas a écrit :Il ne reste plus qu'à formater correctement le résultat mais printf() avec des formats est utilisé et là je ne connais pas. Si vous avez une idée...
Voir https://fr.wikipedia.org/wiki/Printf
Ça fait partie de la lite de souhaits (printf et surtout scanf qui permettrait de filtrer facilement les entrées utilisateurs)
Re: SNMP WinAPI - Conversion d'un code C++
Bon j'ai réuploadé l'archive avec le code qui fonctionne pour GET. Attention dans le code que je vous ai fourni, c'est un WALK que j'ai testé et qui ne fonctionne pas mais ça me parait normal car la structure smiOID est un peu particulière. Je ne vois pas trop comment gérer la variable "ptr" (Pointer to an array of unsigned long integers) https://docs.microsoft.com/en-us/window ... nmp-smioid . La structure smiOCTETS est d'ailleurs identique. Elles permettent de stocker plusieurs résultats et pour l'instant je n'en gère qu'un.
Une idée pour définir cette variable 'ptr' ?
Une idée pour définir cette variable 'ptr' ?
Re: SNMP WinAPI - Conversion d'un code C++
Petite amélioration au niveau du WALK. Remplacez la procédure CreatePduSendRequest par celle-ci :
Ces pointeurs de byte array restent toujours un problème.
Code : Tout sélectionner
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
Re: SNMP WinAPI - Conversion d'un code C++
Bon j'ai fini par réussir à faire fonctionner le GET, WALK et SUB_TREE (reste encore le GET_BULK qui m'intéresse).
J'ai mis à jour l'archive.
J'ai finalement réussi à accéder aux valeurs des structures qui m'embêtaient en jouant avec le pointeur de cette dernière et un décalage en fonction du type stocké.
J'ai mis à jour l'archive.
J'ai finalement réussi à accéder aux valeurs des structures qui m'embêtaient en jouant avec le pointeur de cette dernière et un décalage en fonction du type stocké.
Re: SNMP WinAPI - Conversion d'un code C++
J'avoue que les pointeurs j'ai jamais été bien copain avec. Je ne peux pas t'aiguiller.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels