Go Down

Topic: Agentuino - A lightweight SNMP Agent (Read 21991 times) previous topic - next topic

Spandy19

Yahh oppss!! but I am sure people will find it useful at some stage.

yazgoo

#46
Apr 23, 2012, 11:21 pm Last Edit: Apr 24, 2012, 12:43 pm by yazgoo Reason: 1
Hi everyone, I'm an SNMP newbie.
However, I've added basic trap support.
If you're interested, I've attached the patches to this post.
Here is how you'd use it:
Sending the trap:
Code: [Select]

void send()
{
   SNMP_PDU pdu;
   char agent[] = {192, 168, 0, 177};
   const uint8_t manager[] = {192, 168, 0, 3};
   pdu.OID.size = 2;
   pdu.OID.data[0] = 7;
   pdu.OID.data[1] = 7;
   pdu.address = agent;
   pdu.trap_type = SNMP_TRAP_ENTERPRISE_SPECIFIC;
   pdu.specific_trap = 1;
   pdu.time_ticks = 0;
   /* the size of the data you will add at the end of the packet */
   pdu.trap_data_size = 10;
   /* the function that adds this data */
   pdu.trap_data_adder = add_trap_data;
   Agentuino.sendTrap(&pdu, manager);
}

The trap_data_adder function:
Code: [Select]

void add_trap_data(byte* p)
{
   byte i;
   SNMP_OID var_name;
   var_name.data[0] = 42;
   var_name.data[1] = 2;
   var_name.data[2] = 3;
   var_name.data[3] = 4;
   var_name.size = 4;
   *(p++) = SNMP_SYNTAX_OID;
   *(p++) = var_name.size;
   for(i = 0; i < var_name.size; i++) *(p++) = var_name.data[i];
   *(p++) = SNMP_SYNTAX_INT;
   *(p++) = 2;
   *(p++) = 0x42;
   *(p++) = 0;
}


alex1982

Hello,

I'm new with SNMP but for a project i need it :)

Can anyone help me to get a value from a agent and display it in my serial monitor ?

example
"I need the up time from a NAS server, so i can display it into a LCD on my Arduino".

Thank you


rexinthecity


Hi everyone, I'm an SNMP newbie.
However, I've added basic trap support.
If you're interested, I've attached the patches to this post.



Has anyone been able to successfully merge these changes into the library? 8/12 of the hunks failed when i tried to apply the files as a patch and I can't figure out where the failed pieces are supposed to go.

Wouter202

Hi, this is my first Arduino project after testing some example sketches and making an LCD display menu. I would like to read a few predefined MIB's from a modem with SNMP get-commands. First I want to display a MIB in my serial monitor and finally I'd like to display them on my LCD. The modem I am using for this test is configured for use with SNMP V2c. The modem is not in a "live" environment. When I use a MIB browser I can see one of predefined MIB's at this location: 1.3.6.1.2.1.10.127.1.1.1.1.6.3. The MIB contains a value around -490.

When I check my serial monitor using the code below the only thing I see is "SNMP Agent Initalized…" Can someone tell me how I can display a MIB there?

I used the sketch from the "Agentuino SNMP Astronomy Weather Station" and I adapted it for my own needs. I compared it with the Agentuino example sketch and the only difference I see was an "F" every time this function is used: Serial << F("SNMP Agent Initalized...") << endl;
Can someone tell what the "F" is needed for?

Code: [Select]
/*
* Adaptation of
* Agentuino SNMP Astronomy Weather Station
* http://openhardware.gridshield.net/home/arduino-snmp-temperature-sensor
* example from "yesyesserver.co.uk/temp/wheater_station"
*/

#include <Streaming.h>         // Include the Streaming library
#include <Ethernet.h>          // Include the Ethernet library
#include <SPI.h>
#include <MemoryFree.h>
#include <Agentuino.h>
#include <Flash.h>

#define DEBUG

// SNMP stuff
byte count=0; // count number of processed SNMP requests

// parameters for the Ethernet library
static byte mac[] = { 0x90, 0xA3, 0xDA, 0x0E, 0xAD, 0x3f };
static byte ip[] = { 192, 168, 1, 200 };
static byte gateway[] = { 192, 168, 1, 1 };
static byte subnet[] = { 255, 255, 255, 0 };

// must-have RFC1213-MIB OIDs (taken from agentuino sample sketch)
// .iso.org.dod.internet.mgmt.mib-2.system.sysDescr (.1.3.6.1.2.1.1.1)
static char sysDescr[] PROGMEM      = "1.3.6.1.2.1.1.1.0";  // read-only  (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysObjectID (.1.3.6.1.2.1.1.2)
static char sysObjectID[] PROGMEM   = "1.3.6.1.2.1.1.2.0";  // read-only  (ObjectIdentifier)
// .iso.org.dod.internet.mgmt.mib-2.system.sysUpTime (.1.3.6.1.2.1.1.3)
static char sysUpTime[] PROGMEM     = "1.3.6.1.2.1.1.3.0";  // read-only  (TimeTicks)
// .iso.org.dod.internet.mgmt.mib-2.system.sysContact (.1.3.6.1.2.1.1.4)
static char sysContact[] PROGMEM    = "1.3.6.1.2.1.1.4.0";  // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysName (.1.3.6.1.2.1.1.5)
static char sysName[] PROGMEM       = "1.3.6.1.2.1.1.5.0";  // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysLocation (.1.3.6.1.2.1.1.6)
static char sysLocation[] PROGMEM   = "1.3.6.1.2.1.1.6.0";  // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysServices (.1.3.6.1.2.1.1.7)
static char sysServices[] PROGMEM   = "1.3.6.1.2.1.1.7.0";  // read-only  (Integer)

// custom OIDs -> Aan te passen
static char MyMib[] PROGMEM   = "1.3.6.1.2.1.10.127.1.1.1.1.6.3";     // The MIB I want to read

// RFC1213 local values (taken from agentuino sample sketch) -> Aan te passen
static char locDescr[]              = "Arduino based SNMP Astronomy Weather Station";  // read-only (static)
static char locObjectID[]           = "1.3.6.1.2.1.10.127.1";                       // read-only (static)
static uint32_t locUpTime           = 0;                                        // read-only (static)
static char locContact[20]          = "yesyes";                            // should be stored/read from EEPROM - read/write (not done for simplicity)
static char locName[20]             = "Agentuino";                              // should be stored/read from EEPROM - read/write (not done for simplicity)
static char locLocation[20]         = "Maidenhead, UK";                        // should be stored/read from EEPROM - read/write (not done for simplicity)
static int32_t locServices          = 7;                                        // read-only (static)

uint32_t prevMillis = millis(); // used for system uptime calculation
char oid[SNMP_MAX_OID_LEN];     // will hold the OID of an SNMP request
SNMP_API_STAT_CODES api_status; // agentuino SNMP status
SNMP_ERR_CODES status;

// SNMP callback function, taken from agentuino sample sketch and extended to include my custom OIDs
void pduReceived()  // is being called when an SNMP packet has been received
{
  SNMP_PDU pdu;
  //
  #ifdef DEBUG
   Serial << "UDP Packet Received Start.." << " RAM:" << freeMemory() << endl;
  #endif
  //
  api_status = Agentuino.requestPdu(&pdu);
 
  // check if valid packet
  if ( (pdu.type == SNMP_PDU_GET || pdu.type == SNMP_PDU_GET_NEXT || pdu.type == SNMP_PDU_SET)
        && pdu.error == SNMP_ERR_NO_ERROR && api_status == SNMP_API_STAT_SUCCESS )
    {
    //
    pdu.OID.toString(oid);
    //
    Serial << "OID: " << oid << endl;
    //
   
    if ( strcmp_P(oid, sysDescr ) == 0 )
    {
      // handle sysDescr (set/get) requests
      if ( pdu.type == SNMP_PDU_SET )
      {
        // response packet from set-request - object is read-only
        pdu.type = SNMP_PDU_RESPONSE;
        pdu.error = SNMP_ERR_READ_ONLY;
      }
      else
      {
        // response packet from get-request - locDescr
        status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locDescr);
        pdu.type = SNMP_PDU_RESPONSE;
        pdu.error = status;
      }
      //
      #ifdef DEBUG
        Serial << "sysDescr..." << locDescr << " " << pdu.VALUE.size << endl;
      #endif
    }
   
    else if ( strcmp_P(oid, sysObjectID ) == 0 )
    {
      // handle sysName (set/get) requests
      if ( pdu.type == SNMP_PDU_SET )
      {
        // response packet from set-request - object is read-only
        pdu.type = SNMP_PDU_RESPONSE;
        pdu.error = SNMP_ERR_READ_ONLY;
      }
      else
      {
        // response packet from get-request - locUpTime
        status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locObjectID);
        pdu.type = SNMP_PDU_RESPONSE;
        pdu.error = status;
      }
      //
      #ifdef DEBUG
        Serial << "ObjectID" << locObjectID << " " << pdu.VALUE.size << endl;
      #endif
    }   

//…    had to shorten the code for I can post only 9500 characters in the Arduino forum. Check out the full code at the web page shown at the beginning of this example.
       
// add more custom OID blocks here


   
    else
    {
      // oid does not exist
      //
      // response packet - object not found
      pdu.type = SNMP_PDU_RESPONSE;
      pdu.error = SNMP_ERR_NO_SUCH_NAME;
      Serial << "Unknown OID" << endl;
    }
   
    //
    Serial << "Sending response..." << endl;
   
    Agentuino.responsePdu(&pdu);
    count++;
  }
 
  else
  // packet not valid, send GENERAL_ERROR response. Required, otherwise the invalid packet
  // will get stuck in the buffer and processed over and over again
 
  {
    Serial << "Unknown Packet!!" << endl;
    Serial << "PDU Type: " << pdu.type << " PDU Error: " << pdu.error << " API status: "<< api_status << endl;
    pdu.type = SNMP_PDU_RESPONSE;
    pdu.error = SNMP_ERR_GEN_ERROR;
    Agentuino.responsePdu(&pdu);
    Serial << "Sent 'GENERAL_ERROR' response" << endl;
  }

  //
  Serial << "freeing PDU.." << " RAM:" << freeMemory() << endl;
  Agentuino.freePdu(&pdu);
  //
  Serial << "UDP Packet Received End.." << " RAM:" << freeMemory() << endl;
}

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
 
  // start Agentuino SNMP library
  api_status = Agentuino.begin();
  if ( api_status == SNMP_API_STAT_SUCCESS )
  {
    Agentuino.onPduReceive(pduReceived); // register callback function that is being called when an SNMP packet has been received
    delay(10);
    Serial << "SNMP Agent Initalized..." << endl;
  }
  else
  {
    delay(10);
    Serial << "SNMP Agent Initalization Problem..." << status << endl;
  }
}

void loop()
{
  Serial.print(MyMib); 
 
  // listen for / handle incoming SNMP requests
  Agentuino.listen();

  // sysUpTime - The time (in hundredths of a second) since
  // the network management portion of the system was last
  // re-initialized.
  if ( millis() - prevMillis > 1000 ) {
    // increment previous milliseconds
    prevMillis += 1000;
    //
    // increment up-time counter
    locUpTime += 100;
  }
}


rexinthecity

#50
Apr 10, 2013, 06:06 pm Last Edit: Apr 10, 2013, 06:16 pm by rexinthecity Reason: 1

Hi, this is my first Arduino project after testing some example sketches and making an LCD display menu. I would like to read a few predefined MIB's from a modem with SNMP get-commands. First I want to display a MIB in my serial monitor and finally I'd like to display them on my LCD. The modem I am using for this test is configured for use with SNMP V2c. The modem is not in a "live" environment. When I use a MIB browser I can see one of predefined MIB's at this location: 1.3.6.1.2.1.10.127.1.1.1.1.6.3. The MIB contains a value around -490.

When I check my serial monitor using the code below the only thing I see is "SNMP Agent Initalized…" Can someone tell me how I can display a MIB there?

I used the sketch from the "Agentuino SNMP Astronomy Weather Station" and I adapted it for my own needs. I compared it with the Agentuino example sketch and the only difference I see was an "F" every time this function is used: Serial << F("SNMP Agent Initalized...") << endl;
Can someone tell what the "F" is needed for?



I believe the F function is part of the Flash library. "SNMP Agent Initialized..." is probably stored in EEPROM to save on memory. The F function pulls it out of EEPROM so that it can be sent to the Serial port.

MIB: File that contains a list of OIDs and their definitions, kind of a dictionary.
OID: Object Identifier, think of it as an encoded variable name.
Agent: An SNMP device that responds to GET and SET commands and can also send out traps/notifications.
Manager: An SNMP device or application that sends out GET and SET commands and listens for traps/notifications.
Versions: There are three common SNMP versions used today. 1, 2c, and 3.

The Agentuino library allows your Arduino to act as an SNMP v1 Agent. It sounds like you are wanting to use your Arduino as a v2c Manager, is that correct?

Wouter202

Hi there Rex, thank you for your reply. So maybe I should be placing the "F" in front every time Serial is called. Because in the SNMP Astronomy Weather Station example that wasn't the case?

Do you think it would be possible to use the Arduino as a v2c SNMP Manager with the Agentuino code? I think the GET-command is about the same in V1 as in V2. But maybe the code would need some adaptation then?

rexinthecity


Hi there Rex, thank you for your reply. So maybe I should be placing the "F" in front every time Serial is called. Because in the SNMP Astronomy Weather Station example that wasn't the case?

Do you think it would be possible to use the Arduino as a v2c SNMP Manager with the Agentuino code? I think the GET-command is about the same in V1 as in V2. But maybe the code would need some adaptation then?


You can either include the Flash library or alter all of the serial calls, up to you. All it is doing is writing to the serial port.

It would be possible to adapt the Agentuino library but you're going to have to get very familiar with the SNMP packet structure. I spent about 3 weeks learning about SNMP, bought an SNMP software suite, and made heavy modifications to the Agentuino library to bring it up to v2c specs (and make it a little easier to use with traps).

I haven't had a need to make it a manager but thinking off the top of my head (I don't have the Agentuino library open right now) it would go something like this:
Take the method that is used to send the get/set responses and use that as a template for sending a GET or SET PDU.
The PDU parsing method should work for parsing the response PDUs that will come back since they follow the same structure.
Find all of the references to the PDU version attribute, I believe it was hardcoded for v1, a value of 0. v2c has a value of 1.
v2c traps may work as well since, unlike v1 traps, they follow the standard PDU structure.

Wouter202

Quote
Find all of the references to the PDU version attribute, I believe it was hardcoded for v1, a value of 0. v2c has a value of 1.


Okay, I've been diving into the .cpp and .h file of the Agentuino library. This is the only place where a saw a version mentioned (cpp file):

Code: [Select]
//
// extract version
pdu->version = 0;
for ( i = 0; i < verLen; i++ ) {
pdu->version = (pdu->version << 8) | _packet[5 + i];


So I should change "pdu->version = 0;" into "=1"?

Quote
Take the method that is used to send the get/set responses and use that as a template for sending a GET or SET PDU.


Do you mean I should use this (below) as a template? Or do I need to go looking in the .h or .cpp file?

Code: [Select]
void pduReceived()
{
  SNMP_PDU pdu;
  //
  #ifdef DEBUG
    Serial << F("UDP Packet Received Start..") << F(" RAM:") << freeMemory() << endl;
  #endif
  //
  api_status = Agentuino.requestPdu(&pdu);
  //
  if ( pdu.type == SNMP_PDU_GET || pdu.type == SNMP_PDU_GET_NEXT || pdu.type == SNMP_PDU_SET
    && pdu.error == SNMP_ERR_NO_ERROR && api_status == SNMP_API_STAT_SUCCESS ) {
    //
    pdu.OID.toString(oid);
    //
    //Serial << "OID: " << oid << endl;
    //
    if ( strcmp_P(oid, sysDescr ) == 0 ) {
      // handle sysDescr (set/get) requests
      if ( pdu.type == SNMP_PDU_SET ) {
        // response packet from set-request - object is read-only
        pdu.type = SNMP_PDU_RESPONSE;
        pdu.error = SNMP_ERR_READ_ONLY;
      } else {
        // response packet from get-request - locDescr
        status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locDescr);
        pdu.type = SNMP_PDU_RESPONSE;
        pdu.error = status;
      }
      //
      #ifdef DEBUG
        Serial << F("sysDescr...") << locDescr << F(" ") << pdu.VALUE.size << endl;
      #endif


Quote
v2c traps may work as well since, unlike v1 traps, they follow the standard PDU structure.


I don't think I will need traps to get the info out of my mib?

Thank you for looking into this with me. And thank you for sharing your knowledge, this is all pretty new for me. I would really like to get this working.








craigkenny

I realize this is an old thread. Does anyone have the library with the changes above for the send trap example to work? I need to send basic V1 SNMP traps. Receive and walk is working aok but I just cant find a way to send the traps.

regards
Craig.

:) :)
Dear try to upload the changes to send traps but do not quite understand the diff file, could someone post the files and the cpp .h with somenew to start working from there.
stay tuned to your comments.
:) :)
Ubuntu and OSX.

Fred_Tuga

Does anyone knows if it is possible to receive SNMP Traps in Arduino (with Ethernet Shield)??

Thanks!

Kayzh3r

Hi All,

I follow you in many places at Internet i love work you do!!!
I trying to monitor by Nagios throught SNMP but i have  a lot of problems with the library. I can't receive any response. List of tools i use:
-Arduino UNO R3
-Ethernet Shield
-IDE 1.0.6
-iReasoning MIB Browser
-Agentuino library from https://code.google.com/p/agentuino/source/browse/#svn%2Ftrunk%2FAgentuino
    *Agentuino.h rev47 (alfsolli)
    *Agentuino.cpp rev46 (alfsolli)
    *Agent.pde rev42 (LAVco)

I show you what i received


Microsoft Windows [Versión 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\Ignazio F.Finazzi>ping 192.168.1.105

Haciendo ping a 192.168.1.105 con 32 bytes de datos:
Respuesta desde 192.168.1.105: bytes=32 tiempo<1m TTL=128
Respuesta desde 192.168.1.105: bytes=32 tiempo<1m TTL=128
Respuesta desde 192.168.1.105: bytes=32 tiempo<1m TTL=128
Respuesta desde 192.168.1.105: bytes=32 tiempo<1m TTL=128

Estadísticas de ping para 192.168.1.105:
    Paquetes: enviados = 4, recibidos = 4, perdidos = 0
    (0% perdidos),
Tiempos aproximados de ida y vuelta en milisegundos:
    Mínimo = 0ms, Máximo = 0ms, Media = 0ms

C:\Program Files (x86)\ireasoning\mibbrowser>cd C:\Program Files (x86)\ireasonin
g\mibbrowser\bin

C:\Program Files (x86)\ireasoning\mibbrowser\bin>ipconfig/all

Configuración IP de Windows

   Nombre de host. . . . . . . . . : Ignazio-PC
   Sufijo DNS principal  . . . . . :
   Tipo de nodo. . . . . . . . . . : híbrido
   Enrutamiento IP habilitado. . . : no
   Proxy WINS habilitado . . . . . : no
   Lista de búsqueda de sufijos DNS: hitronhub.home

Adaptador de Ethernet Conexión de área local:

   Sufijo DNS específico para la conexión. . : hitronhub.home
   Descripción . . . . . . . . . . . . . . . : Realtek PCIe GBE Family Controlle
r
   Dirección física. . . . . . . . . . . . . : 40-16-7E-29-0D-A5
   DHCP habilitado . . . . . . . . . . . . . : sí
   Configuración automática habilitada . . . : sí
   Vínculo: dirección IPv6 local. . . : fe80::1934:6e79:4667:3181%11(Preferido)

   Dirección IPv4. . . . . . . . . . . . . . : 192.168.1.154(Preferido)
   Máscara de subred . . . . . . . . . . . . : 255.255.255.0
   Concesión obtenida. . . . . . . . . . . . : lunes, 29 de septiembre de 2014 1
2:42:45
   La concesión expira . . . . . . . . . . . : lunes, 13 de octubre de 2014 13:1
2:02
   Puerta de enlace predeterminada . . . . . : 192.168.1.1
   Servidor DHCP . . . . . . . . . . . . . . : 192.168.1.1
   IAID DHCPv6 . . . . . . . . . . . . . . . : 239081086
   DUID de cliente DHCPv6. . . . . . . . . . : 00-01-00-01-1B-56-18-BE-40-16-7E-
29-0D-A5
   Servidores DNS. . . . . . . . . . . . . . : 192.168.1.1
   NetBIOS sobre TCP/IP. . . . . . . . . . . : habilitado

Adaptador de túnel isatap.hitronhub.home:

   Estado de los medios. . . . . . . . . . . : medios desconectados
   Sufijo DNS específico para la conexión. . : hitronhub.home
   Descripción . . . . . . . . . . . . . . . : Adaptador ISATAP de Microsoft
   Dirección física. . . . . . . . . . . . . : 00-00-00-00-00-00-00-E0
   DHCP habilitado . . . . . . . . . . . . . : no
   Configuración automática habilitada . . . : sí

Adaptador de túnel Teredo Tunneling Pseudo-Interface:

   Sufijo DNS específico para la conexión. . :
   Descripción . . . . . . . . . . . . . . . : Teredo Tunneling Pseudo-Interface

   Dirección física. . . . . . . . . . . . . : 00-00-00-00-00-00-00-E0
   DHCP habilitado . . . . . . . . . . . . . : no
   Configuración automática habilitada . . . : sí
   Dirección IPv6 . . . . . . . . . . : 2001:0:5ef5:79fd:1486:343c:aa77:4db3(Pre
ferido)
   Vínculo: dirección IPv6 local. . . : fe80::1486:343c:aa77:4db3%13(Preferido)

   Puerta de enlace predeterminada . . . . . : ::
   NetBIOS sobre TCP/IP. . . . . . . . . . . : deshabilitado

C:\Program Files (x86)\ireasoning\mibbrowser\bin>snmpget.bat -v 1 -r 1 -c public
192.168.1.105 sysUpTime.0
Exception in thread "main" java.lang.IllegalArgumentException: Passed MIB node n
ame can't be translated to numeric OID. Either the corresponding MIB is not load
ed (call loadMib method to load) or OID name is not spelled correctly
        at com.ireasoning.c.a.f.a(f.java:1032)
        at com.ireasoning.c.a.f.b(f.java:1011)
        at com.ireasoning.c.a.f.a(f.java:1117)
        at com.ireasoning.c.a.f.snmpGetRequest(f.java:946)
        at com.ireasoning.app.mibbrowser.SnmpGet.a(SnmpGet.java:54)
        at com.ireasoning.app.mibbrowser.SnmpGet.main(SnmpGet.java:34)


Thanks...

I need help...

Thanks so much

Go Up