SNMP traps : replacement code for traps.c containing bug fixes and additional features

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SNMP traps : replacement code for traps.c containing bug fixes and additional features

Jump to solution
2,724 Views
trailman
Contributor V

Hi all,

 

I used the SNMP trap code in MQX34 and MQX37 to send some V1/V2 traps and found the following problems :in rtcs/source/snmp/traps.c :

- code is too big because it is made of several functions that where copied and modified from other functions; a more generic and unique function can be used instead (except maybe for linkup/linkdown that contain some additonal code)

- user specific trap V2 messages seem to have some wrong data : message type not recognized by SNMPB tool (SNMP Browser, a nice software for everyone working with SNMP)

- some inconsistencies between signed / unsignes types and ASN1 macros used

- ASN1_BKWRITE..... macros are made of several lines of code, and I'm not sure that the compiler can optimize the code size if these macros are used many times in the code. The code is duplicated leading to excessive code size (text section). It would probably be better to define these macros as functions.

 

To fix these problems, except the ASN1_BKWRITE... size (that is easy to fix if needed), I wrote.a new code as replacement for traps.c. You can put this code in your application or move it to the BSP tree (as you want).

Instead of calling functions in traps.c, you call SNMP_trap_send() instead.

This function :

- is a low level one so your can specify the target IP directly (needed to implement V2 inform traps)

- you can specify the request-id (usefull for resending message)

- you can override timestamp

- you can add as many additional bindings (data) you need

- you can send INFORMV2 traps in addition to TRAPV1 and TRAPV2

 

Within this code I added a demo function SNMP_send_trap_demo() to send several kind of traps for testing.

 

Please find the code attached below

 

NOTE : for debug, the traps can be displayed by running the SNMPB software on a system without the need to configure it to receive traps : just run SNMPB

 

Labels (1)
Tags (1)
1 Solution
945 Views
trailman
Contributor V

In order to handle responses to INFORMV2 notifications, I've slightly modified the RTCS source code to add support for a user provided handler called each time a response is received.

 

When you send an INFORMV2 to an IP address, you specify a unique request-id to identify the request (parameter to SNMP_trap_send()). The requets-id may be a value incremented each time a notification in sent.

 

When the response is received from the IP address, the handler is called with the IP address and request-id as parameter, so that you know that this IP address has received this notification.

 

Especially if your application supports multiple target IP addresses or multiple INFORMV2 notifications, you should use a queue to remember what has been sent to which IP by creating an entry in the queue for each packet sent, remove the entry from queue when the related response is received, and resend if no response is received.

 

NOTE : as INFORMV2 is sent from port 161 (SNMP) to port SNMP-TRAP (162), the target IP replies to port 161, so we do not have to create a new socket to receive responses : we use the existing one (used for set/get/...)

 

Here is the patch for RTCS to implement the handler.

View solution in original post

0 Kudos
7 Replies
945 Views
trailman
Contributor V

Hi all,

I have prepared the code.

- trap_code.zip : the new code for trap management (V1 and V2), also supporting V2 inform (replaces code of MQX RTCS in traps.c)

- rtcs_snmp_inform.patch : the patch to MQX37 to add support for V2 inform response handler (modifies snmp.c; need to rebuild MQX)

First you have to declare a global_data_config_net structure and fill all its fields (see snmp_task.h).

You select V1 trap, V2 trap, or V2 inform

Also the retry period and the retry count to determine how many traps are sent or how many informs are sent without reply

For IP addresses if targets, fill each value with an IP address or 0.0.0.0; for example :

_ip_address ip_addr;

  Shell_parse_ip_address("192.168.0.1", &ip_addr);

  RTCS_to_IPbytes(ip_addr, global_data_config_net.snmp_notify_target_IP[0]);

  Shell_parse_ip_address("0.0.0.0", &ip_addr);

  RTCS_to_IPbytes(ip_addr, global_data_config_net.snmp_notify_target_IP[1]);

  RTCS_to_IPbytes(ip_addr, global_data_config_net.snmp_notify_target_IP[2]);

(I don't use the standard "add_target" function)

You also need to define some MIB nodes related to you product (required for product specific traps/informs) :

extern RTCSMIB_NODE MIBNODE_myCompany;

extern const RTCSMIB_NODE MIBNODE_myProduct;

extern const RTCSMIB_NODE MIBNODE_myProductTrap1;

extern const RTCSMIB_NODE MIBNODE_myProductTrap2;

Then you call

void snmp_task_init(void)

and run

void snmp_task_main(uint_32 initial_data)

as a task (for example stack size 2048 and prio 8)

each time you want ot send a trap, you call snmp_task_update()

For example :snmp_task_update(SNMP_TASK_SEND_MYPRODUCTTRAP1);

945 Views
pozz
Contributor III

Dear Gilles,

I can't find your code. Can you post it again?

0 Kudos
945 Views
trailman
Contributor V

!!!!!! Hi Guys at Freescale !!!!!!

It seems the attachment I made has been lost during the migration of the forum.

It is the same for all the other attachments I made in several other threads.

For some of them, I did not keep a copy on my computer thinking they will always be available on the forum. This is the case for the SNMP code.

Any hope to see them back ?

0 Kudos
945 Views
Monica
Senior Contributor III

Hello Gilles!

Unfortunately, the script that helped us during the migration swiped out all the attachments and original settings of the posts made before. There is no way to recover the content :smileysad:

The following post explains more about it.

Migration happened last September...FAQs

0 Kudos
946 Views
trailman
Contributor V

In order to handle responses to INFORMV2 notifications, I've slightly modified the RTCS source code to add support for a user provided handler called each time a response is received.

 

When you send an INFORMV2 to an IP address, you specify a unique request-id to identify the request (parameter to SNMP_trap_send()). The requets-id may be a value incremented each time a notification in sent.

 

When the response is received from the IP address, the handler is called with the IP address and request-id as parameter, so that you know that this IP address has received this notification.

 

Especially if your application supports multiple target IP addresses or multiple INFORMV2 notifications, you should use a queue to remember what has been sent to which IP by creating an entry in the queue for each packet sent, remove the entry from queue when the related response is received, and resend if no response is received.

 

NOTE : as INFORMV2 is sent from port 161 (SNMP) to port SNMP-TRAP (162), the target IP replies to port 161, so we do not have to create a new socket to receive responses : we use the existing one (used for set/get/...)

 

Here is the patch for RTCS to implement the handler.

0 Kudos
945 Views
sw_bob
Contributor I

Thanks for posting your code.

I tried caling your function instead of MQX's supplied SNMPv2_trap_userSpec() and I don't see any traps coming out.

I am trying to send a generic linkup.

I am doing it exactly the same as your demo code does.

 

Are there any gochas that exist with this code?

0 Kudos
945 Views
trailman
Contributor V

Hi,

 

Sorry for the delayed response due to that I currently no more work on MQX.

 

After network interface initialization (IP address set and interface up), you have to run the SNMP server because the trap code uses some internal data inited by the server.

You can do it as follows :

 

void snmp_start(void)
{
    printf("SNMP start\n");

    /* init MIBs */
    MIB1213_init();
#ifdef SNMP_MQX_MIB //takes 5KB of flash space
    MIBMQX_init();
#endif

    printf("SNMP: starting SNMP server\n");
    if (SNMP_init("SNMP", SNMP_TASK_PRIO, SNMP_TASK_STACK_SIZE))
    {
        printf("ERROR: failed to init SNMP server\n");
        return;
    }
}

 

Then you add trap receivers to the list of receivers using RTCS_trap_target_add()

 

See example code in BSP sources at Freescale MQX 3.7/rtcs/examples/snmp/snmptraps.c for SNMP initialization.

 

When done you can call the trap code.

 

0 Kudos