📄 expexpression.c
字号:
/* * DisMan Expression MIB: * Core implementation of the expression handling behaviour */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "disman/expr/expExpression.h"#include "disman/expr/expObject.h"netsnmp_tdata *expr_table_data; /* * Initializes the container for the expExpression table, * regardless of which module initialisation routine is called first. */voidinit_expr_table_data(void){ DEBUGMSGTL(("disman:expr:init", "init expression container\n")); if (!expr_table_data) { expr_table_data = netsnmp_tdata_create_table("expExpressionTable", 0); DEBUGMSGTL(("disman:expr:init", "create expression container (%x)\n", expr_table_data)); }}/** Initialize the expExpression module */voidinit_expExpression(void){ init_expr_table_data();} /* =================================================== * * APIs for maintaining the contents of the * expression table container. * * =================================================== */void_mteExpr_dump(void){ struct mteExpression *entry; netsnmp_tdata_row *row; int i = 0; for (row = netsnmp_tdata_row_first(expr_table_data); row; row = netsnmp_tdata_row_next(expr_table_data, row)) { entry = (struct mteExpression *)row->data; DEBUGMSGTL(("disman:expr:dump", "ExpressionTable entry %d: ", i)); DEBUGMSGOID(("disman:expr:dump", row->oid_index.oids, row->oid_index.len)); DEBUGMSG(("disman:expr:dump", "(%s, %s)", row->indexes->val.string, row->indexes->next_variable->val.string)); DEBUGMSG(("disman:expr:dump", ": %x, %x\n", row, entry)); i++; } DEBUGMSGTL(("disman:expr:dump", "ExpressionTable %d entries\n", i));}/* * Create a new row in the expression table */struct expExpression *expExpression_createEntry(char *expOwner, char *expName, int fixed){ netsnmp_tdata_row *row; row = expExpression_createRow(expOwner, expName, fixed); return row ? (struct expExpression *)row->data : NULL;} netsnmp_tdata_row *expExpression_createRow(char *expOwner, char *expName, int fixed){ struct expExpression *entry; netsnmp_tdata_row *row; size_t expOwner_len = (expOwner) ? strlen(expOwner) : 0; size_t expName_len = (expName) ? strlen(expName) : 0; /* * Create the expExpression entry, and the * (table-independent) row wrapper structure... */ entry = SNMP_MALLOC_TYPEDEF(struct expExpression); if (!entry) return NULL; row = netsnmp_tdata_create_row(); if (!row) { SNMP_FREE(entry); return NULL; } row->data = entry; /* * ... initialize this row with the indexes supplied * and the default values for the row... */ if (expOwner) memcpy(entry->expOwner, expOwner, expOwner_len); netsnmp_tdata_row_add_index(row, ASN_OCTET_STR, entry->expOwner, expOwner_len); if (expName) memcpy(entry->expName, expName, expName_len); netsnmp_tdata_row_add_index(row, ASN_OCTET_STR, entry->expName, expName_len); entry->expValueType = EXPVALTYPE_COUNTER; entry->expErrorCount = 0; if (fixed) entry->flags |= EXP_FLAG_FIXED; /* * ... and insert the row into the table container. */ netsnmp_tdata_add_row(expr_table_data, row); DEBUGMSGTL(("disman:expr:table", "Expression entry created (%s, %s)\n", expOwner, expName)); return row;}/* * Remove a row from the expression table */voidexpExpression_removeEntry(netsnmp_tdata_row *row){ struct expExpression *entry; if (!row) return; /* Nothing to remove */ entry = (struct expExpression *) netsnmp_tdata_remove_and_delete_row(expr_table_data, row); if (entry) { /* expExpression_disable( entry ) */ SNMP_FREE(entry); }}struct expExpression *expExpression_getFirstEntry( void ){ return (struct expExpression *) netsnmp_tdata_row_entry(netsnmp_tdata_row_first(expr_table_data));}struct expExpression *expExpression_getNextEntry( char *owner, char *name ){ netsnmp_variable_list owner_var, name_var; memset(&owner_var, 0, sizeof(netsnmp_variable_list)); memset(&name_var, 0, sizeof(netsnmp_variable_list)); snmp_set_var_typed_value( &owner_var, ASN_OCTET_STR, (u_char*)owner, strlen(owner)); snmp_set_var_typed_value( &name_var, ASN_OCTET_STR, (u_char*)name, strlen(name)); owner_var.next_variable = &name_var; return (struct expExpression *) netsnmp_tdata_row_entry( netsnmp_tdata_row_next_byidx(expr_table_data, &owner_var));}struct expExpression *expExpression_getEntry( char *owner, char *name ){ netsnmp_variable_list owner_var, name_var; memset(&owner_var, 0, sizeof(netsnmp_variable_list)); memset(&name_var, 0, sizeof(netsnmp_variable_list)); snmp_set_var_typed_value( &owner_var, ASN_OCTET_STR, (u_char*)owner, strlen(owner)); snmp_set_var_typed_value( &name_var, ASN_OCTET_STR, (u_char*)name, strlen(name)); owner_var.next_variable = &name_var; return (struct expExpression *) netsnmp_tdata_row_entry( netsnmp_tdata_row_get_byidx(expr_table_data, &owner_var));} /* =================================================== * * APIs for evaluating an expression - data gathering * * =================================================== *//* * Gather the data necessary for evaluating an expression. * * This will retrieve *all* the data relevant for all * instances of this expression, rather than just the * just the values needed for expanding a given instance. */voidexpExpression_getData( unsigned int reg, void *clientarg ){ struct expExpression *entry = (struct expExpression *)clientarg; netsnmp_tdata_row *row; netsnmp_variable_list *var; int ret; if ( !entry && reg ) { snmp_alarm_unregister( reg ); return; } if (( entry->expExpression[0] == '\0' ) || !(entry->flags & EXP_FLAG_ACTIVE) || !(entry->flags & EXP_FLAG_VALID)) return; DEBUGMSGTL(("disman:expr:run", "Gathering expression data (%s, %s)\n", entry->expOwner, entry->expName)); /* * This routine can be called in two situations: * - regularly by 'snmp_alarm' (reg != 0) * (as part of ongoing delta-value sampling) * - on-demand (reg == 0) * (for evaluating a particular entry) * * If a regularly sampled expression (entry->alarm != 0) * is invoked on-demand (reg == 0), then use the most * recent sampled values, rather than retrieving them again. */ if ( !reg && entry->alarm ) return; /* * XXX - may want to implement caching for on-demand evaluation * of non-regularly sampled expressions. */ /* * For a wildcarded expression, expExpressionPrefix is used * to determine which object instances to retrieve. * (For a non-wildcarded expression, we already know * explicitly which object instances will be needed). * * If we walk this object here, then the results can be * used to build the necessary GET requests for each * individual parameter object (within expObject_getData) * * This will probably be simpler (and definitely more efficient) * than walking the object instances separately and merging * merging the results). * * NB: Releasing any old results is handled by expObject_getData. * Assigning to 'entry->pvars' without first releasing the * previous contents does *not* introduce a memory leak. */ if ( entry->expPrefix_len ) { var = (netsnmp_variable_list *) SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); snmp_set_var_objid( var, entry->expPrefix, entry->expPrefix_len); ret = netsnmp_query_walk( var, entry->session ); DEBUGMSGTL(("disman:expr:run", "Walk returned %d\n", ret )); entry->pvars = var; } /* XXX - retrieve sysUpTime.0 value, and check for discontinuity */ /* entry->flags &= ~EXP_FLAG_SYSUT; var = (netsnmp_variable_list *) SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); snmp_set_var_objid( var, sysUT_oid, sysUT_oid_len ); netsnmp_query_get( var, entry->session ); if ( *var->val.integer != entry->sysUpTime ) { entry->flags |= EXP_FLAG_SYSUT; entry->sysUpTime = *var->val.integer; } snmp_free_varbind(var); */ /* * Loop through the list of relevant objects, * and retrieve the corresponding values. */ for ( row = expObject_getFirst( entry->expOwner, entry->expName ); row; row = expObject_getNext( row )) { /* XXX - may need to check whether owner/name still match */ expObject_getData( entry, (struct expObject *)row->data); }}voidexpExpression_enable( struct expExpression *entry ){ DEBUGMSG(("disman:expr:run", "Enabling %s\n", entry->expName)); if (!entry) return; if (entry->alarm) { /* or explicitly call expExpression_disable ?? */ snmp_alarm_unregister( entry->alarm ); entry->alarm = 0; } if (entry->expDeltaInterval) { entry->alarm = snmp_alarm_register( entry->expDeltaInterval, SA_REPEAT, expExpression_getData, entry ); expExpression_getData( entry->alarm, (void*)entry ); }}voidexpExpression_disable( struct expExpression *entry ){ if (!entry) return; if (entry->alarm) { snmp_alarm_unregister( entry->alarm ); entry->alarm = 0; /* Perhaps release any previous results ?? */ }}long _expExpression_MaxCount = 0;long _expExpression_countEntries(void){ struct expExpression *entry; netsnmp_tdata_row *row; long count = 0; for (row = netsnmp_tdata_row_first(expr_table_data); row; row = netsnmp_tdata_row_next(expr_table_data, row)) { entry = (struct expExpression *)row->data; count += entry->count; } return count;}long expExpression_getNumEntries(int max){ long count; /* XXX - implement some form of caching ??? */ count = _expExpression_countEntries(); if ( count > _expExpression_MaxCount ) _expExpression_MaxCount = count; return ( max ? _expExpression_MaxCount : count);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -