Accueil > > > 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
Information sur la source
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.
Sources de la même categorie
Commentaires et avis
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
|
Derniers Blogs
[WP7] DYNAMICALLY CHANGE STARTUP PAGE[WP7] DYNAMICALLY CHANGE STARTUP PAGE par KooKiz
Let's say that you want to allow the user to customize the startup page of your application. You can easily change the startup page by editing the 'NavigationPage' attribute in the manifest file. But the manifest cannot be modified once the applicatio...
Cliquez pour lire la suite de l'article par KooKiz SESSION SILVERLIGHT 5 3D : SLIDES ET DEMOSSESSION SILVERLIGHT 5 3D : SLIDES ET DEMOS par Groc
Durant les techdays, j'ai eu le plaisir d'animer une session sur Silverlight 5 et la 3D avec Simon Ferquel. Comme promis, voici nos slides et mes démos (celles avec le viper BSG) ici et là. Pour mémoire, les démos utilisent toutes le viper BSG...
Cliquez pour lire la suite de l'article par Groc [TECHDAYS 2012] SESSION WEBMATRIX 2 : LE COUTEAU SUISSE GRATUIT POUR VOS DéVELOPPEMENTS WEB - SLIDES[TECHDAYS 2012] SESSION WEBMATRIX 2 : LE COUTEAU SUISSE GRATUIT POUR VOS DéVELOPPEMENTS WEB - SLIDES par gpommier
Suite à la session que j'ai présenté sur WebMatrix 2, vous pouvez trouver les slides ici, ainsi que les démos en packages nuget : démos1 et démos2 J'en profite pour remercier chaleureusement tous ceux qui sont venus très nombreux à cette sess...
Cliquez pour lire la suite de l'article par gpommier [SHAREPOINT] LES SESSIONS TECHDAYS 2012.[SHAREPOINT] LES SESSIONS TECHDAYS 2012. par Patrick Guimonet
Voici donc pour ceux qui n'ont pas pu venir, ou ceux qui n'ont pas pu toutes les suivre la liste des sessions SharePoint aux TechDays 2012, que je mettrais à jour dès que les liens des vidéo seront disponibles. Ou ici : http...
Cliquez pour lire la suite de l'article par Patrick Guimonet TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3 par ROMELARD Fabrice
Speaker: Bernard Ourghanlian Cette session est comme chaque jour transmise en live par BrainSonic, et j'ai donc suivi cette troisième pleinière par ce moyen sur mon iPad . Elle est dédiée comme chaque année à la mise en perspective de l'é...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
Tribler (2012)TRIBLER (2012)Tribler est un client pair à pair (P2P/Peer-to-Peer) open source avec la capacité de regarder des... Cliquez pour télécharger Tribler OneSwarm (2012)ONESWARM (2012)Le peer-to-peer qui protège votre vie privée, c'est OneSwarm.
Ce logiciel de peer-to-peer crypté... Cliquez pour télécharger OneSwarm PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V8.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V8.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning
|