I'm still having a crash issue with my table agent, I can't figure out a
solution, hoping the list members could help. In a nutshell I want to read a
QNX pps object (file) each time (no caching) it is queried (snmpwalk). The data
gets read and returned but a crash happens on the free (datactx).
I would really appreciate a hand.
thanks,Ian
Net-Snmp 5.9QNX 7.1
/* * Note: this file originally auto-generated by mib2c using
* : mib2c.iterate.conf 19302 2010-08-13 12:19:42Z dts12 $
*/
/* generated from net-snmp-config */
extern "C" {
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "chAsinHwSbcNtpTable.h"
#include <syslog.h>
#include <string.h>
}
void populateLocalSNMPstruct( struct chAsinHwSbcNtpTable_entry **table, const
char channel );
/** Initializes the chAsinHwSbcNtpTable module */
extern "C" void
init_chAsinHwSbcNtpTable(void)
{
/* here we initialize all the tables we're planning on supporting */
//syslog( LOG_DEBUG, "init_chAsinHwSbcNtpTable()");
initialize_table_chAsinHwSbcNtpTable();
}
// # Determine the first/last column names
void
nsModuleTable_loop_free(void *context, netsnmp_iterator_info *dont_care)
{
free(context);
}
void freeTableEntry( void *data_context, netsnmp_iterator_info *useless ) {
if (data_context != NULL) {
free(data_context); <<<<<<<==== CRASHES HERE ON 1st CALL
}
return;
}
/** Initialize the chAsinHwSbcNtpTable table by defining its contents and how
it's structured */
void
initialize_table_chAsinHwSbcNtpTable(void)
{
//syslog( LOG_ERR, "initialize_table_chAsinHwSbcNtpTable()");
const oid chAsinHwSbcNtpTable_oid[] = {1,3,6,1,4,1,12345,3,3,1,9,6,6}; //
12345 is fictitious
const size_t chAsinHwSbcNtpTable_oid_len =
OID_LENGTH(chAsinHwSbcNtpTable_oid);
netsnmp_handler_registration *reg;
netsnmp_iterator_info *iinfo;
netsnmp_table_registration_info *table_info;
DEBUGMSGTL(("chAsinHwSbcNtpTable:init", "initializing table
chAsinHwSbcNtpTable\n"));
reg = netsnmp_create_handler_registration(
"chAsinHwSbcNtpTable", chAsinHwSbcNtpTable_handler,
chAsinHwSbcNtpTable_oid, chAsinHwSbcNtpTable_oid_len,
HANDLER_CAN_RONLY
);
table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
netsnmp_table_helper_add_indexes(table_info,
ASN_OCTET_STR, /* index: chAsinHwSbcNtpSbcName */
0);
table_info->min_column = COLUMN_CHASINHWSBCNTPSBCNAME;
table_info->max_column = COLUMN_CHASINHWSBCNTPSTATUSSTRING;
iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
iinfo->get_first_data_point = chAsinHwSbcNtpTable_get_first_data_point;
iinfo->get_next_data_point = chAsinHwSbcNtpTable_get_next_data_point;
iinfo->table_reginfo = table_info;
iinfo->free_loop_context_at_end = nsModuleTable_loop_free;
iinfo->free_data_context = freeTableEntry; // <<<<<<==== MEM LEAK WITHOUT
THIS!
netsnmp_register_table_iterator( reg, iinfo );
/* Initialise the contents of the table here */
}
struct chAsinHwSbcNtpTable_entry *chAsinHwSbcNtpTable_head;
/* create a new row in the (unsorted) table */
struct chAsinHwSbcNtpTable_entry *
chAsinHwSbcNtpTable_createEntry(
char* chAsinHwSbcNtpSbcName,
size_t chAsinHwSbcNtpSbcName_len
) {
struct chAsinHwSbcNtpTable_entry *entry;
entry = SNMP_MALLOC_TYPEDEF(struct chAsinHwSbcNtpTable_entry);
if (!entry)
return NULL;
memcpy(entry->chAsinHwSbcNtpSbcName, chAsinHwSbcNtpSbcName,
chAsinHwSbcNtpSbcName_len);
entry->chAsinHwSbcNtpSbcName_len = chAsinHwSbcNtpSbcName_len;
entry->next = chAsinHwSbcNtpTable_head;
chAsinHwSbcNtpTable_head = entry;
return entry;
}
/* remove a row from the table */
void
chAsinHwSbcNtpTable_removeEntry( struct chAsinHwSbcNtpTable_entry *entry ) {
struct chAsinHwSbcNtpTable_entry *ptr, *prev;
if (!entry)
return; /* Nothing to remove */
for ( ptr = chAsinHwSbcNtpTable_head, prev = NULL;
ptr != NULL;
prev = ptr, ptr = ptr->next ) {
if ( ptr == entry )
break;
}
if ( !ptr )
return; /* Can't find it */
if ( prev == NULL )
chAsinHwSbcNtpTable_head = ptr->next;
else
prev->next = ptr->next;
SNMP_FREE( entry ); /* XXX - release any other internal resources */
}
/* Example iterator hook routines - using 'get_next' to do most of the work */
netsnmp_variable_list *
chAsinHwSbcNtpTable_get_first_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
populateLocalSNMPstruct( &chAsinHwSbcNtpTable_head, 'A' ); // collect NTP
data for channel 'A'
*my_loop_context = chAsinHwSbcNtpTable_head;
return chAsinHwSbcNtpTable_get_next_data_point(my_loop_context,
my_data_context,
put_index_data, mydata );
}
netsnmp_variable_list *
chAsinHwSbcNtpTable_get_next_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
struct chAsinHwSbcNtpTable_entry *entry = (struct chAsinHwSbcNtpTable_entry
*)*my_loop_context;
netsnmp_variable_list *idx = put_index_data;
if ( entry ) {
snmp_set_var_value( idx, entry->chAsinHwSbcNtpSbcName,
sizeof(entry->chAsinHwSbcNtpSbcName) );
idx = idx->next_variable;
*my_data_context = (void *)entry;
*my_loop_context = (void *)entry->next;
return put_index_data;
} else {
return NULL;
}
}
/** handles requests for the chAsinHwSbcNtpTable table */
int
chAsinHwSbcNtpTable_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 chAsinHwSbcNtpTable_entry *table_entry;
DEBUGMSGTL(("chAsinHwSbcNtpTable: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) {
table_entry = (struct chAsinHwSbcNtpTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);
switch (table_info->colnum) {
case COLUMN_CHASINHWSBCNTPSBCNAME:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
table_entry->chAsinHwSbcNtpSbcName,
table_entry->chAsinHwSbcNtpSbcName_len);
break;
case COLUMN_CHASINHWSBCNTPSTATUSSTRING:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
table_entry->chAsinHwSbcNtpStatusString,
table_entry->chAsinHwSbcNtpStatusString_len);
break;
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHOBJECT);
break;
}
}
break;
}
return SNMP_ERR_NOERROR;
}
//
====================================================================================================
// Populate the given Net-Snmp-generated struct with PPS data, in this case we
want all /pps/ntp
// data from all SBCs of the given channel.
//
void populateLocalSNMPstruct( struct chAsinHwSbcNtpTable_entry **table, const
char channel )
{
std::list< fpair_type > allSbcNtps; // full path, sbc name
// For testing/dev only one file to read...
allSbcNtps.push_back( std::make_pair( "/pps/ntp", "A1" )); // pps is
QNX-specific, think of it as a file
// process the list of paths extracting the json formatted ntp data
struct chAsinHwSbcNtpTable_entry * tail, * head;
head = NULL;
tail = NULL;
BOOST_FOREACH( const fpair_type & s, allSbcNtps ) {
// open, read and close pps object
char ppsData[2000];
readFile( s.first.c_str(), ppsData, sizeof( ppsData )); // readFile
reads entire pps/file in one shot (impl not included here)
std::string json( ppsData );
// get rid of all lines before json line (which starts with "sources:"
size_t pos;
if( std::string::npos != ( pos = json.find("sources:"))) {
json.erase( 0, pos );
}
// get rid of all lines after the json line (which ends with "}]}"
if( std::string::npos != ( pos = json.find("}]}"))) {
json.erase( pos + strlen("}]}") );
}
// at this point ppsData is of the form "sources:json:{"data":[{...}]}
// the 'sources:json:' isn't actually part of our json data, it's the
way QNX PPS objects identify json data, so strip it away
json.erase( 0, strlen("sources:json:"));
struct chAsinHwSbcNtpTable_entry * current;
current = reinterpret_cast< chAsinHwSbcNtpTable_entry *>(
SNMP_MALLOC_TYPEDEF( struct chAsinHwSbcNtpTable_entry ));
strncpy( current->chAsinHwSbcNtpStatusString, json.c_str(), JSONSIZE );
current->chAsinHwSbcNtpStatusString_len = json.size();
strncpy( current->chAsinHwSbcNtpSbcName, s.second.c_str(), NAMESIZE );
current->chAsinHwSbcNtpSbcName_len = s.second.size();
current->next = NULL;
if( head == NULL ) {
head = current;
}
else {
tail->next = current;
}
tail = current;
}
*table = head;
}
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders