1 /**************************************************************
2 * Copyright (C) 2001 Alex Rozin, Optical Access
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation for any purpose and without fee is hereby granted,
8 * provided that the above copyright notice appear in all copies and that
9 * both that copyright notice and this permission notice appear in
10 * supporting documentation.
12 * ALEX ROZIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
14 * ALEX ROZIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
15 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
16 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
17 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
19 ******************************************************************/
24 #include <net-snmp/net-snmp-config.h>
25 #include <net-snmp/net-snmp-includes.h>
26 #include <net-snmp/agent/net-snmp-agent-includes.h>
27 #include "util_funcs.h"
30 * Implementation headers
32 #include "agutil_api.h"
35 * File scope definitions section
38 * from MIB compilation
40 #define alarmEntryFirstIndexBegin 11
41 #define MMM_MAX 0xFFFFFFFFl
42 #define IDalarmIndex 1
43 #define IDalarmInterval 2
44 #define IDalarmVariable 3
45 #define IDalarmSampleType 4
46 #define IDalarmValue 5
47 #define IDalarmStartupAlarm 6
48 #define IDalarmRisingThreshold 7
49 #define IDalarmFallingThreshold 8
50 #define IDalarmRisingEventIndex 9
51 #define IDalarmFallingEventIndex 10
52 #define IDalarmOwner 11
53 #define IDalarmStatus 12
54 #define MIN_alarmEventIndex 0
55 #define MAX_alarmEventIndex 65535
57 SAMPLE_TYPE_ABSOLUTE =
80 startup_type; /* RISING | FALLING | BOTH */
96 prev_alarm; /* NOTHING | RISING | FALLING */
103 static TABLE_DEFINTION_T
105 static TABLE_DEFINTION_T *
118 * find & enjoy it in event.c
121 event_api_send_alarm(u_char is_rising,
125 size_t alarmed_var_length,
128 u_long the_threshold, char *alarm_descr);
131 fetch_var_val(oid * name, size_t namelen, u_long * new_value)
133 netsnmp_subtree *tree_ptr;
135 WriteMethod *write_method;
136 struct variable called_var;
137 register struct variable *s_var_ptr;
139 register u_char *access;
142 tree_ptr = netsnmp_subtree_find(name, namelen, NULL, "");
144 return SNMP_ERR_NOSUCHNAME;
147 memcpy(called_var.name, tree_ptr->name_a,
148 tree_ptr->namelen * sizeof(oid));
149 s_var_ptr = tree_ptr->variables;
150 for (iii = 0; iii < tree_ptr->variables_len; iii++) {
151 if (s_var_ptr->namelen) {
152 if (0 >= snmp_oidtree_compare(name + tree_ptr->namelen,
153 namelen - tree_ptr->namelen,
155 s_var_ptr->namelen)) {
156 memcpy(called_var.name + tree_ptr->namelen,
157 s_var_ptr->name, s_var_ptr->namelen * sizeof(oid));
159 tree_ptr->namelen + s_var_ptr->namelen;
160 called_var.type = s_var_ptr->type;
161 called_var.magic = s_var_ptr->magic;
162 called_var.acl = s_var_ptr->acl;
163 called_var.findVar = s_var_ptr->findVar;
166 (*(s_var_ptr->findVar)) (&called_var, name, &namelen,
167 1, &var_len, &write_method);
169 && snmp_oid_compare(name, namelen, tree_ptr->end_a,
170 tree_ptr->end_len) > 0) {
171 memcpy(name, tree_ptr->end_a, tree_ptr->end_len);
173 ag_trace("access := 0");
185 switch (called_var.type) {
193 ag_trace("invalid type: %d",
194 (int) called_var.type);
195 return SNMP_ERR_GENERR;
197 *new_value = *(u_long *) access;
198 return SNMP_ERR_NOERROR;
204 (struct variable *) ((char *) s_var_ptr +
205 tree_ptr->variables_width);
208 return SNMP_ERR_NOSUCHNAME;
212 alarm_check_var(unsigned int clientreg, void *clientarg)
214 RMON_ENTRY_T *hdr_ptr;
219 hdr_ptr = (RMON_ENTRY_T *) clientarg;
222 ("Err: history_get_backet: hdr_ptr=NULL ? (Inserted in shock)");
226 body = (CRTL_ENTRY_T *) hdr_ptr->body;
229 ("Err: history_get_backet: body=NULL ? (Inserted in shock)");
233 if (RMON1_ENTRY_VALID != hdr_ptr->status) {
234 ag_trace("Err: history_get_backet when entry %d is not valid ?!!",
235 (int) hdr_ptr->ctrl_index);
236 snmp_alarm_unregister(body->timer_id);
240 ierr = fetch_var_val(body->var_name.objid,
241 body->var_name.length, &new_value);
242 if (SNMP_ERR_NOERROR != ierr) {
243 ag_trace("Err: Can't fetch var_name");
247 body->value = (SAMPLE_TYPE_ABSOLUTE == body->sample_type) ?
248 new_value : new_value - body->last_abs_value;
249 body->last_abs_value = new_value;
251 * ag_trace ("fetched value=%ld check %ld", (long) new_value, (long) body->value);
254 kuku_sum += body->value;
258 if (ALARM_RISING != body->prev_alarm &&
259 body->value >= body->rising_threshold &&
260 SNMP_ERR_NOERROR == event_api_send_alarm(1, hdr_ptr->ctrl_index,
261 body->rising_event_index,
262 body->var_name.objid,
263 body->var_name.length,
264 ALARM_RISING, body->value,
265 body->rising_threshold,
267 body->prev_alarm = ALARM_RISING;
268 else if (ALARM_FALLING != body->prev_alarm &&
269 body->value <= body->falling_threshold &&
270 SNMP_ERR_NOERROR == event_api_send_alarm(0,
274 body->var_name.objid,
276 length, ALARM_RISING,
281 body->prev_alarm = ALARM_FALLING;
285 * Control Table RowApi Callbacks
289 alarm_Create(RMON_ENTRY_T * eptr)
290 { /* create the body: alloc it and set defaults */
292 static VAR_OID_T DEFAULT_VAR = { 12, /* etherStatsPkts.1 */
293 {1, 3, 6, 1, 2, 1, 16, 1, 1, 1, 5, 1}
297 eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T));
300 body = (CRTL_ENTRY_T *) eptr->body;
306 memcpy(&body->var_name, &DEFAULT_VAR, sizeof(VAR_OID_T));
307 body->sample_type = SAMPLE_TYPE_ABSOLUTE;
308 body->startup_type = ALARM_BOTH;
309 body->rising_threshold = MMM_MAX;
310 body->falling_threshold = 0;
311 body->rising_event_index = body->falling_event_index = 0;
313 body->prev_alarm = ALARM_NOTHING;
319 alarm_Validate(RMON_ENTRY_T * eptr)
321 CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
323 if (body->rising_threshold <= body->falling_threshold) {
324 ag_trace("alarm_Validate failed: %lu must be > %lu",
325 body->rising_threshold, body->falling_threshold);
326 return SNMP_ERR_BADVALUE;
333 alarm_Activate(RMON_ENTRY_T * eptr)
335 CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
342 ierr = fetch_var_val(body->var_name.objid,
343 body->var_name.length, &body->last_abs_value);
344 if (SNMP_ERR_NOERROR != ierr) {
345 ag_trace("Can't fetch var_name");
349 if (SAMPLE_TYPE_ABSOLUTE != body->sample_type) {
351 * check startup alarm
353 if (ALARM_RISING == body->startup_type ||
354 ALARM_BOTH == body->startup_type) {
355 if (body->last_abs_value >= body->rising_threshold) {
356 event_api_send_alarm(1, eptr->ctrl_index,
357 body->rising_event_index,
358 body->var_name.objid,
359 body->var_name.length,
360 ALARM_RISING, body->value,
361 body->rising_threshold,
366 if (ALARM_FALLING == body->startup_type ||
367 ALARM_BOTH == body->startup_type) {
368 if (body->last_abs_value <= body->falling_threshold) {
369 event_api_send_alarm(0, eptr->ctrl_index,
370 body->falling_event_index,
371 body->var_name.objid,
372 body->var_name.length,
373 ALARM_RISING, body->value,
374 body->falling_threshold,
381 body->timer_id = snmp_alarm_register(body->interval, SA_REPEAT,
382 alarm_check_var, eptr);
387 alarm_Deactivate(RMON_ENTRY_T * eptr)
389 CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
391 snmp_alarm_unregister(body->timer_id);
393 ag_trace("kuku_sum=%ld kuku_cnt=%ld sp=%ld",
394 (long) kuku_sum, (long) kuku_cnt,
395 (long) (kuku_sum / kuku_cnt));
401 alarm_Copy(RMON_ENTRY_T * eptr)
403 CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
404 CRTL_ENTRY_T *clone = (CRTL_ENTRY_T *) eptr->tmp;
406 if (RMON1_ENTRY_VALID == eptr->status &&
407 clone->rising_threshold <= clone->falling_threshold) {
408 ag_trace("alarm_Copy failed: invalid thresholds");
409 return SNMP_ERR_BADVALUE;
412 if (clone->interval != body->interval) {
413 if (RMON1_ENTRY_VALID == eptr->status) {
414 snmp_alarm_unregister(body->timer_id);
416 snmp_alarm_register(clone->interval, SA_REPEAT,
417 alarm_check_var, eptr);
419 body->interval = clone->interval;
422 if (snmp_oid_compare(clone->var_name.objid, clone->var_name.length,
423 body->var_name.objid, body->var_name.length)) {
424 memcpy(&body->var_name, &clone->var_name, sizeof(VAR_OID_T));
427 body->sample_type = clone->sample_type;
428 body->startup_type = clone->startup_type;
429 body->sample_type = clone->sample_type;
430 body->rising_threshold = clone->rising_threshold;
431 body->falling_threshold = clone->falling_threshold;
432 body->rising_event_index = clone->rising_event_index;
433 body->falling_event_index = clone->falling_event_index;
435 * ag_trace ("alarm_Copy: rising_threshold=%lu falling_threshold=%lu",
436 * body->rising_threshold, body->falling_threshold);
442 write_alarmEntry(int action, u_char * var_val, u_char var_val_type,
443 size_t var_val_len, u_char * statP,
444 oid * name, size_t name_len)
447 int leaf_id, snmp_status;
448 static int prev_action = COMMIT;
450 CRTL_ENTRY_T *cloned_body;
460 return ROWAPI_do_another_action(name, alarmEntryFirstIndexBegin,
461 action, &prev_action,
462 table_ptr, sizeof(CRTL_ENTRY_T));
465 * get values from PDU, check them and save them in the cloned entry
467 long_tmp = name[alarmEntryFirstIndexBegin];
468 leaf_id = (int) name[alarmEntryFirstIndexBegin - 1];
469 hdr = ROWAPI_find(table_ptr, long_tmp); /* it MUST be OK */
470 cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
471 body = (CRTL_ENTRY_T *) hdr->body;
473 case IDalarmInterval:
474 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
476 0, MMM_MAX, &long_tmp);
477 if (SNMP_ERR_NOERROR != snmp_status) {
480 cloned_body->interval = long_tmp;
482 case IDalarmVariable:
483 snmp_status = AGUTIL_get_oid_value(var_val, var_val_type,
485 &cloned_body->var_name);
486 if (SNMP_ERR_NOERROR != snmp_status) {
489 if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
490 snmp_oid_compare(cloned_body->var_name.objid,
491 cloned_body->var_name.length,
492 body->var_name.objid,
493 body->var_name.length))
494 return SNMP_ERR_BADVALUE;
498 case IDalarmSampleType:
499 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
501 SAMPLE_TYPE_ABSOLUTE,
504 if (SNMP_ERR_NOERROR != snmp_status) {
507 cloned_body->sample_type = long_tmp;
509 case IDalarmStartupAlarm:
510 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
513 ALARM_BOTH, &long_tmp);
514 if (SNMP_ERR_NOERROR != snmp_status) {
517 cloned_body->startup_type = long_tmp;
519 case IDalarmRisingThreshold:
520 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
522 0, MMM_MAX, &long_tmp);
523 if (SNMP_ERR_NOERROR != snmp_status) {
526 cloned_body->rising_threshold = long_tmp;
528 case IDalarmFallingThreshold:
529 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
531 0, 0xFFFFFFFFl, &long_tmp);
532 if (SNMP_ERR_NOERROR != snmp_status) {
535 cloned_body->falling_threshold = long_tmp;
537 case IDalarmRisingEventIndex:
538 snmp_status = AGUTIL_get_int_value(var_val, var_val_type, var_val_len, 0, /* min. value */
541 if (SNMP_ERR_NOERROR != snmp_status) {
544 cloned_body->rising_event_index = long_tmp;
546 case IDalarmFallingEventIndex:
547 snmp_status = AGUTIL_get_int_value(var_val, var_val_type, var_val_len, 0, /* min. value */
550 if (SNMP_ERR_NOERROR != snmp_status) {
553 cloned_body->falling_event_index = long_tmp;
557 AGFREE(hdr->new_owner);
558 hdr->new_owner = AGMALLOC(MAX_OWNERSTRING);;
560 return SNMP_ERR_TOOBIG;
561 snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
564 1, NULL, hdr->new_owner);
565 if (SNMP_ERR_NOERROR != snmp_status) {
571 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
576 if (SNMP_ERR_NOERROR != snmp_status) {
579 hdr->new_status = long_tmp;
582 ag_trace("%s:unknown leaf_id=%d\n", table_ptr->name,
584 return SNMP_ERR_NOSUCHNAME;
585 } /* of switch by 'leaf_id' */
588 } /* of switch by actions */
590 prev_action = action;
591 return SNMP_ERR_NOERROR;
595 var_alarmEntry(struct variable * vp, oid * name, size_t * length,
596 int exact, size_t * var_len, WriteMethod ** write_method)
598 static long long_return;
599 static CRTL_ENTRY_T theEntry;
602 *write_method = write_alarmEntry;
603 hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
605 &theEntry, sizeof(CRTL_ENTRY_T));
609 *var_len = sizeof(long); /* default */
613 long_return = hdr->ctrl_index;
614 return (u_char *) & long_return;
615 case IDalarmInterval:
616 long_return = theEntry.interval;
617 return (u_char *) & long_return;
618 case IDalarmVariable:
619 *var_len = sizeof(oid) * theEntry.var_name.length;
620 return (unsigned char *) theEntry.var_name.objid;
621 return (u_char *) & long_return;
622 case IDalarmSampleType:
623 long_return = theEntry.sample_type;
624 return (u_char *) & long_return;
626 long_return = theEntry.value;
627 return (u_char *) & long_return;
628 case IDalarmStartupAlarm:
629 long_return = theEntry.startup_type;
630 return (u_char *) & long_return;
631 case IDalarmRisingThreshold:
632 long_return = theEntry.rising_threshold;
633 return (u_char *) & long_return;
634 case IDalarmFallingThreshold:
635 long_return = theEntry.falling_threshold;
636 return (u_char *) & long_return;
637 case IDalarmRisingEventIndex:
638 long_return = theEntry.rising_event_index;
639 return (u_char *) & long_return;
640 case IDalarmFallingEventIndex:
641 long_return = theEntry.falling_event_index;
642 return (u_char *) & long_return;
645 *var_len = strlen(hdr->owner);
646 return (unsigned char *) hdr->owner;
649 return (unsigned char *) "";
653 long_return = hdr->status;
654 return (u_char *) & long_return;
656 ag_trace("%s: unknown vp->magic=%d", table_ptr->name,
659 }; /* of switch by 'vp->magic' */
665 * Registration & Initializatio section
668 oid oidalarmVariablesOid[] = { 1, 3, 6, 1, 2, 1, 16, 3 };
670 struct variable7 oidalarmVariables[] = {
671 {IDalarmIndex, ASN_INTEGER, RONLY, var_alarmEntry, 3, {1, 1, 1}},
672 {IDalarmInterval, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 2}},
673 {IDalarmVariable, ASN_OBJECT_ID, RWRITE, var_alarmEntry, 3, {1, 1, 3}},
674 {IDalarmSampleType, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 4}},
675 {IDalarmValue, ASN_INTEGER, RONLY, var_alarmEntry, 3, {1, 1, 5}},
676 {IDalarmStartupAlarm, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
678 {IDalarmRisingThreshold, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
680 {IDalarmFallingThreshold, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
682 {IDalarmRisingEventIndex, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
684 {IDalarmFallingEventIndex, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
686 {IDalarmOwner, ASN_OCTET_STR, RWRITE, var_alarmEntry, 3, {1, 1, 11}},
687 {IDalarmStatus, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 12}}
693 REGISTER_MIB("alarmTable", oidalarmVariables, variable7,
694 oidalarmVariablesOid);
696 ROWAPI_init_table(&AlarmCtrlTable, "Alarm", 0, &alarm_Create, NULL, /* &alarm_Clone, */
697 NULL, /* &alarm_Delete, */
699 &alarm_Activate, &alarm_Deactivate, &alarm_Copy);
703 * end of file alarm.c