diff options
Diffstat (limited to 'agent/mibgroup/Rmon/statistics.c')
-rw-r--r-- | agent/mibgroup/Rmon/statistics.c | 544 |
1 files changed, 544 insertions, 0 deletions
diff --git a/agent/mibgroup/Rmon/statistics.c b/agent/mibgroup/Rmon/statistics.c new file mode 100644 index 0000000..3ed4acb --- /dev/null +++ b/agent/mibgroup/Rmon/statistics.c @@ -0,0 +1,544 @@ +/************************************************************** + * Copyright (C) 2001 Tali 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. + * + * TALI 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 +#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 "statistics.h" + /* + * Implementation headers + */ +#include "agutil_api.h" +#include "row_api.h" + /* + * File scope definitions section + */ + /* + * from MIB compilation + */ +#define MIB_DESCR "EthStat" +#define etherStatsEntryFirstIndexBegin 11 +#define IDetherStatsDroppedFrames 1 +#define IDetherStatsCreateTime 2 +#define IDetherStatsIndex 3 +#define IDetherStatsDataSource 4 +#define IDetherStatsDropEvents 5 +#define IDetherStatsOctets 6 +#define IDetherStatsPkts 7 +#define IDetherStatsBroadcastPkts 8 +#define IDetherStatsMulticastPkts 9 +#define IDetherStatsCRCAlignErrors 10 +#define IDetherStatsUndersizePkts 11 +#define IDetherStatsOversizePkts 12 +#define IDetherStatsFragments 13 +#define IDetherStatsJabbers 14 +#define IDetherStatsCollisions 15 +#define IDetherStatsPkts64Octets 16 +#define IDetherStatsPkts65to127Octets 17 +#define IDetherStatsPkts128to255Octets 18 +#define IDetherStatsPkts256to511Octets 19 +#define IDetherStatsPkts512to1023Octets 20 +#define IDetherStatsPkts1024to1518Octets 21 +#define IDetherStatsOwner 22 +#define IDetherStatsStatus 23 +#define Leaf_etherStatsDataSource 2 +#define Leaf_etherStatsOwner 20 +#define Leaf_etherStatsStatus 21 +#define MIN_etherStatsIndex 1 +#define MAX_etherStatsIndex 65535 + typedef struct { + VAR_OID_T + data_source; + u_long + etherStatsCreateTime; + ETH_STATS_T + eth; + } CRTL_ENTRY_T; + +/* + * Main section + */ + + static TABLE_DEFINTION_T + StatCtrlTable; + static TABLE_DEFINTION_T * + table_ptr = & + StatCtrlTable; + +/* + * Control Table RowApi Callbacks + */ + + int + stat_Create(RMON_ENTRY_T * eptr) +{ /* create the body: alloc it and set defaults */ + CRTL_ENTRY_T *body; + static VAR_OID_T data_src_if_index_1 = + { 11, {1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1} }; + + eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T)); + if (!eptr->body) + return -3; + body = (CRTL_ENTRY_T *) eptr->body; + + /* + * set defaults + */ + memcpy(&body->data_source, &data_src_if_index_1, sizeof(VAR_OID_T)); + body->data_source.objid[body->data_source.length - 1] = + eptr->ctrl_index; + eptr->owner = AGSTRDUP("Startup Mgmt"); + memset(&body->eth, 0, sizeof(ETH_STATS_T)); + + return 0; +} + +int +stat_Validate(RMON_ENTRY_T * eptr) +{ + /* + * T.B.D. (system dependent) check valid inteface in body->data_source; + */ + + return 0; +} + +int +stat_Activate(RMON_ENTRY_T * eptr) +{ + CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body; + + body->etherStatsCreateTime = AGUTIL_sys_up_time(); + + return 0; +} + +int +stat_Copy(RMON_ENTRY_T * eptr) +{ + CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body; + CRTL_ENTRY_T *clone = (CRTL_ENTRY_T *) eptr->tmp; + + 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; +} + +int +stat_Deactivate(RMON_ENTRY_T * eptr) +{ + CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body; + memset(&body->eth, 0, sizeof(ETH_STATS_T)); + return 0; +} + + +/*************************************************** + * Function:var_etherStats2Entry + * Purpose: Handles the request for etherStats2Entry variable instances + ***************************************************/ +u_char * +var_etherStats2Entry(struct variable * vp, oid * name, size_t * length, + int exact, size_t * var_len, + WriteMethod ** write_method) +{ + static long long_return; + static CRTL_ENTRY_T theEntry; + RMON_ENTRY_T *hdr; + + *write_method = NULL; + + 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 IDetherStatsDroppedFrames: + long_return = 0; + return (u_char *) & long_return; + case IDetherStatsCreateTime: + long_return = theEntry.etherStatsCreateTime; + return (u_char *) & long_return; + default: + ag_trace("%s: unknown vp->magic=%d", table_ptr->name, + (int) vp->magic); + ERROR_MSG(""); + }; /* of switch by 'vp->magic' */ + + return NULL; +} + + +/*************************************************** + * Function:write_etherStatsEntry + ***************************************************/ +static int +write_etherStatsEntry(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: + snmp_status = + ROWAPI_do_another_action(name, etherStatsEntryFirstIndexBegin, + action, &prev_action, table_ptr, + sizeof(CRTL_ENTRY_T)); + if (SNMP_ERR_NOERROR != snmp_status) { + ag_trace("failed action %d with %d", action, snmp_status); + } + break; + + case RESERVE2: + /* + * get values from PDU, check them and save them in the cloned entry + */ + long_temp = name[etherStatsEntryFirstIndexBegin]; + leaf_id = (int) name[etherStatsEntryFirstIndexBegin - 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_etherStatsDataSource: + snmp_status = AGUTIL_get_oid_value(var_val, var_val_type, + var_val_len, + &cloned_body->data_source); + if (SNMP_ERR_NOERROR != snmp_status) { + 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)) + return SNMP_ERR_BADVALUE; + break; + + break; + case Leaf_etherStatsOwner: + 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_etherStatsStatus: + 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) { + ag_trace("cannot browse etherStatsStatus"); + return snmp_status; + } + hdr->new_status = long_temp; + break; + 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 'action' */ + + prev_action = action; + return SNMP_ERR_NOERROR; +} + +/*************************************************** + * Function:var_etherStatsEntry + * Purpose: Handles the request for etherStatsEntry variable instances + ***************************************************/ +u_char * +var_etherStatsEntry(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_return; + static CRTL_ENTRY_T theEntry; + RMON_ENTRY_T *hdr; + + *write_method = write_etherStatsEntry; + hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len, + table_ptr, + &theEntry, sizeof(CRTL_ENTRY_T)); + if (!hdr) + return NULL; + + if (RMON1_ENTRY_VALID == hdr->status) + SYSTEM_get_eth_statistics(&theEntry.data_source, &theEntry.eth); + + *var_len = sizeof(long); + + switch (vp->magic) { + case IDetherStatsIndex: + long_return = hdr->ctrl_index; + return (u_char *) & long_return; + case IDetherStatsDataSource: + *var_len = sizeof(oid) * theEntry.data_source.length; + return (unsigned char *) theEntry.data_source.objid; + case IDetherStatsDropEvents: + long_return = 0; /* theEntry.eth.etherStatsDropEvents; */ + return (u_char *) & long_return; + case IDetherStatsOctets: + long_return = theEntry.eth.octets; + return (u_char *) & long_return; + case IDetherStatsPkts: + long_return = theEntry.eth.packets; + return (u_char *) & long_return; + case IDetherStatsBroadcastPkts: + long_return = theEntry.eth.bcast_pkts; + return (u_char *) & long_return; + case IDetherStatsMulticastPkts: + long_return = theEntry.eth.mcast_pkts; + return (u_char *) & long_return; + case IDetherStatsCRCAlignErrors: + long_return = theEntry.eth.crc_align; + return (u_char *) & long_return; + case IDetherStatsUndersizePkts: + long_return = theEntry.eth.undersize; + return (u_char *) & long_return; + case IDetherStatsOversizePkts: + long_return = theEntry.eth.oversize; + return (u_char *) & long_return; + case IDetherStatsFragments: + long_return = theEntry.eth.fragments; + return (u_char *) & long_return; + case IDetherStatsJabbers: + long_return = theEntry.eth.jabbers; + return (u_char *) & long_return; + case IDetherStatsCollisions: + long_return = theEntry.eth.collisions; + return (u_char *) & long_return; + case IDetherStatsPkts64Octets: + long_return = theEntry.eth.pkts_64; + return (u_char *) & long_return; + case IDetherStatsPkts65to127Octets: + long_return = theEntry.eth.pkts_65_127; + return (u_char *) & long_return; + case IDetherStatsPkts128to255Octets: + long_return = theEntry.eth.pkts_128_255; + return (u_char *) & long_return; + case IDetherStatsPkts256to511Octets: + long_return = theEntry.eth.pkts_256_511; + return (u_char *) & long_return; + case IDetherStatsPkts512to1023Octets: + long_return = theEntry.eth.pkts_512_1023; + return (u_char *) & long_return; + case IDetherStatsPkts1024to1518Octets: + long_return = theEntry.eth.pkts_1024_1518; + return (u_char *) & long_return; + case IDetherStatsOwner: + if (hdr->owner) { + *var_len = strlen(hdr->owner); + return (unsigned char *) hdr->owner; + } else { + *var_len = 0; + return zero_octet_string; + } + case IDetherStatsStatus: + long_return = hdr->status; + return (u_char *) & long_return; + default: + ERROR_MSG(""); + }; /* of switch by 'vp->magic' */ + + return NULL; +} + +#if 1 /* debug, but may be used for init. TBD: may be token snmpd.conf ? */ +int +add_statistics_entry(int ctrl_index, int ifIndex) +{ + int ierr; + + ierr = ROWAPI_new(table_ptr, ctrl_index); + switch (ierr) { + case -1: + ag_trace("max. number exedes\n"); + break; + case -2: + ag_trace("malloc failed"); + break; + case -3: + ag_trace("ClbkCreate failed"); + break; + case 0: + break; + default: + ag_trace("Unknown code %d", ierr); + break; + } + + if (!ierr) { + register RMON_ENTRY_T *eptr = ROWAPI_find(table_ptr, ctrl_index); + if (!eptr) { + ag_trace("cannot find it"); + ierr = -4; + } else { + CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body; + + body->data_source.objid[body->data_source.length - 1] = + ifIndex; + + eptr->new_status = RMON1_ENTRY_VALID; + ierr = ROWAPI_commit(table_ptr, ctrl_index); + if (ierr) { + ag_trace("ROWAPI_commit returned %d", ierr); + } + } + } + + return ierr; +} +#endif + +/*************************************************** + * define Variables callbacks + ***************************************************/ +oid oidstatisticsVariablesOid[] = { 1, 3, 6, 1, 2, 1, 16, 1 }; + +struct variable7 oidstatisticsVariables[] = { + {IDetherStatsIndex, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 1}}, + {IDetherStatsDataSource, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE, + var_etherStatsEntry, 3, {1, 1, 2}}, + {IDetherStatsDropEvents, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 3}}, + {IDetherStatsOctets, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 4}}, + {IDetherStatsPkts, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 5}}, + {IDetherStatsBroadcastPkts, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 6}}, + {IDetherStatsMulticastPkts, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 7}}, + {IDetherStatsCRCAlignErrors, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 8}}, + {IDetherStatsUndersizePkts, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 9}}, + {IDetherStatsOversizePkts, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 10}}, + {IDetherStatsFragments, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 11}}, + {IDetherStatsJabbers, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 12}}, + {IDetherStatsCollisions, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 13}}, + {IDetherStatsPkts64Octets, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 14}}, + {IDetherStatsPkts65to127Octets, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 15}}, + {IDetherStatsPkts128to255Octets, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 16}}, + {IDetherStatsPkts256to511Octets, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 17}}, + {IDetherStatsPkts512to1023Octets, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 18}}, + {IDetherStatsPkts1024to1518Octets, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStatsEntry, 3, {1, 1, 19}}, + {IDetherStatsOwner, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_etherStatsEntry, 3, {1, 1, 20}}, + {IDetherStatsStatus, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_etherStatsEntry, 3, {1, 1, 21}}, + {IDetherStatsDroppedFrames, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_etherStats2Entry, 3, {4, 1, 1}}, + {IDetherStatsCreateTime, ASN_TIMETICKS, NETSNMP_OLDAPI_RONLY, + var_etherStats2Entry, 3, {4, 1, 2}}, +}; + +/*************************************************** + * Function:init_statistics + * Purpose: register statistics objects in the agent + ***************************************************/ +void +init_statistics(void) +{ + REGISTER_MIB(MIB_DESCR, oidstatisticsVariables, variable7, + oidstatisticsVariablesOid); + + ROWAPI_init_table(&StatCtrlTable, MIB_DESCR, 0, &stat_Create, NULL, /* &stat_Clone, */ + NULL, /* &stat_Delete, */ + &stat_Validate, + &stat_Activate, &stat_Deactivate, &stat_Copy); + +#if 0 /* debug */ + { + int iii; + for (iii = 1; iii < 6; iii++) { + add_statistics_entry(iii, iii); + } + + add_statistics_entry(10, 16); + add_statistics_entry(12, 11); + } +#endif +} + +/* + * end of file statistics.c + */ |