components/net-snmp-57/sun/sdk/demo/demo_module_4/me4LoadGroup.c
changeset 5867 445e2cf1c845
parent 252 ee0fb1eabcbf
equal deleted inserted replaced
5866:683c5c035a79 5867:445e2cf1c845
       
     1 /*
       
     2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  * 
       
     4  * U.S. Government Rights - Commercial software. Government users are subject to
       
     5  * the Sun Microsystems, Inc. standard license agreement and applicable
       
     6  * provisions of the FAR and its supplements.
       
     7  * 
       
     8  * 
       
     9  * This distribution may include materials developed by third parties. Sun, Sun
       
    10  * Microsystems, the Sun logo and Solaris are trademarks or registered
       
    11  * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
       
    12  * 
       
    13  */
       
    14 
       
    15 
       
    16 /*
       
    17  * demo_module_4:
       
    18  * 
       
    19  * This module is based on the SDK-DEMO4-MIB.txt MIB. It implements the
       
    20  * me4LoadGroup objects.
       
    21  * 
       
    22  * This example module demonstrates following features: - Automatic Refresh of
       
    23  * data in regular intervals - Check for alarm condition in regular intervals
       
    24  * and generate trap if necessary. - Read threshold values from an external
       
    25  * configuration file called demo_module_4.conf
       
    26  */
       
    27 
       
    28 
       
    29 #include <net-snmp/net-snmp-config.h>
       
    30 #include <net-snmp/net-snmp-includes.h>
       
    31 #include <net-snmp/agent/net-snmp-agent-includes.h>
       
    32 #include "me4LoadGroup.h"
       
    33 #include <sys/loadavg.h>
       
    34 #include <netdb.h>
       
    35 
       
    36 
       
    37 /*
       
    38  * Data for demo_module_4: loadavg1 stores data for me4SystemLoadAvg1min
       
    39  * loadavg5 stores data for me4SystemLoadAvg5min loadavg15 stores data for
       
    40  * me4SystemLoadAvg15min
       
    41  */
       
    42 
       
    43 char           *loadavg1, *loadavg5, *loadavg15;
       
    44 
       
    45 /* Alarm thresholds for demo_module_4 */
       
    46 
       
    47 float           threshold_loadavg1 = 1.0, threshold_loadavg5 = 2.0, threshold_loadavg15 = 3.0;
       
    48 
       
    49 /* Maintain previous alarm states for comparison */
       
    50 
       
    51 int             prev_loadavg1_state = OK;
       
    52 int             prev_loadavg5_state = OK;
       
    53 int             prev_loadavg15_state = OK;
       
    54 
       
    55 /* Common variables for information to be included in traps */
       
    56 
       
    57 u_char          hostName[MAXHOSTNAMELEN], moduleName[15];
       
    58 
       
    59 
       
    60 /** Initializes the demo_module_4 module
       
    61  * This is the Init function which is called when the module is loaded by the agent.
       
    62  *
       
    63  * Note: The name of this function has been changed from "init_me4LoadGroup" to
       
    64  * "init_demo_module_4" to give unique names to example modules across the SMA
       
    65  * SDK.
       
    66  */
       
    67 
       
    68 
       
    69 void
       
    70 init_demo_module_4(void)
       
    71 {
       
    72 
       
    73     int             retCode;
       
    74 
       
    75     static oid      me4SystemLoadAvg15min_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 3, 0};
       
    76     static oid      me4SystemLoadAvg1min_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 1, 0};
       
    77     static oid      me4SystemLoadAvg5min_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 2, 0};
       
    78 
       
    79     DEBUGMSGTL(("me4LoadGroup", "Initializing\n"));
       
    80 
       
    81     netsnmp_register_read_only_instance(netsnmp_create_handler_registration
       
    82 					("me4SystemLoadAvg15min",
       
    83 					 get_me4SystemLoadAvg15min,
       
    84 					 me4SystemLoadAvg15min_oid,
       
    85 				      OID_LENGTH(me4SystemLoadAvg15min_oid),
       
    86 					 HANDLER_CAN_RONLY));
       
    87     netsnmp_register_read_only_instance(netsnmp_create_handler_registration
       
    88 					("me4SystemLoadAvg1min",
       
    89 					 get_me4SystemLoadAvg1min,
       
    90 					 me4SystemLoadAvg1min_oid,
       
    91 				       OID_LENGTH(me4SystemLoadAvg1min_oid),
       
    92 					 HANDLER_CAN_RONLY));
       
    93     netsnmp_register_read_only_instance(netsnmp_create_handler_registration
       
    94 					("me4SystemLoadAvg5min",
       
    95 					 get_me4SystemLoadAvg5min,
       
    96 					 me4SystemLoadAvg5min_oid,
       
    97 				       OID_LENGTH(me4SystemLoadAvg5min_oid),
       
    98 					 HANDLER_CAN_RONLY));
       
    99 
       
   100     /* Initialize some common data */
       
   101 
       
   102     retCode = gethostname((char *) hostName, MAXHOSTNAMELEN);
       
   103     if (retCode != 0)
       
   104 	strcpy((char *) hostName, "null\0");
       
   105 
       
   106     strcpy((char *) moduleName, "demo_module_4\0");
       
   107 
       
   108 
       
   109     /* Allocate memory once. These variables will hold load data */
       
   110 
       
   111     loadavg1 = malloc(10 * sizeof(char));
       
   112     loadavg5 = malloc(10 * sizeof(char));
       
   113     loadavg15 = malloc(10 * sizeof(char));
       
   114 
       
   115     /*
       
   116      * Register for thresholds. When a token (say threshold_loadavg1) is
       
   117      * found in demo_module_4.conf file, the read_load_thresholds function is
       
   118      * called by the agent
       
   119      */
       
   120 
       
   121     register_config_handler("demo_module_4", "threshold_loadavg1",
       
   122 			    read_load_thresholds, NULL, NULL);
       
   123 
       
   124     register_config_handler("demo_module_4", "threshold_loadavg5",
       
   125 			    read_load_thresholds, NULL, NULL);
       
   126 
       
   127     register_config_handler("demo_module_4", "threshold_loadavg15",
       
   128 			    read_load_thresholds, NULL, NULL);
       
   129 
       
   130 
       
   131     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG,
       
   132 			   demo_4_post_read_config, NULL);
       
   133 
       
   134 
       
   135 }
       
   136 
       
   137 /**
       
   138  * The callback function that is called after the configuration files are
       
   139  * read by the agent ( the thresholds are loaded into the module )
       
   140  */
       
   141 
       
   142 int 
       
   143 demo_4_post_read_config(int a, int b, void *c, void *d)
       
   144 {
       
   145 
       
   146     /* Refresh the load data every 60 seconds */
       
   147     snmp_alarm_register(60, SA_REPEAT, refreshLoadAvg, NULL);
       
   148 
       
   149     /* Acquire the data first time */
       
   150     refreshLoadAvg(0, NULL);
       
   151 
       
   152     return 1;
       
   153 
       
   154 }
       
   155 
       
   156 
       
   157 /*
       
   158  * This function is generated by mib2c. It is called when an SNMP "get"
       
   159  * request arrives for the node me4SystemLoadAvg15min
       
   160  * 
       
   161  */
       
   162 
       
   163 int
       
   164 get_me4SystemLoadAvg15min(netsnmp_mib_handler * handler,
       
   165 			  netsnmp_handler_registration * reginfo,
       
   166 			  netsnmp_agent_request_info * reqinfo,
       
   167 			  netsnmp_request_info * requests)
       
   168 {
       
   169     /*
       
   170      * We are never called for a GETNEXT if it's registered as a "instance",
       
   171      * as it's "magically" handled for us.
       
   172      */
       
   173 
       
   174     /*
       
   175      * a instance handler also only hands us one request at a time, so we
       
   176      * don't need to loop over a list of requests; we'll only get one.
       
   177      */
       
   178 
       
   179     /* Refresh the load data by calling the refresh function */
       
   180     refreshLoadAvg(0, NULL);
       
   181 
       
   182     switch (reqinfo->mode) {
       
   183 
       
   184     case MODE_GET:
       
   185 
       
   186 	refreshLoadAvg(0, NULL);
       
   187 
       
   188 	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) loadavg15, strlen(loadavg15));
       
   189 	break;
       
   190 
       
   191 
       
   192     default:
       
   193 	/* we should never get here, so this is a really bad error */
       
   194 	return SNMP_ERR_GENERR;
       
   195     }
       
   196 
       
   197     return SNMP_ERR_NOERROR;
       
   198 }
       
   199 
       
   200 /*
       
   201  * This function is generated by mib2c. It is called when an SNMP "get"
       
   202  * request arrives for the node me4SystemLoadAvg1min
       
   203  * 
       
   204  */
       
   205 
       
   206 
       
   207 int
       
   208 get_me4SystemLoadAvg1min(netsnmp_mib_handler * handler,
       
   209 			 netsnmp_handler_registration * reginfo,
       
   210 			 netsnmp_agent_request_info * reqinfo,
       
   211 			 netsnmp_request_info * requests)
       
   212 {
       
   213     /*
       
   214      * We are never called for a GETNEXT if it's registered as a "instance",
       
   215      * as it's "magically" handled for us.
       
   216      */
       
   217 
       
   218     /*
       
   219      * a instance handler also only hands us one request at a time, so we
       
   220      * don't need to loop over a list of requests; we'll only get one.
       
   221      */
       
   222 
       
   223     switch (reqinfo->mode) {
       
   224 
       
   225 	case MODE_GET:
       
   226 
       
   227 	refreshLoadAvg(0, NULL);
       
   228 	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) loadavg1, strlen(loadavg1));
       
   229 	break;
       
   230 
       
   231 
       
   232     default:
       
   233 	/* we should never get here, so this is a really bad error */
       
   234 	return SNMP_ERR_GENERR;
       
   235     }
       
   236 
       
   237     return SNMP_ERR_NOERROR;
       
   238 }
       
   239 
       
   240 /*
       
   241  * This function is generated by mib2c. It is called when an SNMP "get"
       
   242  * request arrives for the node me4SystemLoadAvg5min
       
   243  * 
       
   244  */
       
   245 
       
   246 
       
   247 int
       
   248 get_me4SystemLoadAvg5min(netsnmp_mib_handler * handler,
       
   249 			 netsnmp_handler_registration * reginfo,
       
   250 			 netsnmp_agent_request_info * reqinfo,
       
   251 			 netsnmp_request_info * requests)
       
   252 {
       
   253     /*
       
   254      * We are never called for a GETNEXT if it's registered as a "instance",
       
   255      * as it's "magically" handled for us.
       
   256      */
       
   257 
       
   258     /*
       
   259      * a instance handler also only hands us one request at a time, so we
       
   260      * don't need to loop over a list of requests; we'll only get one.
       
   261      */
       
   262 
       
   263     refreshLoadAvg(0, NULL);
       
   264 
       
   265     switch (reqinfo->mode) {
       
   266 
       
   267     case MODE_GET:
       
   268 
       
   269 	refreshLoadAvg(0, NULL);
       
   270 
       
   271 	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) loadavg5, strlen(loadavg5));
       
   272 	break;
       
   273 
       
   274     default:
       
   275 	/* we should never get here, so this is a really bad error */
       
   276 	return SNMP_ERR_GENERR;
       
   277     }
       
   278 
       
   279     return SNMP_ERR_NOERROR;
       
   280 }
       
   281 
       
   282 
       
   283 /*
       
   284  * refreshLoadAvg: This is the function which "refreshes" the load data using
       
   285  * the system call "getloadavg". The data is stored in the 3 variables
       
   286  * loadavg1, loadavg5, loadavg15. Once the data is refreshed, the "check"
       
   287  * functions are called to check for alarm conditions
       
   288  */
       
   289 
       
   290 void 
       
   291 refreshLoadAvg(unsigned int clientreg, void *clientarg)
       
   292 {
       
   293 
       
   294     double          loadavg[3];
       
   295     int             numOfSamples = getloadavg(loadavg, 3);
       
   296     sprintf(loadavg1, "%.3f\0", loadavg[LOADAVG_1MIN]);
       
   297     sprintf(loadavg5, "%.3f\0", loadavg[LOADAVG_5MIN]);
       
   298     sprintf(loadavg15, "%.3f\0", loadavg[LOADAVG_15MIN]);
       
   299 
       
   300     check_loadavg1_state();
       
   301     check_loadavg5_state();
       
   302     check_loadavg15_state();
       
   303 
       
   304 }
       
   305 
       
   306 
       
   307 /*
       
   308  * Function: conv_alarm_state : This function returns appropriate charecter
       
   309  * string for each integer alarm type
       
   310  */
       
   311 
       
   312 char           *
       
   313 conv_alarm_state(int state)
       
   314 {
       
   315     switch (state) {
       
   316 	case 0:
       
   317 	return "OK\0";
       
   318     case 1:
       
   319 	return "ERROR\0";
       
   320     default:
       
   321 	return "NULL\0";
       
   322     }
       
   323 }
       
   324 
       
   325 
       
   326 
       
   327 /*
       
   328  * read_load_thresholds: This function is called when a registered token (see
       
   329  * Init_demo_module_4 function) is found in the appropriate configuration
       
   330  * file. The token's values (thresholds) are then stored in some variables.
       
   331  */
       
   332 
       
   333 void
       
   334 read_load_thresholds(const char *token, char *cptr)
       
   335 {
       
   336 
       
   337     if (strcmp(token, "threshold_loadavg1") == 0) {
       
   338 	threshold_loadavg1 = atof(cptr);
       
   339     } else if (strcmp(token, "threshold_loadavg5") == 0) {
       
   340 	threshold_loadavg5 = atof(cptr);
       
   341     } else if (strcmp(token, "threshold_loadavg15") == 0) {
       
   342 	threshold_loadavg15 = atof(cptr);
       
   343     } else {
       
   344 	/* Do nothing */
       
   345     }
       
   346 
       
   347     return;
       
   348 
       
   349 }
       
   350 
       
   351 
       
   352 
       
   353 /* send_trap: This function generates an snmpv2 trap */
       
   354 
       
   355 void
       
   356 send_trap(u_char * hostname, u_char * modulename, oid * trapoid, int size, u_char * status, u_char * description)
       
   357 {
       
   358 
       
   359     /* This is the notification type itself. This is statusChange trap */
       
   360 
       
   361     oid             notification_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 2, 1};
       
   362 
       
   363     size_t          notification_oid_len = OID_LENGTH(notification_oid);
       
   364 
       
   365     /*
       
   366      * In the notification, we have to assign our notification OID to the
       
   367      * snmpTrapOID.0 object. Here is it's definition.
       
   368      */
       
   369 
       
   370     oid             objid_snmptrap[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0};
       
   371     size_t          objid_snmptrap_len = OID_LENGTH(objid_snmptrap);
       
   372 
       
   373     /*
       
   374      * here is where we store the variables to be sent in the trap
       
   375      */
       
   376 
       
   377     netsnmp_variable_list *notification_vars = NULL;
       
   378 
       
   379     oid             hostname_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 1, 0};
       
   380 
       
   381     size_t          hostname_oid_len = OID_LENGTH(hostname_oid);
       
   382 
       
   383 
       
   384     oid             modulename_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 2, 0};
       
   385 
       
   386     size_t          modulename_oid_len = OID_LENGTH(modulename_oid);
       
   387 
       
   388 
       
   389     oid             nodeoid_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 3, 0};
       
   390 
       
   391     size_t          nodeoid_oid_len = OID_LENGTH(nodeoid_oid);
       
   392 
       
   393 
       
   394     oid             status_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 4, 0};
       
   395 
       
   396     size_t          status_oid_len = OID_LENGTH(status_oid);
       
   397 
       
   398 
       
   399     oid             description_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 5, 0};
       
   400 
       
   401     size_t          description_oid_len = OID_LENGTH(description_oid);
       
   402 
       
   403 
       
   404     /*
       
   405      * add in the trap definition object
       
   406      */
       
   407 
       
   408     snmp_varlist_add_variable(&notification_vars,
       
   409     /*
       
   410      * the snmpTrapOID.0 variable
       
   411      */
       
   412 			      objid_snmptrap, objid_snmptrap_len,
       
   413     /*
       
   414      * value type is an OID
       
   415      */
       
   416 			      ASN_OBJECT_ID,
       
   417     /*
       
   418      * value contents is our notification OID
       
   419      */
       
   420 			      (u_char *) notification_oid,
       
   421     /*
       
   422      * size in bytes = oid length * sizeof(oid)
       
   423      */
       
   424 			      notification_oid_len * sizeof(oid));
       
   425 
       
   426 
       
   427     /*
       
   428      * if we wanted to insert additional objects, we'd do it here
       
   429      */
       
   430 
       
   431 
       
   432     snmp_varlist_add_variable(&notification_vars,
       
   433 			      hostname_oid, hostname_oid_len,
       
   434     /*
       
   435      * value type is an OID
       
   436      */
       
   437 			      ASN_OCTET_STR,
       
   438     /*
       
   439      * value contents is our notification OID
       
   440      */
       
   441 			      (u_char *) hostname,
       
   442     /*
       
   443      * size in bytes = oid length * sizeof(oid)
       
   444      */
       
   445 			      strlen((char *) hostname));
       
   446 
       
   447 
       
   448     snmp_varlist_add_variable(&notification_vars,
       
   449 			      modulename_oid, modulename_oid_len,
       
   450     /*
       
   451      * value type is an OID
       
   452      */
       
   453 			      ASN_OCTET_STR,
       
   454     /*
       
   455      * value contents is our notification OID
       
   456      */
       
   457 			      (u_char *) modulename,
       
   458     /*
       
   459      * size in bytes = oid length * sizeof(oid)
       
   460      */
       
   461 			      strlen((char *) modulename));
       
   462 
       
   463 
       
   464     snmp_varlist_add_variable(&notification_vars,
       
   465 			      nodeoid_oid, nodeoid_oid_len,
       
   466     /*
       
   467      * value type is an OID
       
   468      */
       
   469 			      ASN_OBJECT_ID,
       
   470     /*
       
   471      * value contents is our notification OID
       
   472      */
       
   473 			      (u_char *) trapoid,
       
   474     /*
       
   475      * size in bytes = oid length * sizeof(oid)
       
   476      */
       
   477 			      size * sizeof(oid));
       
   478 
       
   479 
       
   480     snmp_varlist_add_variable(&notification_vars,
       
   481 			      status_oid, status_oid_len,
       
   482     /*
       
   483      * value type is an OID
       
   484      */
       
   485 			      ASN_OCTET_STR,
       
   486     /*
       
   487      * value contents is our notification OID
       
   488      */
       
   489 			      (u_char *) status,
       
   490     /*
       
   491      * size in bytes = oid length * sizeof(oid)
       
   492      */
       
   493 			      strlen((char *) status));
       
   494 
       
   495 
       
   496     snmp_varlist_add_variable(&notification_vars,
       
   497 			      description_oid, description_oid_len,
       
   498     /*
       
   499      * value type is an OID
       
   500      */
       
   501 			      ASN_OCTET_STR,
       
   502     /*
       
   503      * value contents is our notification OID
       
   504      */
       
   505 			      (u_char *) description,
       
   506     /*
       
   507      * size in bytes = oid length * sizeof(oid)
       
   508      */
       
   509 			      strlen((char *) description));
       
   510 
       
   511 
       
   512     /* SEND THE TRAP !!!! */
       
   513 
       
   514     send_v2trap(notification_vars);
       
   515 
       
   516     /*
       
   517      * free the created notification variable list
       
   518      */
       
   519 
       
   520     DEBUGMSGTL(("example_notification", "cleaning up\n"));
       
   521     snmp_free_varbind(notification_vars);
       
   522 
       
   523     return;
       
   524 
       
   525 }
       
   526 
       
   527 
       
   528 
       
   529 /*
       
   530  * check_loadavg1_state: This function does 2 things: step-1) Determine the
       
   531  * current alarm state of the node by comparing it's value with threshold.
       
   532  * step-2) Depending on the new state of the node, generate a trap
       
   533  */
       
   534 
       
   535 void 
       
   536 check_loadavg1_state()
       
   537 {
       
   538 
       
   539     /* Trap stuff */
       
   540 
       
   541     oid             trapoid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 1, 0};
       
   542     u_char          status[8];
       
   543     u_char          description[] = "Load Average over last 1 minute crossed the threshold \0";
       
   544     int             size;
       
   545     int             new_loadavg1_state = OK;
       
   546     float           currentLoad = atof(loadavg1);
       
   547 
       
   548     /* Step-1 */
       
   549 
       
   550     /* If threshold is crossed, set state to ERROR */
       
   551     if (currentLoad > threshold_loadavg1) {
       
   552 	new_loadavg1_state = ERROR;
       
   553     }
       
   554     /* Step-2 */
       
   555 
       
   556     /* Depending on the new state, send trap if necessary */
       
   557 
       
   558     size = sizeof(trapoid) / sizeof(oid);
       
   559     strcpy((char *) status, conv_alarm_state(new_loadavg1_state));
       
   560 
       
   561     if (new_loadavg1_state > prev_loadavg1_state) {
       
   562 	/* Send trap */
       
   563 	send_trap(hostName, moduleName, trapoid, size, status, description);
       
   564 	prev_loadavg1_state = new_loadavg1_state;
       
   565     } else if (new_loadavg1_state == prev_loadavg1_state) {
       
   566 	/* No Change in state .. Do nothing */
       
   567     } else if (new_loadavg1_state < prev_loadavg1_state) {
       
   568 	if (new_loadavg1_state == OK) {
       
   569 	    /* Send OK trap */
       
   570 	    prev_loadavg1_state = OK;
       
   571 	    send_trap(hostName, moduleName, trapoid, size, status, description);
       
   572 	}
       
   573     }
       
   574 }
       
   575 
       
   576 /*
       
   577  * check_loadavg5_state: This function does 2 things: step-1) Determine the
       
   578  * current alarm state of the node by comparing it's value with threshold.
       
   579  * step-2) Depending on the new state of the node, generate a trap
       
   580  */
       
   581 
       
   582 
       
   583 void 
       
   584 check_loadavg5_state()
       
   585 {
       
   586 
       
   587     /* Trap stuff */
       
   588 
       
   589     oid             trapoid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 2, 0};
       
   590     u_char          status[8];
       
   591     u_char          description[] = "Load Average over last 5 minute crossed the threshold \0";
       
   592     int             size;
       
   593 
       
   594     int             new_loadavg5_state = OK;
       
   595     double          currentLoad = atof(loadavg5);
       
   596 
       
   597     /* If threshold is crossed, set state to ERROR */
       
   598     if (currentLoad > threshold_loadavg5)
       
   599 	new_loadavg5_state = ERROR;
       
   600 
       
   601     /* Depending on the new state, send trap if necessary */
       
   602 
       
   603     size = sizeof(trapoid) / sizeof(oid);
       
   604     strcpy((char *) status, conv_alarm_state(new_loadavg5_state));
       
   605 
       
   606     if (new_loadavg5_state > prev_loadavg5_state) {
       
   607 	/* Send trap */
       
   608 	send_trap(hostName, moduleName, trapoid, size, status, description);
       
   609 	prev_loadavg5_state = new_loadavg5_state;
       
   610     } else if (new_loadavg5_state == prev_loadavg5_state) {
       
   611 	/* No Change in state .. Do nothing */
       
   612     } else if (new_loadavg5_state < prev_loadavg5_state) {
       
   613 	if (new_loadavg5_state == OK) {
       
   614 	    /* Send OK trap */
       
   615 	    prev_loadavg5_state = OK;
       
   616 	    send_trap(hostName, moduleName, trapoid, size, status, description);
       
   617 	}
       
   618     }
       
   619 }
       
   620 
       
   621 /*
       
   622  * check_loadavg15_state: This function does 2 things: step-1) Determine the
       
   623  * current alarm state of the node by comparing it's value with threshold.
       
   624  * step-2) Depending on the new state of the node, generate a trap
       
   625  */
       
   626 
       
   627 
       
   628 void 
       
   629 check_loadavg15_state()
       
   630 {
       
   631 
       
   632     /* Trap stuff */
       
   633 
       
   634     oid             trapoid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 3, 0};
       
   635     u_char          status[8];
       
   636     u_char          description[] = "Load Average over last 15 minute crossed the threshold \0";
       
   637     int             size;
       
   638 
       
   639     int             new_loadavg15_state = OK;
       
   640     double          currentLoad = atof(loadavg15);
       
   641 
       
   642     /* If threshold is crossed, set state to ERROR */
       
   643     if (currentLoad > threshold_loadavg15)
       
   644 	new_loadavg15_state = ERROR;
       
   645 
       
   646     /* Depending on the new state, send trap if necessary */
       
   647 
       
   648     size = sizeof(trapoid) / sizeof(oid);
       
   649     strcpy((char *) status, conv_alarm_state(new_loadavg15_state));
       
   650 
       
   651     if (new_loadavg15_state > prev_loadavg15_state) {
       
   652 	/* Send trap */
       
   653 	prev_loadavg15_state = new_loadavg15_state;
       
   654 	send_trap(hostName, moduleName, trapoid, size, status, description);
       
   655     } else if (new_loadavg15_state == prev_loadavg15_state) {
       
   656 	/* No Change in state .. Do nothing */
       
   657     } else if (new_loadavg15_state < prev_loadavg15_state) {
       
   658 	if (new_loadavg15_state == OK) {
       
   659 	    /* Send OK trap */
       
   660 	    prev_loadavg15_state = OK;
       
   661 	    send_trap(hostName, moduleName, trapoid, size, status, description);
       
   662 	}
       
   663     }
       
   664 }