blob: 534d18c893d9c597be35b0d2b528541e1bd8f914 [file] [log] [blame]
#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/scalar.h>
#ifdef HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include "agent/nsDebug.h"
#define nsConfigDebug 1, 3, 6, 1, 4, 1, 8072, 1, 7, 1
void
init_nsDebug(void)
{
/*
* OIDs for the debugging control scalar objects
*
* Note that these we're registering the full object rather
* than the (sole) valid instance in each case, in order
* to handle requests for invalid instances properly.
*/
const oid nsDebugEnabled_oid[] = { nsConfigDebug, 1};
const oid nsDebugOutputAll_oid[] = { nsConfigDebug, 2};
const oid nsDebugDumpPdu_oid[] = { nsConfigDebug, 3};
/*
* ... and for the token table.
*/
#define DBGTOKEN_PREFIX 2
#define DBGTOKEN_ENABLED 3
#define DBGTOKEN_STATUS 4
const oid nsDebugTokenTable_oid[] = { nsConfigDebug, 4};
netsnmp_table_registration_info *table_info;
netsnmp_iterator_info *iinfo;
/*
* Register the scalar objects...
*/
DEBUGMSGTL(("nsDebugScalars", "Initializing\n"));
netsnmp_register_scalar(
netsnmp_create_handler_registration(
"nsDebugEnabled", handle_nsDebugEnabled,
nsDebugEnabled_oid, OID_LENGTH(nsDebugEnabled_oid),
HANDLER_CAN_RWRITE)
);
netsnmp_register_scalar(
netsnmp_create_handler_registration(
"nsDebugOutputAll", handle_nsDebugOutputAll,
nsDebugOutputAll_oid, OID_LENGTH(nsDebugOutputAll_oid),
HANDLER_CAN_RWRITE)
);
netsnmp_register_scalar(
netsnmp_create_handler_registration(
"nsDebugDumpPdu", handle_nsDebugDumpPdu,
nsDebugDumpPdu_oid, OID_LENGTH(nsDebugDumpPdu_oid),
HANDLER_CAN_RWRITE)
);
/*
* ... and the table.
* We need to define the column structure and indexing....
*/
table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
if (!table_info) {
return;
}
netsnmp_table_helper_add_indexes(table_info, ASN_PRIV_IMPLIED_OCTET_STR, 0);
table_info->min_column = DBGTOKEN_STATUS;
table_info->max_column = DBGTOKEN_STATUS;
/*
* .... and the iteration information ....
*/
iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
if (!iinfo) {
return;
}
iinfo->get_first_data_point = get_first_debug_entry;
iinfo->get_next_data_point = get_next_debug_entry;
iinfo->table_reginfo = table_info;
/*
* .... and register the table with the agent.
*/
netsnmp_register_table_iterator(
netsnmp_create_handler_registration(
"tzDebugTable", handle_nsDebugTable,
nsDebugTokenTable_oid, OID_LENGTH(nsDebugTokenTable_oid),
HANDLER_CAN_RWRITE),
iinfo);
}
int
handle_nsDebugEnabled(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
long enabled;
netsnmp_request_info *request=NULL;
switch (reqinfo->mode) {
case MODE_GET:
enabled = snmp_get_do_debugging();
if ( enabled==0 )
enabled=2; /* false */
for (request = requests; request; request=request->next) {
if (request->processed != 0)
continue;
snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
(u_char*)&enabled, sizeof(enabled));
}
break;
case MODE_SET_RESERVE1:
for (request = requests; request; request=request->next) {
if (request->processed != 0)
continue;
if ( request->status != 0 ) {
return SNMP_ERR_NOERROR; /* Already got an error */
}
if ( request->requestvb->type != ASN_INTEGER ) {
netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
return SNMP_ERR_WRONGTYPE;
}
if (( *request->requestvb->val.integer != 1 ) &&
( *request->requestvb->val.integer != 2 )) {
netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
return SNMP_ERR_WRONGVALUE;
}
}
break;
case MODE_SET_COMMIT:
enabled = *requests->requestvb->val.integer;
if (enabled == 2 ) /* false */
enabled = 0;
snmp_set_do_debugging( enabled );
break;
}
return SNMP_ERR_NOERROR;
}
int
handle_nsDebugOutputAll(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
long enabled;
netsnmp_request_info *request=NULL;
switch (reqinfo->mode) {
case MODE_GET:
enabled = snmp_get_do_debugging();
if ( enabled==0 )
enabled=2; /* false */
for (request = requests; request; request=request->next) {
if (request->processed != 0)
continue;
snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
(u_char*)&enabled, sizeof(enabled));
}
break;
case MODE_SET_RESERVE1:
for (request = requests; request; request=request->next) {
if (request->processed != 0)
continue;
if ( request->status != 0 ) {
return SNMP_ERR_NOERROR; /* Already got an error */
}
if ( request->requestvb->type != ASN_INTEGER ) {
netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
return SNMP_ERR_WRONGTYPE;
}
if (( *request->requestvb->val.integer != 1 ) &&
( *request->requestvb->val.integer != 2 )) {
netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
return SNMP_ERR_WRONGVALUE;
}
}
break;
case MODE_SET_COMMIT:
enabled = *requests->requestvb->val.integer;
if (enabled == 2 ) /* false */
enabled = 0;
snmp_set_do_debugging( enabled );
break;
}
return SNMP_ERR_NOERROR;
}
int
handle_nsDebugDumpPdu(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
long enabled;
netsnmp_request_info *request=NULL;
switch (reqinfo->mode) {
case MODE_GET:
enabled = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
NETSNMP_DS_LIB_DUMP_PACKET);
if ( enabled==0 )
enabled=2; /* false */
for (request = requests; request; request=request->next) {
if (request->processed != 0)
continue;
snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
(u_char*)&enabled, sizeof(enabled));
}
break;
case MODE_SET_RESERVE1:
for (request = requests; request; request=request->next) {
if (request->processed != 0)
continue;
if ( request->status != 0 ) {
return SNMP_ERR_NOERROR; /* Already got an error */
}
if ( request->requestvb->type != ASN_INTEGER ) {
netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
return SNMP_ERR_WRONGTYPE;
}
if (( *request->requestvb->val.integer != 1 ) &&
( *request->requestvb->val.integer != 2 )) {
netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
return SNMP_ERR_WRONGVALUE;
}
}
break;
case MODE_SET_COMMIT:
enabled = *requests->requestvb->val.integer;
if (enabled == 2 ) /* false */
enabled = 0;
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
NETSNMP_DS_LIB_DUMP_PACKET, enabled);
break;
}
return SNMP_ERR_NOERROR;
}
/*
* var_tzIntTableFixed():
* Handle the tzIntTable as a fixed table of NUMBER_TZ_ENTRIES rows,
* with the timezone offset hardwired to be the same as the index.
*/
netsnmp_variable_list *
get_first_debug_entry(void **loop_context, void **data_context,
netsnmp_variable_list *index,
netsnmp_iterator_info *data)
{
int i;
for (i=0; i<debug_num_tokens; i++) {
/* skip excluded til mib is updated */
if (dbg_tokens[i].token_name && (dbg_tokens[i].enabled != 2))
break;
}
if ( i==debug_num_tokens )
return NULL;
snmp_set_var_value(index, dbg_tokens[i].token_name,
strlen(dbg_tokens[i].token_name));
*loop_context = (void*)(intptr_t)i;
*data_context = (void*)&dbg_tokens[i];
return index;
}
netsnmp_variable_list *
get_next_debug_entry(void **loop_context, void **data_context,
netsnmp_variable_list *index,
netsnmp_iterator_info *data)
{
int i = (int)(intptr_t)*loop_context;
for (i++; i<debug_num_tokens; i++) {
/* skip excluded til mib is updated */
if (dbg_tokens[i].token_name && (dbg_tokens[i].enabled != 2))
break;
}
if ( i==debug_num_tokens )
return NULL;
snmp_set_var_value(index, dbg_tokens[i].token_name,
strlen(dbg_tokens[i].token_name));
*loop_context = (void*)(intptr_t)i;
*data_context = (void*)&dbg_tokens[i];
return index;
}
int
handle_nsDebugTable(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
long status;
netsnmp_request_info *request =NULL;
netsnmp_table_request_info *table_info =NULL;
netsnmp_token_descr *debug_entry=NULL;
switch (reqinfo->mode) {
case MODE_GET:
for (request=requests; request; request=request->next) {
if (request->processed != 0)
continue;
debug_entry = (netsnmp_token_descr*)
netsnmp_extract_iterator_context(request);
if (!debug_entry)
continue;
status = (debug_entry->enabled ? RS_ACTIVE : RS_NOTINSERVICE);
snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
(u_char*)&status, sizeof(status));
}
break;
case MODE_SET_RESERVE1:
for (request = requests; request; request=request->next) {
if (request->processed != 0)
continue;
if ( request->status != 0 ) {
return SNMP_ERR_NOERROR; /* Already got an error */
}
if ( request->requestvb->type != ASN_INTEGER ) {
netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
return SNMP_ERR_WRONGTYPE;
}
debug_entry = (netsnmp_token_descr*)
netsnmp_extract_iterator_context(request);
switch (*request->requestvb->val.integer) {
case RS_ACTIVE:
case RS_NOTINSERVICE:
/*
* These operations require an existing row
*/
if (!debug_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_ERR_INCONSISTENTVALUE);
return SNMP_ERR_INCONSISTENTVALUE;
}
break;
case RS_CREATEANDWAIT:
case RS_CREATEANDGO:
/*
* These operations assume the row doesn't already exist
*/
if (debug_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_ERR_INCONSISTENTVALUE);
return SNMP_ERR_INCONSISTENTVALUE;
}
break;
case RS_DESTROY:
/*
* This operation can work regardless
*/
break;
case RS_NOTREADY:
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_ERR_WRONGVALUE);
return SNMP_ERR_WRONGVALUE;
}
}
break;
case MODE_SET_COMMIT:
for (request = requests; request; request=request->next) {
if (request->processed != 0)
continue;
if ( request->status != 0 ) {
return SNMP_ERR_NOERROR; /* Already got an error */
}
switch (*request->requestvb->val.integer) {
case RS_ACTIVE:
case RS_NOTINSERVICE:
/*
* Update the enabled field appropriately
*/
debug_entry = (netsnmp_token_descr*)
netsnmp_extract_iterator_context(request);
if (debug_entry)
debug_entry->enabled =
(*request->requestvb->val.integer == RS_ACTIVE);
break;
case RS_CREATEANDWAIT:
case RS_CREATEANDGO:
/*
* Create the entry, and set the enabled field appropriately
*/
table_info = netsnmp_extract_table_info(request);
debug_register_tokens((char *) table_info->indexes->val.string);
#ifdef UMMMMM
if (*request->requestvb->val.integer == RS_CREATEANDWAIT) {
/* XXX - how to locate the entry ?? */
debug_entry->enabled = 0;
}
#endif
break;
case RS_DESTROY:
/*
* XXX - there's no "remove" API :-(
*/
debug_entry = (netsnmp_token_descr*)
netsnmp_extract_iterator_context(request);
if (debug_entry) {
debug_entry->enabled = 0;
free(debug_entry->token_name);
debug_entry->token_name = NULL;
}
break;
}
}
break;
}
return SNMP_ERR_NOERROR;
}