C'était un peu trop compliqué alors j'ai pris
le problème à l'envers : beaucoup plus facile ainsi de créer une requête SNMP dans le bon format !
Ensuite une procédure inverse le buffer mémoire pour présenter la requête dans le bon sens sur l'interface réseau...
Je teste ça demain (avec Wireshark) et l'analyse d'une trame entrante devrait être moins difficile !
J'ai abandonné l'utilisation du code allemand car certaines subtilités du langage ASN-1 n'étaient pas respectées ==> moins compatible avec les différentes requêtes possibles
Code : Tout sélectionner
OID.s = "1.3.6.1.2.1.4096"
*OIDBuffer = AllocateMemory(1024)
long = CodeValeur(1045, *OIDBuffer)
Debug "Longeur = "+Str(long)
;a = DecodeValeur(long, *OIDBuffer)
;Debug "Resultat = "+Str(a)
Debug "--------------------------------------"
longueur = OIDCode(OID.s, "SELEC", *OIDBuffer)
a = inverseBuffer(*OIDBuffer, longueur)
Procedure.l OIDCode(OID.s, Community.s, *OIDbuffer)
; la procédure écrit la requête à l'envers (1er oct. = Fin de l'OID)
; 100% TERMINE
OIDinverse.s = inverse(OID.s)
nbParam = CountString(OIDinverse.s, ".")
lng = 2 ; Offset +2 ($00 $05)
PokeB(*OIDBuffer,$00) ; End of OID
PokeB(*OIDBuffer+1,$05) ; NULL Type ($05)
For t = 1 To nbParam-1 ; Loop but avoid 2 last values (3.1)
valeur = Val(StringField(OIDinverse.s, t, "."));
longueur = CodeValeur(valeur, *OIDBuffer+lng)
Debug Str(valeur)+". ==> "+Str(PeekB(*OIDBuffer+lng)+128)
lng = lng + longueur
Next t
PokeB(*OIDBuffer+lng, $2B) ; 1.3. is coded $2B ==> don't check 2 first values
lng = lng + 1 ; $2B = 1 byte
Llng = CodeValeur(lng, *OIDBuffer+lng) ; get the LEN of lng encoding (one or more byte)
Debug "longueur OID = "+Str(lng)+" codé sur "+Str(Llng)+" oct."
; il faut ajout $30 L1 $30 L2 $06 lng [$2B + OID]
lng = lng + Llng
PokeB(*OIDBuffer+lng, $06)
Llng = CodeValeur(lng, *OIDBuffer+lng) ; Llng = lng + 1 (could be coded on more than 1 byte)
lng = lng + Llng ; add Llng to lng (how many byte were added...)
PokeB(*OIDBuffer+lng, $30)
Llng = CodeValeur(lng, *OIDBuffer+lng) ; Llng = lng + 1 (could be coded on more than 1 byte)
lng = lng + Llng ; add Llng to lng (how many byte were added...)
PokeB(*OIDBuffer+lng, $30)
;
PokeB(*OIDBuffer+lng+1,$00) ; T L(V) ERROR INDEX
PokeB(*OIDBuffer+lng+2,$01) ; T(L)V 1 byte length
PokeB(*OIDBuffer+lng+3,$02) ; (T)L V Integer (type 2)
PokeB(*OIDBuffer+lng+4,$00) ; T L(V) ERROR STATUS
PokeB(*OIDBuffer+lng+5,$01) ; T(L)V
PokeB(*OIDBuffer+lng+6,$02) ; (T)L V
PokeB(*OIDBuffer+lng+7,$01) ; T L(V) ID SEQUENCE
PokeB(*OIDBuffer+lng+8,$01) ; T(L)V
PokeB(*OIDBuffer+lng+9,$02) ; (T)L V
lng = lng + 10
Llng = CodeValeur(lng, *OIDBuffer+lng) ; Llng = lng + 1 (could be coded on more than 1 byte)
lng = lng + Llng ; add Llng to lng (how many byte were added...)
PokeB(*OIDBuffer+lng, $A0) ; GET REQUEST
lng = lng + 1
;
L = Len(community.s) ; COMMUNITY
PokeS(*OIDBuffer+lng, inverse(Community.s), L, #PB_Ascii)
lng = lng + L
Llng = CodeValeur(L, *OIDBuffer+lng) ; T(L)V Community Length
lng = lng + Llng ; add Llng to lng (how many byte were added...)
PokeB(*OIDBuffer+lng, $04) ; (T)L V Community Type
PokeB(*OIDBuffer+lng+1,$00) ; T L(V) VERSION
PokeB(*OIDBuffer+lng+2,$01) ; T(L)V 1 byte length
PokeB(*OIDBuffer+lng+3,$02) ; (T)L V Integer (type 2)
lng = lng + 4
Llng = CodeValeur(lng, *OIDBuffer+lng) ; Llng = lng + 1 (could be coded on more than 1 byte)
lng = lng + Llng ; add Llng to lng (how many byte were added...)
PokeB(*OIDBuffer+lng, $30) ; GET REQUEST
a$ = ""
For t=0 To lng
a$=a$+" $"+Hex(PeekC(*OIDBuffer+t))
Next t
Debug a$
ProcedureReturn lng
EndProcedure
Procedure.l CodeValeur(valeur.l, *b)
; Procedure OK (100%)
; CodeValeur permet de coder une valeur au format INTEGER décrit dans ASN.1
; Valeur < 128 --> 1 byte, 16384 < valeur < 128 --> 2 bytes, etc...
Debug "-------- Procedure CodeValeur"
d.l = 0
While valeur > 127
reste = valeur % 128 + 128 ;
PokeB(*b+d, reste)
deb$ = Str(reste)+"/" + deb$
valeur = Int(valeur/128)
d = d + 1
Wend
PokeB(*b+d, valeur)
deb$ = Str(valeur+128)+"/" + deb$
; Debug deb$
; For t = 0 To d
; Debug "Oct("+Str(t)+") = "+Str((PeekB(*b+t)+128)%128)
; Next t
ProcedureReturn d+1 ; return length's data (renvoit la longeur de la donnée)
EndProcedure
Procedure.l DecodeValeur(long.l, *b)
; Procédure TERMINE (100%)
; 128^t -> t:0 = 1, t:1 = 128, t:2 = 16384...
Debug "------ Procedure DecodeValeur"
valeur.l = 0
octet.l = 0
For t = 0 To long-1
If t < long-1
octet.l = (PeekB(*b+t)+128)%128
Else
octet.l = PeekB(*b+t)
EndIf
valeur.l = valeur.l + (octet.l * Pow(128,long-t-1))
; Debug "Valeur = "+Str((octet.l * Pow(128,long-t-1)))
Next t
ProcedureReturn valeur.l
EndProcedure
Procedure.s inverse(chaine.s)
; Procedure OK (100%)
a.s = ""
lng.l = CountString(chaine.s,".")+1
For t=1 To lng.l
a.s = a.s + "."+StringField(chaine.s,lng.l - t+1,".")
Next t
a.s = Right(a.s, Len(a.s)-1)
Debug chaine.s
Debug a.s
ProcedureReturn a.s
EndProcedure
Procedure.l inverseBuffer(*buffer, longueur.l)
*buffer2 = AllocateMemory(longueur.l)
; a$=""
For t = 0 To longueur
PokeB(*buffer2+t, PeekB(*buffer+longueur-t))
; a$=a$+" $"+Hex(PeekC(*Buffer2+t))
Next t
; Debug a$
CopyMemory(*buffer2, *buffer, longueur)
FreeMemory(*buffer2)
ProcedureReturn 0
EndProcedure
Bonne nuit !
PS : si quelqu'un peut me dire comment afficher correctement mon code sur le forum...
