|
The SNMP agent supports to generate SNMPv1 trap and SNMPv2/v3 notification. User can generate SNMPv1 trap by defining a TRAP-TYPE construct in the MIB. SNMPv2/v3 Notification can be generated by defining a NOTIFICATION-TYPE construct in the MIB. The MIB file is then loaded in the Agent Compiler to generate source files with necessary options.
For each trap definition in the MIB, the corresponding trap generation function will be generated by Agent Compiler in the file <WebNMS/C-Agent\projects\<ProjectName>\agent\stubs\<Mib Name>\src\<Mib Name> + traps.c. This file will have necessary function calls to generate the defined trap.
If the option Generate Traps on Set is enabled in the Settings options tab of the Agent Compiler, the trap generation function is invoked on SNMP SET of each variable in trap definition. The user can also call this function with required arguments from anywhere in the agent or his application to send the trap to corresponding managers.
Sending Notification (Event) is an important module in agent implementation. In the Multi-Protocol Agent, the notification model consists of two different modules Notification Broadcaster and Receiver. The following diagram will explain its implementation.

Notification Broadcaster
The main objective of this module is to take a notification and broadcast it to all its registered listeners. For this purpose, it maintains a table, which will have all registered listeners information. There are three methods used in this module to broadcast notification, which are defined in notificationsupport.c.
Register Method
A listener can be added to the listeners table using the following method call:
|
CHAR AddNotifListener(Vector *table, NotificationListener *listener, NotificationFilter *filter, CHAR *handback) |
where,
table: listener to be added.
listener: method to receive notification.
filter: method to filter the notification before receiving it.
handback: the context used to receive notification.
After successful registration it will return SUCCESS otherwise FAILURE.
Unregister Method
The registered notification can be deleted from the listeners table using the following function call,
|
CHAR RemoveNotifListener(Vector *table, NotificationListener *listener, CHAR *handback) |
listener: the registered listener.
handback: the context used in the registration.
After successful de-registeration it will return SUCCESS otherwise FAILURE.
Send Method
When SendNotification() method is called with the created Notification, the notification broadcaster takes each entry of the listeners table. It will call Filter method first. If the return value is SUCCESS then it will call listener method, otherwise not. This is repeated for each entry in the listener table. The following function call is used to broadcast notification:
|
void SendNotification(Vector *table, Notification *notif); |
where,
table: contains registered listeners.
notif: the created notification.
|
|
Note: These three methods of notificationsupport.c cannot be used directly. User should write one wrapper file where he should declare and initialize a table (Vector). For each of the above mentioned functions, this wrapper file should have one wrapper function, so all these methods of notificationsupport.c can be accessed using the wrapper functions. |
Notification Receiver
It will receive the notification and process it. In order to receive notification from a notification broadcaster, it must register itself as a listener to the broadcaster using the add notification listener function call (e.g. AddTimerServiceNotificationListener() ) with valid notification filter and listener methods to filter and process the received notification.
Example
The file mynotificationbroadcaster.c has two variables declarations and four methods definition,
|
/* To store the listeners information */ Vector gv_myNotifBroadcasterTable; /* The broadcaster information which is to be registered with agentServer. */ ModuleInfo gv_myNotifBroadcasterInfo = { "My Notification Broadcaster", NULL , NULL, 0, NULL, NULL, NULL, AddMyNotificationListener, RemoveMyNotificationListener };
void InitMyNotifBroadcaster(void) |
It is used to register the notification broadcaster module with agent server, and also it will initialize the notification broadcaster variables (vector, etc.).
|
CHAR AddMyNotificationListener(NotificationListener *listener, NotificationFilter *filter, CHAR *handback); |
It is a wrapper method for AddNotifListener() method to add notification listener in the listeners table (gv_myNotifBroadcasterTable).
CHAR RemoveMyNotificationListener(NotificationListener *listener,
CHAR *handback);
It is a wrapper method for RemoveNotifListener() method to remove notification from the listeners table (gv_myNotifBroadcasterTable).
void SendMyNotification(Notification *notif);
It is a wrapper method for SendNotification() method to broadcast the given notification to all registered listeners of the listeners table (gv_myNotifBroadcasterTable).
Please click the link for Example on notification model.
The prototype of the function to generate notification under MultiPrtocolAgent is
|
void Create<Trap Name>Notification() |
The notification message sent by the agent contains notification-specific information, such as notification variables/objects names and protocol-specific information, such as Enterprises OID, Generic Trap Type, Specific Trap Type, Trap OID, Trap version, etc.
This function contains necessary code to generate a notification message. It will broadcast the notification message to all protocol adapters (SNMP and HTTP) through agent server. Each protocol adapter will create a notification message based on the protocol type and send it to all its registered managers. The user can update these notification variables/objects value before calling this function based on the event occurred.
This notification function contains the notification attributes, where each notification variable/object is represented in the following format:
|
{"<Mib Module Name>:<Module Name>","<"Trap variable name">,RowIndex} |
where,
Mib Module Name: The name of the MIB.
Module Name name: the name of the module in which the notification variable/object is defined.
Trap variable name: the name of the notification variable/object defined in the notification.
RowIndex: It is used to specify a particular row in the table. For scalars the RowIndex is zero and for tables the user can specify the Row Index.
Example for scalar notificaton
The code generated for the notification type scalarnotifications defined in the AGENT-SAMPLE-MIB is given below:
|
notificationAttribute notifAttrbs[4] = { { "AGENT-SAMPLE-MIB:Utilities", "agentNetstat", 0 }, { "AGENT-SAMPLE-MIB:AgentSystem", "agentLocation", 0 }, { "AGENT-SAMPLE-MIB:AgentSystem", "agentAvailMemory", 0 }, { "AGENT-SAMPLE-MIB:Utilities", "agentPing", 0 } }; |
Example for Table Notification
For example, the code generated for the notification type tablenotifications defined in the AGENT-SAMPLE-MIB is given below:
|
notificationAttribute notifAttrbs[3] = { { "AGENT-SAMPLE-MIB:AdiskTable", "adiskName", 0 }, { "AGENT-SAMPLE-MIB:AaplicationUserTable", "aaplicationUserName", 0 }, { "AGENT-SAMPLE-MIB:AdiskTable", "adiskUsed", 0 } }; |
The notification function contains the protocol attributes, which varies for v1 and v2 MIBs. For v2 MIBs, the following information is generated.
SnmpVersion: The SNMP version of the MIB.
TrapOid: OID value of the node which defines the notification.
InformMsg: In SNMPv2, the agent sends unconfirmed trap (NOTIFICATION) and confirmed trap (NFORM) to manager. If the user wants confirmation (response) for the traps sent make informFlag as "YES" else make it as "NO".
For example, the protocol attributes for the notification type scalarnotifications defined in the AGENT-SAMPLE-MIB is given below:
|
attribute protocolsAttrbs[] = { { "SnmpVersion", "SNMP_VERSION_2c" }, { "TrapOid", ".1.3.6.1.4.1.2162.4.7.2" }, { "InformMsg", "NO" } }; |
For v1 MIBs, the following information is generated
Snmp version: The SNMP version of the MIB.
GenericTrap: If the Trap Type value is zero through five, then the trap is one of the generic SNMP traps defined by the SNMP group of MIB-II and the Specific TrapType will be zero.
Specific Trap: If the Trap Type value is six, then this trap is an enterprise-specific trap that is defined in a private MIB.
EnterpriseOId: The OID specified in the Enterprises field indicates exactly which management enterprise defines the trap.
For example, the protocol attributes for the notification type "Traps" defined in RFC-1213 MIB is given below:
|
attribute protocolsAttrbs[] = { { "SnmpVersion", "SNMP_VERSION_1" }, { "GenericTrap", "5" }, { "SpecificTrap", "0" }, { "EnterpriseOid", ".1.3.6.1.2.1.11" } }; |
The SNMP agent supports to generate SNMPv2 INFORM i.e., Confirmed Notification. But in SNMPv3, INFORM generations is not supported.
Generate SNMPv2 INFORM
The generated notification method of traps.c file will have a Protocol Attributes variable. It will have SNMP protocol-specific information, such as SnmpVersion, TrapOid, InformMsg, etc. If the user changes the InformMsg attribute as "YES" then the notification will send us INFORM.
For example, the protocol attributes for the notification type "scalarnotifications" defined in the AGENT-SAMPLE-MIB is given below:
|
attribute protocolsAttrbs[] = { { "SnmpVersion", "SNMP_VERSION_2c" }, { "TrapOid", ".1.3.6.1.4.1.2162.4.7.1" }, { "InformMsg", "YES" } } |
Receive SNMPv2 INFORM
The agent can also receive a SNMPv2 INFORM request from the manager. For this no extra configuration is required. After receiving the INFORM, the agent will call the following function from the file <WebNMS>/C-Agent/projects/<Project Name>/agent/stubs/inform.c.
|
void DisplayInformInfo(snmpPdu *pdu) |
Before calling the above method the agent will call the authentication module to authenticate the received INFORM request. The DisplayInformInfo() function will display all the information of the received INFORM message. If the user wants to take some action on receiving INFORM request from the manager, then he can edit this function.
Receive SNMPv3 INFORM
The agent can also receive a SNMPv3 INFORM request from the manager. For this no extra configuration is required. After receiving the INFORM the agent will call the following function from the file <WebNMS>/C-Agent/projects/<Project Name>/agent/stubs/inform.c.
|
void DisplayInformInfo(snmpPdu *pdu) |
Before calling the above method the agent will do the authentication as defined in the USM security module and VACM access control module to authenticate the received INFORM request. The DisplayInformInfo() function will display all the information of the received INFORM message. If the user wants to take some action on receiving INFORM request from the manager, then he can edit this function.
Identifying the Instance of a Trap Object in a Table
A trap may be defined for a scalar/table column object defined in the MIB. But when a trap is sent for a table column object, how does the agent identify the row whose data are to be sent with the trap? The MIB standards do not specify which instance of a columnar object to return. The DESCRIPTION clause must be used for this purpose wherein you can describe which instance of a columnar object to return in the event report..
When the WebNMS C Agent generates a trap/notification, by default it uses the data in the first row to be sent along with the trap even if the data belong to second row or third row, etc. But, it is possible to indicate to the trap function which instance of the variable should be included in the trap.
Identifying a particular row in a table to collect trap variable data is purely implementation dependent. For example, you may want to retrieve Table A's data from second row or from the third row to be sent with the trap.
In Multi-Protocol Agent, the function CreateNotification() in ./stubs/agent-sample-mib/src/ agentsamplemibtraps.c file defines the following notification attributes for each trap object defined where RowIndex is generated as '0'. This, by default takes the first row from the table as instance.
|
{ <Mib Module Name>:<Module Name>","<"Trap variable name">, 0} |
Here, instead of 0 you can give any valid row number.
There are different ways of identifying the row of a table column whose data is to be sent with the trap function :
Change the prototype of the above methods, by adding one extra argument for row index.
Do some processing in the trap function to retrieve the particular row from the table.
Example
In this example, we will explain the working of table notifications sent out when a particular column is set with index of the object identifying the affected row in the notification.
Let us take the AGENT-SAMPLE-MIB as an example. A notification is sent out when a set request is made for the trap object aaplicationUserName of the aaplicationUserTable. The notification is sent with the instance for which the set request is made.
In this example we made the following modification to the ./stubs/agent-sample-mib/src/ agentsamplemibtraps.c file to specify the row index in the trap function :
Add one extra argument for row index in the CreateNotification function as shown below:
|
void CreatetableNotificationsNotification(INT32 rowIndex) |
In the above function, specify the rowindex for notification attribute aaplicationUserName as shown below before calling the SendagentsamplemibNotification() function, where noifAttrbs[1] refers to aaplicationUserName.
|
notifAttrbs[1].rowIndex = rowIndex; notif = CreateEnterpriseNotification(protocolsAttrbs, 4, notifAttrbs, 3, NULL, NULL); if (notif != NULL) { SendagentsamplemibNotification(notif); } |
The method GetRowIndexByEntry() defined in ./utils/table.c file is used to return the index corresponding to the matching entry pointer. In SetAaplicationUserName() defined in ./stubs/agent-sample-mib/src/ aplicationusertableinstru.c the following modifications are made:
Declare the variable INT32 rowIndex
Call the GetRowIndexByEntry() method before calling CreatetableNotificationsNotification() as shown below:
|
rowIndex = GetRowIndexByEntry(&gv_aaplicationUserTableVector, tableEntryPtr); CreatetableNotificationsNotification(rowIndex); |
Now if you do a set for 1st row of the aaplicationUserName, then trap will contain 1st row's attribute, if 2nd row, then 2nd rows attribute, and so on.
To use this file,
Create a project for AGENT-SAMPLE-MIB with Agent Type as Multi-Protocol Agent.
Generate source code.
Copy the attached agentsamplemibtraps.c and aaplicationusertableinstru.c file to ./stubs/agent-sample-mib/src directory.
Compile the agent.
Run the agent.
Now if you do a set (aplicationuserName)for 1st row then trap will contain 1st row's attribute.(if it is 2nd row then 2nd row attributes. so on).
For snmpv1 MIB
If the MIB is snmpv1 MIB, the trap function generates code for the trap version as v1 by default. Hence, the trap generated will be v1 trap. In this case, the SNMP version cannot be changed from v1 to v2/v3 to generate v2/v3 traps.
{ "SnmpVersion", "SNMP_VERSION_1" },
For snmpv2 MIB
If the MIB is snmpv2 MIB, the trap function generates code for the trap version as v2 by default. Hence, the trap generated will be v2 trap. In this case, the SNMP version can be changed to v1/v3 to generate v1/v3 traps.
{ "SnmpVersion", "SNMP_VERSION_2c" },
To change the version from v2 to v1,
Comment the code for TrapOid. But this is optional.
Provide values for Enterprise OID.
Provide values for Generic trap as per RFC specifications.
Provide values for Specific trap as per RFC specifications.
Change the version as : { "SnmpVersion", "SNMP_VERSION_1" }
To change the version from v2 to v3 change the version as : { "SnmpVersion", "SNMP_VERSION_3" },
|