Go Down

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

Enmyerp

Hi, i don't know if this goes here, but i made a code that allows to send SNMP version 1 traps, but only sends data as string. You must modify the Agentuino.cpp and Agentuino.h files. I'm gonna leave my modifies files down in this post, but if you want to modify your own files you must paste the next function into your Agentuino.cpp file:

Code: [Select]

void AgentuinoClass::Trampa(char Mensaje[], byte RemIP[4], uint32_t Tiempo) {
byte TipoyLongitud[2] = {48, 68+strlen(Mensaje)};   // Here is defined the full packet size
byte Version[3] = {2, 1, 0};   // Defined versión 1
byte Comunidad[8] = {4, 6, 112, 117, 98, 108, 105, 99};  // Second byte from the left is the number of characters in the community name. Last four bytes = public in ASCII characters
byte TipoSNMP[4] = {164, 130, 0, 53+strlen(Mensaje)};   // Here is defined the size
byte OID[11] = {6, 9, 43, 6, 1, 4, 1, 130, 153, 93, 0};   // Here is defined the enterprise OID
byte IPdefinida[2] = {64, 4};
byte TrapIP[4] = {192, 168, 0, 64};   // Here you can change the trap IP address
byte TipoTrampa[3] = {2, 1, 6};
byte extraOID[3] = {2, 1, 1};
byte TipoTiempo[2] = {67, 4};
byte VarBind[4] = {48, 130, 0, 20+strlen(Mensaje)};   // Here is defined the size
byte VarBind1[4] = {48, 130, 0 , 16+strlen(Mensaje)};   // Here is defined the size
byte OID1[14] = {6, 12, 43, 6, 1, 4, 1, 130, 153, 93, 3, 1, 1, 1};   // Here is defined the trap OID
byte Value1[2] = {4, strlen(Mensaje)};

// The next part is to change the locUpTime into bytes
int i=0,k=1,temp;
byte suma = 0;
uint32_t quotient;
quotient = Tiempo;
byte hexadecimalNumber[4] ={0, 0, 0, 0};
while (quotient!=0)
{
temp = quotient % 16;
if (k == 1)
{
suma = temp;
k = 2;
}
else
{
suma = suma + temp*16;
hexadecimalNumber[3-i] = suma;
i = i + 1;
k = 1;
}
quotient = quotient / 16;
}
if (k == 2)
{
hexadecimalNumber[3-i] = suma;
}

Udp.beginPacket(RemIP, 162);   // Here is defined the UDP port 162 to send the trap
Udp.write(TipoyLongitud,2);
Udp.write(Version,3);
Udp.write(Comunidad,8);
Udp.write(TipoSNMP,4);
Udp.write(OID,11);
Udp.write(IPdefinida,2);
Udp.write(TrapIP,4);
Udp.write(TipoTrampa,3);
Udp.write(extraOID,3);
Udp.write(TipoTiempo,2);
Udp.write(hexadecimalNumber,4);
Udp.write(VarBind,4);
Udp.write(VarBind1,4);
Udp.write(OID1,14);
Udp.write(Value1,2);
Udp.write(Mensaje,strlen(Mensaje));
Udp.endPacket();
}


Also, you must search into Agentuino.h the line "class AgentuinoClass", and add the line that is indicated below:

Code: [Select]

public:
// Agent functions
SNMP_API_STAT_CODES begin();
SNMP_API_STAT_CODES begin(char *getCommName, char *setCommName, uint16_t port);
void listen(void);
SNMP_API_STAT_CODES requestPdu(SNMP_PDU *pdu);
SNMP_API_STAT_CODES responsePdu(SNMP_PDU *pdu);
void onPduReceive(onPduReceiveCallback pduReceived);

void Trampa(char Mensaje[], byte RemIP[4], uint32_t Tiempo);     // This is the line you must add

void freePdu(SNMP_PDU *pdu);



The function would be used in an Agentuino code like this:

Code: [Select]

static byte RemoteIP[4] = {192, 168, 0, 65};     // The IP address of the host that will receive the trap
static uint32_t locUpTime = 0;

void loop()
{
  // A trap saying "Trap test" will be send if readed a LOW state on pin 7
  if (digitalRead(7) == 0) {
    Agentuino.Trampa("Trap test",RemoteIP, locUpTime);     // You need to specify a message, the remote host and the locUpTime
    delay(1000);
    locUpTime = locUpTime + 100;
  }
  Agentuino.listen();
  if ( millis() - prevMillis > 1000 ) {
    prevMillis += 1000;
    locUpTime += 100;
  }
}


The traps are sent on the public community, specified on the function Trampa. I RECOMMEND not to change it, unless you know how the frame works. I attached a picture of how the trap would be seen on the receiver host. If you want to understand how the SNMP trap works (and the code) i recommend you this two pages:http://12000.org/my_notes/snmp/snmp.pdf
http://www.opencircuits.com/SNMP_MIB_Implementation

I hope it is of use to someone

johnyHV

Version where everything is in a heap on GitHub

Github

sergramos

johnyHV,

Can you please expand on the differences between the two versions that were placed in Github?

Simple and Expanded versions.

Thanks

lennit

A way to switch relays on and off. Maybe not the best out there, so please feel free to correct me:

Code: [Select]

if ( strcmp(oid, relayOID1 ) == 0 ) {
      // handle sysName (set/get) requests
      if ( pdu.type == SNMP_PDU_SET ) {
        // response packet from set-request - object is read/write
        status = pdu.VALUE.decode(relayPointer1);
        if (status == 0) {
          relayCommand[1] = *pdu.VALUE.data;
          if (relayCommand[1] == 1) {
            digitalWrite(relay[1], LOW);
            relayState[1]=1;
          }
          else {
            digitalWrite(relay[1], HIGH);
            relayState[1]=0;
          }
        }
        pdu.type = SNMP_PDU_RESPONSE;
        pdu.error = status;
      } else {
        // response packet from get-request - locUpTime
        status = pdu.VALUE.encode(SNMP_SYNTAX_INT32, relayState[1]);
        pdu.type = SNMP_PDU_RESPONSE;
        pdu.error = status;
      }


where:
Code: [Select]

static char relayOID1 [] = "1.3.6.1.4.1.36582.2.0";     // R1 OID
static int32_t relayCommand[9];     // Stores the command received from the client - 1 and 0
int32_t *relayPointer1;           // For the decode pointer was required, still a bit dark matter for me
static int32_t relayState[9];    // saves the state of the relay for SNMP_GET checks
static byte relay[9];              // here the pin of the relay is stored
Aquila non captat muscas.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy