|
Hi I am new to Net-SNMP I am working on one shared library using Net-SNMP to integrate with solaris 10 SMA. I have one table structure. I want to poll it every 60 second. To generate the code I have used mib2c tool with the option mib2c.iterate.conf. The generated code is works fine if I don't pol it and initialize teh data with init_modulename() function. If I use snmp_alarm_register() to to register an calll back function it does not work. I debug the code and saw , that If i am using the polling ,cache->reqinfo->mode = MODE_GETNEXT is coming . But the generated code is Saying you don't have to handle the MODE_GETNEXT case. MODE_GET will be good enough. The following message has been generated by the mib2c. Even I handle the MODE_GETNEXT case as MODE_GET , It does not work as iwsCpuTable_get_next_data_point() is returning NULL " /* the table_iterator helper should change all GETNEXTs into GETs for you automatically, so you don't have to worry about the GETNEXT case. Only GETs and SETs need to be dealt with here */" For you referrence I am attaching the souce code with you . Please let me know what is wrong Thanks in advance. |
/* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 1.3 2003/07/07 17:43:17 rr144420 Exp $ */ #ifndef IWSCPUTABLE_H #define IWSCPUTABLE_H
/* function declarations */
void init_iwsCpuTable(void);
void initialize_table_iwsCpuTable(void);
Netsnmp_Node_Handler iwsCpuTable_handler_Poll;
SNMPAlarmCallback iwsCpuTable_handler;
Netsnmp_First_Data_Point iwsCpuTable_get_first_data_point;
Netsnmp_Next_Data_Point iwsCpuTable_get_next_data_point;
/* column number definitions for table iwsCpuTable */
#define COLUMN_IWSCPUINDEX 1
#define COLUMN_IWSCPUID 2
#define COLUMN_IWSCPUIDLETIME 3
#define COLUMN_IWSCPUUSERTIME 4
#define COLUMN_IWSCPUKERNELTIME 5
typedef struct wsCpuEntry_s{
long iwsCpuIndex;
char iwsCpuId[255];
char iwsCpuIdleTime[255];
char iwsCpuUserTime[255];
char iwsCpuKernelTime[255];
struct wsCpuEntry_s* pNext;
} wsCpuEntry;
#endif /* IWSCPUTABLE_H */
/*
* Note: this file originally auto-generated by mib2c using
* : mib2c.iterate.conf,v 1.3 2003/07/07 17:43:17 rr144420 Exp $
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "iwsCpuTable.h"
// default delay time for SNMP alarm
static u_long delay_time = 60;
wsCpuEntry* testhead ;
void construct_cpu_table(){
int total = 3, i;
wsCpuEntry* prevPtr = 0;
/* Too lazy, so I make an ordered list */
for (i=1; i<=total; i++) {
wsCpuEntry* ptr = (wsCpuEntry *) malloc(sizeof(wsCpuEntry));
ptr->iwsCpuIndex = i;
sprintf(ptr->iwsCpuId,"SUN Ultra %d",i);
sprintf(ptr->iwsCpuIdleTime," = %d",i);
sprintf(ptr->iwsCpuUserTime," = %d",i*10);
sprintf(ptr->iwsCpuKernelTime," = %d",i*5);
ptr->pNext = NULL;
if (prevPtr == NULL) {
testhead = prevPtr = ptr;
}
prevPtr->pNext = ptr;
prevPtr = ptr;
}
}
/** Initialize the iwsCpuTable table by defining its contents and how it's
structured */
void
initialize_table_iwsCpuTable(void)
{
static oid iwsCpuTable_oid[] = {1,3,6,1,4,1,42,1,60,1,6};
netsnmp_table_registration_info *table_info;
netsnmp_handler_registration *my_handler;
netsnmp_iterator_info *iinfo;
/* create the table structure itself */
table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
/* if your table is read only, it's easiest to change the
HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */
my_handler = netsnmp_create_handler_registration("iwsCpuTable",
iwsCpuTable_handler_Poll,
iwsCpuTable_oid,
OID_LENGTH(iwsCpuTable_oid),
HANDLER_CAN_RWRITE);
if (!my_handler || !table_info || !iinfo)
return; /* mallocs failed */
/***************************************************
* Setting up the table's definition
*/
netsnmp_table_helper_add_indexes(table_info,
ASN_INTEGER, /* index: iwsInstanceIndex */
ASN_INTEGER, /* index: iwsCpuIndex */
0);
table_info->min_column = 1;
table_info->max_column = 5;
/* iterator access routines */
iinfo->get_first_data_point = iwsCpuTable_get_first_data_point;
iinfo->get_next_data_point = iwsCpuTable_get_next_data_point;
iinfo->table_reginfo = table_info;
/***************************************************
* registering the table with the master agent
*/
DEBUGMSGTL(("initialize_table_iwsCpuTable",
"Registering table iwsCpuTable as a table iterator\n"));
netsnmp_register_table_iterator(my_handler, iinfo);
}
/** Initializes the iwsCpuTable module */
void
init_iwsCpuTable(void)
{
/* here we initialize all the tables we're planning on supporting */
initialize_table_iwsCpuTable();
construct_cpu_table();
}
/** returns the first data point within the iwsCpuTable table data.
Set the my_loop_context variable to the first data point structure
of your choice (from which you can find the next one). This could
be anything from the first node in a linked list, to an integer
pointer containing the beginning of an array variable.
Set the my_data_context variable to something to be returned to
you later (in your main iwsCpuTable_handler routine) that will provide
you with the data to return in a given row. This could be the
same pointer as what my_loop_context is set to, or something
different.
The put_index_data variable contains a list of snmp variable
bindings, one for each index in your table. Set the values of
each appropriately according to the data matching the first row
and return the put_index_data variable at the end of the function.
*/
netsnmp_variable_list *
iwsCpuTable_get_first_data_point(void **my_loop_context, void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
netsnmp_variable_list *vptr;
wsCpuEntry* firstNode = testhead;
if (!firstNode) {
printf("The head is NULL ***********\n");
return NULL;
}
*my_loop_context = firstNode;
*my_data_context = firstNode;
vptr = put_index_data;
snmp_set_var_value(vptr, (u_char *) &firstNode->iwsCpuIndex,
sizeof(firstNode->iwsCpuIndex));
vptr = vptr->next_variable;
return put_index_data;
}
/** functionally the same as iwsCpuTable_get_first_data_point, but
my_loop_context has already been set to a previous value and should
be updated to the next in the list. For example, if it was a
linked list, you might want to cast it and the return
my_loop_context->next. The my_data_context pointer should be set
to something you need later and the indexes in put_index_data
updated again. */
netsnmp_variable_list *
iwsCpuTable_get_next_data_point(void **my_loop_context, void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
netsnmp_variable_list *vptr;
wsCpuEntry* nextNode = (wsCpuEntry*) *my_loop_context;
nextNode = nextNode->pNext;
if (!nextNode) {
printf("No data returned in get_next\n");
return NULL;
}
*my_loop_context = nextNode;
*my_data_context = nextNode;
vptr = put_index_data;
snmp_set_var_value(vptr, (u_char *) &nextNode->iwsCpuIndex,
sizeof(nextNode->iwsCpuIndex));
vptr = vptr->next_variable;
return put_index_data;
}
int
iwsCpuTable_handler_Poll(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/*
This handler is called to handle SNMP GET and SNMP SET
requests for the my_delayed_oid object. If it is called to
handle SNMP GET requests, the handler does not need to
handle a GETNEXT if it is registered as an instance handler.
Instance handlers only deliver one request at a time, so we
do not need to loop over a list of requests. */
DEBUGMSGTL(("SUN-WS-MIB", "Handler got request, mode = %d:\n",
reqinfo->mode));
switch (reqinfo->mode) {
default:
/*
* Mark this variable as something that cannot be handled now
* by setting the delegated member of the requests structure
* to 1. The agent queues the request to be handled at a later
* time and continues responding to other client requests.
*
*/
requests->delegated = 1;
DEBUGMSGTL(("SUN-WS-MIB", "Delegated is %d\n",
requests->delegated));
/*
* Register an alarm to update the results at a later
* time. Normally, we might have to query something else
* (like an external request sent to a different network
* or system socket, etc), but for this example we'll do
* something really simply and just insert an alarm for a
* certain period of time.
*/
DEBUGMSGTL(("SUN-WS-MIB", "Delay is %d\n",
delay_time));
snmp_alarm_register(delay_time, /* seconds */
SA_REPEAT, /* repeat. */
iwsCpuTable_handler, /* the function
* to call */
/*
* Create a "cache" of useful
* information that can be retrieved
* at a later time. This argument is
* passed back to the module in the callback
* function for an alarm.
*/
(void *)
netsnmp_create_delegated_cache(handler,
reginfo,
reqinfo,
requests,
NULL));
break;
}
return SNMP_ERR_NOERROR;
}
/** handles requests for the iwsCpuTable table, if anything else needs to be
done */
void
iwsCpuTable_handler(unsigned int clientreg, void *clientarg)
{
netsnmp_request_info *request;
netsnmp_table_request_info *table_info;
netsnmp_variable_list *var;
wsCpuEntry* data;
/*
* Extract the cache from the passed argument.
*/
netsnmp_delegated_cache *cache = (netsnmp_delegated_cache *) clientarg;
netsnmp_request_info *requests;
netsnmp_agent_request_info *reqinfo;
u_long *delay_time_cache = NULL;
/*
* Make sure the cache created earlier is still
* valid. If not, the request timed out for some reason and we
* do not need to keep processing things. Should never happen, but
* this double checks.
*/
cache = netsnmp_handler_check_cache(cache);
if (!cache) {
snmp_log(LOG_ERR, "illegal call to return delayed response\n");
return;
}
/*
* Re-establish the previous pointers,
*/
reqinfo = cache->reqinfo;
requests = cache->requests;
DEBUGMSGTL(("SUN-WS-MIB",
"continuing delayed request, mode = %d\n",
cache->reqinfo->mode));
/*
* Set delegated to zero to indicate that the request is no longer
* delegated and answer the query.
*/
/* requests->delegated = 0;*/
DEBUGMSGTL(("SUN-WS-MIB", "Set delegated to %d\n",
requests->delegated));
for(request = requests; request; request = request->next) {
var = request->requestvb;
if (request->processed != 0)
continue;
/* perform anything here that you need to do before each
request is processed. */
/* the following extracts the my_data_context pointer set in
the loop functions above. You can then use the results to
help return data for the columns of the iwsCpuTable table in
question */
data = (wsCpuEntry *) netsnmp_extract_iterator_context(request);
if ( data == NULL) {
if (reqinfo->mode == MODE_GET) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
/* XXX: no row existed, if you support creation and this is a
set, start dealing with it here, else continue */
}
/* extracts the information about the table from the request */
table_info = netsnmp_extract_table_info(request);
/* table_info->colnum contains the column number requested */
/* table_info->indexes contains a linked list of snmp variable
bindings for the indexes of the table. Values in the list
have been set corresponding to the indexes of the
request */
if (table_info==NULL) {
continue;
}
switch(cache->reqinfo->mode) {
/* the table_iterator helper should change all GETNEXTs
into GETs for you automatically, so you don't have to
worry about the GETNEXT case. Only GETs and SETs need
to be dealt with here */
case MODE_GET:
switch(table_info->colnum) {
case COLUMN_IWSCPUINDEX:
snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *)
&data->iwsCpuIndex,sizeof(data->iwsCpuIndex));
break;
case COLUMN_IWSCPUID:
snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *)
data->iwsCpuId, strlen(data->iwsCpuId));
break;
case COLUMN_IWSCPUIDLETIME:
snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *)
data->iwsCpuIdleTime, strlen(data->iwsCpuIdleTime));
break;
case COLUMN_IWSCPUUSERTIME:
snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *)
data->iwsCpuUserTime, strlen(data->iwsCpuUserTime));
break;
case COLUMN_IWSCPUKERNELTIME:
snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *)
data->iwsCpuKernelTime, strlen(data->iwsCpuKernelTime));
break;
default:
/* We shouldn't get here */
snmp_log(LOG_ERR, "problem encountered in
iwsCpuTable_handler: unknown column\n");
}
break;
case MODE_SET_RESERVE1:
/* set handling... */
default:
snmp_log(LOG_ERR, "problem encountered in iwsCpuTable_handler:
unsupported mode\n");
}
}
return ;
}
