diff options
Diffstat (limited to 'agent/mibgroup/examples/notification.c')
-rw-r--r-- | agent/mibgroup/examples/notification.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/agent/mibgroup/examples/notification.c b/agent/mibgroup/examples/notification.c new file mode 100644 index 0000000..ab60201 --- /dev/null +++ b/agent/mibgroup/examples/notification.c @@ -0,0 +1,175 @@ +/** @example notification.c + * This example shows how to send a notification from inside the + * agent. In this case we do something really boring to decide + * whether to send a notification or not: we simply sleep for 30 + * seconds and send it, then we sleep for 30 more and send it again. + * We do this through the snmp_alarm mechanisms (which are safe to + * use within the agent. Don't use the system alarm() call, it won't + * work properly). Normally, you would probably want to do something + * to test whether or not to send an alarm, based on the type of mib + * module you were creating. + * + * When this module is compiled into the agent (run configure with + * --with-mib-modules="examples/notification") then it should send + * out traps, which when received by the snmptrapd demon will look + * roughly like: + * + * 2002-05-08 08:57:05 localhost.localdomain [udp:127.0.0.1:32865]: + * sysUpTimeInstance = Timeticks: (3803) 0:00:38.03 snmpTrapOID.0 = OID: netSnmpExampleNotification + * + */ + +/* + * start be including the appropriate header files + */ +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +/* + * contains prototypes + */ +#include "notification.h" + +/* + * our initialization routine + * (to get called, the function name must match init_FILENAME() + */ +void +init_notification(void) +{ + DEBUGMSGTL(("example_notification", + "initializing (setting callback alarm)\n")); + snmp_alarm_register(30, /* seconds */ + SA_REPEAT, /* repeat (every 30 seconds). */ + send_example_notification, /* our callback */ + NULL /* no callback data needed */ + ); +} + +/** here we send a SNMP v2 trap (which can be sent through snmpv3 and + * snmpv1 as well) and send it out. + * + * The various "send_trap()" calls allow you to specify traps in different + * formats. And the various "trapsink" directives allow you to specify + * destinations to receive different formats. + * But *all* traps are sent to *all* destinations, regardless of how they + * were specified. + * + * + * I.e. it's + * @verbatim + * ___ trapsink + * / + * send_easy_trap \___ [ Trap ] ____ trap2sink + * ___ [ Generator ] + * send_v2trap / [ ] ----- informsink + * \____ + * trapsess + * + * *Not* + * send_easy_trap -------------------> trapsink + * send_v2trap -------------------> trap2sink + * ???? -------------------> informsink + * ???? -------------------> trapsess + * @endverbatim + */ +void +send_example_notification(unsigned int clientreg, void *clientarg) +{ + /* + * define the OID for the notification we're going to send + * NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification + */ + oid notification_oid[] = + { 1, 3, 6, 1, 4, 1, 8072, 2, 3, 0, 1 }; + size_t notification_oid_len = OID_LENGTH(notification_oid); + static u_long count = 0; + + /* + * In the notification, we have to assign our notification OID to + * the snmpTrapOID.0 object. Here is it's definition. + */ + oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; + size_t objid_snmptrap_len = OID_LENGTH(objid_snmptrap); + + /* + * define the OIDs for the varbinds we're going to include + * with the notification - + * NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatRate and + * NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatName + */ + oid hbeat_rate_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 3, 2, 1, 0 }; + size_t hbeat_rate_oid_len = OID_LENGTH(hbeat_rate_oid); + oid hbeat_name_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 3, 2, 2, 0 }; + size_t hbeat_name_oid_len = OID_LENGTH(hbeat_name_oid); + + /* + * here is where we store the variables to be sent in the trap + */ + netsnmp_variable_list *notification_vars = NULL; + const char *heartbeat_name = "A girl named Maria"; +#ifdef RANDOM_HEARTBEAT + int heartbeat_rate = rand() % 60; +#else + int heartbeat_rate = 30; +#endif + + DEBUGMSGTL(("example_notification", "defining the trap\n")); + + /* + * add in the trap definition object + */ + snmp_varlist_add_variable(¬ification_vars, + /* + * the snmpTrapOID.0 variable + */ + objid_snmptrap, objid_snmptrap_len, + /* + * value type is an OID + */ + ASN_OBJECT_ID, + /* + * value contents is our notification OID + */ + (u_char *) notification_oid, + /* + * size in bytes = oid length * sizeof(oid) + */ + notification_oid_len * sizeof(oid)); + + /* + * add in the additional objects defined as part of the trap + */ + + snmp_varlist_add_variable(¬ification_vars, + hbeat_rate_oid, hbeat_rate_oid_len, + ASN_INTEGER, + (u_char *)&heartbeat_rate, + sizeof(heartbeat_rate)); + + /* + * if we want to insert additional objects, we do it here + */ + if (heartbeat_rate < 30 ) { + snmp_varlist_add_variable(¬ification_vars, + hbeat_name_oid, hbeat_name_oid_len, + ASN_OCTET_STR, + heartbeat_name, strlen(heartbeat_name)); + } + + /* + * send the trap out. This will send it to all registered + * receivers (see the "SETTING UP TRAP AND/OR INFORM DESTINATIONS" + * section of the snmpd.conf manual page. + */ + ++count; + DEBUGMSGTL(("example_notification", "sending trap %ld\n",count)); + send_v2trap(notification_vars); + + /* + * free the created notification variable list + */ + DEBUGMSGTL(("example_notification", "cleaning up\n")); + snmp_free_varbind(notification_vars); +} |