Ce petit bout de code permet d'envoyer un trap SNMP vers un manager SNMP de votre choix. Ce mode de communication est celui utilisé par les équipements réseaux pour informer les aministrateurs des dysfonctionnements rencontrés et est de plus en plus répandu chez les éditeurs de logiciels car il a l'avantage d'être normalisé et donc géré par la quasi totalité des logiciels de supervision. La fonction GetIPAdress utilisée par mon code n'est pas de moi (il faut rendre à César...) mais un bout de code trouvé justement sur CodeS-SourceS.
Pour l'utiliser, mettre ce bout de code dans un module et faire appel à la fonction "SnmpTrap" en lui indiquant un composant Winsock que vous aurez préalablement créé.
Petite précision : Le paramètre "Variables" doit être un tableau de chaines de caractères (je l'ai déclaré en Variant sinon je ne pouvais pas utiliser l'instruction "IsMissing").
Pour simplifier le programme et rendre cette fonction facilement utilisable, je n'ai qu'un seul type de variables : des chaines de caractères (je n'utilise pas les types entiers, timestamp,... du protocole) sinon, ça rend la mise sous forme de fonction trop lourde et n'avait que peu d'intérêt dans la plupart des cas...
Pour ceux qui ne connaissent pas bien le protocole SNMP, les incontournables pour utiliser cette fonction sont :
- L'OID est une chaine de caractères représentant d'une part l'élément émetteur (un constructeur d'équipement, un éditeur de soft,...) et le problème (ou l'information) en question sous forme de numériques séparés par des ".". Les OIDs commencent toujours par ".1.3". Exemple : .1.3.6.1.4.1.482
- Le generic est un élément permettant de définir le type de problème. Dans notre cas (celui d'un programme tournant sur une machine), sa valeur est toujours égale à "6" (=trap d'entreprise) (mais si vous voulez simuler des messages de tombées d'interfaces réseau, vous le pouvez...). Valeur de 0 à 6
- Le specific est un sous-type du message et est uniquement intéressant que le generic vaut 6. A vous de le définir (valeur de 0 à 255)
- La communauté : j'utilise toujours la communauté "public", mais il est aussi possible de préciser "private" (jamais testé)
Pour plus de détails sur le protocole SNMP, il vous reste aussi les RFC...
Source / Exemple :
Public Type WSADATA
wVersion As Integer
wHighVersion As Integer
szDescription As String * 257
szSystemStatus As String * 129
iMaxSockets As Long
iMaxUdpDg As Long
lpVendorInfo As Long
End Type
Public Declare Function WSAStartup Lib "wsock32.dll" (ByVal wVersionRequested As Integer, lpWSAData _
As WSADATA) As Long
Public Declare Function WSACleanup Lib "wsock32.dll" () As Long
Public Type HOSTENT
h_name As Long
h_aliases As Long
h_addrtype As Integer
h_length As Integer
h_addr_list As Long
End Type
Public Const AF_INET = 2
Public Declare Function gethostbyname Lib "wsock32.dll" (ByVal name As String) As Long
Public Declare Function inet_ntoa Lib "wsock32.dll" (ByVal inaddr As Long) As Long
Public Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source _
As Any, ByVal length As Long)
Public Declare Function lstrlen Lib "kernel32.dll" Alias "lstrlenA" (ByVal lpString As Any) As Long
Public Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyA" (ByVal lpString1 As Any, ByVal _
lpString2 As Any) As Long
Public Type Var_snmp
Marq_seq As Byte
Len_tot As Byte
Len_tot1 As Byte
Len_tot2 As Byte
Type_oid As Byte
Len_oid As Byte
OID() As Byte
Type_var As Byte
Len_var As Byte
Len_var1 As Byte
Len_var2 As Byte
Var() As Byte
End Type
Public Type PaqSnmp
Entete As Byte
Longueur_Totale As Byte
Longueur_Totale1 As Byte
Longueur_Totale2 As Byte
Version_type As Byte 'toujours =2 (ENTIER)
Version_longueur As Byte 'toujours =1
Version As Byte 'toujours =0 (SNMP v1)
Comm_type As Byte
Comm_longueur As Byte
Community() As Byte
Type_snmp As Byte 'toujours=&HA4 (=envoi de trap)
Longueur_trap As Byte
Longueur_trap1 As Byte
Longueur_trap2 As Byte
ID_obj As Byte 'toujours=6 (=OID)
Longueur_OID As Byte
OID() As Byte
Addr_type As Byte
Addr_len As Byte
Addr(0 To 3) As Byte
Gen_type As Byte
Gen_len As Byte
Gen As Byte
Spe_type As Byte
Spe_len As Byte
Spe As Byte
Time_type As Byte
Time_len As Byte
TimeStick(0 To 3) As Byte
Marq_seq As Byte 'toujours=&H30
Len_var As Byte
Len_var1 As Byte
Len_var2 As Byte
Liste_var() As Var_snmp
End Type
Public Function MAKEWORD(ByVal bLow As Byte, ByVal bHigh As Byte) As Integer
MAKEWORD = Val("&H" & Right("00" & Hex(bHigh), 2) & Right("00" & Hex(bLow), 2))
End Function
Public Function GetIPAdress(ByVal HostName As String) As String
Dim sockinfo As WSADATA
Dim hostinfo As HOSTENT
Dim pHostinfo As Long
Dim pIPAddress As Long
Dim ipAddress As Long
Dim pIPString As Long
Dim ipString As String
Dim retval As Long
' Open up a Winsock session, using version 2.2.
retval = WSAStartup(MAKEWORD(2, 2), sockinfo)
If retval <> 0 Then
Debug.Print "ERROR: Attempt to open Winsock failed: error"; retval
GetIPAdress = "0.0.0.0"
Exit Function
End If
' Get information about the domain specified in txtDomain.
pHostinfo = gethostbyname(HostName)
If pHostinfo = 0 Then
GetIPAdress = "0.0.0.0"
Else
' Copy the data into a HOSTENT structure.
CopyMemory hostinfo, ByVal pHostinfo, Len(hostinfo)
If hostinfo.h_addrtype <> AF_INET Then
GetIPAdress = "0.0.0.0"
Else
' Copy the pointer to the first (and probably only) IP address in the structure.
CopyMemory pIPAddress, ByVal hostinfo.h_addr_list, 4
' Copy the actual IP address.
CopyMemory ipAddress, ByVal pIPAddress, 4
' Convert the IP address into a human-readable string.
pIPString = inet_ntoa(ipAddress)
' Copy the result into a string variable.
ipString = Space(lstrlen(pIPString))
retval = lstrcpy(ipString, pIPString)
' Print the result: a human-readable IP address.
GetIPAdress = ipString
End If
End If
' Close the Winsock session.
retval = WSACleanup()
End Function
Public Sub SnmpTrap(ByVal Community As String, ByVal OID As String, ByVal Generic As Integer, ByVal Specific As Integer, ByVal Destinataire As String, ByVal Source As String, Socket As Winsock, Optional ByVal Variables As Variant)
Dim Result() As Byte
Dim TmpStruct As PaqSnmp
Dim TbOID As Variant
Dim TbAdrSrc As Variant
Dim Isvariables As Boolean
Dim Taille_var As Long
Dim TmpTaille As Integer
Dim pos As Long
Dim i, j As Integer
Dim decrvar As Integer
Source = Trim(Source)
Destinataire = Trim(Destinataire)
Community = Trim(Community)
If IsMissing(Variables) Then
Isvariables = False
Else
Isvariables = True
End If
OID = Trim(OID)
If Specific > 255 Then Specific = 1
If Generic > 255 Then Generic = 1
If Community = "" Then Exit Sub
If (OID = "") Or Not (OID Like ".1.3.*") Then Exit Sub
If Destinataire = "" Or Source = "" Then Exit Sub
Source = GetIPAdress(Source)
TbAdrSrc = Split(Source, ".")
If UBound(TbAdrSrc) <> 3 Then Exit Sub
OID = Right(OID, Len(OID) - 5)
TbOID = Split(OID, ".")
With TmpStruct
.Entete = &H30
.Addr_type = &H40
.Addr_len = 4
For i = 0 To 3
.Addr(i) = TbAdrSrc(i)
Next i
.Comm_longueur = Len(Community)
.Comm_type = 4
ReDim .Community(0 To .Comm_longueur - 1)
For i = 0 To .Comm_longueur - 1
.Community(i) = Asc(Mid(Community, i + 1, 1))
Next i
.Gen = Generic
.Gen_len = 1
.Gen_type = 2
.ID_obj = 6
.Marq_seq = &H30
.Spe = Specific
.Spe_len = 1
.Spe_type = 2
.Time_len = 4
.Time_type = &H43
.TimeStick(0) = 0
.TimeStick(1) = 0
.TimeStick(2) = 0
.TimeStick(3) = 0
.Type_snmp = &HA4
.Version = 0
.Version_longueur = 1
.Version_type = 2
.Longueur_OID = UBound(TbOID) + 2
ReDim .OID(0 To .Longueur_OID - 1)
.OID(0) = &H2B
pos = 0
i = 1
While i <= UBound(.OID)
If Val(TbOID(pos)) > 127 Then
.Longueur_OID = .Longueur_OID + 1
ReDim Preserve .OID(0 To .Longueur_OID - 1)
.OID(i) = (TbOID(pos) \ 128) + 128
i = i + 1
.OID(i) = TbOID(pos) Mod 128
Else
.OID(i) = TbOID(pos)
End If
pos = pos + 1
i = i + 1
Wend
Taille_var = 0
decrvar = 0
If Isvariables Then
ReDim .Liste_var(0 To UBound(Variables) - LBound(Variables))
For i = 0 To UBound(.Liste_var)
.Liste_var(i).Marq_seq = &H30
Variables(i + LBound(Variables)) = Trim(Variables(i + LBound(Variables)))
If Len(Variables(i + LBound(Variables))) > 255 Then
.Liste_var(i).Len_var1 = Len(Variables(i + LBound(Variables))) \ 255
.Liste_var(i).Len_var2 = Len(Variables(i + LBound(Variables))) Mod 255
.Liste_var(i).Len_var = 130
Else
If Len(Variables(i + LBound(Variables))) > 127 Then
.Liste_var(i).Len_var1 = Len(Variables(i + LBound(Variables)))
.Liste_var(i).Len_var = 129
Else
.Liste_var(i).Len_var = Len(Variables(i + LBound(Variables)))
End If
End If
.Liste_var(i).Type_oid = 6
.Liste_var(i).Len_oid = .Longueur_OID + 1
ReDim .Liste_var(i).OID(0 To .Liste_var(i).Len_oid - 1)
.Liste_var(i).OID(0) = &H2B
For j = 1 To UBound(.OID)
.Liste_var(i).OID(j) = .OID(j)
Next j
.Liste_var(i).OID(UBound(.Liste_var(i).OID)) = i + 1
.Liste_var(i).Type_var = 4
If .Liste_var(i).Len_var > 0 Then
ReDim .Liste_var(i).Var(0 To Len(Variables(i + LBound(Variables))) - 1)
For j = 0 To UBound(.Liste_var(i).Var)
.Liste_var(i).Var(j) = Asc(Mid(Variables(i + LBound(Variables)), j + 1, 1))
Next j
End If
TmpTaille = Len(Variables(i + LBound(Variables))) + Val(.Liste_var(i).Len_oid) + 4
If TmpTaille > 255 Then
.Liste_var(i).Len_tot = 130
.Liste_var(i).Len_tot1 = TmpTaille \ 256
.Liste_var(i).Len_tot2 = TmpTaille Mod 256
Else
If TmpTaille > 127 Then
.Liste_var(i).Len_tot = 129
.Liste_var(i).Len_tot1 = TmpTaille
decrvar = decrvar - 1
Else
.Liste_var(i).Len_tot1 = 0
.Liste_var(i).Len_tot2 = TmpTaille
decrvar = decrvar - 2
End If
End If
Taille_var = Taille_var + TmpTaille + 4
Next i
End If
Taille_var = Taille_var + decrvar
If Taille_var > 255 Then
.Len_var = 130
.Len_var1 = Taille_var \ 256
.Len_var2 = Taille_var Mod 256
Taille_var = Taille_var + 24 + .Longueur_OID
Else
If Taille_var > 127 Then
.Len_var = 129
.Len_var1 = Taille_var
Taille_var = Taille_var + 23 + .Longueur_OID
Else
.Len_var1 = 0
.Len_var2 = Taille_var
Taille_var = Taille_var + 22 + .Longueur_OID
End If
End If
If Taille_var > 255 Then
.Longueur_trap = 130
.Longueur_trap1 = Taille_var \ 256
.Longueur_trap2 = Taille_var Mod 256
Taille_var = Taille_var + 9 + .Comm_longueur
Else
If Taille_var > 127 Then
.Longueur_trap = 129
.Longueur_trap1 = Taille_var
Taille_var = Taille_var + 8 + .Comm_longueur
Else
.Longueur_trap1 = 0
.Longueur_trap2 = Taille_var
Taille_var = Taille_var + 7 + .Comm_longueur
End If
End If
'Taille_var = Taille_var + 2
If Taille_var > 255 Then
.Longueur_Totale = 130
.Longueur_Totale1 = Taille_var \ 256
.Longueur_Totale2 = Taille_var Mod 256
ReDim Result(0 To Taille_var + 3)
Else
If Taille_var > 127 Then
.Longueur_Totale = 129
.Longueur_Totale1 = Taille_var
ReDim Result(0 To Taille_var + 2)
Else
.Longueur_Totale1 = 0
.Longueur_Totale2 = Taille_var
ReDim Result(0 To Taille_var + 1)
End If
End If
Result(0) = .Entete
If .Longueur_Totale = 130 Then
Result(1) = .Longueur_Totale
Result(2) = .Longueur_Totale1
Result(3) = .Longueur_Totale2
pos = 4
Else
If .Longueur_Totale = 129 Then
Result(1) = .Longueur_Totale
Result(2) = .Longueur_Totale1
pos = 3
Else
pos = 2
Result(1) = .Longueur_Totale2
End If
End If
Result(pos) = .Version_type
Result(pos + 1) = .Version_longueur
Result(pos + 2) = .Version
Result(pos + 3) = .Comm_type
Result(pos + 4) = .Comm_longueur
pos = pos + 5
For i = 0 To UBound(.Community)
Result(pos) = .Community(i)
pos = pos + 1
Next i
Result(pos) = .Type_snmp
If .Longueur_trap = 130 Then
Result(pos + 1) = .Longueur_trap
Result(pos + 2) = .Longueur_trap1
Result(pos + 3) = .Longueur_trap2
pos = pos + 4
Else
If .Longueur_trap = 129 Then
Result(pos + 1) = .Longueur_trap
Result(pos + 2) = .Longueur_trap1
pos = pos + 3
Else
Result(pos + 1) = .Longueur_trap2
pos = pos + 2
End If
End If
Result(pos) = .ID_obj
Result(pos + 1) = .Longueur_OID
pos = pos + 2
For i = 0 To UBound(.OID)
Result(pos) = .OID(i)
pos = pos + 1
Next i
Result(pos) = .Addr_type
Result(pos + 1) = .Addr_len
pos = pos + 2
For i = 0 To 3
Result(pos) = .Addr(i)
pos = pos + 1
Next i
Result(pos) = .Gen_type
Result(pos + 1) = .Gen_len
Result(pos + 2) = .Gen
Result(pos + 3) = .Spe_type
Result(pos + 4) = .Spe_len
Result(pos + 5) = .Spe
Result(pos + 6) = .Time_type
Result(pos + 7) = .Time_len
pos = pos + 8
For i = 0 To 3
Result(pos) = .TimeStick(i)
pos = pos + 1
Next i
Result(pos) = .Marq_seq
If .Len_var = 130 Then
Result(pos + 1) = .Len_var
Result(pos + 2) = .Len_var1
Result(pos + 3) = .Len_var2
pos = pos + 4
Else
If .Len_var = 129 Then
Result(pos + 1) = .Len_var
Result(pos + 2) = .Len_var1
pos = pos + 3
Else
Result(pos + 1) = .Len_var2
pos = pos + 2
End If
End If
If Isvariables Then
For i = 0 To UBound(.Liste_var)
Result(pos) = .Liste_var(i).Marq_seq
If .Liste_var(i).Len_tot = 130 Then
Result(pos + 1) = .Liste_var(i).Len_tot
Result(pos + 2) = .Liste_var(i).Len_tot1
Result(pos + 3) = .Liste_var(i).Len_tot2
pos = pos + 4
Else
If .Liste_var(i).Len_tot = 129 Then
Result(pos + 1) = .Liste_var(i).Len_tot
Result(pos + 2) = .Liste_var(i).Len_tot1
pos = pos + 3
Else
Result(pos + 1) = .Liste_var(i).Len_tot2
pos = pos + 2
End If
End If
Result(pos) = .Liste_var(i).Type_oid
Result(pos + 1) = .Liste_var(i).Len_oid
pos = pos + 2
For j = 0 To UBound(.Liste_var(i).OID)
Result(pos) = .Liste_var(i).OID(j)
pos = pos + 1
Next j
Result(pos) = .Liste_var(i).Type_var
If .Liste_var(i).Len_var = 130 Then
Result(pos + 1) = .Liste_var(i).Len_var
Result(pos + 2) = .Liste_var(i).Len_var1
Result(pos + 3) = .Liste_var(i).Len_var2
pos = pos + 4
ReDim Preserve Result(0 To UBound(Result) + 2)
Else
If .Liste_var(i).Len_var = 129 Then
Result(pos + 1) = .Liste_var(i).Len_var
Result(pos + 2) = .Liste_var(i).Len_var1
pos = pos + 3
ReDim Preserve Result(0 To UBound(Result) + 1)
Else
Result(pos + 1) = .Liste_var(i).Len_var
pos = pos + 2
End If
End If
If .Liste_var(i).Len_var > 0 Then
For j = 0 To UBound(.Liste_var(i).Var)
Result(pos) = .Liste_var(i).Var(j)
pos = pos + 1
Next j
End If
Next i
End If
End With
Socket.RemoteHost = Destinataire
Socket.RemotePort = 162
If Socket.Protocol <> sckUDPProtocol Then Socket.Protocol = sckUDPProtocol
Socket.SendData Result
End Sub
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.