~ubuntu-branches/ubuntu/gutsy/net-snmp/gutsy-security

« back to all changes in this revision

Viewing changes to agent/mibgroup/Rmon/event.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-13 12:06:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040913120621-g952ntonlleihcvm
Tags: upstream-5.1.1
ImportĀ upstreamĀ versionĀ 5.1.1

Show diffs side-by-side

added added

removed removed

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