diff options
Diffstat (limited to 'local/mib2c.container.conf')
-rw-r--r-- | local/mib2c.container.conf | 864 |
1 files changed, 864 insertions, 0 deletions
diff --git a/local/mib2c.container.conf b/local/mib2c.container.conf new file mode 100644 index 0000000..e76621f --- /dev/null +++ b/local/mib2c.container.conf @@ -0,0 +1,864 @@ +## -*- c -*- +## Portions of this file ar Copyright (C) Apple, Inc. +## Use is subject to license terms specified in the COPYING file +## distributed with the Net-SNMP package. +###################################################################### +## Do the .h file +###################################################################### +@open ${name}.h@ +/* + * Note: this file originally auto-generated by mib2c using + * $Id$ + */ +#ifndef $name.uc_H +#define $name.uc_H + +/* function declarations */ +void init_$name(void); +@foreach $i table@ +void initialize_table_$i(void); +Netsnmp_Node_Handler ${i}_handler; +@end@ +@foreach $i table@ + +/* column number definitions for table $i */ + @foreach $c column@ + #define COLUMN_$c.uc $c.subid + @end@ +@end@ +#endif /* $name.uc_H */ +###################################################################### +## Do the .c file +###################################################################### +@open ${name}.c@ +/* + * Note: this file originally auto-generated by mib2c using + * $Id$ + */ + +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> +#include <net-snmp/agent/table_container.h> +#include "${name}.h" + +#ifdef ${i.uc}_USE_CACHE +static void _cache_free(netsnmp_cache * cache, void *magic); +static int _cache_load(netsnmp_cache * cache, void *vmagic); +#endif + +/** Initializes the $name module */ +void +init_$name(void) +{ + /* here we initialize all the tables we're planning on supporting */ + @foreach $i table@ + initialize_table_$i(); + @end@ +} +## +@foreach $i table@ +## Determine the first/last column names + @eval $first_column = "-"@ + @eval $last_column = "-"@ + @foreach $c column@ + @if $c.readable@ + @if "$first_column" eq "-"@ + @eval $first_column = $c@ + @end@ + @eval $last_column = $c@ + @end@ + @end@ + +/** Initialize the $i table by defining its contents and how it's structured */ +void +initialize_table_$i(void) +{ + const oid ${i}_oid[] = {$i.commaoid}; + const size_t ${i}_oid_len = OID_LENGTH(${i}_oid); + netsnmp_handler_registration *reg = NULL; + netsnmp_mib_handler *handler = NULL; + netsnmp_container *container = NULL; + netsnmp_table_registration_info *table_info = NULL; +#ifdef ${i.uc}_USE_CACHE + netsnmp_cache *cache = NULL; +#endif + + DEBUGMSGTL(("${name}:init", "initializing table $i\n")); + + reg = netsnmp_create_handler_registration( + "$i", ${i}_handler, + ${i}_oid, ${i}_oid_len, +@if $i.settable@ + HANDLER_CAN_RWRITE +@else@ + HANDLER_CAN_RONLY +@end@ + ); + if (NULL == reg) { + snmp_log(LOG_ERR,"error creating handler registration for $i\n"); + goto bail; + } +@if $i.settable@ + /** should a set on a non-existent row create a new one? */ + /** reg->modes |= HANDLER_CAN_NOT_CREATE; */ +@end@ + + container = netsnmp_container_find( "$i:table_container" ); + if (NULL == container) { + snmp_log(LOG_ERR,"error creating container for $i\n"); + goto bail; + } + + table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info ); + if (NULL == table_info) { + snmp_log(LOG_ERR,"error allocating table registration for $i\n"); + goto bail; + } + netsnmp_table_helper_add_indexes(table_info, + @foreach $idx index@ + $idx.type, /* index: $idx */ + @end@ + 0); + table_info->min_column = COLUMN_$first_column.uc; + table_info->max_column = COLUMN_$last_column.uc; + + /************************************************* + * + * inject container_table helper + */ + handler = netsnmp_container_table_handler_get(table_info, container, + TABLE_CONTAINER_KEY_NETSNMP_INDEX); + if (NULL == handler) { + snmp_log(LOG_ERR,"error allocating table registration for $i\n"); + goto bail; + } + if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { + snmp_log(LOG_ERR,"error injecting container_table handler for $i\n"); + goto bail; + } + handler = NULL; /* reg has it, will reuse below */ + +#ifdef ${i.uc}_USE_CACHE + /************************************************* + * + * inject cache helper + */ + cache = netsnmp_cache_create(30, /* timeout in seconds */ + _cache_load, _cache_free, + ${i}_oid, ${i}_oid_len); + + if (NULL == cache) { + snmp_log(LOG_ERR, "error creating cache for $i\n"); + goto bail; + } + cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET; + cache->magic = container; + + handler = netsnmp_cache_handler_get(cache); + if (NULL == handler) { + snmp_log(LOG_ERR, "error creating cache handler for $i\n"); + goto bail; + } + + if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { + snmp_log(LOG_ERR,"error injecting cache handler for $i\n"); + goto bail; + } + handler = NULL; /* reg has it*/ +#endif + + /* + * register the table + */ + if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) { + snmp_log(LOG_ERR,"error registering table handler for $i\n"); + reg = NULL; /* it was freed inside netsnmp_register_table */ + goto bail; + } + + /* + * Initialise the contents of the table here + */ + + + return; /* ok */ + + /* + * Some error occurred during registration. Clean up and bail. + */ + bail: /* not ok */ + + if (handler) + netsnmp_handler_free(handler); + +#ifdef ${i.uc}_USE_CACHE + if (cache) + netsnmp_cache_free(cache); +#endif + + if (table_info) + netsnmp_table_registration_info_free(table_info); + + if (container) + CONTAINER_FREE(container); + + if (reg) + netsnmp_handler_registration_free(reg); +} + +/** Typical data structure for a row entry */ +typedef struct ${i}_entry_s { + netsnmp_index oid_index; + + /* Index values */ + @foreach $idx index@ + @if $idx.needlength@ + $idx.decl $idx[NNN]; + size_t ${idx}_len; + @else@ + $idx.decl $idx; + @end@ + @end@ + + /* Column values */ + @foreach $c column@ + @if $c.readable@ + @if $c.needlength@ + $c.decl $c[NNN]; + size_t ${c}_len; + @else@ + $c.decl $c; + @end@ + @if $c.settable@ + @if !$c.rowstatus@ + @if $c.needlength@ + $c.decl old_$c[NNN]; + size_t old_${c}_len; + @else@ + $c.decl old_$c; + @end@ + @end@ + @end@ + @end@ + @end@ + + int valid; +} ${i}_entry; + +/** create a new row in the table */ +${i}_entry * +${i}_createEntry(netsnmp_container *container, + @foreach $idx index@ + @if $idx.needlength@ + , $idx.decl* $idx + , size_t ${idx}_len + @else@ + , $idx.decl $idx + @end@ + @end@ + ) { + ${i}_entry *entry; + + entry = SNMP_MALLOC_TYPEDEF(${i}_entry); + if (!entry) + return NULL; + + @foreach $idx index@ + @if $idx.needlength@ + memcpy(entry->$idx, $idx, ${idx}_len); + entry->${idx}_len = ${idx}_len; + @else@ + entry->$idx = $idx; + @end@ + @end@ + entry->oid_index.len = XXX; + entry->oid_index.oids = YYY; + CONTAINER_INSERT( container, entry ); + return entry; +} + +/** remove a row from the table */ +void +${i}_removeEntry(netsnmp_container *container, + ${i}_entry *entry) { + + if (!entry) + return; /* Nothing to remove */ + CONTAINER_REMOVE( container, entry ); + if (entry) + SNMP_FREE( entry ); /* XXX - release any other internal resources */ +} + +/** remove a row from the table */ +void +${i}_freeEntry(${i}_entry *entry) { + + if (!entry) + return; /* Nothing to remove */ + SNMP_FREE( entry ); /* XXX - release any other internal resources */ +} + +/** handles requests for the $i table */ +int +${i}_handler( + netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) { + + netsnmp_request_info *request; + netsnmp_table_request_info *table_info; + netsnmp_container *container; + ${i}_entry *table_entry; +@if $i.settable@ + int ret; +@end@ + + DEBUGMSGTL(("${name}:handler", "Processing request (%d)\n", reqinfo->mode)); + + switch (reqinfo->mode) { + /* + * Read-support (also covers GetNext requests) + */ + case MODE_GET: + for (request=requests; request; request=request->next) { + if (request->processed) + continue; + table_entry = (${i}_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, + "could not extract table entry or info for $i\n"); + snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR, + NULL, 0); + continue; + } + + switch (table_info->colnum) { + @foreach $c column@ + @if $c.readable@ + case COLUMN_$c.uc: + if ( !table_entry ) { + netsnmp_set_request_error(reqinfo, request, + SNMP_NOSUCHINSTANCE); + continue; + } + @if $c.needlength@ + snmp_set_var_typed_value( request->requestvb, $c.type, + table_entry->$c, + table_entry->${c}_len); + @else@ + snmp_set_var_typed_integer( request->requestvb, $c.type, + table_entry->$c); + @end@ + break; + @end@ + @end@ + default: + netsnmp_set_request_error(reqinfo, request, + SNMP_NOSUCHOBJECT); + break; + } + } + break; + +@if $i.settable@ + /* + * Write-support + */ + case MODE_SET_RESERVE1: + for (request=requests; request; request=request->next) { + if (request->processed) + continue; + table_entry = (${i}_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, + "could not extract table entry or info for $i\n"); + snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR, + NULL, 0); + continue; + } + + switch (table_info->colnum) { + @foreach $c column@ + @if $c.settable@ + case COLUMN_$c.uc: + @if $c.rowstatus@ + ret = netsnmp_check_vb_rowstatus(request->requestvb, + (table_entry ? RS_ACTIVE : RS_NONEXISTENT )); + @else@ + @if $c.needlength@ + /* or possibly 'netsnmp_check_vb_type_and_size' */ + ret = netsnmp_check_vb_type_and_max_size( + request->requestvb, $c.type, sizeof(table_entry->$c)); + @else@ + /* or possibly 'netsnmp_check_vb_int_range' */ + ret = netsnmp_check_vb_int( request->requestvb ); + @end@ + @end@ + if ( ret != SNMP_ERR_NOERROR ) { + netsnmp_set_request_error( reqinfo, request, ret ); + return SNMP_ERR_NOERROR; + } + break; + @end@ + @end@ + default: + netsnmp_set_request_error( reqinfo, request, + SNMP_ERR_NOTWRITABLE ); + return SNMP_ERR_NOERROR; + } + } + break; + + case MODE_SET_RESERVE2: +@if $i.creatable@ + for (request=requests; request; request=request->next) { + if (request->processed) + continue; + table_entry = (${i}_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, + "could not extract table entry or info for $i\n"); + snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR, + NULL, 0); + continue; + } + + switch (table_info->colnum) { +@if $i.rowstatus@ + @foreach $c column@ + @if $c.rowstatus@ + case COLUMN_$c.uc: + switch (*request->requestvb->val.integer) { + case RS_CREATEANDGO: + case RS_CREATEANDWAIT: + container = netsnmp_container_table_extract(request); + if (NULL == container) { + snmp_log(LOG_ERR, + "could not extract table container for $i\n"); + snmp_set_var_typed_value(request->requestvb, + SNMP_ERR_GENERR, NULL, 0); + continue; + } + table_entry = ${i}_createEntry(container + @foreach $idx index@ + @if $idx.needlength@ + , table_info->indexes->val.string + , table_info->indexes->val_len + @else@ + , *table_info->indexes->val.integer + @end@ + @end@ + ); + if (table_entry) { + netsnmp_container_table_insert_row( request, table_entry ); + } else { + netsnmp_set_request_error( reqinfo, request, + SNMP_ERR_RESOURCEUNAVAILABLE ); + return SNMP_ERR_NOERROR; + } + } + @end@ + @end@ +@else@ + @foreach $c column@ + @if $c.creatable@ + case COLUMN_$c.uc: + @end@ + @end@ + if ( !table_entry ) { + container = netsnmp_container_table_extract(request); + if (NULL == container) { + snmp_log(LOG_ERR, + "could not extract table container for $i\n"); + snmp_set_var_typed_value(request->requestvb, + SNMP_ERR_GENERR, NULL, 0); + continue; + } + table_entry = ${i}_createEntry(container + @foreach $idx index@ + @if $idx.needlength@ + , table_info->indexes->val.string + , table_info->indexes->val_len + @else@ + , *table_info->indexes->val.integer + @end@ + @end@ + ); + if (table_entry) { + netsnmp_container_table_insert_row( request, table_entry ); + } else { + netsnmp_set_request_error( reqinfo, request, + SNMP_ERR_RESOURCEUNAVAILABLE ); + return SNMP_ERR_NOERROR; + } + } + break; +@end@ + } + } +@end@ + break; + + case MODE_SET_FREE: +@if $i.creatable@ + for (request=requests; request; request=request->next) { + if (request->processed) + continue; + container = netsnmp_container_table_extract(request); + if (NULL == container) { + snmp_log(LOG_ERR, + "could not extract table container for $i\n"); + snmp_set_var_typed_value(request->requestvb, + SNMP_ERR_GENERR, NULL, 0); + continue; + } + table_entry = (${i}_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, + "could not extract table entry or info for $i\n"); + snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR, + NULL, 0); + continue; + } + + switch (table_info->colnum) { +@if $i.rowstatus@ + @foreach $c column@ + @if $c.rowstatus@ + case COLUMN_$c.uc: + switch (*request->requestvb->val.integer) { + case RS_CREATEANDGO: + case RS_CREATEANDWAIT: + if (table_entry && !table_entry->valid) { + ${i}_removeEntry(container, table_entry ); + } + } + @end@ + @end@ +@else@ + @foreach $c column@ + @if $c.creatable@ + case COLUMN_$c.uc: + @end@ + @end@ + if ( table_entry && !table_entry->valid ) { + ${i}_removeEntry(container, table_entry ); + } + break; +@end@ + } + } +@end@ + break; + + case MODE_SET_ACTION: + for (request=requests; request; request=request->next) { + if (request->processed) + continue; + table_entry = (${i}_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, + "could not extract table entry or info for $i\n"); + snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR, + NULL, 0); + continue; + } + + switch (table_info->colnum) { + @foreach $c column@ + @if $c.settable@ + @if !$c.rowstatus@ + case COLUMN_$c.uc: + @if $c.needlength@ + memcpy( table_entry->old_$c, + table_entry->$c, + sizeof(table_entry->$c)); + table_entry->old_${c}_len = + table_entry->${c}_len; + memset( table_entry->$c, 0, + sizeof(table_entry->$c)); + memcpy( table_entry->$c, + request->requestvb->val.string, + request->requestvb->val_len); + table_entry->${c}_len = + request->requestvb->val_len; + @else@ + table_entry->old_$c = table_entry->$c; + table_entry->$c = *request->requestvb->val.integer; + @end@ + break; + @end@ + @end@ + @end@ + } + } +@if $i.rowstatus@ + /* Check the internal consistency of an active row */ + for (request=requests; request; request=request->next) { + if (request->processed) + continue; + table_entry = (${i}_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, + "could not extract table entry or info for $i\n"); + snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR, + NULL, 0); + continue; + } + + switch (table_info->colnum) { + @foreach $c column@ + @if $c.rowstatus@ + case COLUMN_$c.uc: + switch (*request->requestvb->val.integer) { + case RS_ACTIVE: + case RS_CREATEANDGO: + if (/* XXX */) { + netsnmp_set_request_error( reqinfo, request, + SNMP_ERR_INCONSISTENTVALUE ); + return SNMP_ERR_NOERROR; + } + } + @end@ + @end@ + } + } +@end@ + break; + + case MODE_SET_UNDO: + for (request=requests; request; request=request->next) { + if (request->processed) + continue; + container = netsnmp_container_table_extract(request); + if (NULL == container) { + snmp_log(LOG_ERR, + "could not extract table container for $i\n"); + snmp_set_var_typed_value(request->requestvb, + SNMP_ERR_GENERR, NULL, 0); + continue; + } + table_entry = (${i}_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, + "could not extract table entry or info for $i\n"); + snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR, + NULL, 0); + continue; + } + + switch (table_info->colnum) { + @foreach $c column@ + @if $c.settable@ + case COLUMN_$c.uc: +@if $i.rowstatus@ + @if $c.rowstatus@ + switch (*request->requestvb->val.integer) { + case RS_CREATEANDGO: + case RS_CREATEANDWAIT: + if (table_entry && !table_entry->valid) { + ${i}_removeEntry(container, table_entry ); + } + } + @else@ + @if $c.needlength@ + memcpy( table_entry->$c, + table_entry->old_$c, + sizeof(table_entry->$c)); + memset( table_entry->old_$c, 0, + sizeof(table_entry->$c)); + table_entry->${c}_len = + table_entry->old_${c}_len; + @else@ + table_entry->$c = table_entry->old_$c; + table_entry->old_$c = 0; + @end@ + @end@ +@else@ + @if $c.creatable@ + if ( table_entry && !table_entry->valid ) { + ${i}_removeEntry(container, table_row ); + } else { + @if $c.needlength@ + memcpy( table_entry->$c, + table_entry->old_$c, + sizeof(table_entry->$c)); + memset( table_entry->old_$c, 0, + sizeof(table_entry->$c)); + table_entry->${c}_len = + table_entry->old_${c}_len; + @else@ + table_entry->$c = table_entry->old_$c; + table_entry->old_$c = 0; + @end@ + } + @else@ + @if $c.needlength@ + memcpy( table_entry->$c, + table_entry->old_$c, + sizeof(table_entry->$c)); + memset( table_entry->old_$c, 0, + sizeof(table_entry->$c)); + table_entry->${c}_len = + table_entry->old_${c}_len; + @else@ + table_entry->$c = table_entry->old_$c; + table_entry->old_$c = 0; + @end@ + @end@ +@end@ + break; + @end@ + @end@ + } + } + break; + + case MODE_SET_COMMIT: +@if $i.creatable@ + for (request=requests; request; request=request->next) { + if (request->processed) + continue; + table_entry = (${i}_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, + "could not extract table entry or info for $i\n"); + snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR, + NULL, 0); + continue; + } + + switch (table_info->colnum) { +@if $i.rowstatus@ + @foreach $c column@ + @if $c.rowstatus@ + case COLUMN_$c.uc: + switch (*request->requestvb->val.integer) { + case RS_CREATEANDGO: + table_entry->valid = 1; + /* Fall-through */ + case RS_ACTIVE: + table_entry->$c = RS_ACTIVE; + break; + + case RS_CREATEANDWAIT: + table_entry->valid = 1; + /* Fall-through */ + case RS_NOTINSERVICE: + table_entry->$c = RS_NOTINSERVICE; + break; + + case RS_DESTROY: + container = netsnmp_container_table_extract(request); + if (NULL == container) { + snmp_log(LOG_ERR, + "could not extract table container for $i\n"); + snmp_set_var_typed_value(request->requestvb, + SNMP_ERR_GENERR, NULL, 0); + continue; + } + ${i}_removeEntry(container, table_entry ); + } + @end@ + @end@ +@else@ + @foreach $c column@ + @if $c.creatable@ + case COLUMN_$c.uc: + @end@ + @end@ + if ( table_entry && !table_entry->valid ) { + table_entry->valid = 1; + } +@end@ + } + } +@end@ + break; +@end@ + } + return SNMP_ERR_NOERROR; +} + +#ifdef ${i.uc}_USE_CACHE +/** + * @internal + */ +static int +_cache_load(netsnmp_cache * cache, void *vmagic) +{ + netsnmp_container *container; + + DEBUGMSGTL(("internal:${i}:_cache_load", "called\n")); + + if ((NULL == cache) || (NULL == cache->magic)) { + snmp_log(LOG_ERR, "invalid cache for ${i}_cache_load\n"); + return -1; + } + container = (netsnmp_container *)cache->magic; + + /** should only be called for an invalid or expired cache */ + netsnmp_assert((0 == cache->valid) || (1 == cache->expired)); + + /* + * load cache here (or call function to do it) + */ + /** CONTAINER_INSERT(container, record); */ + + return 0; +} /* _cache_load */ + +/** + * @Internal + */ +/** remove a row from the table */ +static void +${i}_freeEntry_cb(${i}_entry *entry, void *magic) { + + ${i}_freeEntry(entry); +} + +/** + * @internal + */ +static void +_cache_free(netsnmp_cache * cache, void *magic) +{ + netsnmp_container *container; + + DEBUGMSGTL(("internal:${i}:_cache_free", "called\n")); + + if ((NULL == cache) || (NULL == cache->magic)) { + snmp_log(LOG_ERR, "invalid cache in ${i}_cache_free\n"); + return; + } + container = (netsnmp_container *) cache->magic; + + /* + * empty (but don't free) cache here + */ + CONTAINER_CLEAR(container, + (netsnmp_container_obj_func*)${i}_freeEntry_cb, + NULL); +} /* _cache_free */ +#endif /* ${i.uc}_USE_CACHE */ +@end@ |