Aller au contenu

Coder Un Paquet Snmp


darklite44

Messages recommandés

Bonjour a tous,

 

Je chercher à  améliorer un script Lua qui me permet d'envoyer un paquet SNMP de type set. Pour faire simple, actuellement je code directement en hexa le paquet à  envoyer. J'ai tronqué le paquet pour l'exemple car c'est trop long.

 

ip = fibaro:get(selfId, 'IPAddress');
local Snmp_Port = 161;


local _snmpPacket = string.char(0x30, 0x30, 0x02, 0x01, 0x00,
  0x00, 0x04, 0x02, 0x30, 0x30);


socket = Net.FUdpSocket(); 


local bytes, errorCode = socket:write(_snmpPacket, ip, Snmp_Port); 
--check for error      
if errorCode == 0 then 
  fibaro:debug("Successfully sent"); 
else 
  fibaro:debug("Transfer failed"); 
end 

 

Je voudrais concaténer plusieurs variables dans un variable (_snmpPacket) contenant l'ensemble du paquet en hexa. Une fonction qui prenne dynamiquement les variables en entrés et me sorte un string.char hexa prêt à  envoyer.

 
The ASN.1 OCTET STRING data type is encoded into a TLV triplet that begins with a Tag byte of 0x04.

 

Par exemple, il faut convertir en hexa la communautée public en ASN.1

http://lapo.it/asn1js/#04067075626C6963

OCTET STRING public 04 06 70 75 62 6C 69 63

Je ne sais pas trop comment manipuler l'hexa en Lua et encore moins en  ASN.1. Pouvez-vous me donner quelques conseils ?

J'utilise pour le moment le site asn1js

 

Merci d'avance
Lien vers le commentaire
Partager sur d’autres sites

Exemple qui fonctionne lorsque je code l'hexa manuellement :
local _snmpPacket = string.char(0x04, 0x06, 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63);
-- fibaro:debug(type (_snmpPacket));
local bytes, errorCode = socket:write(_snmpPacket, _broadcastAddress, Snmp_Port); 

Les octets définis se retrouvent bien dans le segment UDP. 

 

-----------------------------------------------------------------

Par contre si je veux dynamiser la chose j'ai un problème de codage et je ne retrouve pas ce que j'attend dans le segment UDP :

---------- SNMP community ----------
-- Octet string = sequence of bytes
local T = string.format('%02X', 4);
local community = "public":
local L = string.format('%02X', string.len(community))
local V = community:tohex();
local community_bytes = ("Paquet généré ".. T .. L .. V);
fibaro:debug("T="..T ..", L="..L ..", V="..V);


-- Broadcast Address 
local _broadcastAddress = "255.255.255.255";
local Snmp_Port = 161;
local _snmpPacket = community_bytes
local bytes, errorCode = socket:write(_snmpPacket, _broadcastAddress, Snmp_Port); 
Je ne vois pas trop quelle fonction utiliser dans la doc pour formater la chaîne community_bytes est octets prêt à  transmettre.
 
Krikroff, une idée ?
Lien vers le commentaire
Partager sur d’autres sites

J'ai intégré dans le Toolkit (disponible en téléchargement dans la rubrique add-on du forum) un petit éditeur LUA -> Menu Tools / LUA Script Editor ensuite cliquer droit -> Code Snippets / Advanced scripts, tu trouveras une fonction toHex()

function toHex(num)
  local hexstr = '0123456789abcdef';
  local s = '';
  while num > 0 do
     local mod = math.fmod(num, 16);
     s = string.sub(hexstr, mod+1, mod+1) .. s;
     num = math.floor(num / 16);
  end
  if s == '' then s = '0' end
  return s;
end

Je précise que cette fonction n'est pas de moi mais elle est disponible et sans Copyright :)

 

J'espère que cela correspond à  ce que tu souhaites ?

Lien vers le commentaire
Partager sur d’autres sites

Krikroff, je ne comprend pas comment utiliser ta fonction car elle prend en argument un nombre. Dans mon cas, je chercher à  encoder une chaine au format ASN.1 (OCTET STRING) et l'envoyer dans un socket UDP :

[DEBUG] 22:58:52: DUMP OCTET STRING public 04 06 70 75 62 6C 69 63

[DEBUG] 22:58:52: public ==> LEN=6, HEX = 7075626C6963
[DEBUG] 22:58:52: Paquet généré 04067075626C6963

The ASN.1 OCTET STRING data type is encoded into a TLV triplet that begins with a Tag byte of 0x04.

Cf : http://lapo.it/asn1js/#04067075626C6963

 

Exemple pour coder un OID SNMP : 060D2B06010401C407650D01031C00

OBJECT IDENTIFIER1.3.6.1.4.1.8711.101.13.1.3.28.0

A nice description of OID encoding is found here.

http://lapo.it/asn1js/#060D2B06010401C407650D01031C00

Lien vers le commentaire
Partager sur d’autres sites

Sorry darklite44, j'avais pas tout compris effectivement :D ... LuaSNMP étant je pense impossible àfaire tourner pour le moment sur le HC2, je pense que tu trouveras ton bonheur dans un script de Patrick Karlson ici https://svn.nmap.org/nmap/nselib/asn1.lua et avec très peux de modifications sur le code... par contre je ne suis pas sur que le code soit libre d'utilisation -_- àvoir...

Lien vers le commentaire
Partager sur d’autres sites

Justement, j'étais en train d'utiliser la classe snmp.lua pour faire des tests. J'arrive àcoder le paquet SNMP, la sortie est un type "table" par contre je n'en suis pas encore àsavoir le mettre en forme en ASN.1 et le coder en string.char pour l'envoyer sur le socket.

  1. buildSetRequest(options, oid, value) ==> Create an SNMP Set Request PDU
  2. buildPacket(PDU, version, commStr) ==> Create an SNMP packet
  3. encode ==> Encodes a given value according to ASN.1 basic encoding rules for SNMP
  4. socket:write

Je ne sais pas comment utiliser la méthode encode pour générer le payload du segment UDP.

local oid = "1.3.6.1.4.1.8711.101.13.1.3.28.0"
local commStr = "public"
local value = 57

-- Tables:
local requestPDU = buildSetRequest("", oid, value);

local packet = buildPacket(requestPDU, 1, commStr)
fibaro:debug( "Table dump packet".. dump({packet}) )
fibaro:debug(type (oid_t));
-- Broadcast Address
local _broadcastAddress = "255.255.255.255";
local Snmp_Port = 161;
local _snmpPacket = community_bytes
local bytes, errorCode = socket:write(_snmpPacket, _broadcastAddress, Snmp_Port);

Ce qui donne en sortie :

[DEBUG] 12:56:56: Table dump oid_t { [1] = { [1] = 1,[2] = 3,[3] = 6,[4] = 1,[5] = 4,[6] = 1,[7] = 8711,[8] = 101,[9] = 13,[10] = 1,[11] = 3,[12] = 28,[13] = 0,["_snmp"] = 06,} ,}

[DEBUG] 12:56:56: Table dump packet{ [1] = { [1] = 1,[2] = public,[3] = { ["_snmp"] = A3,[4] = { [1] = { [1] = { [1] = 1,[2] = 3,[3] = 6,[4] = 1,[5] = 4,[6] = 1,[7] = 8711,[8] = 101,[9] = 13,[10] = 1,[11] = 3,[12] = 28,[13] = 0,["_snmp"] = 06,} ,[2] = 57,} ,} ,} ,} ,}
[DEBUG] 12:56:56: table
[ERROR] 12:56:56: line :write (arg 2), expected 'string const &' got 'nil'
Lien vers le commentaire
Partager sur d’autres sites

 Je suis enfin parvenu à  envoyer une chaine codé en hexa dans mon paquet UDP. Il faut bien une autre étape qui converti les caractères Hexa codés ASCII en Byte Char :

-- convert every 2 Chars (ASCII), to Byte Char
function convertCharstoBytes(address)
  local s = address;
  local x = "";  -- will contain converted Chars
  --for i=1, 12, 2 do
  for i=1, string.len(s), 2 do
    x = x .. string.char(tonumber(string.sub(s, i, i+1), 16));
  end
  return x;
end

Ensuite on appele cette méthode :

local T = string.format('%02X', 4);
local L = string.format('%02X', string.len("public"))
local V = ("public"):tohex();
local community_bytes = (T .. L ..V);

local comm_packet = convertCharstoBytes(community_bytes);
fibaro:debug("Byte Char="..comm_packet);

Pour finir on vérifie les logs :

[DEBUG] 14:10:34: public ==> LEN=6, HEX = 7075626C6963
[DEBUG] 14:10:34: Paquet généré 04067075626C6963
[DEBUG] 14:10:34: Byte Char=public
[DEBUG] 14:10:34: Successfully sent

Reste à  parvenir à  coder le tableau de la méthode buildPacket en ASN.1 pour essayer de dynamiser tout ça.

Seulement la classe ASN.1 fait appel à  une inclusion "bin" qui n'est pas disponible : http://nmap.org/nsedoc/lib/bin.html#pack

local bin = require "bin"
Lien vers le commentaire
Partager sur d’autres sites

  • 2 ans après...

salut a tous

 

j'ai un souci , j'ai acheter un iTach TCP / IP to Serial pour commander un V35 de bose.

 

je peut prends le Control sur le v35 de bose uniquement par DATA avec iTach TCP / IP to Serial

 

mai mon probleme je s'ai pas comment envoyer le code hexcode1 depuis un bouton virtuel de la hc2 FIBARO

 

adresse ip ok 

port 4999 ok

 

0000 006b 0022 0000 015d 00ac 0015 0015 0015 0041 0015 0015 0015 0041 0015 0041 0015 0041 0015 0015 0015 0041 0015 0041 0015 0041 0015 0015 0015 0041 0015 0015 0015 0015 0015 0041 0015 0015 0015 0015 0015 0015 0015 0041 0015 0041 0015 0015 0015 0015 0015 0041 0015 0041 0015 0041 0015 0041 0015 0015 0015 0015 0015 0041 0015 0041 0015 0015 0015 0015 0015 00ac

 

via un code lua : envoyer le code sur adresse 192.168.0.24 port 4999:D  

Modifié par 971jmd
Lien vers le commentaire
Partager sur d’autres sites

@971jmd ta question n'a rien à voir avec ce topic, en revanche tu as la réponse sous les yeux, il faut que tu utilises string.char() pour chaque mot hexadécimal que tu veux écrire sur la socket TCP.

 

Sinon pour revenir dans le thème de ce topic, pour coder un paquet SNMP vous pouvez regarder mon VD onduleur Eaton, j'ai écris tout ce qu'il faut pour envoyer une requête SNMPGET et lire la réponse. La suite sera d'ajouter la gestion de requêtes d'écriture SNMPSET, je ferai alors un tuto dédié, car les usages du SNMP sont multiples, surtout dans le monde du réseau.

 

Lien vers le commentaire
Partager sur d’autres sites

×
×
  • Créer...