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 # include <sys/time.h>
28 # include <time.h>
29 #else
30 # if HAVE_SYS_TIME_H
31 # include <sys/time.h>
32 # else
33 # include <time.h>
34 # endif
35 #endif
36 #if HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39
40 #include <net-snmp/net-snmp-includes.h>
41 #include <net-snmp/agent/net-snmp-agent-includes.h>
42
43 #include "history.h"
44
45 /*
46 * Implementation headers
47 */
48 #include "agutil_api.h"
49 #include "row_api.h"
50
51 /*
52 * File scope definitions section
53 */
54
55 #define historyControlEntryFirstIndexBegin 11
56
57 #define CTRL_INDEX 3
58 #define CTRL_DATASOURCE 4
59 #define CTRL_BUCKETSREQUESTED 5
60 #define CTRL_BUCKETSGRANTED 6
61 #define CTRL_INTERVAL 7
62 #define CTRL_OWNER 8
63 #define CTRL_STATUS 9
64
65 #define DATA_INDEX 3
66 #define DATA_SAMPLEINDEX 4
67 #define DATA_INTERVALSTART 5
68 #define DATA_DROPEVENTS 6
69 #define DATA_OCTETS 7
70 #define DATA_PKTS 8
71 #define DATA_BROADCASTPKTS 9
72 #define DATA_MULTICASTPKTS 10
73 #define DATA_CRCALIGNERRORS 11
74 #define DATA_UNDERSIZEPKTS 12
75 #define DATA_OVERSIZEPKTS 13
76 #define DATA_FRAGMENTS 14
77 #define DATA_JABBERS 15
78 #define DATA_COLLISIONS 16
79 #define DATA_UTILIZATION 17
80
81 /*
82 * defaults & limitations
83 */
84
85 #define MAX_BUCKETS_IN_CRTL_ENTRY 50
86 #define HIST_DEF_BUCK_REQ 50
87 #define HIST_DEF_INTERVAL 1800
88 static VAR_OID_T DEFAULT_DATA_SOURCE = { 11, /* ifIndex.1 */
89 {1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1}
90 };
91
92 typedef struct data_struct_t {
93 struct data_struct_t *next;
94 u_long data_index;
95 u_long start_interval;
96 u_long utilization;
97 ETH_STATS_T EthData;
98 } DATA_ENTRY_T;
99
100 typedef struct {
101 u_long interval;
102 u_long timer_id;
103 VAR_OID_T data_source;
104
105 u_long coeff;
106 DATA_ENTRY_T previous_bucket;
107 SCROLLER_T scrlr;
108
109 } CRTL_ENTRY_T;
110
111 static TABLE_DEFINTION_T HistoryCtrlTable;
112 static TABLE_DEFINTION_T *table_ptr = &HistoryCtrlTable;
113
114 /*
115 * Main section
116 */
117
118 # define Leaf_historyControlDataSource 2
119 # define Leaf_historyControlBucketsRequested 3
120 # define Leaf_historyControlInterval 5
121 # define Leaf_historyControlOwner 6
122 # define Leaf_historyControlStatus 7
123 # define MIN_historyControlBucketsRequested 1
124 # define MAX_historyControlBucketsRequested 65535
125 # define MIN_historyControlInterval 1
126 # define MAX_historyControlInterval 3600
127
128 static int
write_historyControl(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)129 write_historyControl(int action, u_char * var_val, u_char var_val_type,
130 size_t var_val_len, u_char * statP,
131 oid * name, size_t name_len)
132 {
133 long long_temp;
134 int leaf_id, snmp_status;
135 static int prev_action = COMMIT;
136 RMON_ENTRY_T *hdr;
137 CRTL_ENTRY_T *cloned_body;
138 CRTL_ENTRY_T *body;
139
140 switch (action) {
141 case RESERVE1:
142 case FREE:
143 case UNDO:
144 case ACTION:
145 case COMMIT:
146 default:
147 return ROWAPI_do_another_action(name,
148 historyControlEntryFirstIndexBegin,
149 action, &prev_action, table_ptr,
150 sizeof(CRTL_ENTRY_T));
151 case RESERVE2:
152 /*
153 * get values from PDU, check them and save them in the cloned entry
154 */
155 long_temp = name[historyControlEntryFirstIndexBegin];
156 leaf_id = (int) name[historyControlEntryFirstIndexBegin - 1];
157 hdr = ROWAPI_find(table_ptr, long_temp); /* it MUST be OK */
158 cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
159 body = (CRTL_ENTRY_T *) hdr->body;
160 switch (leaf_id) {
161 case Leaf_historyControlDataSource:
162 snmp_status = AGUTIL_get_oid_value(var_val, var_val_type,
163 var_val_len,
164 &cloned_body->data_source);
165 if (SNMP_ERR_NOERROR != snmp_status) {
166 ag_trace("can't browse historyControlDataSource");
167 return snmp_status;
168 }
169 if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
170 snmp_oid_compare(cloned_body->data_source.objid,
171 cloned_body->data_source.length,
172 body->data_source.objid,
173 body->data_source.length)) {
174 ag_trace
175 ("can't change historyControlDataSource - not Creation");
176 return SNMP_ERR_BADVALUE;
177 }
178 break;
179 case Leaf_historyControlBucketsRequested:
180 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
181 var_val_len,
182 MIN_historyControlBucketsRequested,
183 MAX_historyControlBucketsRequested,
184 (long *) &cloned_body->scrlr.
185 data_requested);
186 if (SNMP_ERR_NOERROR != snmp_status) {
187 return snmp_status;
188 }
189 #if 0
190 if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
191 cloned_body->scrlr.data_requested !=
192 body->scrlr.data_requested)
193 return SNMP_ERR_BADVALUE;
194 #endif
195 break;
196 case Leaf_historyControlInterval:
197 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
198 var_val_len,
199 MIN_historyControlInterval,
200 MAX_historyControlInterval,
201 (long *) &cloned_body->interval);
202 if (SNMP_ERR_NOERROR != snmp_status) {
203 return snmp_status;
204 }
205 #if 0
206 if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
207 cloned_body->interval != body->interval)
208 return SNMP_ERR_BADVALUE;
209 #endif
210 break;
211 case Leaf_historyControlOwner:
212 if (hdr->new_owner)
213 AGFREE(hdr->new_owner);
214 hdr->new_owner = AGMALLOC(MAX_OWNERSTRING);
215 if (!hdr->new_owner)
216 return SNMP_ERR_TOOBIG;
217 snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
218 var_val_len,
219 MAX_OWNERSTRING,
220 1, NULL, hdr->new_owner);
221 if (SNMP_ERR_NOERROR != snmp_status) {
222 return snmp_status;
223 }
224
225 break;
226 case Leaf_historyControlStatus:
227 snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
228 var_val_len,
229 RMON1_ENTRY_VALID,
230 RMON1_ENTRY_INVALID,
231 &long_temp);
232 if (SNMP_ERR_NOERROR != snmp_status) {
233 return snmp_status;
234 }
235 hdr->new_status = long_temp;
236 break;
237 default:
238 ag_trace("%s:unknown leaf_id=%d\n", table_ptr->name,
239 (int) leaf_id);
240 return SNMP_ERR_NOSUCHNAME;
241 } /* of switch by 'leaf_id' */
242 break;
243
244 } /* of switch by actions */
245
246 prev_action = action;
247 return SNMP_ERR_NOERROR;
248 }
249
250 /*
251 * var_historyControlTable():
252 */
253 unsigned char *
var_historyControlTable(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method)254 var_historyControlTable(struct variable *vp,
255 oid * name,
256 size_t * length,
257 int exact,
258 size_t * var_len, WriteMethod ** write_method)
259 {
260 static unsigned char zero_octet_string[1];
261 static long long_ret;
262 static CRTL_ENTRY_T theEntry;
263 RMON_ENTRY_T *hdr;
264
265 *write_method = write_historyControl;
266 hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
267 table_ptr,
268 &theEntry, sizeof(CRTL_ENTRY_T));
269 if (!hdr)
270 return NULL;
271
272 *var_len = sizeof(long); /* default */
273
274 switch (vp->magic) {
275 case CTRL_INDEX:
276 long_ret = hdr->ctrl_index;
277 return (unsigned char *) &long_ret;
278
279 case CTRL_DATASOURCE:
280 *var_len = sizeof(oid) * theEntry.data_source.length;
281 return (unsigned char *) theEntry.data_source.objid;
282
283 case CTRL_BUCKETSREQUESTED:
284 long_ret = theEntry.scrlr.data_requested;
285 return (unsigned char *) &long_ret;
286
287 case CTRL_BUCKETSGRANTED:
288
289 long_ret = theEntry.scrlr.data_granted;
290 return (unsigned char *) &long_ret;
291
292 case CTRL_INTERVAL:
293 long_ret = theEntry.interval;
294 return (unsigned char *) &long_ret;
295
296 case CTRL_OWNER:
297 if (hdr->owner) {
298 *var_len = strlen(hdr->owner);
299 return (unsigned char *) hdr->owner;
300 } else {
301 *var_len = 0;
302 return zero_octet_string;
303 }
304
305 case CTRL_STATUS:
306 long_ret = hdr->status;
307 return (unsigned char *) &long_ret;
308
309 default:
310 ag_trace("HistoryControlTable: unknown vp->magic=%d",
311 (int) vp->magic);
312 ERROR_MSG("");
313 }
314 return NULL;
315 }
316
317 /*
318 * history row management control callbacks
319 */
320
321 static void
compute_delta(ETH_STATS_T * delta,ETH_STATS_T * newval,ETH_STATS_T * prevval)322 compute_delta(ETH_STATS_T * delta,
323 ETH_STATS_T * newval, ETH_STATS_T * prevval)
324 {
325 #define CNT_DIF(X) delta->X = newval->X - prevval->X
326
327 CNT_DIF(octets);
328 CNT_DIF(packets);
329 CNT_DIF(bcast_pkts);
330 CNT_DIF(mcast_pkts);
331 CNT_DIF(crc_align);
332 CNT_DIF(undersize);
333 CNT_DIF(oversize);
334 CNT_DIF(fragments);
335 CNT_DIF(jabbers);
336 CNT_DIF(collisions);
337 }
338
339 static void
history_get_backet(unsigned int clientreg,void * clientarg)340 history_get_backet(unsigned int clientreg, void *clientarg)
341 {
342 RMON_ENTRY_T *hdr_ptr;
343 CRTL_ENTRY_T *body;
344 DATA_ENTRY_T *bptr;
345 ETH_STATS_T newSample;
346
347 /*
348 * ag_trace ("history_get_backet: timer_id=%d", (int) clientreg);
349 */
350 hdr_ptr = (RMON_ENTRY_T *) clientarg;
351 if (!hdr_ptr) {
352 ag_trace
353 ("Err: history_get_backet: hdr_ptr=NULL ? (Inserted in shock)");
354 return;
355 }
356
357 body = (CRTL_ENTRY_T *) hdr_ptr->body;
358 if (!body) {
359 ag_trace
360 ("Err: history_get_backet: body=NULL ? (Inserted in shock)");
361 return;
362 }
363
364 if (RMON1_ENTRY_VALID != hdr_ptr->status) {
365 ag_trace("Err: history_get_backet when entry %d is not valid ?!!",
366 (int) hdr_ptr->ctrl_index);
367 /*
368 * snmp_alarm_print_list ();
369 */
370 snmp_alarm_unregister(body->timer_id);
371 ag_trace("Err: unregistered %ld", (long) body->timer_id);
372 return;
373 }
374
375 SYSTEM_get_eth_statistics(&body->data_source, &newSample);
376
377 bptr = ROWDATAAPI_locate_new_data(&body->scrlr);
378 if (!bptr) {
379 ag_trace
380 ("Err: history_get_backet for %d: empty bucket's list !??\n",
381 (int) hdr_ptr->ctrl_index);
382 return;
383 }
384
385 bptr->data_index = ROWDATAAPI_get_total_number(&body->scrlr);
386
387 bptr->start_interval = body->previous_bucket.start_interval;
388
389 compute_delta(&bptr->EthData, &newSample,
390 &body->previous_bucket.EthData);
391
392 bptr->utilization =
393 bptr->EthData.octets * 8 + bptr->EthData.packets * (96 + 64);
394 bptr->utilization /= body->coeff;
395
396 /*
397 * update previous_bucket
398 */
399 body->previous_bucket.start_interval = AGUTIL_sys_up_time();
400 memcpy(&body->previous_bucket.EthData, &newSample,
401 sizeof(ETH_STATS_T));
402 }
403
404 /*
405 * Control Table RowApi Callbacks
406 */
407
408 int
history_Create(RMON_ENTRY_T * eptr)409 history_Create(RMON_ENTRY_T * eptr)
410 { /* create the body: alloc it and set defaults */
411 CRTL_ENTRY_T *body;
412
413 eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T));
414 if (!eptr->body)
415 return -3;
416 body = (CRTL_ENTRY_T *) eptr->body;
417
418 /*
419 * set defaults
420 */
421 body->interval = HIST_DEF_INTERVAL;
422 body->timer_id = 0;
423 memcpy(&body->data_source, &DEFAULT_DATA_SOURCE, sizeof(VAR_OID_T));
424
425 ROWDATAAPI_init(&body->scrlr, HIST_DEF_BUCK_REQ,
426 MAX_BUCKETS_IN_CRTL_ENTRY, sizeof(DATA_ENTRY_T), NULL);
427
428 return 0;
429 }
430
431 int
history_Validate(RMON_ENTRY_T * eptr)432 history_Validate(RMON_ENTRY_T * eptr)
433 {
434 /*
435 * T.B.D. (system dependent) check valid inteface in body->data_source;
436 */
437 return 0;
438 }
439
440 int
history_Activate(RMON_ENTRY_T * eptr)441 history_Activate(RMON_ENTRY_T * eptr)
442 {
443 CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
444
445 body->coeff = 100000L * (long) body->interval;
446
447 ROWDATAAPI_set_size(&body->scrlr,
448 body->scrlr.data_requested,
449 (u_char)(RMON1_ENTRY_VALID == eptr->status) );
450
451 SYSTEM_get_eth_statistics(&body->data_source,
452 &body->previous_bucket.EthData);
453 body->previous_bucket.start_interval = AGUTIL_sys_up_time();
454
455 body->scrlr.current_data_ptr = body->scrlr.first_data_ptr;
456 /*
457 * ag_trace ("Dbg: registered in history_Activate");
458 */
459 body->timer_id = snmp_alarm_register(body->interval, SA_REPEAT,
460 history_get_backet, eptr);
461 return 0;
462 }
463
464 int
history_Deactivate(RMON_ENTRY_T * eptr)465 history_Deactivate(RMON_ENTRY_T * eptr)
466 {
467 CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
468
469 snmp_alarm_unregister(body->timer_id);
470 /*
471 * ag_trace ("Dbg: unregistered in history_Deactivate timer_id=%d",
472 * (int) body->timer_id);
473 */
474
475 /*
476 * free data list
477 */
478 ROWDATAAPI_descructor(&body->scrlr);
479
480 return 0;
481 }
482
483 int
history_Copy(RMON_ENTRY_T * eptr)484 history_Copy(RMON_ENTRY_T * eptr)
485 {
486 CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
487 CRTL_ENTRY_T *clone = (CRTL_ENTRY_T *) eptr->tmp;
488
489 if (body->scrlr.data_requested != clone->scrlr.data_requested) {
490 ROWDATAAPI_set_size(&body->scrlr, clone->scrlr.data_requested,
491 (u_char)(RMON1_ENTRY_VALID == eptr->status) );
492 }
493
494 if (body->interval != clone->interval) {
495 if (RMON1_ENTRY_VALID == eptr->status) {
496 snmp_alarm_unregister(body->timer_id);
497 body->timer_id =
498 snmp_alarm_register(clone->interval, SA_REPEAT,
499 history_get_backet, eptr);
500 }
501
502 body->interval = clone->interval;
503 }
504
505 if (snmp_oid_compare
506 (clone->data_source.objid, clone->data_source.length,
507 body->data_source.objid, body->data_source.length)) {
508 memcpy(&body->data_source, &clone->data_source, sizeof(VAR_OID_T));
509 }
510
511 return 0;
512 }
513
514 static SCROLLER_T *
history_extract_scroller(void * v_body)515 history_extract_scroller(void *v_body)
516 {
517 CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) v_body;
518 return &body->scrlr;
519 }
520
521 /*
522 * var_etherHistoryTable():
523 */
524 unsigned char *
var_etherHistoryTable(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method)525 var_etherHistoryTable(struct variable *vp,
526 oid * name,
527 size_t * length,
528 int exact,
529 size_t * var_len, WriteMethod ** write_method)
530 {
531 static long long_ret;
532 static DATA_ENTRY_T theBucket;
533 RMON_ENTRY_T *hdr;
534
535 *write_method = NULL;
536 hdr = ROWDATAAPI_header_DataEntry(vp, name, length, exact, var_len,
537 table_ptr,
538 &history_extract_scroller,
539 sizeof(DATA_ENTRY_T), &theBucket);
540 if (!hdr)
541 return NULL;
542
543 *var_len = sizeof(long); /* default */
544
545 switch (vp->magic) {
546 case DATA_INDEX:
547 long_ret = hdr->ctrl_index;
548 return (unsigned char *) &long_ret;
549 case DATA_SAMPLEINDEX:
550 long_ret = theBucket.data_index;
551 return (unsigned char *) &long_ret;
552 case DATA_INTERVALSTART:
553 long_ret = 0;
554 return (unsigned char *) &theBucket.start_interval;
555 case DATA_DROPEVENTS:
556 long_ret = 0;
557 return (unsigned char *) &long_ret;
558 case DATA_OCTETS:
559 long_ret = 0;
560 return (unsigned char *) &theBucket.EthData.octets;
561 case DATA_PKTS:
562 long_ret = 0;
563 return (unsigned char *) &theBucket.EthData.packets;
564 case DATA_BROADCASTPKTS:
565 long_ret = 0;
566 return (unsigned char *) &theBucket.EthData.bcast_pkts;
567 case DATA_MULTICASTPKTS:
568 long_ret = 0;
569 return (unsigned char *) &theBucket.EthData.mcast_pkts;
570 case DATA_CRCALIGNERRORS:
571 long_ret = 0;
572 return (unsigned char *) &theBucket.EthData.crc_align;
573 case DATA_UNDERSIZEPKTS:
574 long_ret = 0;
575 return (unsigned char *) &theBucket.EthData.undersize;
576 case DATA_OVERSIZEPKTS:
577 long_ret = 0;
578 return (unsigned char *) &theBucket.EthData.oversize;
579 case DATA_FRAGMENTS:
580 long_ret = 0;
581 return (unsigned char *) &theBucket.EthData.fragments;
582 case DATA_JABBERS:
583 long_ret = 0;
584 return (unsigned char *) &theBucket.EthData.jabbers;
585 case DATA_COLLISIONS:
586 long_ret = 0;
587 return (unsigned char *) &theBucket.EthData.collisions;
588 case DATA_UTILIZATION:
589 long_ret = 0;
590 return (unsigned char *) &theBucket.utilization;
591 default:
592 ag_trace("etherHistoryTable: unknown vp->magic=%d",
593 (int) vp->magic);
594 ERROR_MSG("");
595 }
596 return NULL;
597 }
598
599 #if 1 /* debug, but may be used for init. TBD: may be token snmpd.conf ? */
600 int
add_hist_entry(int ctrl_index,int ifIndex,u_long interval,u_long requested)601 add_hist_entry(int ctrl_index, int ifIndex,
602 u_long interval, u_long requested)
603 {
604 register RMON_ENTRY_T *eptr;
605 register CRTL_ENTRY_T *body;
606 int ierr;
607
608 ierr = ROWAPI_new(table_ptr, ctrl_index);
609 if (ierr) {
610 ag_trace("ROWAPI_new failed with %d", ierr);
611 return ierr;
612 }
613
614 eptr = ROWAPI_find(table_ptr, ctrl_index);
615 if (!eptr) {
616 ag_trace("ROWAPI_find failed");
617 return -4;
618 }
619
620 body = (CRTL_ENTRY_T *) eptr->body;
621
622 /*
623 * set parameters
624 */
625
626 body->data_source.objid[body->data_source.length - 1] = ifIndex;
627 body->interval = interval;
628 body->scrlr.data_requested = requested;
629
630 eptr->new_status = RMON1_ENTRY_VALID;
631 ierr = ROWAPI_commit(table_ptr, ctrl_index);
632 if (ierr) {
633 ag_trace("ROWAPI_commit failed with %d", ierr);
634 }
635
636 return ierr;
637
638 }
639
640 #endif
641
642 /*
643 * Registration & Initializatio section
644 */
645
646 oid historyControlTable_variables_oid[] =
647 { 1, 3, 6, 1, 2, 1, 16, 2, 1 };
648
649 struct variable2 historyControlTable_variables[] = {
650 /*
651 * magic number , variable type, ro/rw , callback fn , L, oidsuffix
652 */
653 {CTRL_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
654 var_historyControlTable, 2, {1, 1}},
655 {CTRL_DATASOURCE, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
656 var_historyControlTable, 2, {1, 2}},
657 {CTRL_BUCKETSREQUESTED, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
658 var_historyControlTable, 2, {1, 3}},
659 {CTRL_BUCKETSGRANTED, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
660 var_historyControlTable, 2, {1, 4}},
661 {CTRL_INTERVAL, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
662 var_historyControlTable, 2, {1, 5}},
663 {CTRL_OWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
664 var_historyControlTable, 2, {1, 6}},
665 {CTRL_STATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
666 var_historyControlTable, 2, {1, 7}},
667
668 };
669
670 oid etherHistoryTable_variables_oid[] =
671 { 1, 3, 6, 1, 2, 1, 16, 2, 2 };
672
673 struct variable2 etherHistoryTable_variables[] = {
674 /*
675 * magic number , variable type , ro/rw , callback fn , L, oidsuffix
676 */
677 {DATA_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
678 var_etherHistoryTable, 2, {1, 1}},
679 {DATA_SAMPLEINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
680 var_etherHistoryTable, 2, {1, 2}},
681 {DATA_INTERVALSTART, ASN_TIMETICKS, NETSNMP_OLDAPI_RONLY,
682 var_etherHistoryTable, 2, {1, 3}},
683 {DATA_DROPEVENTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
684 var_etherHistoryTable, 2, {1, 4}},
685 {DATA_OCTETS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
686 var_etherHistoryTable, 2, {1, 5}},
687 {DATA_PKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
688 var_etherHistoryTable, 2, {1, 6}},
689 {DATA_BROADCASTPKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
690 var_etherHistoryTable, 2, {1, 7}},
691 {DATA_MULTICASTPKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
692 var_etherHistoryTable, 2, {1, 8}},
693 {DATA_CRCALIGNERRORS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
694 var_etherHistoryTable, 2, {1, 9}},
695 {DATA_UNDERSIZEPKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
696 var_etherHistoryTable, 2, {1, 10}},
697 {DATA_OVERSIZEPKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
698 var_etherHistoryTable, 2, {1, 11}},
699 {DATA_FRAGMENTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
700 var_etherHistoryTable, 2, {1, 12}},
701 {DATA_JABBERS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
702 var_etherHistoryTable, 2, {1, 13}},
703 {DATA_COLLISIONS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
704 var_etherHistoryTable, 2, {1, 14}},
705 {DATA_UTILIZATION, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
706 var_etherHistoryTable, 2, {1, 15}},
707
708 };
709
710 void
init_history(void)711 init_history(void)
712 {
713 REGISTER_MIB("historyControlTable", historyControlTable_variables,
714 variable2, historyControlTable_variables_oid);
715 REGISTER_MIB("etherHistoryTable", etherHistoryTable_variables,
716 variable2, etherHistoryTable_variables_oid);
717
718 ROWAPI_init_table(&HistoryCtrlTable, "History", 0, &history_Create, NULL, /* &history_Clone, */
719 NULL, /* &history_Delete, */
720 &history_Validate,
721 &history_Activate,
722 &history_Deactivate, &history_Copy);
723
724 /*
725 * add_hist_entry (2, 3, 4, 2);
726 */
727 }
728