alarm.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:24k
- /**************************************************************
- * Copyright (C) 2001 Alex Rozin, Optical Access
- *
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * ALEX ROZIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * ALEX ROZIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- ******************************************************************/
- #include <net-snmp/net-snmp-config.h>
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #if TIME_WITH_SYS_TIME
- # ifdef WIN32
- # include <sys/timeb.h>
- # else
- # include <sys/time.h>
- # endif
- # include <time.h>
- #else
- # if HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
- #endif
- #include <net-snmp/net-snmp-includes.h>
- #include <net-snmp/agent/net-snmp-agent-includes.h>
- #include "util_funcs.h"
- #include "alarm.h"
- /*
- * Implementation headers
- */
- #include "agutil_api.h"
- #include "row_api.h"
- /*
- * File scope definitions section
- */
- /*
- * from MIB compilation
- */
- #define alarmEntryFirstIndexBegin 11
- #define MMM_MAX 0xFFFFFFFFl
- #define IDalarmIndex 1
- #define IDalarmInterval 2
- #define IDalarmVariable 3
- #define IDalarmSampleType 4
- #define IDalarmValue 5
- #define IDalarmStartupAlarm 6
- #define IDalarmRisingThreshold 7
- #define IDalarmFallingThreshold 8
- #define IDalarmRisingEventIndex 9
- #define IDalarmFallingEventIndex 10
- #define IDalarmOwner 11
- #define IDalarmStatus 12
- #define MIN_alarmEventIndex 0
- #define MAX_alarmEventIndex 65535
- typedef enum {
- SAMPLE_TYPE_ABSOLUTE =
- 1,
- SAMPLE_TYPE_DELTE
- } SAMPLE_TYPE_T;
- typedef enum {
- ALARM_NOTHING =
- 0,
- ALARM_RISING,
- ALARM_FALLING,
- ALARM_BOTH
- } ALARM_TYPE_T;
- typedef struct {
- u_long
- interval;
- u_long
- timer_id;
- VAR_OID_T
- var_name;
- SAMPLE_TYPE_T
- sample_type;
- ALARM_TYPE_T
- startup_type; /* RISING | FALLING | BOTH */
- u_long
- rising_threshold;
- u_long
- falling_threshold;
- u_long
- rising_event_index;
- u_long
- falling_event_index;
- u_long
- last_abs_value;
- u_long
- value;
- ALARM_TYPE_T
- prev_alarm; /* NOTHING | RISING | FALLING */
- } CRTL_ENTRY_T;
- /*
- * Main section
- */
- static TABLE_DEFINTION_T
- AlarmCtrlTable;
- static TABLE_DEFINTION_T *
- table_ptr = &
- AlarmCtrlTable;
- #if 0 /* KUKU */
- static u_long
- kuku_sum =
- 0,
- kuku_cnt =
- 0;
- #endif
- /*
- * find & enjoy it in event.c
- */
- extern int
- event_api_send_alarm(u_char is_rising,
- u_long alarm_index,
- u_long event_index,
- oid * alarmed_var,
- size_t alarmed_var_length,
- u_long sample_type,
- u_long value,
- u_long the_threshold, char *alarm_descr);
- static int
- fetch_var_val(oid * name, size_t namelen, u_long * new_value)
- {
- netsnmp_subtree *tree_ptr;
- size_t var_len;
- WriteMethod *write_method;
- struct variable called_var;
- register struct variable *s_var_ptr = NULL;
- register u_char *access;
- tree_ptr = netsnmp_subtree_find(name, namelen, NULL, "");
- if (!tree_ptr) {
- ag_trace("tree_ptr is NULL");
- return SNMP_ERR_NOSUCHNAME;
- }
-
- memcpy(called_var.name, tree_ptr->name_a,
- tree_ptr->namelen * sizeof(oid));
-
- if (tree_ptr->reginfo &&
- tree_ptr->reginfo->handler &&
- tree_ptr->reginfo->handler->next &&
- tree_ptr->reginfo->handler->next->myvoid) {
- s_var_ptr = (struct variable *)tree_ptr->reginfo->handler->next->myvoid;
- }
- if (s_var_ptr) {
- if (s_var_ptr->namelen) {
- called_var.namelen =
- tree_ptr->namelen;
- called_var.type = s_var_ptr->type;
- called_var.magic = s_var_ptr->magic;
- called_var.acl = s_var_ptr->acl;
- called_var.findVar = s_var_ptr->findVar;
- access =
- (*(s_var_ptr->findVar)) (&called_var, name, &namelen,
- 1, &var_len, &write_method);
- if (access
- && snmp_oid_compare(name, namelen, tree_ptr->end_a,
- tree_ptr->end_len) > 0) {
- memcpy(name, tree_ptr->end_a, tree_ptr->end_len);
- access = 0;
- ag_trace("access := 0");
- }
- if (access) {
- /*
- * check 'var_len' ?
- */
- /*
- * check type
- */
- switch (called_var.type) {
- case ASN_INTEGER:
- case ASN_COUNTER:
- case ASN_TIMETICKS:
- case ASN_GAUGE:
- case ASN_COUNTER64:
- break;
- default:
- ag_trace("invalid type: %d",
- (int) called_var.type);
- return SNMP_ERR_GENERR;
- }
- *new_value = *(u_long *) access;
- return SNMP_ERR_NOERROR;
- }
- }
- }
- return SNMP_ERR_NOSUCHNAME;
- }
- static void
- alarm_check_var(unsigned int clientreg, void *clientarg)
- {
- RMON_ENTRY_T *hdr_ptr;
- CRTL_ENTRY_T *body;
- u_long new_value;
- int ierr;
- hdr_ptr = (RMON_ENTRY_T *) clientarg;
- if (!hdr_ptr) {
- ag_trace
- ("Err: history_get_backet: hdr_ptr=NULL ? (Inserted in shock)");
- return;
- }
- body = (CRTL_ENTRY_T *) hdr_ptr->body;
- if (!body) {
- ag_trace
- ("Err: history_get_backet: body=NULL ? (Inserted in shock)");
- return;
- }
- if (RMON1_ENTRY_VALID != hdr_ptr->status) {
- ag_trace("Err: history_get_backet when entry %d is not valid ?!!",
- (int) hdr_ptr->ctrl_index);
- snmp_alarm_unregister(body->timer_id);
- return;
- }
- ierr = fetch_var_val(body->var_name.objid,
- body->var_name.length, &new_value);
- if (SNMP_ERR_NOERROR != ierr) {
- ag_trace("Err: Can't fetch var_name");
- return;
- }
- body->value = (SAMPLE_TYPE_ABSOLUTE == body->sample_type) ?
- new_value : new_value - body->last_abs_value;
- body->last_abs_value = new_value;
- /*
- * ag_trace ("fetched value=%ld check %ld", (long) new_value, (long) body->value);
- */
- #if 0 /* KUKU */
- kuku_sum += body->value;
- kuku_cnt++;
- #endif
- if (ALARM_RISING != body->prev_alarm &&
- body->value >= body->rising_threshold &&
- SNMP_ERR_NOERROR == event_api_send_alarm(1, hdr_ptr->ctrl_index,
- body->rising_event_index,
- body->var_name.objid,
- body->var_name.length,
- ALARM_RISING, body->value,
- body->rising_threshold,
- "Rising"))
- body->prev_alarm = ALARM_RISING;
- else if (ALARM_FALLING != body->prev_alarm &&
- body->value <= body->falling_threshold &&
- SNMP_ERR_NOERROR == event_api_send_alarm(0,
- hdr_ptr->ctrl_index,
- body->
- falling_event_index,
- body->var_name.objid,
- body->var_name.
- length, ALARM_RISING,
- body->value,
- body->
- falling_threshold,
- "Falling"))
- body->prev_alarm = ALARM_FALLING;
- }
- /*
- * Control Table RowApi Callbacks
- */
- int
- alarm_Create(RMON_ENTRY_T * eptr)
- { /* create the body: alloc it and set defaults */
- CRTL_ENTRY_T *body;
- static VAR_OID_T DEFAULT_VAR = { 12, /* etherStatsPkts.1 */
- {1, 3, 6, 1, 2, 1, 16, 1, 1, 1, 5, 1}
- };
- eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T));
- if (!eptr->body)
- return -3;
- body = (CRTL_ENTRY_T *) eptr->body;
- /*
- * set defaults
- */
- body->interval = 1;
- memcpy(&body->var_name, &DEFAULT_VAR, sizeof(VAR_OID_T));
- body->sample_type = SAMPLE_TYPE_ABSOLUTE;
- body->startup_type = ALARM_BOTH;
- body->rising_threshold = MMM_MAX;
- body->falling_threshold = 0;
- body->rising_event_index = body->falling_event_index = 0;
- body->prev_alarm = ALARM_NOTHING;
- return 0;
- }
- int
- alarm_Validate(RMON_ENTRY_T * eptr)
- {
- CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
- if (body->rising_threshold <= body->falling_threshold) {
- ag_trace("alarm_Validate failed: %lu must be > %lu",
- body->rising_threshold, body->falling_threshold);
- return SNMP_ERR_BADVALUE;
- }
- return 0;
- }
- int
- alarm_Activate(RMON_ENTRY_T * eptr)
- {
- CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
- int ierr;
- #if 0 /* KUKU */
- kuku_sum = 0;
- kuku_cnt = 0;
- #endif
- ierr = fetch_var_val(body->var_name.objid,
- body->var_name.length, &body->last_abs_value);
- if (SNMP_ERR_NOERROR != ierr) {
- ag_trace("Can't fetch var_name");
- return ierr;
- }
- if (SAMPLE_TYPE_ABSOLUTE != body->sample_type) {
- /*
- * check startup alarm
- */
- if (ALARM_RISING == body->startup_type ||
- ALARM_BOTH == body->startup_type) {
- if (body->last_abs_value >= body->rising_threshold) {
- event_api_send_alarm(1, eptr->ctrl_index,
- body->rising_event_index,
- body->var_name.objid,
- body->var_name.length,
- ALARM_RISING, body->value,
- body->rising_threshold,
- "Startup Rising");
- }
- }
- if (ALARM_FALLING == body->startup_type ||
- ALARM_BOTH == body->startup_type) {
- if (body->last_abs_value <= body->falling_threshold) {
- event_api_send_alarm(0, eptr->ctrl_index,
- body->falling_event_index,
- body->var_name.objid,
- body->var_name.length,
- ALARM_RISING, body->value,
- body->falling_threshold,
- "Startup Falling");
- }
- }
- }
- body->timer_id = snmp_alarm_register(body->interval, SA_REPEAT,
- alarm_check_var, eptr);
- return 0;
- }
- int
- alarm_Deactivate(RMON_ENTRY_T * eptr)
- {
- CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
- snmp_alarm_unregister(body->timer_id);
- #if 0 /* KUKU */
- ag_trace("kuku_sum=%ld kuku_cnt=%ld sp=%ld",
- (long) kuku_sum, (long) kuku_cnt,
- (long) (kuku_sum / kuku_cnt));
- #endif
- return 0;
- }
- int
- alarm_Copy(RMON_ENTRY_T * eptr)
- {
- CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
- CRTL_ENTRY_T *clone = (CRTL_ENTRY_T *) eptr->tmp;
- if (RMON1_ENTRY_VALID == eptr->status &&
- clone->rising_threshold <= clone->falling_threshold) {
- ag_trace("alarm_Copy failed: invalid thresholds");
- return SNMP_ERR_BADVALUE;
- }
- if (clone->interval != body->interval) {
- if (RMON1_ENTRY_VALID == eptr->status) {
- snmp_alarm_unregister(body->timer_id);
- body->timer_id =
- snmp_alarm_register(clone->interval, SA_REPEAT,
- alarm_check_var, eptr);
- }
- body->interval = clone->interval;
- }
- if (snmp_oid_compare(clone->var_name.objid, clone->var_name.length,
- body->var_name.objid, body->var_name.length)) {
- memcpy(&body->var_name, &clone->var_name, sizeof(VAR_OID_T));
- }
- body->sample_type = clone->sample_type;
- body->startup_type = clone->startup_type;
- body->sample_type = clone->sample_type;
- body->rising_threshold = clone->rising_threshold;
- body->falling_threshold = clone->falling_threshold;
- body->rising_event_index = clone->rising_event_index;
- body->falling_event_index = clone->falling_event_index;
- /*
- * ag_trace ("alarm_Copy: rising_threshold=%lu falling_threshold=%lu",
- * body->rising_threshold, body->falling_threshold);
- */
- return 0;
- }
- static int
- write_alarmEntry(int action, u_char * var_val, u_char var_val_type,
- size_t var_val_len, u_char * statP,
- oid * name, size_t name_len)
- {
- long long_tmp;
- int leaf_id, snmp_status;
- static int prev_action = COMMIT;
- RMON_ENTRY_T *hdr;
- CRTL_ENTRY_T *cloned_body;
- CRTL_ENTRY_T *body;
- switch (action) {
- case RESERVE1:
- case FREE:
- case UNDO:
- case ACTION:
- case COMMIT:
- default:
- return ROWAPI_do_another_action(name, alarmEntryFirstIndexBegin,
- action, &prev_action,
- table_ptr, sizeof(CRTL_ENTRY_T));
- case RESERVE2:
- /*
- * get values from PDU, check them and save them in the cloned entry
- */
- long_tmp = name[alarmEntryFirstIndexBegin];
- leaf_id = (int) name[alarmEntryFirstIndexBegin - 1];
- hdr = ROWAPI_find(table_ptr, long_tmp); /* it MUST be OK */
- cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
- body = (CRTL_ENTRY_T *) hdr->body;
- switch (leaf_id) {
- case IDalarmInterval:
- snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
- var_val_len,
- 0, MMM_MAX, &long_tmp);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- cloned_body->interval = long_tmp;
- break;
- case IDalarmVariable:
- snmp_status = AGUTIL_get_oid_value(var_val, var_val_type,
- var_val_len,
- &cloned_body->var_name);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
- snmp_oid_compare(cloned_body->var_name.objid,
- cloned_body->var_name.length,
- body->var_name.objid,
- body->var_name.length))
- return SNMP_ERR_BADVALUE;
- break;
- break;
- case IDalarmSampleType:
- snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
- var_val_len,
- SAMPLE_TYPE_ABSOLUTE,
- SAMPLE_TYPE_DELTE,
- &long_tmp);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- cloned_body->sample_type = long_tmp;
- break;
- case IDalarmStartupAlarm:
- snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
- var_val_len,
- ALARM_RISING,
- ALARM_BOTH, &long_tmp);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- cloned_body->startup_type = long_tmp;
- break;
- case IDalarmRisingThreshold:
- snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
- var_val_len,
- 0, MMM_MAX, &long_tmp);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- cloned_body->rising_threshold = long_tmp;
- break;
- case IDalarmFallingThreshold:
- snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
- var_val_len,
- 0, 0xFFFFFFFFl, &long_tmp);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- cloned_body->falling_threshold = long_tmp;
- break;
- case IDalarmRisingEventIndex:
- snmp_status = AGUTIL_get_int_value(var_val, var_val_type, var_val_len, 0, /* min. value */
- 0, /* max. value */
- &long_tmp);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- cloned_body->rising_event_index = long_tmp;
- break;
- case IDalarmFallingEventIndex:
- snmp_status = AGUTIL_get_int_value(var_val, var_val_type, var_val_len, 0, /* min. value */
- 0, /* max. value */
- &long_tmp);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- cloned_body->falling_event_index = long_tmp;
- break;
- case IDalarmOwner:
- if (hdr->new_owner)
- AGFREE(hdr->new_owner);
- hdr->new_owner = AGMALLOC(MAX_OWNERSTRING);;
- if (!hdr->new_owner)
- return SNMP_ERR_TOOBIG;
- snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
- var_val_len,
- MAX_OWNERSTRING,
- 1, NULL, hdr->new_owner);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- break;
- case IDalarmStatus:
- snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
- var_val_len,
- RMON1_ENTRY_VALID,
- RMON1_ENTRY_INVALID,
- &long_tmp);
- if (SNMP_ERR_NOERROR != snmp_status) {
- return snmp_status;
- }
- hdr->new_status = long_tmp;
- break;
- default:
- ag_trace("%s:unknown leaf_id=%dn", table_ptr->name,
- (int) leaf_id);
- return SNMP_ERR_NOSUCHNAME;
- } /* of switch by 'leaf_id' */
- break;
- } /* of switch by actions */
- prev_action = action;
- return SNMP_ERR_NOERROR;
- }
- u_char *
- var_alarmEntry(struct variable * vp, oid * name, size_t * length,
- int exact, size_t * var_len, WriteMethod ** write_method)
- {
- static long long_return;
- static CRTL_ENTRY_T theEntry;
- RMON_ENTRY_T *hdr;
- *write_method = write_alarmEntry;
- hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
- table_ptr,
- &theEntry, sizeof(CRTL_ENTRY_T));
- if (!hdr)
- return NULL;
- *var_len = sizeof(long); /* default */
- switch (vp->magic) {
- case IDalarmIndex:
- long_return = hdr->ctrl_index;
- return (u_char *) & long_return;
- case IDalarmInterval:
- long_return = theEntry.interval;
- return (u_char *) & long_return;
- case IDalarmVariable:
- *var_len = sizeof(oid) * theEntry.var_name.length;
- return (unsigned char *) theEntry.var_name.objid;
- return (u_char *) & long_return;
- case IDalarmSampleType:
- long_return = theEntry.sample_type;
- return (u_char *) & long_return;
- case IDalarmValue:
- long_return = theEntry.value;
- return (u_char *) & long_return;
- case IDalarmStartupAlarm:
- long_return = theEntry.startup_type;
- return (u_char *) & long_return;
- case IDalarmRisingThreshold:
- long_return = theEntry.rising_threshold;
- return (u_char *) & long_return;
- case IDalarmFallingThreshold:
- long_return = theEntry.falling_threshold;
- return (u_char *) & long_return;
- case IDalarmRisingEventIndex:
- long_return = theEntry.rising_event_index;
- return (u_char *) & long_return;
- case IDalarmFallingEventIndex:
- long_return = theEntry.falling_event_index;
- return (u_char *) & long_return;
- case IDalarmOwner:
- if (hdr->owner) {
- *var_len = strlen(hdr->owner);
- return (unsigned char *) hdr->owner;
- } else {
- *var_len = 0;
- return (unsigned char *) "";
- }
- case IDalarmStatus:
- long_return = hdr->status;
- return (u_char *) & long_return;
- default:
- ag_trace("%s: unknown vp->magic=%d", table_ptr->name,
- (int) vp->magic);
- ERROR_MSG("");
- }; /* of switch by 'vp->magic' */
- return NULL;
- }
- /*
- * Registration & Initializatio section
- */
- oid oidalarmVariablesOid[] = { 1, 3, 6, 1, 2, 1, 16, 3 };
- struct variable7 oidalarmVariables[] = {
- {IDalarmIndex, ASN_INTEGER, RONLY, var_alarmEntry, 3, {1, 1, 1}},
- {IDalarmInterval, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 2}},
- {IDalarmVariable, ASN_OBJECT_ID, RWRITE, var_alarmEntry, 3, {1, 1, 3}},
- {IDalarmSampleType, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 4}},
- {IDalarmValue, ASN_INTEGER, RONLY, var_alarmEntry, 3, {1, 1, 5}},
- {IDalarmStartupAlarm, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
- {1, 1, 6}},
- {IDalarmRisingThreshold, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
- {1, 1, 7}},
- {IDalarmFallingThreshold, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
- {1, 1, 8}},
- {IDalarmRisingEventIndex, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
- {1, 1, 9}},
- {IDalarmFallingEventIndex, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
- {1, 1, 10}},
- {IDalarmOwner, ASN_OCTET_STR, RWRITE, var_alarmEntry, 3, {1, 1, 11}},
- {IDalarmStatus, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 12}}
- };
- void
- init_alarm(void)
- {
- REGISTER_MIB("alarmTable", oidalarmVariables, variable7,
- oidalarmVariablesOid);
- ROWAPI_init_table(&AlarmCtrlTable, "Alarm", 0, &alarm_Create, NULL, /* &alarm_Clone, */
- NULL, /* &alarm_Delete, */
- &alarm_Validate,
- &alarm_Activate, &alarm_Deactivate, &alarm_Copy);
- }
- /*
- * end of file alarm.c
- */