summaryrefslogtreecommitdiff
path: root/agent/mibgroup/Rmon/history.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/Rmon/history.c')
-rw-r--r--agent/mibgroup/Rmon/history.c727
1 files changed, 727 insertions, 0 deletions
diff --git a/agent/mibgroup/Rmon/history.c b/agent/mibgroup/Rmon/history.c
new file mode 100644
index 0000000..c8e9c25
--- /dev/null
+++ b/agent/mibgroup/Rmon/history.c
@@ -0,0 +1,727 @@
+/**************************************************************
+ * Copyright (C) 2001 Alex Rozin, Optical Access
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * ALEX ROZIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * ALEX ROZIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ ******************************************************************/
+
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "history.h"
+
+/*
+ * Implementation headers
+ */
+#include "agutil_api.h"
+#include "row_api.h"
+
+/*
+ * File scope definitions section
+ */
+
+#define historyControlEntryFirstIndexBegin 11
+
+#define CTRL_INDEX 3
+#define CTRL_DATASOURCE 4
+#define CTRL_BUCKETSREQUESTED 5
+#define CTRL_BUCKETSGRANTED 6
+#define CTRL_INTERVAL 7
+#define CTRL_OWNER 8
+#define CTRL_STATUS 9
+
+#define DATA_INDEX 3
+#define DATA_SAMPLEINDEX 4
+#define DATA_INTERVALSTART 5
+#define DATA_DROPEVENTS 6
+#define DATA_OCTETS 7
+#define DATA_PKTS 8
+#define DATA_BROADCASTPKTS 9
+#define DATA_MULTICASTPKTS 10
+#define DATA_CRCALIGNERRORS 11
+#define DATA_UNDERSIZEPKTS 12
+#define DATA_OVERSIZEPKTS 13
+#define DATA_FRAGMENTS 14
+#define DATA_JABBERS 15
+#define DATA_COLLISIONS 16
+#define DATA_UTILIZATION 17
+
+/*
+ * defaults & limitations
+ */
+
+#define MAX_BUCKETS_IN_CRTL_ENTRY 50
+#define HIST_DEF_BUCK_REQ 50
+#define HIST_DEF_INTERVAL 1800
+static VAR_OID_T DEFAULT_DATA_SOURCE = { 11, /* ifIndex.1 */
+ {1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1}
+};
+
+typedef struct data_struct_t {
+ struct data_struct_t *next;
+ u_long data_index;
+ u_long start_interval;
+ u_long utilization;
+ ETH_STATS_T EthData;
+} DATA_ENTRY_T;
+
+typedef struct {
+ u_long interval;
+ u_long timer_id;
+ VAR_OID_T data_source;
+
+ u_long coeff;
+ DATA_ENTRY_T previous_bucket;
+ SCROLLER_T scrlr;
+
+} CRTL_ENTRY_T;
+
+static TABLE_DEFINTION_T HistoryCtrlTable;
+static TABLE_DEFINTION_T *table_ptr = &HistoryCtrlTable;
+
+/*
+ * Main section
+ */
+
+# define Leaf_historyControlDataSource 2
+# define Leaf_historyControlBucketsRequested 3
+# define Leaf_historyControlInterval 5
+# define Leaf_historyControlOwner 6
+# define Leaf_historyControlStatus 7
+# define MIN_historyControlBucketsRequested 1
+# define MAX_historyControlBucketsRequested 65535
+# define MIN_historyControlInterval 1
+# define MAX_historyControlInterval 3600
+
+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)
+{
+ long long_temp;
+ int leaf_id, snmp_status;
+ static int prev_action = COMMIT;
+ RMON_ENTRY_T *hdr;
+ CRTL_ENTRY_T *cloned_body;
+ CRTL_ENTRY_T *body;
+
+ switch (action) {
+ case RESERVE1:
+ case FREE:
+ case UNDO:
+ case ACTION:
+ case COMMIT:
+ default:
+ return ROWAPI_do_another_action(name,
+ historyControlEntryFirstIndexBegin,
+ action, &prev_action, table_ptr,
+ sizeof(CRTL_ENTRY_T));
+ case RESERVE2:
+ /*
+ * get values from PDU, check them and save them in the cloned entry
+ */
+ long_temp = name[historyControlEntryFirstIndexBegin];
+ leaf_id = (int) name[historyControlEntryFirstIndexBegin - 1];
+ hdr = ROWAPI_find(table_ptr, long_temp); /* it MUST be OK */
+ cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
+ body = (CRTL_ENTRY_T *) hdr->body;
+ switch (leaf_id) {
+ case Leaf_historyControlDataSource:
+ snmp_status = AGUTIL_get_oid_value(var_val, var_val_type,
+ var_val_len,
+ &cloned_body->data_source);
+ if (SNMP_ERR_NOERROR != snmp_status) {
+ ag_trace("can't browse historyControlDataSource");
+ return snmp_status;
+ }
+ if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
+ snmp_oid_compare(cloned_body->data_source.objid,
+ cloned_body->data_source.length,
+ body->data_source.objid,
+ body->data_source.length)) {
+ ag_trace
+ ("can't change historyControlDataSource - not Creation");
+ return SNMP_ERR_BADVALUE;
+ }
+ break;
+ case Leaf_historyControlBucketsRequested:
+ snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
+ var_val_len,
+ MIN_historyControlBucketsRequested,
+ MAX_historyControlBucketsRequested,
+ (long *) &cloned_body->scrlr.
+ data_requested);
+ if (SNMP_ERR_NOERROR != snmp_status) {
+ return snmp_status;
+ }
+#if 0
+ if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
+ cloned_body->scrlr.data_requested !=
+ body->scrlr.data_requested)
+ return SNMP_ERR_BADVALUE;
+#endif
+ break;
+ case Leaf_historyControlInterval:
+ snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
+ var_val_len,
+ MIN_historyControlInterval,
+ MAX_historyControlInterval,
+ (long *) &cloned_body->interval);
+ if (SNMP_ERR_NOERROR != snmp_status) {
+ return snmp_status;
+ }
+#if 0
+ if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
+ cloned_body->interval != body->interval)
+ return SNMP_ERR_BADVALUE;
+#endif
+ break;
+ case Leaf_historyControlOwner:
+ if (hdr->new_owner)
+ AGFREE(hdr->new_owner);
+ hdr->new_owner = AGMALLOC(MAX_OWNERSTRING);;
+ if (!hdr->new_owner)
+ return SNMP_ERR_TOOBIG;
+ snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
+ var_val_len,
+ MAX_OWNERSTRING,
+ 1, NULL, hdr->new_owner);
+ if (SNMP_ERR_NOERROR != snmp_status) {
+ return snmp_status;
+ }
+
+ break;
+ case Leaf_historyControlStatus:
+ snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
+ var_val_len,
+ RMON1_ENTRY_VALID,
+ RMON1_ENTRY_INVALID,
+ &long_temp);
+ if (SNMP_ERR_NOERROR != snmp_status) {
+ return snmp_status;
+ }
+ hdr->new_status = long_temp;
+ break;
+ default:
+ ag_trace("%s:unknown leaf_id=%d\n", table_ptr->name,
+ (int) leaf_id);
+ return SNMP_ERR_NOSUCHNAME;
+ } /* of switch by 'leaf_id' */
+ break;
+
+ } /* of switch by actions */
+
+ prev_action = action;
+ return SNMP_ERR_NOERROR;
+}
+
+/*
+ * var_historyControlTable():
+ */
+unsigned char *
+var_historyControlTable(struct variable *vp,
+ oid * name,
+ size_t * length,
+ int exact,
+ size_t * var_len, WriteMethod ** write_method)
+{
+ static unsigned char zero_octet_string[1];
+ static long long_ret;
+ static CRTL_ENTRY_T theEntry;
+ RMON_ENTRY_T *hdr;
+
+ *write_method = write_historyControl;
+ hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
+ table_ptr,
+ &theEntry, sizeof(CRTL_ENTRY_T));
+ if (!hdr)
+ return NULL;
+
+ *var_len = sizeof(long); /* default */
+
+ switch (vp->magic) {
+ case CTRL_INDEX:
+ long_ret = hdr->ctrl_index;
+ return (unsigned char *) &long_ret;
+
+ case CTRL_DATASOURCE:
+ *var_len = sizeof(oid) * theEntry.data_source.length;
+ return (unsigned char *) theEntry.data_source.objid;
+
+ case CTRL_BUCKETSREQUESTED:
+ long_ret = theEntry.scrlr.data_requested;
+ return (unsigned char *) &long_ret;
+
+ case CTRL_BUCKETSGRANTED:
+
+ long_ret = theEntry.scrlr.data_granted;
+ return (unsigned char *) &long_ret;
+
+ case CTRL_INTERVAL:
+ long_ret = theEntry.interval;
+ return (unsigned char *) &long_ret;
+
+ case CTRL_OWNER:
+ if (hdr->owner) {
+ *var_len = strlen(hdr->owner);
+ return (unsigned char *) hdr->owner;
+ } else {
+ *var_len = 0;
+ return zero_octet_string;
+ }
+
+ case CTRL_STATUS:
+ long_ret = hdr->status;
+ return (unsigned char *) &long_ret;
+
+ default:
+ ag_trace("HistoryControlTable: unknown vp->magic=%d",
+ (int) vp->magic);
+ ERROR_MSG("");
+ }
+ return NULL;
+}
+
+/*
+ * history row management control callbacks
+ */
+
+static void
+compute_delta(ETH_STATS_T * delta,
+ ETH_STATS_T * newval, ETH_STATS_T * prevval)
+{
+#define CNT_DIF(X) delta->X = newval->X - prevval->X
+
+ CNT_DIF(octets);
+ CNT_DIF(packets);
+ CNT_DIF(bcast_pkts);
+ CNT_DIF(mcast_pkts);
+ CNT_DIF(crc_align);
+ CNT_DIF(undersize);
+ CNT_DIF(oversize);
+ CNT_DIF(fragments);
+ CNT_DIF(jabbers);
+ CNT_DIF(collisions);
+}
+
+static void
+history_get_backet(unsigned int clientreg, void *clientarg)
+{
+ RMON_ENTRY_T *hdr_ptr;
+ CRTL_ENTRY_T *body;
+ DATA_ENTRY_T *bptr;
+ ETH_STATS_T newSample;
+
+ /*
+ * ag_trace ("history_get_backet: timer_id=%d", (int) clientreg);
+ */
+ hdr_ptr = (RMON_ENTRY_T *) clientarg;
+ if (!hdr_ptr) {
+ ag_trace
+ ("Err: history_get_backet: hdr_ptr=NULL ? (Inserted in shock)");
+ return;
+ }
+
+ body = (CRTL_ENTRY_T *) hdr_ptr->body;
+ if (!body) {
+ ag_trace
+ ("Err: history_get_backet: body=NULL ? (Inserted in shock)");
+ return;
+ }
+
+ if (RMON1_ENTRY_VALID != hdr_ptr->status) {
+ ag_trace("Err: history_get_backet when entry %d is not valid ?!!",
+ (int) hdr_ptr->ctrl_index);
+ /*
+ * snmp_alarm_print_list ();
+ */
+ snmp_alarm_unregister(body->timer_id);
+ ag_trace("Err: unregistered %ld", (long) body->timer_id);
+ return;
+ }
+
+ SYSTEM_get_eth_statistics(&body->data_source, &newSample);
+
+ bptr = ROWDATAAPI_locate_new_data(&body->scrlr);
+ if (!bptr) {
+ ag_trace
+ ("Err: history_get_backet for %d: empty bucket's list !??\n",
+ (int) hdr_ptr->ctrl_index);
+ return;
+ }
+
+ bptr->data_index = ROWDATAAPI_get_total_number(&body->scrlr);
+
+ bptr->start_interval = body->previous_bucket.start_interval;
+
+ compute_delta(&bptr->EthData, &newSample,
+ &body->previous_bucket.EthData);
+
+ bptr->utilization =
+ bptr->EthData.octets * 8 + bptr->EthData.packets * (96 + 64);
+ bptr->utilization /= body->coeff;
+
+ /*
+ * update previous_bucket
+ */
+ body->previous_bucket.start_interval = AGUTIL_sys_up_time();
+ memcpy(&body->previous_bucket.EthData, &newSample,
+ sizeof(ETH_STATS_T));
+}
+
+/*
+ * Control Table RowApi Callbacks
+ */
+
+int
+history_Create(RMON_ENTRY_T * eptr)
+{ /* create the body: alloc it and set defaults */
+ CRTL_ENTRY_T *body;
+
+ eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T));
+ if (!eptr->body)
+ return -3;
+ body = (CRTL_ENTRY_T *) eptr->body;
+
+ /*
+ * set defaults
+ */
+ body->interval = HIST_DEF_INTERVAL;
+ body->timer_id = 0;
+ memcpy(&body->data_source, &DEFAULT_DATA_SOURCE, sizeof(VAR_OID_T));
+
+ ROWDATAAPI_init(&body->scrlr, HIST_DEF_BUCK_REQ,
+ MAX_BUCKETS_IN_CRTL_ENTRY, sizeof(DATA_ENTRY_T), NULL);
+
+ return 0;
+}
+
+int
+history_Validate(RMON_ENTRY_T * eptr)
+{
+ /*
+ * T.B.D. (system dependent) check valid inteface in body->data_source;
+ */
+ return 0;
+}
+
+int
+history_Activate(RMON_ENTRY_T * eptr)
+{
+ CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
+
+ body->coeff = 100000L * (long) body->interval;
+
+ ROWDATAAPI_set_size(&body->scrlr,
+ body->scrlr.data_requested,
+ (u_char)(RMON1_ENTRY_VALID == eptr->status) );
+
+ SYSTEM_get_eth_statistics(&body->data_source,
+ &body->previous_bucket.EthData);
+ body->previous_bucket.start_interval = AGUTIL_sys_up_time();
+
+ body->scrlr.current_data_ptr = body->scrlr.first_data_ptr;
+ /*
+ * ag_trace ("Dbg: registered in history_Activate");
+ */
+ body->timer_id = snmp_alarm_register(body->interval, SA_REPEAT,
+ history_get_backet, eptr);
+ return 0;
+}
+
+int
+history_Deactivate(RMON_ENTRY_T * eptr)
+{
+ CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
+
+ snmp_alarm_unregister(body->timer_id);
+ /*
+ * ag_trace ("Dbg: unregistered in history_Deactivate timer_id=%d",
+ * (int) body->timer_id);
+ */
+
+ /*
+ * free data list
+ */
+ ROWDATAAPI_descructor(&body->scrlr);
+
+ return 0;
+}
+
+int
+history_Copy(RMON_ENTRY_T * eptr)
+{
+ CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;
+ CRTL_ENTRY_T *clone = (CRTL_ENTRY_T *) eptr->tmp;
+
+ if (body->scrlr.data_requested != clone->scrlr.data_requested) {
+ ROWDATAAPI_set_size(&body->scrlr, clone->scrlr.data_requested,
+ (u_char)(RMON1_ENTRY_VALID == eptr->status) );
+ }
+
+ if (body->interval != clone->interval) {
+ if (RMON1_ENTRY_VALID == eptr->status) {
+ snmp_alarm_unregister(body->timer_id);
+ body->timer_id =
+ snmp_alarm_register(clone->interval, SA_REPEAT,
+ history_get_backet, eptr);
+ }
+
+ body->interval = clone->interval;
+ }
+
+ if (snmp_oid_compare
+ (clone->data_source.objid, clone->data_source.length,
+ body->data_source.objid, body->data_source.length)) {
+ memcpy(&body->data_source, &clone->data_source, sizeof(VAR_OID_T));
+ }
+
+ return 0;
+}
+
+static SCROLLER_T *
+history_extract_scroller(void *v_body)
+{
+ CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) v_body;
+ return &body->scrlr;
+}
+
+/*
+ * var_etherHistoryTable():
+ */
+unsigned char *
+var_etherHistoryTable(struct variable *vp,
+ oid * name,
+ size_t * length,
+ int exact,
+ size_t * var_len, WriteMethod ** write_method)
+{
+ static long long_ret;
+ static DATA_ENTRY_T theBucket;
+ RMON_ENTRY_T *hdr;
+
+ *write_method = NULL;
+ hdr = ROWDATAAPI_header_DataEntry(vp, name, length, exact, var_len,
+ table_ptr,
+ &history_extract_scroller,
+ sizeof(DATA_ENTRY_T), &theBucket);
+ if (!hdr)
+ return NULL;
+
+ *var_len = sizeof(long); /* default */
+
+ switch (vp->magic) {
+ case DATA_INDEX:
+ long_ret = hdr->ctrl_index;
+ return (unsigned char *) &long_ret;
+ case DATA_SAMPLEINDEX:
+ long_ret = theBucket.data_index;
+ return (unsigned char *) &long_ret;
+ case DATA_INTERVALSTART:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.start_interval;
+ case DATA_DROPEVENTS:
+ long_ret = 0;
+ return (unsigned char *) &long_ret;
+ case DATA_OCTETS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.octets;
+ case DATA_PKTS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.packets;
+ case DATA_BROADCASTPKTS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.bcast_pkts;
+ case DATA_MULTICASTPKTS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.mcast_pkts;
+ case DATA_CRCALIGNERRORS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.crc_align;
+ case DATA_UNDERSIZEPKTS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.undersize;
+ case DATA_OVERSIZEPKTS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.oversize;
+ case DATA_FRAGMENTS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.fragments;
+ case DATA_JABBERS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.jabbers;
+ case DATA_COLLISIONS:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.EthData.collisions;
+ case DATA_UTILIZATION:
+ long_ret = 0;
+ return (unsigned char *) &theBucket.utilization;
+ default:
+ ag_trace("etherHistoryTable: unknown vp->magic=%d",
+ (int) vp->magic);
+ ERROR_MSG("");
+ }
+ return NULL;
+}
+
+#if 1 /* debug, but may be used for init. TBD: may be token snmpd.conf ? */
+int
+add_hist_entry(int ctrl_index, int ifIndex,
+ u_long interval, u_long requested)
+{
+ register RMON_ENTRY_T *eptr;
+ register CRTL_ENTRY_T *body;
+ int ierr;
+
+ ierr = ROWAPI_new(table_ptr, ctrl_index);
+ if (ierr) {
+ ag_trace("ROWAPI_new failed with %d", ierr);
+ return ierr;
+ }
+
+ eptr = ROWAPI_find(table_ptr, ctrl_index);
+ if (!eptr) {
+ ag_trace("ROWAPI_find failed");
+ return -4;
+ }
+
+ body = (CRTL_ENTRY_T *) eptr->body;
+
+ /*
+ * set parameters
+ */
+
+ body->data_source.objid[body->data_source.length - 1] = ifIndex;
+ body->interval = interval;
+ body->scrlr.data_requested = requested;
+
+ eptr->new_status = RMON1_ENTRY_VALID;
+ ierr = ROWAPI_commit(table_ptr, ctrl_index);
+ if (ierr) {
+ ag_trace("ROWAPI_commit failed with %d", ierr);
+ }
+
+ return ierr;
+
+}
+
+#endif
+
+/*
+ * Registration & Initializatio section
+ */
+
+oid historyControlTable_variables_oid[] =
+ { 1, 3, 6, 1, 2, 1, 16, 2, 1 };
+
+struct variable2 historyControlTable_variables[] = {
+ /*
+ * magic number , variable type, ro/rw , callback fn , L, oidsuffix
+ */
+ {CTRL_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_historyControlTable, 2, {1, 1}},
+ {CTRL_DATASOURCE, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
+ var_historyControlTable, 2, {1, 2}},
+ {CTRL_BUCKETSREQUESTED, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_historyControlTable, 2, {1, 3}},
+ {CTRL_BUCKETSGRANTED, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_historyControlTable, 2, {1, 4}},
+ {CTRL_INTERVAL, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_historyControlTable, 2, {1, 5}},
+ {CTRL_OWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
+ var_historyControlTable, 2, {1, 6}},
+ {CTRL_STATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_historyControlTable, 2, {1, 7}},
+
+};
+
+oid etherHistoryTable_variables_oid[] =
+ { 1, 3, 6, 1, 2, 1, 16, 2, 2 };
+
+struct variable2 etherHistoryTable_variables[] = {
+ /*
+ * magic number , variable type , ro/rw , callback fn , L, oidsuffix
+ */
+ {DATA_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 1}},
+ {DATA_SAMPLEINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 2}},
+ {DATA_INTERVALSTART, ASN_TIMETICKS, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 3}},
+ {DATA_DROPEVENTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 4}},
+ {DATA_OCTETS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 5}},
+ {DATA_PKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 6}},
+ {DATA_BROADCASTPKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 7}},
+ {DATA_MULTICASTPKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 8}},
+ {DATA_CRCALIGNERRORS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 9}},
+ {DATA_UNDERSIZEPKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 10}},
+ {DATA_OVERSIZEPKTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 11}},
+ {DATA_FRAGMENTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 12}},
+ {DATA_JABBERS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 13}},
+ {DATA_COLLISIONS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 14}},
+ {DATA_UTILIZATION, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_etherHistoryTable, 2, {1, 15}},
+
+};
+
+void
+init_history(void)
+{
+ REGISTER_MIB("historyControlTable", historyControlTable_variables,
+ variable2, historyControlTable_variables_oid);
+ REGISTER_MIB("etherHistoryTable", etherHistoryTable_variables,
+ variable2, etherHistoryTable_variables_oid);
+
+ ROWAPI_init_table(&HistoryCtrlTable, "History", 0, &history_Create, NULL, /* &history_Clone, */
+ NULL, /* &history_Delete, */
+ &history_Validate,
+ &history_Activate,
+ &history_Deactivate, &history_Copy);
+
+ /*
+ * add_hist_entry (2, 3, 4, 2);
+ */
+}