I am developing an application for an embedded device. I want to send traps when some situation occurred. I found some examples but not really helped to me. There is a function called send_v2trap()
in net-snmp. Can someone help me? Is there need to do in snmpd.conf
and snmptrapd.conf
?

- 1,487
- 1
- 14
- 38

- 21
- 1
- 3
-
1send_v2trap() is/has to be called inside your sub-agent process (I practised under Linux but have no clue how it is under Windows). The trap/inform data will be sent to all the trapsink, trap2sink or inform/trapsess options listed in the snmpd.conf file of the SNMP Daemon (see snmpd.conf man page). The snmptrapd.conf will serve the SNMPTRAP Daemon and list what operations are allowed for which community. I do not have a [MCVE](https://stackoverflow.com/help/mcve) at the present time to give a more detailed answer. Note also that the FAQ text file in the source code archive may help – NGI Feb 15 '19 at 21:35
-
On the other hand the snmptrap shell command may help you but your question was about C language and not command line. – NGI Feb 15 '19 at 21:39
-
In the archive there is also a good example, e.g for 5.7.3 : /net-snmp-5.7.3/agent/mibgroup/examples/notification.c – NGI Feb 15 '19 at 21:56
1 Answers
We will try to make something maybe closer to real need: sending traps/informs when your OID is touched
Let's take the example ... net-snmp-5.7.x/agent/mibgroup/examples/watched.c
We change:
reginfo = netsnmp_create_handler_registration("my example string", NULL,
by
reginfo = netsnmp_create_handler_registration("my example string", handler_for_changes,
and the definition of handler_for_changes(...) is
int handler_for_changes ( netsnmp_mib_handler * p_handler,
netsnmp_handler_registration * p_reginfo,
netsnmp_agent_request_info * p_requestinfo,
netsnmp_request_info * p_requests)
{
u_char * data_ptr = NULL;
switch ( p_requestinfo->mode )
{
case MODE_SET_COMMIT:
{
switch ( p_requests->requestvb->type )
{
case ASN_INTEGER:
//...
{
data_ptr = (u_char*)p_requests->requestvb->val.integer;
}
break;
case ASN_OCTET_STR:
//...
{
data_ptr = (u_char*)p_requests->requestvb->val.string;
}
break;
}
break;
}
default:
break;
}
if ( data_ptr )
{
//This is likely not the place to do this but this is for example
netsnmp_variable_list * notification_vars = NULL;
static const oid objid_snmptrap[] = {1,3,6,1,6,3,1,1,4,1,0};
//you will need your own notif OID defined in your own MIB
static const oid notification_oid[] = {1,3,6,1,4,1,8072,2,3,0,1};
snmp_varlist_add_variable ( ¬ification_vars,
objid_snmptrap, OID_LENGTH(objid_snmptrap),
ASN_OBJECT_ID,
(u_char *) notification_oid,
OID_LENGTH(notification_oid) * sizeof(oid));
//the data that changed
snmp_varlist_add_variable ( ¬ification_vars,
p_reginfo->rootoid,p_reginfo->rootoid_len,
p_requests->requestvb->type,
data_ptr, p_requests->requestvb->val_len);
//send the trap is now one line ( + void return )
send_v2trap(notification_vars);
snmp_free_varbind(notification_vars);
}
return SNMPERR_SUCCESS;
}
There is net-snmp-config utility that let us compile an agent (see Net-SNMP tutorials)
[nils@localhost trapMCVE]$ net-snmp-config --compile-subagent mysubagent --norm watched.c
generating the temporary code file: netsnmptmp.24494.c
void init_watched(void);
checking for init_watched in watched.c
void init_watched_string(void);
void init_watched(void)
init_watched_string();
void init_watched_string(void)
checking for shutdown_watched in watched.c
running: gcc -fno-strict-aliasing -g -O2 -Ulinux -Dlinux=linux -I. -I/usr/local/include -o mysubagent netsnmptmp.24494.c watched.c -L/usr/local/lib -lnetsnmpmibs -lnetsnmpagent -lnetsnmp -lnetsnmpmibs -ldl -lnetsnmpagent -lnetsnmp
leaving the temporary code file: netsnmptmp.24494.c
subagent program mysubagent created
We can then start our SNMP Daemon with its local conf file
#likely not a best practise but for example only
rwcommunity public localhost
#inform Request
#informsink localhost:16200
trapsess -Ci -v 2c -c private localhost:16200
and we start it so that it listen to incoming SNMP request on localhost and port 1161 (randomly chosen so that > 1024 and unpriviledge). Traps will be sent to localhost on port 16200 ( randomly ... )
[nils@localhost trapMCVE]$ snmpd -f -Lo -C -c local_snmpd.conf --master=agentx --agentXSocket=tcp:localhost:1705 udp:localhost:1161
We start our sub-agent which communicates with SNMP Daemon through tcp socket on port 1705 ( randomly ... )
./mysubagent -f -Lo -x tcp:localhost:1705
At that point we may also define a local configuration file for our SNMP TRAP Daemon
#likely not a best practise but for example only
authCommunity log,execute,net private
and we start it:
snmptrapd -f -Lo -C -c local_snmptrapd.conf localhost:16200
So going back to test our sub-agent we can try a snmpget
[nils@localhost trapMCVE]$ snmpget -v 2c -c public localhost:1161 NET-SNMP-EXAMPLES-MIB::netSnmpExampleString.0
NET-SNMP-EXAMPLES-MIB::netSnmpExampleString.0 = STRING: So long, and thanks for all the fish!
and now we want to modify this string and see if a trap/inform was generated. So we do a snmpset
[nils@localhost trapMCVE]$ snmpset -v 2c -c public localhost:1161 NET-SNMP-EXAMPLES-MIB::netSnmpExampleString.0 s "Hello world: 42"
NET-SNMP-EXAMPLES-MIB::netSnmpExampleString.0 = STRING: Hello world: 42
and by miracle on the snmptrapd process
2019-02-16 01:49:10 localhost [UDP: [127.0.0.1]:45864->[127.0.0.1]:16200]:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (54342) 0:09:03.42 SNMPv2-
MIB::snmpTrapOID.0 = OID: NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification
NET-SNMP-EXAMPLES-MIB::netSnmpExampleString.0 = STRING: Hello world: 42
VOILA !!!
end of rant...
hope it helps

- 852
- 1
- 12
- 31