## -*- c -*- ###################################################################### ## Do the .h file ###################################################################### @open ${name}.h@ /* * Note: this file originally auto-generated by mib2c * using mib2c.raw-table.conf */ #ifndef $name.uc_H #define $name.uc_H void init_$name(void); #endif /* $name.uc_H */ ###################################################################### ## Do the .c file ###################################################################### @open ${name}.c@ /* * Note: this file originally auto-generated by mib2c * using mib2c.raw-table.conf */ #include #include #include #include "${name}.h" @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@ /* column number definitions for table $i */ @foreach $c column@ #define COLUMN_$c.uc $c.subid @end@ /* Typical data structure for a row entry */ struct ${i}_entry { /* 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 nonindex@ @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; }; /* create a new row in the table */ static struct ${i}_entry * ${i}_createEntry( int dummy @foreach $idx index@ @if $idx.needlength@ , $idx.decl* $idx , size_t ${idx}_len @else@ , $idx.decl $idx @end@ @end@ ) { struct ${i}_entry *entry; entry = SNMP_MALLOC_TYPEDEF(struct ${i}_entry); if (!entry) return NULL; /* XXX - insert entry into local data structure */ return entry; } /* remove a row from the table */ static void ${i}_removeEntry(struct ${i}_entry *entry) { if (!entry) return; /* Nothing to remove */ /* XXX - remove entry from local data structure */ if (entry) SNMP_FREE( entry ); /* XXX - release any other internal resources */ } /** determine the appropriate row for an exact request */ static struct ${i}_entry * ${i}_get_entry( netsnmp_variable_list *indexes ) { struct ${i}_entry *row = NULL; /* XXX - Use the 'indexes' parameter to retrieve the data structure for the requested row, and return this. */ return row; } /** determine the appropriate row for an fuzzy request */ static struct ${i}_entry * ${i}_get_next_entry( netsnmp_handler_registration *reginfo, netsnmp_request_info *request, int column, netsnmp_variable_list *indexes ) { struct ${i}_entry *row = NULL; oid build_space[MAX_OID_LEN]; size_t build_space_len = 0; size_t index_oid_len = 0; /* XXX - Use the 'indexes' parameter to identify the next row in the table.... */ /* XXX .... update the 'indexes' parameter with the appropriate index values ... */ /* ... and update the requested OID to match this instance */ memcpy(build_space, reginfo->rootoid, /* registered oid */ reginfo->rootoid_len * sizeof(oid)); build_space_len = reginfo->rootoid_len; build_space[build_space_len++] = 1; /* entry */ build_space[build_space_len++] = column; /* column */ build_oid_noalloc(build_space + build_space_len, MAX_OID_LEN - build_space_len, &index_oid_len, NULL, 0, indexes); snmp_set_var_objid(request->requestvb, build_space, build_space_len + index_oid_len); /* Finally, return the data structure for this row */ return row; } /** handles requests for the $i table */ static 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; struct ${i}_entry *table_entry; @if $i.settable@ int ret; @end@ switch (reqinfo->mode) { /* * Read-support */ case MODE_GET: for (request=requests; request; request=request->next) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_entry( table_info->indexes ); 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; case MODE_GETNEXT: for (request=requests; request; request=request->next) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_next_entry( reginfo, request, table_info->colnum, table_info->indexes ); 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) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_entry( table_info->indexes ); 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) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_entry( table_info->indexes ); 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: table_entry = ${i}_createEntry( 0 @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_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 ) { table_entry = ${i}_createEntry( 0 @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_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) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_entry( table_info->indexes ); 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(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(table_entry); } break; @end@ } } @end@ break; case MODE_SET_ACTION: for (request=requests; request; request=request->next) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_entry( table_info->indexes ); 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) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_entry( table_info->indexes ); 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) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_entry( table_info->indexes ); 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(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(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@ } @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) { table_info = netsnmp_extract_table_info( request); table_entry = ${i}_get_entry( table_info->indexes ); 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: ${i}_removeEntry(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; } /** Initialize the $i table by defining its contents and how it's structured */ static void initialize_table_$i(void) { const oid ${i}_oid[] = {$i.commaoid}; netsnmp_handler_registration *reg; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration( "$i", ${i}_handler, ${i}_oid, OID_LENGTH(${i}_oid), @if $i.settable@ HANDLER_CAN_RWRITE @else@ HANDLER_CAN_RONLY @end@ ); table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info ); 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; netsnmp_register_table( reg, table_info ); /* Initialise the contents of the table here */ } @end@ /** 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@ }