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