1 /**************************************************************
2  * Copyright (C) 2001 Alex Rozin, Optical Access
3  *
4  *                     All Rights Reserved
5  *
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.
11  *
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
18  * SOFTWARE.
19  ******************************************************************/
20 
21 #include <net-snmp/net-snmp-config.h>
22 #include <net-snmp/net-snmp-features.h>
23 
24 #if HAVE_STDLIB_H
25 #include <stdlib.h>
26 #endif
27 #if TIME_WITH_SYS_TIME
28 # include <sys/time.h>
29 # include <time.h>
30 #else
31 # if HAVE_SYS_TIME_H
32 #  include <sys/time.h>
33 # else
34 #  include <time.h>
35 # endif
36 #endif
37 #if HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40 #include <ctype.h>
41 
42 #include <net-snmp/net-snmp-includes.h>
43 #include <net-snmp/agent/net-snmp-agent-includes.h>
44 
45 #include "event.h"
46 
47 /*
48  * Implementation headers
49  */
50 #include "agutil_api.h"
51 #include "row_api.h"
52 
53 netsnmp_feature_require(snprint_objid);
54 
55 /*
56  * File scope definitions section
57  */
58 
59 /*
60  * from MIB compilation
61  */
62 #define eventEntryFirstIndexBegin       11
63 
64 #define EVENTINDEX            3
65 #define EVENTDESCRIPTION      4
66 #define EVENTTYPE             5
67 #define EVENTCOMMUNITY        6
68 #define EVENTLASTTIMESENT     7
69 #define EVENTOWNER            8
70 #define EVENTSTATUS           9
71 
72 #define Leaf_event_index        1
73 #define Leaf_event_description  2
74 #define MIN_event_description   0
75 #define MAX_event_description   127
76 #define Leaf_event_type         3
77 #define Leaf_event_community    4
78 #define MIN_event_community     0
79 #define MAX_event_community     127
80 #define Leaf_event_last_time_sent 5
81 #define Leaf_eventOwner        6
82 #define Leaf_eventStatus       7
83 
84 
85 #define LOGEVENTINDEX         3
86 #define LOGINDEX              4
87 #define LOGTIME               5
88 #define LOGDESCRIPTION        6
89 
90 
91 /*
92  * defaults & limitations
93  */
94 
95 #define MAX_LOG_ENTRIES_PER_CTRL	200
96 
97 typedef struct data_struct_t {
98     struct data_struct_t *next;
99     u_long          data_index;
100     u_long          log_time;
101     char           *log_description;
102 } DATA_ENTRY_T;
103 
104 typedef enum {
105     EVENT_NONE = 1,
106     EVENT_LOG,
107     EVENT_TRAP,
108     EVENT_LOG_AND_TRAP
109 } EVENT_TYPE_T;
110 
111 typedef struct {
112     char           *event_description;
113     char           *event_community;
114     EVENT_TYPE_T    event_type;
115     u_long          event_last_time_sent;
116 
117     SCROLLER_T      scrlr;
118 #if 0
119     u_long          event_last_logged_index;
120     u_long          event_number_of_log_entries;
121     DATA_ENTRY_T   *log_list;
122     DATA_ENTRY_T   *last_log_ptr;
123 #endif
124 } CRTL_ENTRY_T;
125 
126 /*
127  * Main section
128  */
129 
130 static TABLE_DEFINTION_T EventCtrlTable;
131 static TABLE_DEFINTION_T *table_ptr = &EventCtrlTable;
132 static unsigned char zero_octet_string[1];
133 
134 /*
135  * Control Table RowApi Callbacks
136  */
137 
138 static int
data_destructor(SCROLLER_T * scrlr,void * free_me)139 data_destructor(SCROLLER_T * scrlr, void *free_me)
140 {
141     DATA_ENTRY_T   *lptr = free_me;
142 
143     if (lptr->log_description)
144         AGFREE(lptr->log_description);
145 
146     return 0;
147 }
148 
149 int
event_Create(RMON_ENTRY_T * eptr)150 event_Create(RMON_ENTRY_T * eptr)
151 {                               /* create the body: alloc it and set defaults */
152     CRTL_ENTRY_T   *body;
153 
154     eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T));
155     if (!eptr->body)
156         return -3;
157     body = (CRTL_ENTRY_T *) eptr->body;
158 
159     /*
160      * set defaults
161      */
162 
163     body->event_description = NULL;
164     body->event_community = AGSTRDUP("public");
165     /*
166      * ag_trace ("Dbg: created event_community=<%s>", body->event_community);
167      */
168     body->event_type = EVENT_NONE;
169     ROWDATAAPI_init(&body->scrlr,
170                     MAX_LOG_ENTRIES_PER_CTRL,
171                     MAX_LOG_ENTRIES_PER_CTRL,
172                     sizeof(DATA_ENTRY_T), &data_destructor);
173 
174 
175     return 0;
176 }
177 
178 int
event_Clone(RMON_ENTRY_T * eptr)179 event_Clone(RMON_ENTRY_T * eptr)
180 {                               /* copy entry_bod -> clone */
181     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
182     CRTL_ENTRY_T   *clone = (CRTL_ENTRY_T *) eptr->tmp;
183 
184     if (body->event_description)
185         clone->event_description = AGSTRDUP(body->event_description);
186 
187     if (body->event_community)
188         clone->event_community = AGSTRDUP(body->event_community);
189     return 0;
190 }
191 
192 int
event_Copy(RMON_ENTRY_T * eptr)193 event_Copy(RMON_ENTRY_T * eptr)
194 {
195     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
196     CRTL_ENTRY_T   *clone = (CRTL_ENTRY_T *) eptr->tmp;
197 
198     if (body->event_type != clone->event_type) {
199         body->event_type = clone->event_type;
200     }
201 
202     if (clone->event_description) {
203         if (body->event_description)
204             AGFREE(body->event_description);
205         body->event_description = AGSTRDUP(clone->event_description);
206     }
207 
208     if (clone->event_community) {
209         if (body->event_community)
210             AGFREE(body->event_community);
211         body->event_community = AGSTRDUP(clone->event_community);
212     }
213 
214     return 0;
215 }
216 
217 int
event_Delete(RMON_ENTRY_T * eptr)218 event_Delete(RMON_ENTRY_T * eptr)
219 {
220     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr;
221 
222     if (body->event_description)
223         AGFREE(body->event_description);
224 
225     if (body->event_community)
226         AGFREE(body->event_community);
227 
228     return 0;
229 }
230 
231 int
event_Activate(RMON_ENTRY_T * eptr)232 event_Activate(RMON_ENTRY_T * eptr)
233 {                               /* init logTable */
234     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
235 
236     ROWDATAAPI_set_size(&body->scrlr,
237                         body->scrlr.data_requested,
238                         (u_char)(RMON1_ENTRY_VALID == eptr->status) );
239 
240     return 0;
241 }
242 
243 int
event_Deactivate(RMON_ENTRY_T * eptr)244 event_Deactivate(RMON_ENTRY_T * eptr)
245 {                               /* free logTable */
246     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
247 
248     /*
249      * free data list
250      */
251     ROWDATAAPI_descructor(&body->scrlr);
252 
253     return 0;
254 }
255 
256 static int
write_eventControl(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)257 write_eventControl(int action, u_char * var_val, u_char var_val_type,
258                    size_t var_val_len, u_char * statP,
259                    oid * name, size_t name_len)
260 {
261     long            long_temp;
262     char           *char_temp;
263     int             leaf_id, snmp_status;
264     static int      prev_action = COMMIT;
265     RMON_ENTRY_T   *hdr;
266     CRTL_ENTRY_T   *cloned_body;
267 
268     switch (action) {
269     case RESERVE1:
270     case FREE:
271     case UNDO:
272     case ACTION:
273     case COMMIT:
274     default:
275         return ROWAPI_do_another_action(name, eventEntryFirstIndexBegin,
276                                         action, &prev_action,
277                                         table_ptr, sizeof(CRTL_ENTRY_T));
278 
279     case RESERVE2:
280         /*
281          * get values from PDU, check them and save them in the cloned entry
282          */
283         long_temp = name[eventEntryFirstIndexBegin];
284         leaf_id = (int) name[eventEntryFirstIndexBegin - 1];
285         hdr = ROWAPI_find(table_ptr, long_temp);        /* it MUST be OK */
286         cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
287         switch (leaf_id) {
288         case Leaf_event_index:
289             return SNMP_ERR_NOTWRITABLE;
290         case Leaf_event_description:
291             char_temp = AGMALLOC(1 + MAX_event_description);
292             if (!char_temp)
293                 return SNMP_ERR_TOOBIG;
294             snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
295                                                   var_val_len,
296                                                   MAX_event_description,
297                                                   1, NULL, char_temp);
298             if (SNMP_ERR_NOERROR != snmp_status) {
299                 AGFREE(char_temp);
300                 return snmp_status;
301             }
302 
303             if (cloned_body->event_description)
304                 AGFREE(cloned_body->event_description);
305 
306             cloned_body->event_description = AGSTRDUP(char_temp);
307             /*
308              * ag_trace ("rx: event_description=<%s>", cloned_body->event_description);
309              */
310             AGFREE(char_temp);
311 
312             break;
313         case Leaf_event_type:
314             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
315                                                var_val_len,
316                                                EVENT_NONE,
317                                                EVENT_LOG_AND_TRAP,
318                                                &long_temp);
319             if (SNMP_ERR_NOERROR != snmp_status) {
320                 return snmp_status;
321             }
322             cloned_body->event_type = long_temp;
323             break;
324         case Leaf_event_last_time_sent:
325             return SNMP_ERR_NOTWRITABLE;
326         case Leaf_event_community:
327             char_temp = AGMALLOC(1 + MAX_event_community);
328             if (!char_temp)
329                 return SNMP_ERR_TOOBIG;
330             snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
331                                                   var_val_len,
332                                                   MAX_event_community,
333                                                   1, NULL, char_temp);
334             if (SNMP_ERR_NOERROR != snmp_status) {
335                 AGFREE(char_temp);
336                 return snmp_status;
337             }
338 
339             if (cloned_body->event_community)
340                 AGFREE(cloned_body->event_community);
341 
342             cloned_body->event_community = AGSTRDUP(char_temp);
343             AGFREE(char_temp);
344 
345             break;
346         case Leaf_eventOwner:
347             if (hdr->new_owner)
348                 AGFREE(hdr->new_owner);
349             hdr->new_owner = AGMALLOC(MAX_OWNERSTRING);
350             if (!hdr->new_owner)
351                 return SNMP_ERR_TOOBIG;
352             snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
353                                                   var_val_len,
354                                                   MAX_OWNERSTRING,
355                                                   1, NULL, hdr->new_owner);
356             if (SNMP_ERR_NOERROR != snmp_status) {
357                 return snmp_status;
358             }
359 
360             break;
361         case Leaf_eventStatus:
362             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
363                                                var_val_len,
364                                                RMON1_ENTRY_VALID,
365                                                RMON1_ENTRY_INVALID,
366                                                &long_temp);
367             if (SNMP_ERR_NOERROR != snmp_status) {
368                 return snmp_status;
369             }
370             hdr->new_status = long_temp;
371             break;
372         default:
373             ag_trace("%s:unknown leaf_id=%d\n", table_ptr->name,
374                      (int) leaf_id);
375             return SNMP_ERR_NOSUCHNAME;
376         }                       /* of switch by 'leaf_id' */
377         break;
378     }                           /* of switch by actions */
379 
380     prev_action = action;
381     return SNMP_ERR_NOERROR;
382 }
383 
384 unsigned char  *
var_eventTable(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method)385 var_eventTable(struct variable *vp,
386                oid * name,
387                size_t * length,
388                int exact, size_t * var_len, WriteMethod ** write_method)
389 {
390     static long     long_ret;
391     static CRTL_ENTRY_T theEntry;
392     RMON_ENTRY_T   *hdr;
393 
394     *write_method = write_eventControl;
395     hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
396                                      table_ptr,
397                                      &theEntry, sizeof(CRTL_ENTRY_T));
398     if (!hdr)
399         return NULL;
400 
401     *var_len = sizeof(long);    /* default */
402 
403     switch (vp->magic) {
404     case EVENTINDEX:
405         long_ret = hdr->ctrl_index;
406         return (unsigned char *) &long_ret;
407     case EVENTDESCRIPTION:
408         if (theEntry.event_description) {
409             *var_len = strlen(theEntry.event_description);
410             return (unsigned char *) theEntry.event_description;
411         } else {
412             *var_len = 0;
413             return zero_octet_string;
414         }
415     case EVENTTYPE:
416         long_ret = theEntry.event_type;
417         return (unsigned char *) &long_ret;
418     case EVENTCOMMUNITY:
419         if (theEntry.event_community) {
420             *var_len = strlen(theEntry.event_community);
421             return (unsigned char *) theEntry.event_community;
422         } else {
423             *var_len = 0;
424             return zero_octet_string;
425         }
426     case EVENTLASTTIMESENT:
427         long_ret = theEntry.event_last_time_sent;
428         return (unsigned char *) &long_ret;
429     case EVENTOWNER:
430         if (hdr->owner) {
431             *var_len = strlen(hdr->owner);
432             return (unsigned char *) hdr->owner;
433         } else {
434             *var_len = 0;
435             return zero_octet_string;
436         }
437     case EVENTSTATUS:
438         long_ret = hdr->status;
439         return (unsigned char *) &long_ret;
440     default:
441         ag_trace("EventControlTable: unknown vp->magic=%d",
442                  (int) vp->magic);
443         ERROR_MSG("");
444     }
445     return NULL;
446 }
447 
448 static SCROLLER_T *
event_extract_scroller(void * v_body)449 event_extract_scroller(void *v_body)
450 {
451     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) v_body;
452     return &body->scrlr;
453 }
454 
455 unsigned char  *
var_logTable(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method)456 var_logTable(struct variable *vp,
457              oid * name,
458              size_t * length,
459              int exact, size_t * var_len, WriteMethod ** write_method)
460 {
461     static long     long_ret;
462     static DATA_ENTRY_T theEntry;
463     RMON_ENTRY_T   *hdr;
464 
465     *write_method = NULL;
466     hdr = ROWDATAAPI_header_DataEntry(vp, name, length, exact, var_len,
467                                       table_ptr,
468                                       &event_extract_scroller,
469                                       sizeof(DATA_ENTRY_T), &theEntry);
470     if (!hdr)
471         return NULL;
472 
473     *var_len = sizeof(long);    /* default */
474 
475     switch (vp->magic) {
476     case LOGEVENTINDEX:
477         long_ret = hdr->ctrl_index;
478         return (unsigned char *) &long_ret;
479     case LOGINDEX:
480         long_ret = theEntry.data_index;
481         return (unsigned char *) &long_ret;
482     case LOGTIME:
483         long_ret = theEntry.log_time;
484         return (unsigned char *) &long_ret;
485     case LOGDESCRIPTION:
486         if (theEntry.log_description) {
487             *var_len = strlen(theEntry.log_description);
488             return (unsigned char *) theEntry.log_description;
489         } else {
490             *var_len = 0;
491             return zero_octet_string;
492         }
493     default:
494         ERROR_MSG("");
495     }
496 
497     return NULL;
498 }
499 
500 /*
501  * External API section
502  */
503 
504 static char    *
create_explanaition(CRTL_ENTRY_T * evptr,u_char is_rising,u_long alarm_index,u_long event_index,oid * alarmed_var,size_t alarmed_var_length,u_long value,u_long the_threshold,u_long sample_type,const char * alarm_descr)505 create_explanaition(CRTL_ENTRY_T * evptr, u_char is_rising,
506                     u_long alarm_index, u_long event_index,
507                     oid * alarmed_var,
508                     size_t alarmed_var_length,
509                     u_long value, u_long the_threshold,
510                     u_long sample_type, const char *alarm_descr)
511 {
512 #define UNEQ_LENGTH	(1 + 11 + 4 + 11 + 1 + 20)
513     char            expl[UNEQ_LENGTH];
514     static char     c_oid[SPRINT_MAX_LEN];
515     size_t          sz;
516     char           *descr;
517     register char  *pch;
518     register char  *tmp;
519 
520 
521     snprint_objid(c_oid, sizeof(c_oid)-1, alarmed_var, alarmed_var_length);
522     c_oid[sizeof(c_oid)-1] = '\0';
523     for (pch = c_oid;;) {
524         tmp = strchr(pch, '.');
525         if (!tmp)
526             break;
527         if (isdigit((unsigned char)tmp[1]) || '"' == tmp[1])
528             break;
529         pch = tmp + 1;
530     }
531 
532     snprintf(expl, UNEQ_LENGTH, "=%ld %s= %ld :%ld, %ld",
533              (unsigned long) value,
534              is_rising ? ">" : "<",
535              (unsigned long) the_threshold,
536              (long) alarm_index, (long) event_index);
537     sz = 3 + strlen(expl) + strlen(pch);
538     if (alarm_descr)
539         sz += strlen(alarm_descr);
540 
541     descr = AGMALLOC(sz);
542     if (!descr) {
543         ag_trace("Can't allocate event description");
544         return NULL;
545     }
546 
547     if (alarm_descr) {
548         strcpy(descr, alarm_descr);
549         strcat(descr, ":");
550     } else
551         *descr = '\0';
552 
553     strcat(descr, pch);
554     strcat(descr, expl);
555     return descr;
556 }
557 
558 static void
event_send_trap(CRTL_ENTRY_T * evptr,u_char is_rising,u_int alarm_index,u_int value,u_int the_threshold,oid * alarmed_var,size_t alarmed_var_length,u_int sample_type)559 event_send_trap(CRTL_ENTRY_T * evptr, u_char is_rising,
560                 u_int alarm_index,
561                 u_int value, u_int the_threshold,
562                 oid * alarmed_var, size_t alarmed_var_length,
563                 u_int sample_type)
564 {
565     static oid      objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
566     static oid      rmon1_trap_oid[] = { 1, 3, 6, 1, 2, 1, 16, 0, 0 };
567     static oid      alarm_index_oid[] =
568         { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 1, 0 };
569     static oid      alarmed_var_oid[] =
570         { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 3, 0 };
571     static oid      sample_type_oid[] =
572         { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 4, 0 };
573     static oid      value_oid[] = { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 5, 0 };
574     static oid      threshold_oid[] = { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 7, 0 };     /* rising case */
575     netsnmp_variable_list *var_list = NULL;
576 
577     /*
578      * set the last 'oid' : risingAlarm or fallingAlarm
579      */
580     if (is_rising) {
581         rmon1_trap_oid[8] = 1;
582         threshold_oid[10] = 7;
583     } else {
584         rmon1_trap_oid[8] = 2;
585         threshold_oid[10] = 8;
586     }
587     alarm_index_oid[11] = alarm_index;
588     alarmed_var_oid[11] = alarm_index;
589     sample_type_oid[11] = alarm_index;
590     value_oid[11]       = alarm_index;
591     threshold_oid[11]   = alarm_index;
592 
593     /*
594      * build the var list
595      */
596     snmp_varlist_add_variable(&var_list, objid_snmptrap,
597                               OID_LENGTH(objid_snmptrap),
598                               ASN_OBJECT_ID, (u_char *) rmon1_trap_oid,
599                               sizeof(rmon1_trap_oid));
600     snmp_varlist_add_variable(&var_list, alarm_index_oid,
601                               OID_LENGTH(alarm_index_oid),
602                               ASN_INTEGER, (u_char *) &alarm_index,
603                               sizeof(u_int));
604     snmp_varlist_add_variable(&var_list, alarmed_var_oid,
605                               OID_LENGTH(alarmed_var_oid),
606                               ASN_OBJECT_ID, (u_char *) alarmed_var,
607                               alarmed_var_length * sizeof(oid));
608     snmp_varlist_add_variable(&var_list, sample_type_oid,
609                               OID_LENGTH(sample_type_oid),
610                               ASN_INTEGER, (u_char *) &sample_type,
611                               sizeof(u_int));
612     snmp_varlist_add_variable(&var_list, value_oid,
613                               OID_LENGTH(value_oid),
614                               ASN_INTEGER, (u_char *) &value,
615                               sizeof(u_int));
616     snmp_varlist_add_variable(&var_list, threshold_oid,
617                               OID_LENGTH(threshold_oid),
618                               ASN_INTEGER, (u_char *) &the_threshold,
619                               sizeof(u_int));
620 
621     send_v2trap(var_list);
622     ag_trace("rmon trap has been sent");
623     snmp_free_varbind(var_list);
624 }
625 
626 
627 static void
event_save_log(CRTL_ENTRY_T * body,char * event_descr)628 event_save_log(CRTL_ENTRY_T * body, char *event_descr)
629 {
630     register DATA_ENTRY_T *lptr;
631 
632     lptr = ROWDATAAPI_locate_new_data(&body->scrlr);
633     if (!lptr) {
634         ag_trace("Err: event_save_log:cannot locate ?");
635         return;
636     }
637 
638     lptr->log_time = body->event_last_time_sent;
639     if (lptr->log_description)
640         AGFREE(lptr->log_description);
641     lptr->log_description = AGSTRDUP(event_descr);
642     lptr->data_index = ROWDATAAPI_get_total_number(&body->scrlr);
643 
644     /*
645      * ag_trace ("log has been saved, data_index=%d", (int) lptr->data_index);
646      */
647 }
648 
649 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,const char * alarm_descr)650 event_api_send_alarm(u_char is_rising,
651                      u_long alarm_index,
652                      u_long event_index,
653                      oid * alarmed_var,
654                      size_t alarmed_var_length,
655                      u_long sample_type,
656                      u_long value, u_long the_threshold,
657                      const char *alarm_descr)
658 {
659     RMON_ENTRY_T   *eptr;
660     CRTL_ENTRY_T   *evptr;
661 
662     if (!event_index)
663         return SNMP_ERR_NOERROR;
664 
665 #if 0
666     ag_trace("event_api_send_alarm(%d,%d,%d,'%s')",
667              (int) is_rising, (int) alarm_index, (int) event_index,
668              alarm_descr);
669 #endif
670     eptr = ROWAPI_find(table_ptr, event_index);
671     if (!eptr) {
672         /*
673          * ag_trace ("event cannot find entry %ld", event_index);
674          */
675         return SNMP_ERR_NOSUCHNAME;
676     }
677 
678     evptr = (CRTL_ENTRY_T *) eptr->body;
679     evptr->event_last_time_sent = AGUTIL_sys_up_time();
680 
681 
682     if (EVENT_TRAP == evptr->event_type
683         || EVENT_LOG_AND_TRAP == evptr->event_type) {
684         event_send_trap(evptr, is_rising, alarm_index, value,
685                         the_threshold, alarmed_var, alarmed_var_length,
686                         sample_type);
687     }
688 
689     if (EVENT_LOG == evptr->event_type
690         || EVENT_LOG_AND_TRAP == evptr->event_type) {
691         register char  *explain;
692 
693         explain = create_explanaition(evptr, is_rising,
694                                       alarm_index, event_index,
695                                       alarmed_var, alarmed_var_length,
696                                       value, the_threshold,
697                                       sample_type, alarm_descr);
698         /*
699          * if (explain) ag_trace ("Dbg:'%s'", explain);
700          */
701         event_save_log(evptr, explain);
702         if (explain)
703             AGFREE(explain);
704     }
705 
706     return SNMP_ERR_NOERROR;
707 }
708 
709 #if 1                           /* debug, but may be used for init. TBD: may be token snmpd.conf ? */
710 int
add_event_entry(int ctrl_index,char * event_description,EVENT_TYPE_T event_type,char * event_community)711 add_event_entry(int ctrl_index,
712                 char *event_description,
713                 EVENT_TYPE_T event_type, char *event_community)
714 {
715     register RMON_ENTRY_T *eptr;
716     register CRTL_ENTRY_T *body;
717     int             ierr;
718 
719     ierr = ROWAPI_new(table_ptr, ctrl_index);
720     if (ierr) {
721         ag_trace("ROWAPI_new failed with %d", ierr);
722         return ierr;
723     }
724 
725     eptr = ROWAPI_find(table_ptr, ctrl_index);
726     if (!eptr) {
727         ag_trace("ROWAPI_find failed");
728         return -4;
729     }
730 
731     body = (CRTL_ENTRY_T *) eptr->body;
732 
733     /*
734      * set parameters
735      */
736 
737     if (event_description) {
738         if (body->event_description)
739             AGFREE(body->event_description);
740         body->event_description = AGSTRDUP(event_description);
741     }
742 
743     if (event_community) {
744         if (body->event_community)
745             AGFREE(body->event_community);
746         body->event_community = AGSTRDUP(event_community);
747     }
748 
749     body->event_type = event_type;
750 
751     eptr->new_status = RMON1_ENTRY_VALID;
752     ierr = ROWAPI_commit(table_ptr, ctrl_index);
753     if (ierr) {
754         ag_trace("ROWAPI_commit failed with %d", ierr);
755     }
756 
757     return ierr;
758 }
759 #endif
760 
761 /*
762  * Registration & Initializatio section
763  */
764 
765 oid             eventTable_variables_oid[] =
766     { 1, 3, 6, 1, 2, 1, 16, 9, 1 };
767 oid             logTable_variables_oid[] = { 1, 3, 6, 1, 2, 1, 16, 9, 2 };
768 
769 struct variable2 eventTable_variables[] = {
770     /*
771      * magic number        , variable type, ro/rw , callback fn  ,           L, oidsuffix
772      */
773     {EVENTINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
774      var_eventTable, 2, {1, 1}},
775     {EVENTDESCRIPTION, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
776      var_eventTable, 2, {1, 2}},
777     {EVENTTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
778      var_eventTable, 2, {1, 3}},
779     {EVENTCOMMUNITY, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
780      var_eventTable, 2, {1, 4}},
781     {EVENTLASTTIMESENT, ASN_TIMETICKS, NETSNMP_OLDAPI_RONLY,
782      var_eventTable, 2, {1, 5}},
783     {EVENTOWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
784      var_eventTable, 2, {1, 6}},
785     {EVENTSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
786      var_eventTable, 2, {1, 7}}
787 };
788 
789 struct variable2 logTable_variables[] = {
790     /*
791      * magic number        , variable type, ro/rw , callback fn  ,           L, oidsuffix
792      */
793     {LOGEVENTINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
794      var_logTable, 2, {1, 1}},
795     {LOGINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
796      var_logTable, 2, {1, 2}},
797     {LOGTIME, ASN_TIMETICKS, NETSNMP_OLDAPI_RONLY,
798      var_logTable, 2, {1, 3}},
799     {LOGDESCRIPTION, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
800      var_logTable, 2, {1, 4}}
801 
802 };
803 
804 void
init_event(void)805 init_event(void)
806 {
807     REGISTER_MIB("eventTable", eventTable_variables, variable2,
808                  eventTable_variables_oid);
809     REGISTER_MIB("logTable", logTable_variables, variable2,
810                  logTable_variables_oid);
811 
812     ROWAPI_init_table(&EventCtrlTable, "Event", 0, &event_Create, &event_Clone, &event_Delete, NULL,    /* &event_Validate, */
813                       &event_Activate, &event_Deactivate, &event_Copy);
814 #if 0
815     add_event_entry(3, "Alarm", EVENT_LOG_AND_TRAP, NULL);
816     /*
817      * add_event_entry (5, ">=", EVENT_LOG_AND_TRAP, NULL);
818      */
819 #endif
820 }
821