begin process at 2012 02 13 01:14:12
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Réseaux & Internet

 > RÉCEPTION DE TRAPS SNMP EN QUELQUES LIGNES DE C++ AVEC L'API DE WINDOWS

RÉCEPTION DE TRAPS SNMP EN QUELQUES LIGNES DE C++ AVEC L'API DE WINDOWS


 Description

Voici un exemple de programme permettant de recevoir des traps SNMP sous Windows, en utilisant l'API disponible, en C/C++.
Cet exemple servira à tous ceux qui, comme moi, pensaient que c'est difficile alors que quelques lignes suffisent.

Brève description de SNMP : SNMP sert à dialoguer avec des composants réseaux, ou autres. Le type de dialogue est défini par une arborescence qu'on appelle MIB, faisant l'objet d'une normalisation, mais que je ne détaillerai pas ici.

Je suggère la lecture des ouvrages disponibles, tels :
"Essential SNMP, 2nd Edition" de Douglas R.MAURO & Kevin J. SCHIMDT aux éditions O'REILLY. ISBN: 0-596-00840-6. ISBN13: 978-0-596-00840-6.
Vous trouverez dedans toute la description du protocole.
Traps SNMP : Tout composant utilisant SNMP peut envoyer des informations "spontanées", vers tous les composants/ordinateurs qui sont déclarés dans sa configuration. L'envoi est fait en UDP, sans garantie de délivrance. Si le programme destinataire n'est pas à l'écoute, le message est perdu sans que l'émetteur le sache.
Les traps SNMP sont utilisés pour informer que "quelque chose" s'est passé, c'est le récepteur qui doit savoir décoder le message, suivant la MIB, ou sans en tenir compte, dans ce cas le récepteur peut très bien n'utiliser que le texte "en clair" contenu dans le message trap.

L'exemple que je fournis va dans ce sens : j'utilise tout ce qui vient, avec un décodage automatique, et peu importe si c'est mal formaté. A vous de voir si vous avez besoin de plus de formalisme.
Je me suis servi des exemples du site http://www.winsnmp.com/samples/c/index.htm,
j'ai juste adapté pour que ça tourne dans une fenêtre Windows.
Le compilateur utilisé est C++ Builder 6, mais tout bon compilateur C est utilisable.
Il faut que le service SNMP soit activé sous Windows, si ce n'est pas le cas :
Démarrer, Paramètres, Panneau de configuration, Ajout/Sup de prog, Composants de Windows, Outils de gestion et d'analyse, détails, cocher : SNMP.

Source

  • //---------------------------------------------------------------------------
  • //Exemple de réception de traps SNMP sous Windows
  • //Ce programme nécessite C++ Builder 6 ou suivant pour fonctionner
  • // mais il peut être adapté pour fonctionner avec n'importe quel compilateur C
  • //
  • //(C) UPUS 2008 par JC CHARRETEUR
  • // Ce programme très simple est dérivé des sources fournis à l'adresse :
  • // http://www.winsnmp.com/samples/c/index.htm
  • //
  • // =====================================================================
  • // == Ce programme est fourni à titre d'exemple, sans garantie aucune ==
  • // == Il est gratuit, sous licence GNU, aucune rémunération ne peut ==
  • // == être demandée pour la partie adaptée dans cet exemple. ==
  • // =====================================================================
  • //
  • //---------------------------------------------------------------------------
  • // Ce programme fonctionne sous Windows XP, Vista, 2000, 2003...
  • // Il montre comment recevoir et décoder des traps SNMP en quelques lignes seulement.
  • //
  • //---------------------------------------------------------------------------
  • #include <vcl.h>
  • #include <stdio.h>
  • #include <winsnmp.h>
  • #pragma hdrstop
  • #include "Base.h"
  • #include "Val2Str.h"
  • //---------------------------------------------------------------------------
  • #pragma package(smart_init)
  • #pragma resource "*.dfm"
  • TBaseWindow *BaseWindow;
  • HANDLE xWait;
  • SNMPAPI_STATUS Val2Str(smiLPVALUE Value, smiUINT32 Size, LPSTR lpString);
  • SNMPAPI_STATUS CALLBACK cbFuncWaitTrap
  • (HSNMP_SESSION hSession, HWND hWnd, UINT wMsg,
  • WPARAM wParam, LPARAM lParam, LPVOID lpClientData);
  • //---------------------------------------------------------------------------
  • //---------------------------------------------------------------------------
  • //---------------------------------------------------------------------------
  • //Déclaration ici pour fonctions hors contexte
  • // Ces fonctions peuvent être appelées depuis la fonction "registered",
  • // qui n'a pas besoin de connaître notre fenêtre de base
  • void __fastcall ClearStatusLine(void)
  • {
  • BaseWindow->ClearStatusLine();
  • }
  • void __fastcall Logging(AnsiString S)
  • {
  • BaseWindow->Logging(S);
  • }
  • void __fastcall Alert(AnsiString S)
  • {
  • BaseWindow->Alert(S);
  • }
  • //---------------------------------------------------------------------------
  • SNMPAPI_STATUS CALLBACK cbFuncWaitTrap
  • (HSNMP_SESSION hSession, HWND hWnd, UINT wMsg,
  • WPARAM wParam, LPARAM lParam, LPVOID lpClientData)
  • {
  • HSNMP_PDU hPdu;
  • HSNMP_VBL hVbl;
  • smiOID dName;
  • smiVALUE dValue;
  • smiUINT32 nVb;
  • smiINT32 lReqId;
  • smiINT32 lType, lErr, lIdx;
  • smiINT32 lStat;
  • smiUINT32 i;
  • char szName[64];
  • char szValue[80];
  • char Texte[LGTEXTE];
  • //
  • if (wParam != 0) // Invalid state for trap messages
  • {
  • sprintf (Texte, "Invalid WinSNMP message: wParam = %d, lParam = %d",
  • wParam, lParam);
  • Alert(Texte);
  • return SNMPAPI_SUCCESS;
  • }
  • lStat = SnmpRecvMsg (hSession, NULL, NULL, NULL, &hPdu);
  • if (lStat != SNMPAPI_SUCCESS)
  • {
  • printf ("SnmpRecvMsg() failed");
  • return 0;
  • }
  • lStat = SnmpGetPduData (hPdu, &lType, &lReqId, &lErr, &lIdx, &hVbl);
  • if (lStat != SNMPAPI_SUCCESS)
  • {
  • sprintf(Texte, "SnmpGetPduData() failed");
  • Alert(Texte);
  • return 0;
  • }
  • sprintf (Texte, "Trap RequestId = %u", lReqId);
  • Logging(Texte);
  • nVb = SnmpCountVbl (hVbl);
  • for (i=0; i<nVb; i++)
  • {
  • lStat = SnmpGetVb (hVbl, i+1, &dName, &dValue);
  • lStat = SnmpOidToStr (&dName, sizeof(szName), szName);
  • lStat = Val2Str (&dValue, sizeof(szValue), szValue);
  • sprintf (Texte, "%s: %s", szName, szValue);
  • Logging(Texte);
  • lStat = SnmpFreeDescriptor (SNMP_SYNTAX_OID, (smiLPOPAQUE)&dName);
  • lStat = SnmpFreeDescriptor (dValue.syntax,
  • (smiLPOPAQUE)&dValue.value.oid);
  • } // end_for
  • lStat = SnmpFreeVbl (hVbl);
  • lStat = SnmpFreePdu (hPdu);
  • return SNMPAPI_SUCCESS;
  • }
  • //---------------------------------------------------------------------------
  • //Cette fonction est recopiée quasiment telle quelle depuis l'exemple initial
  • SNMPAPI_STATUS Val2Str (smiLPVALUE Value, smiUINT32 Size, LPSTR lpString)
  • {
  • // Time formatting defines
  • #define DAY (24L*60L*60L)
  • #define HOUR (60L*60L)
  • #define MINUTE (60L)
  • #define HUNDRED (100L)
  • smiUINT32 lDays = 0;
  • smiUINT32 lHours = 0;
  • smiUINT32 lMinutes = 0;
  • smiUINT32 lSeconds = 0;
  • smiUINT32 lHundreths = 0;
  • //
  • smiUINT32 i, j;
  • ULARGE_INTEGER c64;
  • smiBYTE cB;
  • if (!Size) return (0); // need some string to return value
  • // actually need more tests on remaining output string length!!!
  • lpString[0] = '\0'; // initialize default return value
  • switch (Value->syntax)
  • {
  • case SNMP_SYNTAX_INT:
  • ltoa ((long)Value->value.sNumber, lpString, 10);
  • break;
  • // Note that a case for SNMP_SYNTAX_UINT32 is no longer included
  • // because in SMIv2 it is indistinguishable from SNMP_SYNTAX_GAUGE32
  • case SNMP_SYNTAX_CNTR32:
  • case SNMP_SYNTAX_GAUGE32:
  • ultoa ((long)Value->value.uNumber, lpString, 10);
  • break;
  • case SNMP_SYNTAX_TIMETICKS:
  • if (Value->value.uNumber != 0)
  • {
  • lHundreths = Value->value.uNumber % HUNDRED;
  • lSeconds = Value->value.uNumber / HUNDRED;
  • if (lSeconds !=0)
  • {
  • lDays = lSeconds / DAY;
  • lSeconds %= DAY;
  • if (lSeconds != 0)
  • {
  • lHours = lSeconds / HOUR;
  • lSeconds %= HOUR;
  • if (lSeconds != 0)
  • {
  • lMinutes = lSeconds / MINUTE;
  • lSeconds %= MINUTE;
  • }
  • }
  • }
  • }
  • wsprintf (lpString, "%lu,%lu:%lu:%lu.%lu",
  • lDays, lHours, lMinutes, lSeconds, lHundreths);
  • break;
  • case SNMP_SYNTAX_OCTETS:
  • case SNMP_SYNTAX_BITS:
  • case SNMP_SYNTAX_OPAQUE:
  • if (Value->value.string.ptr)
  • {
  • BOOL fBinary = FALSE;
  • for (i=0; i<Value->value.string.len && i<Size-1; i++)
  • {
  • cB = Value->value.string.ptr[i];
  • if ((cB < 0x20 && (cB != 0x0A && cB != 0x0D)) || cB > 0x7E)
  • { // Out of range...
  • fBinary = TRUE; // it's some binary thing
  • break; // and we must hexify output
  • }
  • lpString[i] = cB;
  • }
  • lpString[i] = '\0';
  • if (fBinary)
  • {
  • for (i=0, j=0; i<Value->value.string.len && j<Size-1; i++, j+=3)
  • {
  • wsprintf (&lpString[j], "%02X-", Value->value.string.ptr[i]);
  • }
  • lpString[j-1] = '\0'; // Lose terminating '-' character
  • }
  • }
  • break;
  • case SNMP_SYNTAX_IPADDR:
  • case SNMP_SYNTAX_NSAPADDR:
  • if (Value->value.string.ptr)
  • {
  • for (i=0, j=0; i<Value->value.string.len && j<Size-1; i++)
  • {
  • wsprintf (&lpString[j], "%d.", Value->value.string.ptr[i]);
  • j = lstrlen (lpString);
  • }
  • lpString[j-1] = '\0'; // Lose terminating '.' character
  • }
  • break;
  • case SNMP_SYNTAX_OID:
  • SnmpOidToStr (&Value->value.oid, Size, lpString);
  • break;
  • case SNMP_SYNTAX_CNTR64:
  • #ifdef WIN32
  • // Convert big-endian to little-endian for x86 processors
  • c64.LowPart = Value->value.hNumber.lopart;
  • c64.HighPart = Value->value.hNumber.hipart;
  • wsprintf (lpString, "%I64u", c64);
  • #endif
  • #ifdef SOLARIS
  • memmove (&c64, &Value->value.hNumber, sizeof (ULARGE_INTEGER));
  • // c64.hipart=Value->value.hNumber.hipart;
  • // c64.lopart=Value->value.hNumber.lopart;
  • ulltostr (c64, lpString);
  • #endif
  • break;
  • case SNMP_SYNTAX_NULL:
  • default:
  • break;
  • } // switch
  • return (smiUINT32)lstrlen (lpString);
  • } // end_Val2Str
  • //---------------------------------------------------------------------------
  • //---------------------------------------------------------------------------
  • //---------------------------------------------------------------------------
  • //Cette fonction est "registered" au gestionnaire SNMP de Windows
  • // Quand l'initialisation est faite, le gestionnaire SNMP appelle
  • // cette fonction et lui passe ce qui a été reçu.
  • SNMPAPI_STATUS CALLBACK cbFuncSendMsg
  • (HSNMP_SESSION hSession,
  • HWND hWnd,
  • UINT wMsg,
  • WPARAM wParam,
  • LPARAM lParam,
  • LPVOID lpClientData)
  • {
  • char Texte[LGTEXTE];
  • if (wParam == 0) // Normal response
  • {
  • HSNMP_PDU hPdu;
  • HSNMP_VBL hVbl;
  • smiOID dName;
  • smiVALUE dValue;
  • smiUINT32 nVb;
  • smiINT32 lReqId;
  • smiINT32 lType, lErr, lIdx;
  • // smiINT32 lStat;
  • smiUINT32 i;
  • char szName[LGTEXTE];
  • char szValue[LGTEXTE];
  • SnmpRecvMsg(hSession, NULL, NULL, NULL, &hPdu);
  • SnmpGetPduData(hPdu, &lType, &lReqId, &lErr, &lIdx, &hVbl);
  • if (lErr != 0)
  • {
  • sprintf(Texte, "SNMP Error for RequestID = %d: Value = %d, Index = %d",
  • lReqId, lErr, lIdx);
  • Alert(Texte);
  • }
  • else
  • {
  • nVb = SnmpCountVbl(hVbl);
  • for (i = 0; i < nVb; i++)
  • {
  • SnmpGetVb(hVbl, i+1, &dName, &dValue);
  • SnmpOidToStr(&dName, sizeof(szName), szName);
  • Val2Str(&dValue, sizeof(szValue), szValue);
  • sprintf(Texte, "%s: %s", szName, szValue);
  • Logging(Texte);
  • SnmpFreeDescriptor(SNMP_SYNTAX_OCTETS, (smiLPOPAQUE)&dName);
  • SnmpFreeDescriptor(dValue.syntax, (smiLPOPAQUE)&dValue.value.oid);
  • } // end_for
  • } // end_else
  • SnmpFreeVbl(hVbl);
  • SnmpFreePdu(hPdu);
  • } // end_if wParam == 0
  • else
  • {
  • sprintf(Texte, "Request #%d timed out.", lParam);
  • Alert(Texte);
  • }
  • SetEvent(xWait);
  • return SNMPAPI_SUCCESS;
  • }
  • //---------------------------------------------------------------------------
  • __fastcall TBaseWindow::TBaseWindow(TComponent* Owner)
  • : TForm(Owner)
  • {
  • Init();
  • }
  • //---------------------------------------------------------------------------
  • void __fastcall TBaseWindow::Init (void)
  • {
  • SNMP_Connected = false;
  • }
  • //---------------------------------------------------------------------------
  • void __fastcall TBaseWindow::ClearStatusLine (void)
  • {
  • StatusBar->SimpleText = "";
  • }
  • //---------------------------------------------------------------------------
  • void __fastcall TBaseWindow::Logging(AnsiString S)
  • {
  • StatusBar->SimpleText = S;
  • LogWindow->Items->Add(S);
  • }
  • //---------------------------------------------------------------------------
  • void __fastcall TBaseWindow::Alert(AnsiString S)
  • {
  • ::Logging(S);
  • Application->MessageBox(S.c_str(), "Alert", MB_ICONEXCLAMATION);
  • }
  • //---------------------------------------------------------------------------
  • void __fastcall TBaseWindow::FormCreate(TObject */*Sender*/)
  • {
  • TimerInit->Enabled = true;//On laisse le temps d'afficher la fenêtre
  • }
  • //---------------------------------------------------------------------------
  • void __fastcall TBaseWindow::FormClose(TObject */*Sender*/,
  • TCloseAction &Action)
  • {
  • if (SNMP_Connected)
  • CloseSNMP();//Ferme correctement avant de quitter
  • }
  • //---------------------------------------------------------------------------
  • //On a laissé 1 peu de temps à Windows pour afficher la fenêtre
  • void __fastcall TBaseWindow::TimerInitTimer(TObject */*Sender*/)
  • {
  • TimerInit->Enabled = false;//Plus besoin
  • Logging("Ready.");
  • }
  • //---------------------------------------------------------------------------
  • bool __fastcall TBaseWindow::InitSNMP (void)
  • {
  • smiUINT32 lStat;
  • lStat = SnmpStartup(&lStat, &lStat, &lStat, &lStat, &lStat);
  • if (lStat == SNMPAPI_FAILURE)
  • {
  • Alert("Connexion SNMP initialization failed");
  • return false;
  • }
  • Logging("SNMP session initialized");
  • SNMP_Connected = true;
  • return true;
  • }
  • //---------------------------------------------------------------------------
  • bool __fastcall TBaseWindow::CloseSNMP (void)
  • {
  • // smiUINT32 lStat;
  • if (!SNMP_Connected)
  • return true;//Alread closed
  • SnmpClose(hSession);
  • SnmpCleanup();
  • SNMP_Connected = false;
  • return true;
  • }
  • //---------------------------------------------------------------------------
  • void __fastcall TBaseWindow::ActionClearLogExecute(TObject *Sender)
  • {
  • LogWindow->Items->Clear();
  • }
  • //---------------------------------------------------------------------------
  • //L'utilisateur demande à s'enregistrer pour recevoir les traps SNMP
  • // On déclare la fonction de réception,
  • // elle sera appelée par Windows à chaque fois qu'un trap SNMP sera reçu.
  • // Note : Plein de programmes peuvent s'enregistrer simultanément, tous reçoivent
  • // alors les mêmes messages
  • void __fastcall TBaseWindow::ActionReceiveTrapExecute(TObject */*Sender*/)
  • {
  • SNMPAPI_CALLBACK cB = &cbFuncWaitTrap;
  • smiUINT32 lM, lN, lL, lR, lX;
  • SNMPAPI_STATUS lStat;
  • char Texte[LGTEXTE];
  • if (!SNMP_Connected)
  • {
  • if (!InitSNMP())
  • return;
  • }//End if !Connecte
  • hSession = SnmpCreateSession(NULL, 0, cB, NULL);
  • if (hSession == SNMPAPI_FAILURE)
  • {
  • sprintf(Texte, "SnmpCreateSession failed!");
  • Alert(Texte);
  • return;
  • }
  • //Demande au service SNMP de Windows de nous appeler
  • // à chaque fois qu'un trap sera reçu.
  • lStat = SnmpRegister(hSession, NULL, NULL, NULL, NULL, SNMPAPI_ON);
  • if (lStat == SNMPAPI_FAILURE)
  • {
  • sprintf(Texte, "SnmpRegister failed!");
  • Alert(Texte);
  • }
  • }
  • //---------------------------------------------------------------------------
  • //End of Source
  • //---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//Exemple de réception de traps SNMP sous Windows
//Ce programme nécessite C++ Builder 6 ou suivant pour fonctionner
//  mais il peut être adapté pour fonctionner avec n'importe quel compilateur C
//
//(C) UPUS 2008 par JC CHARRETEUR
// Ce programme très simple est dérivé des sources fournis à l'adresse :
//     http://www.winsnmp.com/samples/c/index.htm
//
// =====================================================================
// == Ce programme est fourni à titre d'exemple, sans garantie aucune ==
// == Il est gratuit, sous licence GNU, aucune rémunération ne peut   ==
// ==   être demandée pour la partie adaptée dans cet exemple.        ==
// =====================================================================
//
//---------------------------------------------------------------------------
// Ce programme fonctionne sous Windows XP, Vista, 2000, 2003...
// Il montre comment recevoir et décoder des traps SNMP en quelques lignes seulement.
//
//---------------------------------------------------------------------------

#include <vcl.h>
#include <stdio.h>
#include <winsnmp.h>
#pragma hdrstop

#include "Base.h"
#include "Val2Str.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TBaseWindow *BaseWindow;
HANDLE xWait;

SNMPAPI_STATUS Val2Str(smiLPVALUE Value, smiUINT32 Size, LPSTR lpString);
SNMPAPI_STATUS CALLBACK cbFuncWaitTrap
   (HSNMP_SESSION hSession, HWND hWnd, UINT wMsg,
    WPARAM wParam, LPARAM lParam, LPVOID lpClientData);

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//Déclaration ici pour fonctions hors contexte
// Ces fonctions peuvent être appelées depuis la fonction "registered",
// qui n'a pas besoin de connaître notre fenêtre de base

void __fastcall ClearStatusLine(void)
{
 BaseWindow->ClearStatusLine();
}
void __fastcall Logging(AnsiString S)
{
 BaseWindow->Logging(S);
}
void __fastcall Alert(AnsiString S)
{
 BaseWindow->Alert(S);
}
//---------------------------------------------------------------------------
SNMPAPI_STATUS CALLBACK cbFuncWaitTrap
   (HSNMP_SESSION hSession, HWND hWnd, UINT wMsg,
    WPARAM wParam, LPARAM lParam, LPVOID lpClientData)
{
HSNMP_PDU hPdu;
HSNMP_VBL hVbl;
smiOID dName;
smiVALUE dValue;
smiUINT32 nVb;
smiINT32 lReqId;
smiINT32 lType, lErr, lIdx;
smiINT32 lStat;
smiUINT32 i;
char szName[64];
char szValue[80];
char Texte[LGTEXTE];

//
 if (wParam !=  0) // Invalid state for trap messages
  {
   sprintf (Texte, "Invalid WinSNMP message: wParam = %d, lParam = %d",
      wParam, lParam);
   Alert(Texte);
   return SNMPAPI_SUCCESS;
  }

 lStat = SnmpRecvMsg (hSession, NULL, NULL, NULL, &hPdu);
 if (lStat != SNMPAPI_SUCCESS)
  {
   printf ("SnmpRecvMsg() failed");
   return 0;
  }

 lStat = SnmpGetPduData (hPdu, &lType, &lReqId, &lErr, &lIdx, &hVbl);
 if (lStat != SNMPAPI_SUCCESS)
  {
   sprintf(Texte, "SnmpGetPduData() failed");
   Alert(Texte);
   return 0;
  }

 sprintf (Texte, "Trap RequestId = %u", lReqId);
 Logging(Texte);
 nVb = SnmpCountVbl (hVbl);
 for (i=0; i<nVb; i++)
 {
   lStat = SnmpGetVb (hVbl, i+1, &dName, &dValue);
   lStat = SnmpOidToStr (&dName, sizeof(szName), szName);
   lStat = Val2Str (&dValue, sizeof(szValue), szValue);
   sprintf (Texte, "%s: %s", szName, szValue);
   Logging(Texte);
   lStat = SnmpFreeDescriptor (SNMP_SYNTAX_OID, (smiLPOPAQUE)&dName);
   lStat = SnmpFreeDescriptor (dValue.syntax,
                               (smiLPOPAQUE)&dValue.value.oid);
 } // end_for
 lStat = SnmpFreeVbl (hVbl);
 lStat = SnmpFreePdu (hPdu);
 return SNMPAPI_SUCCESS;
}
//---------------------------------------------------------------------------
//Cette fonction est recopiée quasiment telle quelle depuis l'exemple initial

SNMPAPI_STATUS Val2Str (smiLPVALUE Value, smiUINT32 Size, LPSTR lpString)
{
// Time formatting defines
#define DAY       (24L*60L*60L)
#define HOUR      (60L*60L)
#define MINUTE    (60L)
#define HUNDRED   (100L)
smiUINT32 lDays = 0;
smiUINT32 lHours = 0;
smiUINT32 lMinutes = 0;
smiUINT32 lSeconds = 0;
smiUINT32 lHundreths = 0;
//
smiUINT32 i, j;
ULARGE_INTEGER c64;
smiBYTE cB;
if (!Size) return (0);  // need some string to return value
// actually need more tests on remaining output string length!!!
lpString[0] = '\0';     // initialize default return value
switch (Value->syntax)
   {
   case SNMP_SYNTAX_INT:
   ltoa ((long)Value->value.sNumber, lpString, 10);
   break;

   // Note that a case for SNMP_SYNTAX_UINT32 is no longer included
   // because in SMIv2 it is indistinguishable from SNMP_SYNTAX_GAUGE32
   case SNMP_SYNTAX_CNTR32:
   case SNMP_SYNTAX_GAUGE32:
   ultoa ((long)Value->value.uNumber, lpString, 10);
   break;

   case SNMP_SYNTAX_TIMETICKS:
   if (Value->value.uNumber != 0)
      {
      lHundreths = Value->value.uNumber % HUNDRED;
      lSeconds = Value->value.uNumber / HUNDRED;
      if (lSeconds !=0)
         {
         lDays = lSeconds / DAY;
         lSeconds %= DAY;
         if (lSeconds != 0)
            {
            lHours = lSeconds / HOUR;
            lSeconds %= HOUR;
            if (lSeconds != 0)
               {
               lMinutes = lSeconds / MINUTE;
               lSeconds %= MINUTE;
               }
            }
         }
      }
   wsprintf (lpString, "%lu,%lu:%lu:%lu.%lu",
             lDays, lHours, lMinutes, lSeconds, lHundreths);
   break;

   case SNMP_SYNTAX_OCTETS:
   case SNMP_SYNTAX_BITS:
   case SNMP_SYNTAX_OPAQUE:
   if (Value->value.string.ptr)
      {
      BOOL fBinary = FALSE;
      for (i=0; i<Value->value.string.len && i<Size-1; i++)
         {
         cB = Value->value.string.ptr[i];
         if ((cB < 0x20 && (cB != 0x0A && cB != 0x0D)) || cB > 0x7E)
               { // Out of range...
               fBinary = TRUE; // it's some binary thing
               break;          // and we must hexify output
               }
         lpString[i] = cB;
         }
      lpString[i] = '\0';
      if (fBinary)
         {
         for (i=0, j=0; i<Value->value.string.len && j<Size-1; i++, j+=3)
            {
            wsprintf (&lpString[j], "%02X-", Value->value.string.ptr[i]);
            }
         lpString[j-1] = '\0'; // Lose terminating '-' character
         }
      }
   break;

   case SNMP_SYNTAX_IPADDR:
   case SNMP_SYNTAX_NSAPADDR:
   if (Value->value.string.ptr)
      {
      for (i=0, j=0; i<Value->value.string.len && j<Size-1; i++)
         {
         wsprintf (&lpString[j], "%d.", Value->value.string.ptr[i]);
         j = lstrlen (lpString);
         }
      lpString[j-1] = '\0'; // Lose terminating '.' character
      }
   break;

   case SNMP_SYNTAX_OID:
   SnmpOidToStr (&Value->value.oid, Size, lpString);
   break;

   case SNMP_SYNTAX_CNTR64:
#ifdef WIN32
   // Convert big-endian to little-endian for x86 processors
   c64.LowPart = Value->value.hNumber.lopart;
   c64.HighPart = Value->value.hNumber.hipart;
   wsprintf (lpString, "%I64u", c64);
#endif
#ifdef SOLARIS
   memmove (&c64, &Value->value.hNumber, sizeof (ULARGE_INTEGER));
//   c64.hipart=Value->value.hNumber.hipart;
//   c64.lopart=Value->value.hNumber.lopart;
   ulltostr (c64, lpString);
#endif
   break;

   case SNMP_SYNTAX_NULL:
   default:
   break;
   } // switch

return (smiUINT32)lstrlen (lpString);
}  // end_Val2Str


//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//Cette fonction est "registered" au gestionnaire SNMP de Windows
// Quand l'initialisation est faite, le gestionnaire SNMP appelle
//   cette fonction et lui passe ce qui a été reçu.

SNMPAPI_STATUS CALLBACK cbFuncSendMsg
   (HSNMP_SESSION hSession,
    HWND          hWnd,
    UINT          wMsg,
    WPARAM        wParam,
    LPARAM        lParam,
    LPVOID        lpClientData)
{
 char Texte[LGTEXTE];

 if (wParam ==  0) // Normal response
  {
   HSNMP_PDU hPdu;
   HSNMP_VBL hVbl;
   smiOID    dName;
   smiVALUE  dValue;
   smiUINT32 nVb;
   smiINT32  lReqId;
   smiINT32  lType, lErr, lIdx;
//   smiINT32  lStat;
   smiUINT32 i;
   char      szName[LGTEXTE];
   char      szValue[LGTEXTE];

   SnmpRecvMsg(hSession, NULL, NULL, NULL, &hPdu);
   SnmpGetPduData(hPdu, &lType, &lReqId, &lErr, &lIdx, &hVbl);
   if (lErr != 0)
    {
      sprintf(Texte, "SNMP Error for RequestID = %d: Value = %d, Index =  %d",
               lReqId, lErr, lIdx);
      Alert(Texte);
    }
   else
    {
      nVb = SnmpCountVbl(hVbl);
      for (i = 0; i < nVb; i++)
      {
       SnmpGetVb(hVbl, i+1, &dName, &dValue);
       SnmpOidToStr(&dName, sizeof(szName), szName);
       Val2Str(&dValue, sizeof(szValue), szValue);
       sprintf(Texte, "%s: %s", szName, szValue);
       Logging(Texte);
       SnmpFreeDescriptor(SNMP_SYNTAX_OCTETS, (smiLPOPAQUE)&dName);
       SnmpFreeDescriptor(dValue.syntax,      (smiLPOPAQUE)&dValue.value.oid);
       } // end_for
    } // end_else

   SnmpFreeVbl(hVbl);
   SnmpFreePdu(hPdu);
  } // end_if wParam == 0
 else
  {
   sprintf(Texte, "Request #%d timed out.", lParam);
   Alert(Texte);
  }

 SetEvent(xWait);
 return SNMPAPI_SUCCESS;
}
//---------------------------------------------------------------------------

__fastcall TBaseWindow::TBaseWindow(TComponent* Owner)
	: TForm(Owner)

{
 Init();
}
//---------------------------------------------------------------------------

void __fastcall TBaseWindow::Init (void)
{
 SNMP_Connected = false;
}
//---------------------------------------------------------------------------

void __fastcall TBaseWindow::ClearStatusLine (void)
{
 StatusBar->SimpleText = "";
}
//---------------------------------------------------------------------------

void __fastcall TBaseWindow::Logging(AnsiString S)
{
 StatusBar->SimpleText = S;
 LogWindow->Items->Add(S);
}
//---------------------------------------------------------------------------

void __fastcall TBaseWindow::Alert(AnsiString S)
{
 ::Logging(S);
 Application->MessageBox(S.c_str(), "Alert", MB_ICONEXCLAMATION);
}
//---------------------------------------------------------------------------

void __fastcall TBaseWindow::FormCreate(TObject */*Sender*/)
{
 TimerInit->Enabled = true;//On laisse le temps d'afficher la fenêtre
}
//---------------------------------------------------------------------------

void __fastcall TBaseWindow::FormClose(TObject */*Sender*/,
      TCloseAction &Action)
{
 if (SNMP_Connected)
     CloseSNMP();//Ferme correctement avant de quitter
}
//---------------------------------------------------------------------------
//On a laissé 1 peu de temps à Windows pour afficher la fenêtre

void __fastcall TBaseWindow::TimerInitTimer(TObject */*Sender*/)
{
 TimerInit->Enabled = false;//Plus besoin
 Logging("Ready.");
}
//---------------------------------------------------------------------------

bool __fastcall TBaseWindow::InitSNMP (void)
{
 smiUINT32 lStat;

 lStat = SnmpStartup(&lStat, &lStat, &lStat, &lStat, &lStat);
 if (lStat == SNMPAPI_FAILURE)
  {
   Alert("Connexion SNMP initialization failed");
   return false;
 }

 Logging("SNMP session initialized");
 SNMP_Connected = true;
 return true;
}
//---------------------------------------------------------------------------

bool __fastcall TBaseWindow::CloseSNMP (void)
{
// smiUINT32 lStat;

 if (!SNMP_Connected)
   return true;//Alread closed

 SnmpClose(hSession);
 SnmpCleanup();

 SNMP_Connected = false;
 return true;
}
//---------------------------------------------------------------------------

void __fastcall TBaseWindow::ActionClearLogExecute(TObject *Sender)
{
 LogWindow->Items->Clear();
}
//---------------------------------------------------------------------------
//L'utilisateur demande à s'enregistrer pour recevoir les traps SNMP
// On déclare la fonction de réception,
//   elle sera appelée par Windows à chaque fois qu'un trap SNMP sera reçu.
// Note : Plein de programmes peuvent s'enregistrer simultanément, tous reçoivent
//        alors les mêmes messages

void __fastcall TBaseWindow::ActionReceiveTrapExecute(TObject */*Sender*/)
{
 SNMPAPI_CALLBACK cB = &cbFuncWaitTrap;
 smiUINT32 lM, lN, lL, lR, lX;
 SNMPAPI_STATUS lStat;
 char Texte[LGTEXTE];

 if (!SNMP_Connected)
  {
   if (!InitSNMP())
     return;
  }//End if !Connecte

 hSession = SnmpCreateSession(NULL, 0, cB, NULL);
 if (hSession == SNMPAPI_FAILURE)
  {
   sprintf(Texte, "SnmpCreateSession failed!");
   Alert(Texte);
   return;
  }

        //Demande au service SNMP de Windows de nous appeler
        // à chaque fois qu'un trap sera reçu.

 lStat = SnmpRegister(hSession, NULL, NULL, NULL, NULL, SNMPAPI_ON);
 if (lStat == SNMPAPI_FAILURE)
  {
   sprintf(Texte, "SnmpRegister failed!");
   Alert(Texte);
  }
}
//---------------------------------------------------------------------------
//End of Source
//---------------------------------------------------------------------------

 Conclusion

Ces quelques lignes de programme permettent de recevoir les traps SNMP sans se fatiguer, et sans avoir besoin de comprendre tout le protocole.

Le source complet du projet peut être téléchargé à l'adresse :
http://www.upus.fr/demo/rcv_snmp_traps.zip

Il faut les DLL de Borland pour exécuter :
http://www.upus.fr/demo/vcl60.zip

Bonne utilisation.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources de la même categorie

Source avec Zip Source avec une capture TRACEROUTE [WINPCAP] par ganjarasta
Source avec Zip SERVEUR MULTITHREAD [LINUX/WIN] par nipepsinicolas
Source avec Zip Source avec une capture SECURE REMOTE SHELL [WIN32] par ganjarasta
Source avec Zip Source avec une capture SUIVI DE PRODUCTION ONDULEUR PHOTOVOLTAÏQUE SOLARMAX par brunovan
Source avec Zip MINICHAT MULTI-CLIENT par wisar

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture POUR AFFICHER LES CARACTÈRES ACCENTUÉS SOUS WINDOWS EN MODE ... par pgl10
Source avec Zip Source avec une capture SOKOBAN EN C POUR DÉBUTANT (VERSION AMÉLIORÉE BASÉE SUR LE T... par eustatika
Source avec Zip [MYLIB] GESTION DE FICHIERS par Galaad2908
Source avec Zip PROTECTION AU DÉMARAGE DE WINDOWS ET PENDANT par daminator2
Source avec Zip MODIFIER RAPIDEMENT SON FICHIER HOST par sholvaC

Commentaires et avis

Commentaire de omnia le 25/07/2008 21:18:49

bonjour,

as-tu réussi a utilisé ces api en thread en effectuant plusieurs appels ?
chez moi ce genre d'utilisation ne le permet pas et je recherche :).

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Récupéré Trap SNMP avec la class CSocket [ par blasko370 ] Bonjour,Dans le cadre de mon BTS IRIS je dois réaliser une application qui récupererait les traps SNMP émise par un Autocommutateurs. Je précise que j Configurer l'agent SNMP d'un automate pour receuillir les TRAP [ par weedy78955 ] Bonjour à tous,Je travaille actuellement sur u nprojet mettant en oeuvre des automates programmables et le protocole SNMP.J'utilise un automate de che Par défaut [SNMP] Comment creer et envoyer une trap SNMP simplement en C [ par KurpeusLondon ] Bonjour, Je cherche a générer et envoyer une trap SNMP écrite en C de façon simple. J'utilise une liaison RS485 pour interroger un panneau de control snmpwalk API windows [ par Max77240 ] Bonjour à tous, Je travail avec VisualC++ 2008 et le l'API SNMP de Windows. J'aurais voulu savoir s'il est possible de faire l'équivalent d'un "snmpw comment afficher les windows form en plein ecran [ par emna77 ] Bonjour à tous, J'utilise les windows form avec visual c++. Je voudrais que les form s'affichent sur tout l'ecran comme le cas des jeux, j'ai trouvé Comment détecter Windows Update sous Windows 7 [ par PriMe2302 ] Bonjour, Je voudrais savoir comment détecter si Windows Update est lancé, entrain de vérifier les mises à jours, de les télécharger ou de les instal Changer une icône de fichier [ par calamsro ] BONJOUR Question toute simple car je savais faire. Hélas avec l'âge j'ai oublié. Je crée un fichier. Comment je peux lui attribuer une icône ( type, t [BAR]Problème avec mon dell m14x alienware ! [ par Tunechi ] Bonjour , je suis nouveau sur le site de codeS-SourceS donc n'hésitez pas à me corriger si je me trompe de thème ou autres ... Je demande votre aide DLL sous windows seven 64b [ par napadbol ] Bonjour, dans le cadre de mon boulot, on élabore des règles de conception mécanique et développons un freeware qui permet de les mettre en oeuvre ce q


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,203 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales