PureBasic

Forums PureBasic
Nous sommes le Sam 08/Aoû/2020 19:03

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 7 messages ] 
Auteur Message
 Sujet du message: SNMP WinAPI - Conversion d'un code C++
MessagePosté: Mar 04/Fév/2020 8:15 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 28
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...


Dernière édition par tatanas le Mer 05/Fév/2020 10:42, édité 2 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SNMP WinAPI - Conversion d'un code C++
MessagePosté: Mar 04/Fév/2020 13:53 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 9016
Citation:
mais printf() avec des formats est utilisé et là je ne connais pas

Salut..
J'ai pas bien compris ta phrase.
Tu peux écrire un exemple concret

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.6x / 5.7x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SNMP WinAPI - Conversion d'un code C++
MessagePosté: Mar 04/Fév/2020 16:12 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1840
tatanas 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...

Si c'est juste printf(), ça fonctionne exactement comme FormatDate() et FormatNumber() mais avec plus de type de formats
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) :wink:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SNMP WinAPI - Conversion d'un code C++
MessagePosté: Mar 04/Fév/2020 17:45 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 28
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' ?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SNMP WinAPI - Conversion d'un code C++
MessagePosté: Mar 04/Fév/2020 19:18 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 28
Petite amélioration au niveau du WALK. Remplacez la procédure CreatePduSendRequest par celle-ci :
Code:
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

Ces pointeurs de byte array restent toujours un problème.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SNMP WinAPI - Conversion d'un code C++
MessagePosté: Mer 05/Fév/2020 10:42 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 28
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é.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: SNMP WinAPI - Conversion d'un code C++
MessagePosté: Mer 05/Fév/2020 22:12 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 9016
J'avoue que les pointeurs j'ai jamais été bien copain avec. Je ne peux pas t'aiguiller.

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.6x / 5.7x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 7 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye