Re: Question regarding Tables in net-snmp
Reza Salehi <[email protected]>
| Newsgroups | gmane.network.net-snmp.user |
|---|---|
| Message-ID | <[email protected]> |
Hi Dave,
Thanks for your response.
I put the whole code generated by mib2c below for your review. You are right there is a function call named athStatusTable_get_first_data_point() and one named athStatusTable_get_next_data_point() as you can see below. I put a printf("test"); inside the former one ( athStatusTable_get_first_data_point() ).It gets called once if I run snmpget but still it gets called multiple time ( up to number of column in the table) if I run snmpwalk or snmptable.
Maybe I need to run mib2c diffrently? or I am missing something here.
To mention it again snmpwalk and snmpget return the whole table successfully. The only problem is I need to put my function which fills the table somewhere to gets called once in response to snmptable or snmpwalk but anywhere I put it in the following functions it gets called multiple time.
Best Regards,
Reza
/** Initialize the athStatusTable table by defining its contents and how it's structured */
void
initialize_table_athStatusTable(void)
{
static oid athStatusTable_oid[] =
{ 1, 3, 6, 1, 4, 1, 13182, 2, 1, 14, 1 };
size_t athStatusTable_oid_len =
OID_LENGTH(athStatusTable_oid);
netsnmp_handler_registration *reg;
netsnmp_iterator_info *iinfo;
netsnmp_table_registration_info *table_info;
reg =
netsnmp_create_handler_registration("athStatusTable",
athStatusTable_handler,
athStatusTable_oid,
athStatusTable_oid_len,
HANDLER_CAN_RWRITE);
table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: athIndex */
0);
table_info->min_column = COLUMN_ATHINDEX;
table_info->max_column = COLUMN_ATHLONGR;
iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
iinfo->get_first_data_point = athStatusTable_get_first_data_point;
iinfo->get_next_data_point = athStatusTable_get_next_data_point;
iinfo->table_reginfo = table_info;
netsnmp_register_table_iterator(reg, iinfo);
/*
* Initialise the contents of the table here
*/
}
/*
* Example iterator hook routines - using 'get_next' to do most of the work
*/
netsnmp_variable_list *
athStatusTable_get_first_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list * put_index_data,
netsnmp_iterator_info *mydata)
{
*my_loop_context = athStatusTable_head;
return athStatusTable_get_next_data_point(my_loop_context,
my_data_context,
put_index_data, mydata);
}
netsnmp_variable_list *
athStatusTable_get_next_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list * put_index_data,
netsnmp_iterator_info *mydata)
{
struct athStatusTable_entry *entry =
(struct athStatusTable_entry *) *my_loop_context;
netsnmp_variable_list *idx = put_index_data;
if (entry) {
snmp_set_var_typed_integer(idx, ASN_INTEGER, entry->athIndex);
idx = idx->next_variable;
*my_data_context = (void *) entry;
*my_loop_context = (void *) entry->next;
return put_index_data;
} else {
return NULL;
}
}
/*
* create a new row in the (unsorted) table
*/
struct athStatusTable_entry *
athStatusTable_createEntry(long athIndex)
{
struct athStatusTable_entry *entry;
entry = SNMP_MALLOC_TYPEDEF(struct athStatusTable_entry);
if (!entry)
return NULL;
entry->athIndex = athIndex;
entry->next = athStatusTable_head;
athStatusTable_head = entry;
return entry;
}
void
athStatusTable_removeEntry(struct athStatusTable_entry *entry)
{
struct athStatusTable_entry *ptr, *prev;
if (!entry)
return; /* Nothing to remove */
for (ptr = athStatusTable_head, prev = NULL;
ptr != NULL; prev = ptr, ptr = ptr->next) {
if (ptr == entry)
break;
}
if (!ptr)
return; /* Can't find it */
if (prev == NULL)
athStatusTable_head = ptr->next;
else
prev->next = ptr->next;
SNMP_FREE(entry); /* XXX - release any other internal resources */
}
/** handles requests for the athStatusTable table */
int
athStatusTable_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 athStatusTable_entry *table_entry;
int ret;
switch (reqinfo->mode) {
/*
* Read-support (also covers GetNext requests)
*/
case MODE_GET:
//We should fill the data here//
fill_table();
for (request = requests; request; request = request->next) {
table_entry = (struct athStatusTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info(request);
switch (table_info->colnum) {
case COLUMN_ATHINDEX:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
table_entry->athIndex);
break;
case COLUMN_ATHNAMES:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
(u_char *) table_entry->athNames,
table_entry->athNames_len);
break;
case COLUMN_ATHSCANNINGPERIOD:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
(u_char *) table_entry->
athScanningPeriod,
table_entry->
athScanningPeriod_len);
break;
case COLUMN_ATHOUTPUT:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
table_entry->athOutput);
break;
case COLUMN_ATHINPUT:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
table_entry->athInput);
break;
case COLUMN_ATHCRC:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
table_entry->athCrc);
break;
case COLUMN_ATHPHY:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
table_entry->athPhy);
break;
case COLUMN_ATHLONGR:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
table_entry->athLongr);
break;
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHOBJECT);
break;
}
}
break;
/*
* Write-support
*/
case MODE_SET_RESERVE1:
for (request = requests; request; request = request->next) {
table_entry = (struct athStatusTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info(request);
switch (table_info->colnum) {
case COLUMN_ATHSCANNINGPERIOD:
/*
* or possiblc 'netsnmp_check_vb_type_and_size'
*/
ret =
netsnmp_check_vb_type_and_max_size(request->requestvb,
ASN_OCTET_STR,
sizeof(table_entry->
athScanningPeriod));
if (ret != SNMP_ERR_NOERROR) {
netsnmp_set_request_error(reqinfo, request, ret);
return SNMP_ERR_NOERROR;
}
break;
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_ERR_NOTWRITABLE);
return SNMP_ERR_NOERROR;
}
}
break;
case MODE_SET_RESERVE2:
break;
case MODE_SET_FREE:
break;
case MODE_SET_ACTION:
for (request = requests; request; request = request->next) {
table_entry = (struct athStatusTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info(request);
switch (table_info->colnum) {
case COLUMN_ATHSCANNINGPERIOD:
memcpy(table_entry->old_athScanningPeriod,
table_entry->athScanningPeriod,
sizeof(table_entry->athScanningPeriod));
table_entry->old_athScanningPeriod_len =
table_entry->athScanningPeriod_len;
memset(table_entry->athScanningPeriod, 0,
sizeof(table_entry->athScanningPeriod));
memcpy(table_entry->athScanningPeriod,
request->requestvb->val.string,
request->requestvb->val_len);
table_entry->athScanningPeriod_len =
request->requestvb->val_len;
break;
}
}
break;
case MODE_SET_UNDO:
for (request = requests; request; request = request->next) {
table_entry = (struct athStatusTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info(request);
switch (table_info->colnum) {
case COLUMN_ATHSCANNINGPERIOD:
memcpy(table_entry->athScanningPeriod,
table_entry->old_athScanningPeriod,
sizeof(table_entry->athScanningPeriod));
memset(table_entry->old_athScanningPeriod, 0,
sizeof(table_entry->athScanningPeriod));
table_entry->athScanningPeriod_len =
table_entry->old_athScanningPeriod_len;
break;
}
}
break;
case MODE_SET_COMMIT:
break;
}
printf("exittt\n");
just_once =0;
return SNMP_ERR_NOERROR;
}
________________________________
From: Dave Shield <[email protected]>
To: Reza Salehi <[email protected]>
Cc: SNMP FORUM <[email protected]>
Sent: Thursday, January 3, 2013 10:40 PM
Subject: Re: Question regarding Tables in net-snmp
On 3 January 2013 18:54, Reza Salehi <[email protected]> wrote:
> I don't have any get_first or get_next in my code.
I'm not sure I believe that.
You said that you were using the 'table_iterator' helper.
As part of that, mib2c will generate three routines
(which you will have needed to tweak to match your environment):
- the table handler
- a routine to identify the first row in the table
- a routine to identify each subsequent row in the table
It's these latter two that I was referring to.
They *must* be present, if the walk is to succeed.
Dave
------------------------------------------------------------------------------
Master HTML5, CSS3, ASP.NET, MVC, AJAX, Knockout.js, Web API and
much more. Get web development skills now with LearnDevNow -
350+ hours of step-by-step video tutorials by Microsoft MVPs and experts.
SALE $99.99 this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122812
_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users