/************************************************************ * RESERVE is used to check the syntax of all the variables * provided, that the values being set are sensible and consistent, * and to allocate any resources required for performing the SET. * After this stage, the expectation is that the set ought to * succeed, though this is not guaranteed. (In fact, with the UCD * agent, this is done in two passes - RESERVE1, and * RESERVE2, to allow for dependancies between variables). * * BEFORE calling this routine, the agent will call duplicate_row * to create a copy of the row (unless this is a new row; i.e. * row_created == 1). * * next state -> SET_RESERVE2 || SET_FREE */ void saHpiSensorThdUpMinorTable_set_reserve1( netsnmp_request_group *rg ) { saHpiSensorThdUpMinorTable_context *row_ctx = (saHpiSensorThdUpMinorTable_context *)rg->existing_row; // saHpiSensorThdUpMinorTable_context *undo_ctx = // (saHpiSensorThdUpMinorTable_context *)rg->undo_info; netsnmp_variable_list *var; netsnmp_request_group_item *current; int rc; DEBUGMSGTL ((AGENT, "saHpiSensorThdUpMinorTable_set_reserve1, called\n")); /* * TODO: loop through columns, check syntax and lengths. For * columns which have no dependencies, you could also move * the value/range checking here to attempt to catch error * cases as early as possible. */ for ( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; rc = SNMP_ERR_NOERROR; switch (current->tri->colnum) { case COLUMN_SAHPISENSORTHDUPMINORVALUE: /** SaHpiSensorReadingValue = ASN_OCTET_STR */ rc = netsnmp_check_vb_type(var, ASN_OCTET_STR); if (rc == SNMP_ERR_NOERROR ) { rc = check_sensor_reading_value( var->val_len, row_ctx->saHpiSensorThdUpMinorType); if (rc != SNMP_ERR_NOERROR) { DEBUGMSGTL ((AGENT, "COLUMN_SAHPISENSORTHDUPMINORVALUE ERROR: %d\n", rc)); } } break; default: /** We shouldn't get here */ rc = SNMP_ERR_GENERR; snmp_log(LOG_ERR, "unknown column in " "saHpiSensorThdUpMinorTable_set_reserve1\n"); } if (rc) netsnmp_request_set_error( current->ri, rc ); rg->status = SNMP_MAX( rg->status, current->ri->status ); } /* * done with all the columns. Could check row related * requirements here. */ }
/************************************************************ * RESERVE is used to check the syntax of all the variables * provided, that the values being set are sensible and consistent, * and to allocate any resources required for performing the SET. * After this stage, the expectation is that the set ought to * succeed, though this is not guaranteed. (In fact, with the UCD * agent, this is done in two passes - RESERVE1, and * RESERVE2, to allow for dependancies between variables). * * BEFORE calling this routine, the agent will call duplicate_row * to create a copy of the row (unless this is a new row; i.e. * row_created == 1). * * next state -> SET_RESERVE2 || SET_FREE */ void saHpiAutoInsertTimeoutTable_set_reserve1( netsnmp_request_group *rg ) { // saHpiAutoInsertTimeoutTable_context *row_ctx = // (saHpiAutoInsertTimeoutTable_context *)rg->existing_row; // saHpiAutoInsertTimeoutTable_context *undo_ctx = // (saHpiAutoInsertTimeoutTable_context *)rg->undo_info; netsnmp_variable_list *var; netsnmp_request_group_item *current; int rc; /* * TODO: loop through columns, check syntax and lengths. For * columns which have no dependencies, you could also move * the value/range checking here to attempt to catch error * cases as early as possible. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; rc = SNMP_ERR_NOERROR; switch(current->tri->colnum) { case COLUMN_SAHPIAUTOINSERTTIMEOUTFORINSERT: /** SafUnsigned64 = ASN_OPAQUE */ rc = netsnmp_check_vb_type(var, ASN_OPAQUE); if (rc == SNMP_ERR_NOERROR ) { if (var->val_len > SAF_UNSIGNED_64_LEN) { rc = SNMP_ERR_WRONGLENGTH; DEBUGMSGTL ((AGENT, "COLUMN_SAHPIAUTOINSERTTIMEOUTFORINSERT" " SNMP_ERR_WRONGLENGTH\n", rc)); } } break; default: /** We shouldn't get here */ rc = SNMP_ERR_GENERR; snmp_log(LOG_ERR, "unknown column in " "saHpiAutoInsertTimeoutTable_set_reserve1\n"); } if (rc) netsnmp_request_set_error( current->ri, rc ); rg->status = SNMP_MAX( rg->status, current->ri->status ); } /* * done with all the columns. Could check row related * requirements here. */ }
NETSNMP_INLINE int netsnmp_check_vb_oid(const netsnmp_variable_list *var) { register int rc = SNMP_ERR_NOERROR; if (NULL == var) return SNMP_ERR_GENERR; if ((rc = netsnmp_check_vb_type(var,ASN_OBJECT_ID))) ; else rc = netsnmp_check_vb_max_size(var, MAX_OID_LEN*sizeof(oid)); return rc; }
NETSNMP_INLINE int netsnmp_check_vb_type_and_max_size(const netsnmp_variable_list *var, int type, size_t size) { register int rc = SNMP_ERR_NOERROR; if (NULL == var) return SNMP_ERR_GENERR; if ((rc = netsnmp_check_vb_type(var,type))) ; else rc = netsnmp_check_vb_max_size(var, size); return rc; }
/* * @internal * Check the syntax for a particular column */ NETSNMP_STATIC_INLINE int _dot11ConfTotalTrapGroupTable_check_column( dot11ConfTotalTrapGroupTable_rowreq_ctx *rowreq_ctx, netsnmp_variable_list *var, int column ) { int rc = SNMPERR_SUCCESS; DEBUGMSGTL(("internal:dot11ConfTotalTrapGroupTable:_dot11ConfTotalTrapGroupTable_check_column","called\n")); netsnmp_assert(NULL != rowreq_ctx); switch(column) { /* NewTrapDescr(3)/DisplayString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H */ case COLUMN_NEWTRAPDESCR: rc = netsnmp_check_vb_type( var, ASN_OCTET_STR ); if(SNMPERR_SUCCESS == rc) { /* check that the value is in the defined range(s); inefficent * but keeps rc value knowledge in libarary where it belongs. */ if( 1 && ((rc = netsnmp_check_vb_size_range(var, 0,255)) != SNMP_ERR_NOERROR) ) { ; /* rc set in condition */ } } if(SNMPERR_SUCCESS == rc) { rc = NewTrapDescr_check_value( rowreq_ctx, (char *)var->val.string, var->val_len ); if((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc) && (MFD_NOT_VALID_NOW != rc)) { snmp_log(LOG_ERR, "bad rc %d from NewTrapDescr_check_value\n", rc); rc = SNMP_ERR_GENERR; } } break; /* NewTrapOnOff(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h */ case COLUMN_NEWTRAPONOFF: rc = netsnmp_check_vb_type_and_size( var, ASN_INTEGER, sizeof( rowreq_ctx->data.NewTrapOnOff ) ); if(SNMPERR_SUCCESS == rc) { /* check that the value is one of defined enums */ if( 1 && ( *var->val.integer != NEWTRAPONOFF_ON ) && ( *var->val.integer != NEWTRAPONOFF_OFF ) ) { rc = SNMP_ERR_WRONGVALUE; } } if(SNMPERR_SUCCESS == rc) { rc = NewTrapOnOff_check_value( rowreq_ctx, *((u_long *)var->val.string) ); if((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc) && (MFD_NOT_VALID_NOW != rc)) { snmp_log(LOG_ERR, "bad rc %d from NewTrapOnOff_check_value\n", rc); rc = SNMP_ERR_GENERR; } } break; default: /** We shouldn't get here */ rc = SNMP_ERR_GENERR; snmp_log(LOG_ERR, "unknown column %d in _dot11ConfTotalTrapGroupTable_check_column\n", column); } return rc; } /* _dot11ConfTotalTrapGroupTable_check_column */
/* neIeee8021BridgeBaseTable table mapper */ int neIeee8021BridgeBaseTable_mapper ( 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; neIeee8021BridgeBaseEntry_t *table_entry; register ieee8021BridgeBaseEntry_t *poEntry = NULL; void *pvOldDdata = NULL; int ret; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request != NULL; request = request->next) { poEntry = (ieee8021BridgeBaseEntry_t*) netsnmp_extract_iterator_context (request); table_info = netsnmp_extract_table_info (request); if (poEntry == NULL) { netsnmp_set_request_error (reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } table_entry = &poEntry->oNe; switch (table_info->colnum) { case NEIEEE8021BRIDGEBASECHASSISID: snmp_set_var_typed_integer (request->requestvb, ASN_UNSIGNED, table_entry->u32ChassisId); break; case NEIEEE8021BRIDGEBASENUMPORTSMAX: snmp_set_var_typed_integer (request->requestvb, ASN_UNSIGNED, table_entry->u32NumPortsMax); break; case NEIEEE8021BRIDGEBASEPORTS: snmp_set_var_typed_value (request->requestvb, ASN_OCTET_STR, (u_char*) table_entry->pu8Ports, table_entry->u16Ports_len); break; case NEIEEE8021BRIDGEBASEADMINFLAGS: snmp_set_var_typed_value (request->requestvb, ASN_OCTET_STR, (u_char*) table_entry->au8AdminFlags, table_entry->u16AdminFlags_len); break; case NEIEEE8021BRIDGEBASEOPERSTATE: snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, table_entry->i32OperState); break; default: netsnmp_set_request_error (reqinfo, request, SNMP_NOSUCHOBJECT); break; } } break; /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request != NULL; request = request->next) { poEntry = (ieee8021BridgeBaseEntry_t*) netsnmp_extract_iterator_context (request); table_info = netsnmp_extract_table_info (request); table_entry = &poEntry->oNe; switch (table_info->colnum) { case NEIEEE8021BRIDGEBASECHASSISID: ret = netsnmp_check_vb_type (requests->requestvb, ASN_UNSIGNED); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error (reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case NEIEEE8021BRIDGEBASENUMPORTSMAX: ret = netsnmp_check_vb_type (requests->requestvb, ASN_UNSIGNED); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error (reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case NEIEEE8021BRIDGEBASEADMINFLAGS: ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OCTET_STR, sizeof (table_entry->au8AdminFlags)); 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: for (request = requests; request != NULL; request = request->next) { poEntry = (ieee8021BridgeBaseEntry_t*) netsnmp_extract_iterator_context (request); table_info = netsnmp_extract_table_info (request); if (poEntry == NULL) { netsnmp_set_request_error (reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } switch (table_info->colnum) { case NEIEEE8021BRIDGEBASECHASSISID: case NEIEEE8021BRIDGEBASENUMPORTSMAX: case NEIEEE8021BRIDGEBASEADMINFLAGS: if (poEntry->u8RowStatus == xRowStatus_active_c || poEntry->u8RowStatus == xRowStatus_notReady_c) { netsnmp_set_request_error (reqinfo, request, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } break; } } break; case MODE_SET_FREE: break; case MODE_SET_ACTION: for (request = requests; request != NULL; request = request->next) { pvOldDdata = netsnmp_request_get_list_data (request, ROLLBACK_BUFFER); poEntry = (ieee8021BridgeBaseEntry_t*) netsnmp_extract_iterator_context (request); table_info = netsnmp_extract_table_info (request); table_entry = &poEntry->oNe; switch (table_info->colnum) { case NEIEEE8021BRIDGEBASECHASSISID: if (pvOldDdata == NULL && (pvOldDdata = xBuffer_cAlloc (sizeof (table_entry->u32ChassisId))) == NULL) { netsnmp_set_request_error (reqinfo, request, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } else if (pvOldDdata != table_entry) { memcpy (pvOldDdata, &table_entry->u32ChassisId, sizeof (table_entry->u32ChassisId)); netsnmp_request_add_list_data (request, netsnmp_create_data_list (ROLLBACK_BUFFER, pvOldDdata, &xBuffer_free)); } table_entry->u32ChassisId = *request->requestvb->val.integer; break; case NEIEEE8021BRIDGEBASENUMPORTSMAX: if (pvOldDdata == NULL && (pvOldDdata = xBuffer_cAlloc (sizeof (table_entry->u32NumPortsMax))) == NULL) { netsnmp_set_request_error (reqinfo, request, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } else if (pvOldDdata != table_entry) { memcpy (pvOldDdata, &table_entry->u32NumPortsMax, sizeof (table_entry->u32NumPortsMax)); netsnmp_request_add_list_data (request, netsnmp_create_data_list (ROLLBACK_BUFFER, pvOldDdata, &xBuffer_free)); } table_entry->u32NumPortsMax = *request->requestvb->val.integer; break; case NEIEEE8021BRIDGEBASEADMINFLAGS: if (pvOldDdata == NULL && (pvOldDdata = xBuffer_cAlloc (sizeof (xOctetString_t) + sizeof (table_entry->au8AdminFlags))) == NULL) { netsnmp_set_request_error (reqinfo, request, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } else if (pvOldDdata != table_entry) { ((xOctetString_t*) pvOldDdata)->pData = pvOldDdata + sizeof (xOctetString_t); ((xOctetString_t*) pvOldDdata)->u16Len = table_entry->u16AdminFlags_len; memcpy (((xOctetString_t*) pvOldDdata)->pData, table_entry->au8AdminFlags, sizeof (table_entry->au8AdminFlags)); netsnmp_request_add_list_data (request, netsnmp_create_data_list (ROLLBACK_BUFFER, pvOldDdata, &xBuffer_free)); } memset (table_entry->au8AdminFlags, 0, sizeof (table_entry->au8AdminFlags)); memcpy (table_entry->au8AdminFlags, request->requestvb->val.string, request->requestvb->val_len); table_entry->u16AdminFlags_len = request->requestvb->val_len; break; } } break; case MODE_SET_UNDO: for (request = requests; request != NULL; request = request->next) { pvOldDdata = netsnmp_request_get_list_data (request, ROLLBACK_BUFFER); poEntry = (ieee8021BridgeBaseEntry_t*) netsnmp_extract_iterator_context (request); table_info = netsnmp_extract_table_info (request); if (poEntry == NULL || pvOldDdata == NULL) { continue; } table_entry = &poEntry->oNe; switch (table_info->colnum) { case NEIEEE8021BRIDGEBASECHASSISID: memcpy (&table_entry->u32ChassisId, pvOldDdata, sizeof (table_entry->u32ChassisId)); break; case NEIEEE8021BRIDGEBASENUMPORTSMAX: memcpy (&table_entry->u32NumPortsMax, pvOldDdata, sizeof (table_entry->u32NumPortsMax)); break; case NEIEEE8021BRIDGEBASEADMINFLAGS: memcpy (table_entry->au8AdminFlags, ((xOctetString_t*) pvOldDdata)->pData, ((xOctetString_t*) pvOldDdata)->u16Len); table_entry->u16AdminFlags_len = ((xOctetString_t*) pvOldDdata)->u16Len; break; } } break; case MODE_SET_COMMIT: break; } return SNMP_ERR_NOERROR; }
int handle_shutdown(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { int ret; /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ /* a instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ switch(reqinfo->mode) { case MODE_GET: netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE ); break; /* * SET REQUEST * * multiple states in the transaction. See: * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg */ case MODE_SET_RESERVE1: /* or you could use netsnmp_check_vb_type_and_size instead */ ret = netsnmp_check_vb_type(requests->requestvb, ASN_INTEGER); if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error(reqinfo, requests, ret ); } break; case MODE_SET_RESERVE2: /* XXX malloc "undo" storage buffer */ break; case MODE_SET_FREE: /* XXX: free resources allocated in RESERVE1 and/or RESERVE2. Something failed somewhere, and the states below won't be called. */ break; case MODE_SET_ACTION: /* XXX: perform the value change here */ break; case MODE_SET_COMMIT: /* XXX: delete temporary storage */ break; case MODE_SET_UNDO: /* XXX: UNDO and return to previous value for the object */ break; default: /* we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, "unknown mode (%d) in handle_shutdown\n", reqinfo->mode ); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }
int clSnmpsaAmfClusterAdminStateTriggerHandler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { ClSNMPRequestInfoT requestInfo; netsnmp_variable_list *reqVar = NULL; if(!requests || !reqinfo) return SNMP_ERR_GENERR; reqVar = requests->requestvb; /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ /* An instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ memset(&requestInfo, 0, sizeof(ClSNMPRequestInfoT)); /* Extract the scalar OID, convert it to string form and assign it to requestInfo.oid */ requestInfo.oidLen = OID_LENGTH(saAmfClusterAdminStateTriggerOid); clSnmpOidCpy(&requestInfo, reqVar->name); requestInfo.tableType = CL_SAFAMF_SCALARS; switch(reqinfo->mode) { case MODE_GET: { ClInt32T retVal = 0, errorCode = 0; _ClSnmpGetReqInfoT reqAddInfo = {0}; void * pVal = NULL; ClInt32T saAmfClusterAdminStateTriggerVal = 0; requestInfo.dataLen = sizeof(ClInt32T); pVal = &saAmfClusterAdminStateTriggerVal; requestInfo.index.scalarType = 0; requestInfo.opCode = CL_SNMP_GET; reqAddInfo.pRequest = requests; reqAddInfo.columnType = ASN_INTEGER; clLogDebug("SUB", "SCL", "Received GET request"); retVal = clRequestAdd(&requestInfo, pVal, NULL, &errorCode, &reqAddInfo); if(retVal != 0 || errorCode < 0) { netsnmp_request_set_error (requests, errorCode); return errorCode; } break; } /* * SET REQUEST * * multiple states in the transaction. See: * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg */ case MODE_SET_RESERVE1: { ClInt32T retVal = 0; clLogDebug("SUB", "SCL", "Received RESERVE1 request"); retVal = netsnmp_check_vb_type(reqVar, ASN_INTEGER); if(retVal != SNMP_ERR_NOERROR ) { netsnmp_request_set_error(requests, retVal ); return retVal; } switch(*(reqVar->val.integer)) { case SAAMFCLUSTERADMINSTATETRIGGER_STABLE: break; case SAAMFCLUSTERADMINSTATETRIGGER_UNLOCK: break; case SAAMFCLUSTERADMINSTATETRIGGER_LOCK: break; case SAAMFCLUSTERADMINSTATETRIGGER_LOCKINSTANTIATION: break; case SAAMFCLUSTERADMINSTATETRIGGER_UNLOCKINSTANTIATION: break; case SAAMFCLUSTERADMINSTATETRIGGER_SHUTDOWN: break; /** not a legal enum value. return an error */ default: CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Inconsistent value.")); netsnmp_request_set_error(requests, SNMP_ERR_WRONGVALUE); return SNMP_ERR_WRONGVALUE; } break; } case MODE_SET_RESERVE2: { ClInt32T retVal = 0, errorCode = 0, noOfOp = 1; ClPtrT pVal = NULL; ClInt32T Val = 0; pVal = &Val; requestInfo.dataLen = sizeof(ClInt32T); requestInfo.opCode = CL_SNMP_SET; requestInfo.index.scalarType = 0; memcpy(pVal, (void *)reqVar->val.integer, requestInfo.dataLen); clLogDebug("SUB", "SCL", "Calling request add"); retVal = clRequestAdd( &requestInfo, pVal, &noOfOp, &errorCode, NULL); if(CL_OK != retVal) { clLogError("SUB", "SCL", "Failed to add request to store, rc=[0x%x], errorCode=[0x%x]", retVal, errorCode); netsnmp_request_set_error(requests, errorCode); return retVal; } clLogDebug("SUB", "SCL", "Successfully added request in store"); break; } case MODE_SET_FREE: { clLogDebug("SUB", "SCL", "Received FREE request"); clSnmpUndo(); break; } case MODE_SET_ACTION: { ClInt32T retVal = 0; ClMedErrorListT medErrList; clLogDebug("SUB", "SCL", "Received ACTION request for oid[%s] ",requestInfo.oid); retVal = clSnmpCommit(&medErrList); if (retVal != 0) { clLogDebug("SUB", "SCL", "Error in commit errCount[%d]", medErrList.count); if(retVal == CL_ERR_NO_MEMORY) { retVal = CL_SNMP_ERR_NOCREATION; /* Set SNMP equivalent error from oidErrMapTable in clSnmpInit.c */ clLogError("SUB", "SCL", "ACTION phase failed, setting errorCode[0x%x] for oid[%s]", retVal, requestInfo.oid); netsnmp_request_set_error(requests, retVal); return retVal; } else { ClUint32T i; for(i = 0; i < medErrList.count; i++) { /* the oid matches the request, set error and return*/ if(!memcmp((ClUint8T*)requestInfo.oid, medErrList.pErrorList[i].oidInfo.id, medErrList.pErrorList[i].oidInfo.len)) { clLogError("SUB", "SCL", "ACTION phase failed, setting errorCode[0x%x] for oid[%s]", medErrList.pErrorList[i].errId, requestInfo.oid); netsnmp_request_set_error(requests, medErrList.pErrorList[i].errId); return retVal; } } } } break; } case MODE_SET_COMMIT: { clLogDebug("SUB", "SCL", "Received COMMIT request"); clSnmpUndo(); break; } case MODE_SET_UNDO: { clLogDebug("SUB", "SCL", "Received UNDO request"); clSnmpUndo(); break; } default: /* we should never get here, so this is a really bad error */ CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("unknown mode (%d) in clSnmpsaAmfClusterAdminStateTriggerHandler\n", reqinfo->mode) ); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }
/************************************************************ * RESERVE is used to check the syntax of all the variables * provided, that the values being set are sensible and consistent, * and to allocate any resources required for performing the SET. * After this stage, the expectation is that the set ought to * succeed, though this is not guaranteed. (In fact, with the UCD * agent, this is done in two passes - RESERVE1, and * RESERVE2, to allow for dependancies between variables). * * BEFORE calling this routine, the agent will call duplicate_row * to create a copy of the row (unless this is a new row; i.e. * row_created == 1). * * next state -> SET_RESERVE2 || SET_FREE */ void saHpiCtrlTextTable_set_reserve1( netsnmp_request_group *rg ) { saHpiCtrlTextTable_context *row_ctx = (saHpiCtrlTextTable_context *)rg->existing_row; // saHpiCtrlTextTable_context *undo_ctx = // (saHpiCtrlTextTable_context *)rg->undo_info; netsnmp_variable_list *var; netsnmp_request_group_item *current; int rc; /* * TODO: loop through columns, check syntax and lengths. For * columns which have no dependencies, you could also move * the value/range checking here to attempt to catch error * cases as early as possible. */ for ( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; rc = SNMP_ERR_NOERROR; switch (current->tri->colnum) { case COLUMN_SAHPICTRLTEXTMODE: /** SaHpiCtrlMode = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(row_ctx->saHpiCtrlTextMode)); break; case COLUMN_SAHPICTRLTEXTLINE: /** Unsigned8 = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(row_ctx->saHpiCtrlTextLine)); break; case COLUMN_SAHPICTRLTEXTSTATE: /** SaHpiText = ASN_OCTET_STR */ rc = netsnmp_check_vb_type(var, ASN_OCTET_STR); if (rc == SNMP_ERR_NOERROR ) { if (var->val_len > sizeof(row_ctx->saHpiCtrlTextState)) { rc = SNMP_ERR_WRONGLENGTH; } } if (rc == SNMP_ERR_NOERROR) DEBUGMSGTL ((AGENT, "COLUMN_SAHPICTRLTEXTSTATE NO ERROR: %d\n", rc)); else DEBUGMSGTL ((AGENT, "COLUMN_SAHPICTRLTEXTSTATE ERROR: %d\n", rc)); break; default: /** We shouldn't get here */ rc = SNMP_ERR_GENERR; snmp_log(LOG_ERR, "unknown column in " "saHpiCtrlTextTable_set_reserve1\n"); } if (rc) netsnmp_set_mode_request_error(MODE_SET_BEGIN, current->ri, rc ); rg->status = SNMP_MAX( rg->status, current->ri->status ); } /* * done with all the columns. Could check row related * requirements here. */ }
int handle_wmanTestDataHolder(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { int ret; static char* tmp_ptr; /* * We are never called for a GETNEXT if it's registered as a * "instance", as it's "magically" handled for us. */ /* * a instance handler also only hands us one request at a time, so * we don't need to loop over a list of requests; we'll only get one. */ printf("handle_wmanTestDataHolder Called\n"); wmanTestDataHolder_val++; switch (reqinfo->mode) { case MODE_GET: printf("handle_wmanTestDataHolder MODE_GET...\n"); snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, (u_char *)(&wmanTestDataHolder_val) /* XXX: a pointer to the scalar's data */ ,sizeof(wmanTestDataHolder_val) /* * XXX: the length of the data in bytes */ ); break; /* * SET REQUEST * * multiple states in the transaction. See: * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg */ case MODE_SET_RESERVE1: /* * or you could use netsnmp_check_vb_type_and_size instead */ printf("handle_wmanTestDataHolder MODE_SET_RESERVE1...\n"); tmp_ptr=NULL; ret = netsnmp_check_vb_type(requests->requestvb, ASN_INTEGER); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, requests, ret); } break; case MODE_SET_RESERVE2: /* * XXX malloc "undo" storage buffer */ printf("handle_wmanTestDataHolder MODE_SET_RESERVE2...\n"); tmp_ptr = (char*)malloc(requests->requestvb->val_len); printf("MOD_SET_RESERVE2 [%d]\n", requests->requestvb->val_len); if(tmp_ptr==NULL) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_RESOURCEUNAVAILABLE; } break; case MODE_SET_FREE: /* * XXX: free resources allocated in RESERVE1 and/or * RESERVE2. Something failed somewhere, and the states * below won't be called. */ printf("handle_wmanTestDataHolder MODE_SET_FREE...\n"); if(tmp_ptr) free(tmp_ptr); break; case MODE_SET_ACTION: /* * XXX: perform the value change here */ printf("handle_wmanTestDataHolder MODE_SET_ACTION...\n"); if(tmp_ptr==NULL) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_RESOURCEUNAVAILABLE; } printf("MOD_SET_ACTION\n"); *(long *)tmp_ptr = *requests->requestvb->val.integer; break; case MODE_SET_COMMIT: /* * XXX: delete temporary storage */ printf("handle_wmanTestDataHolder MODE_SET_COMMIT...\n"); wmanTestDataHolder_val = *(long *)tmp_ptr; free(tmp_ptr); break; case MODE_SET_UNDO: /* * XXX: UNDO and return to previous value for the object */ printf("handle_wmanTestDataHolder MODE_SET_UNDO...\n"); free(tmp_ptr); break; default: /* * we should never get here, so this is a really bad error */ printf("handle_wmanTestDataHolder ERROR...\n"); snmp_log(LOG_ERR, "unknown mode (%d) in handle_wmanTestDataHolder\n", reqinfo->mode); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }
/********************************************************************** int CcspScalarHelperSetMibValues ( ANSC_HANDLE hThisObject, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests ); description: This function is called to set MIB values. argument: ANSC_HANDLE hThisObject The handle of the object; netsnmp_agent_request_info *reqinfo, The request info netsnmp_request_info *requests The requests; return: The error code **********************************************************************/ static int verifyTypeAndValueInSetReserved1 ( netsnmp_variable_list* pVb, PCCSP_MIB_MAPPING pMapping ) { int ret = SNMP_ERR_NOERROR; ULONG nType = pMapping->MibInfo.uType; if(!pMapping->MibInfo.bWritable) { return SNMP_ERR_NOTWRITABLE; } /* check type first */ ret = netsnmp_check_vb_type(pVb, nType); if( ret != SNMP_ERR_NOERROR) { return ret; } if( nType == ASN_BOOLEAN) { ret = netsnmp_check_vb_size(pVb, sizeof(BOOLEAN)); } else if( nType == ASN_INTEGER || (nType >= ASN_IPADDRESS && nType <= ASN_OPAQUE)) { ret = netsnmp_check_vb_size(pVb, sizeof(ULONG)); } else if( nType == ASN_COUNTER64) { ret = netsnmp_check_vb_size(pVb, sizeof(U64)); } if( ret != SNMP_ERR_NOERROR) { return ret; } if( pMapping->MibInfo.uMaskLimit == CCSP_MIB_LIMIT_MAX) { if( pMapping->MibInfo.uType == ASN_OCTET_STR) { ret = netsnmp_check_vb_max_size(pVb, pMapping->MibInfo.nMax); } } else if( pMapping->MibInfo.uMaskLimit == CCSP_MIB_LIMIT_BOTH) { if( pMapping->MibInfo.uType == ASN_INTEGER ) { ret = netsnmp_check_vb_int_range(pVb, pMapping->MibInfo.nMin, pMapping->MibInfo.nMax); } else if ( pMapping->MibInfo.uType == ASN_UNSIGNED ) { ret = netsnmp_check_vb_range(pVb, pMapping->MibInfo.nMin, pMapping->MibInfo.nMax); } else if( pMapping->MibInfo.uType == ASN_OCTET_STR) { ret = netsnmp_check_vb_size_range(pVb, pMapping->MibInfo.nMin, pMapping->MibInfo.nMax); } } if( ret != SNMP_ERR_NOERROR) { return ret; } /* check mapping if have */ if( nType == ASN_INTEGER || nType == ASN_UNSIGNED) { if( pMapping->MapQueue.Depth > 0) { if( CcspUtilLookforEnumMapping(&pMapping->MapQueue, (ULONG)*pVb->val.integer) == NULL) { AnscTraceError(("Invalid integer value '%ld'\n", *pVb->val.integer)); ret = SNMP_ERR_WRONGVALUE; } } } return ret; }
static int handle_ipv6IpDefaultHopLimit(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { u_long value; int rc; /* * We are never called for a GETNEXT if it's registered as a * "instance", as it's "magically" handled for us. */ /* * a instance handler also only hands us one request at a time, so * we don't need to loop over a list of requests; we'll only get one. */ switch (reqinfo->mode) { case MODE_GET: rc = netsnmp_arch_ip_scalars_ipv6IpDefaultHopLimit_get(&value); if (rc != 0) { netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE); } else { snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, (u_char *)&value, sizeof(value)); } break; #ifdef NOTYET /* * SET REQUEST * * multiple states in the transaction. See: * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg */ case MODE_SET_RESERVE1: /* * or you could use netsnmp_check_vb_type_and_size instead */ rc = netsnmp_check_vb_type(requests->requestvb, ASN_INTEGER); if (rc != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, requests, rc); } break; case MODE_SET_RESERVE2: /* * XXX malloc "undo" storage buffer */ if ( /* XXX if malloc, or whatever, failed: */ ) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); } break; case MODE_SET_FREE: /* * XXX: free resources allocated in RESERVE1 and/or * RESERVE2. Something failed somewhere, and the states * below won't be called. */ break; case MODE_SET_ACTION: /* * XXX: perform the value change here */ if ( /* XXX: error? */ ) { netsnmp_set_request_error(reqinfo, requests, /* some error */ ); } break; case MODE_SET_COMMIT: /* * XXX: delete temporary storage */ if ( /* XXX: error? */ ) { /* * try _really_really_ hard to never get to this point */ netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_COMMITFAILED); } break; case MODE_SET_UNDO: /* * XXX: UNDO and return to previous value for the object */ if ( /* XXX: error? */ ) { /* * try _really_really_ hard to never get to this point */ netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } break; #endif default: /* * we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, "unknown mode (%d) in handle_ipv6IpDefaultHopLimit\n", reqinfo->mode); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }
/* * @internal * Check the syntax for a particular column */ NETSNMP_STATIC_INLINE int _ifXTable_check_column(ifXTable_rowreq_ctx * rowreq_ctx, netsnmp_variable_list * var, int column) { int rc = SNMPERR_SUCCESS; DEBUGMSGTL(("internal:ifXTable:_ifXTable_check_column", "called\n")); netsnmp_assert(NULL != rowreq_ctx); switch (column) { /* * ifLinkUpDownTrapEnable(14)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h */ case COLUMN_IFLINKUPDOWNTRAPENABLE: rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(rowreq_ctx->data. ifLinkUpDownTrapEnable)); if (SNMPERR_SUCCESS == rc) { /* * check that the value is one of defined enums */ if (1 && (*var->val.integer != IFLINKUPDOWNTRAPENABLE_ENABLED) && (*var->val.integer != IFLINKUPDOWNTRAPENABLE_DISABLED) ) { rc = SNMP_ERR_WRONGVALUE; } } if (SNMPERR_SUCCESS == rc) { rc = ifLinkUpDownTrapEnable_check_value(rowreq_ctx, *((u_long *) var->val. string)); if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc) && (MFD_NOT_VALID_NOW != rc)) { snmp_log(LOG_ERR, "bad rc %d from ifLinkUpDownTrapEnable_check_value\n", rc); rc = SNMP_ERR_GENERR; } } break; /* * ifPromiscuousMode(16)/TruthValue/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h */ case COLUMN_IFPROMISCUOUSMODE: rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(rowreq_ctx->data. ifPromiscuousMode)); if (SNMPERR_SUCCESS == rc) { /* * check that the value is one of defined enums */ if (1 && (*var->val.integer != TRUTHVALUE_TRUE) && (*var->val.integer != TRUTHVALUE_FALSE) ) { rc = SNMP_ERR_WRONGVALUE; } } if (SNMPERR_SUCCESS == rc) { rc = ifPromiscuousMode_check_value(rowreq_ctx, *((u_long *) var->val. string)); if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc) && (MFD_NOT_VALID_NOW != rc)) { snmp_log(LOG_ERR, "bad rc %d from ifPromiscuousMode_check_value\n", rc); rc = SNMP_ERR_GENERR; } } break; /* * ifAlias(18)/DisplayString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H */ case COLUMN_IFALIAS: rc = netsnmp_check_vb_type(var, ASN_OCTET_STR); if (SNMPERR_SUCCESS == rc) { /* * check that the value is in the defined range(s); inefficent * * but keeps rc value knowledge in libarary where it belongs. */ if (1 && ((rc = netsnmp_check_vb_size_range(var, 0, 64)) != SNMP_ERR_NOERROR) ) { ; /* rc set in condition */ } } if (SNMPERR_SUCCESS == rc) { rc = ifAlias_check_value(rowreq_ctx, (char *) var->val.string, var->val_len); if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc) && (MFD_NOT_VALID_NOW != rc)) { snmp_log(LOG_ERR, "bad rc %d from ifAlias_check_value\n", rc); rc = SNMP_ERR_GENERR; } } break; default: /** We shouldn't get here */ rc = SNMP_ERR_GENERR; snmp_log(LOG_ERR, "unknown column %d in _ifXTable_check_column\n", column); } return rc; } /* _ifXTable_check_column */
/************************************************************ * RESERVE is used to check the syntax of all the variables * provided, that the values being set are sensible and consistent, * and to allocate any resources required for performing the SET. * After this stage, the expectation is that the set ought to * succeed, though this is not guaranteed. (In fact, with the UCD * agent, this is done in two passes - RESERVE1, and * RESERVE2, to allow for dependancies between variables). * * BEFORE calling this routine, the agent will call duplicate_row * to create a copy of the row (unless this is a new row; i.e. * row_created == 1). * * next state -> SET_RESERVE2 || SET_FREE */ void saHpiDomainInfoTable_set_reserve1( netsnmp_request_group *rg ) { saHpiDomainInfoTable_context *row_ctx = (saHpiDomainInfoTable_context *)rg->existing_row; // saHpiDomainInfoTable_context *undo_ctx = // (saHpiDomainInfoTable_context *)rg->undo_info; netsnmp_variable_list *var; netsnmp_request_group_item *current; int rc; DEBUGMSGTL ((AGENT, "saHpiDomainInfoTable_set_reserve1: Called\n")); /* * Loop through columns, check syntax and lengths. For * columns which have no dependencies, you could also move * the value/range checking here to attempt to catch error * cases as early as possible. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; rc = SNMP_ERR_NOERROR; switch(current->tri->colnum) { case COLUMN_SAHPIDOMAINTAGTEXTTYPE: /** SaHpiTextType = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size( var, ASN_INTEGER, sizeof(row_ctx->saHpiDomainTagTextType)); break; case COLUMN_SAHPIDOMAINTAGTEXTLANGUAGE: /** SaHpiTextLanguage = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size( var, ASN_INTEGER, sizeof(row_ctx->saHpiDomainTagTextLanguage)); break; case COLUMN_SAHPIDOMAINTAG: /** SaHpiText = ASN_OCTET_STR */ rc = netsnmp_check_vb_type(var, ASN_OCTET_STR); if(rc == SNMP_ERR_NOERROR ) { if (var->val_len > SAHPI_MAX_TEXT_BUFFER_LENGTH) { rc = SNMP_ERR_WRONGLENGTH; } } if (rc == SNMP_ERR_NOERROR) DEBUGMSGTL ((AGENT, "COLUMN_SAHPIDOMAINTAG NO ERROR: %d\n", rc)); else DEBUGMSGTL ((AGENT, "COLUMN_SAHPIDOMAINTAG ERROR: %d\n", rc)); break; default: /** We shouldn't get here */ rc = SNMP_ERR_GENERR; snmp_log(LOG_ERR, "unknown column in " "saHpiDomainInfoTable_set_reserve1\n"); } if (rc) netsnmp_request_set_error( current->ri, rc ); rg->status = SNMP_MAX( rg->status, current->ri->status ); } /* * done with all the columns. Could check row related * requirements here. */ }
int handle_channel(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { int ret; char channel_str[255]; int channel; static int skfd; /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ /* a instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ switch(reqinfo->mode) { case MODE_GET: printf("bitrate MODE_GET\n"); if((skfd = iw_sockets_open()) < 0) { channel = -4; } else { channel = get_channel(skfd, INTERFACE); } sprintf(channel_str, "%d", channel); snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) channel_str, strlen(channel_str)); if(skfd >= 0) iw_sockets_close(skfd); break; /* * SET REQUEST * * multiple states in the transaction. See: * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg */ case MODE_SET_RESERVE1: printf("bitrate MODE_SET_RESERVE1\n"); /* or you could use netsnmp_check_vb_type_and_size instead */ ret = netsnmp_check_vb_type(requests->requestvb, ASN_OCTET_STR); if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error(reqinfo, requests, ret ); } break; case MODE_SET_RESERVE2: printf("bitrate MODE_SET_RESERVE2\n"); /* malloc "undo" storage buffer */ if((skfd = iw_sockets_open()) < 0) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); } break; case MODE_SET_FREE: printf("bitrate MODE_SET_FREE\n"); /* free resources allocated in RESERVE1 and/or RESERVE2. Something failed somewhere, and the states below won't be called. */ if(skfd >= 0) iw_sockets_close(skfd); break; case MODE_SET_ACTION: printf("bitrate MODE_SET_ACTION\n"); /* perform the value change here */ ret = set_channel(skfd, INTERFACE, (char**)&(requests->requestvb->val.string), 1); if (ret <= 0) { netsnmp_set_request_error(reqinfo, requests, ret); } break; case MODE_SET_COMMIT: printf("bitrate MODE_SET_COMMIT\n"); /* delete temporary storage */ if(skfd >= 0) iw_sockets_close(skfd); break; case MODE_SET_UNDO: printf("bitrate MODE_SET_UNDO\n"); break; default: /* we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, "unknown mode (%d) in handle_channel\n", reqinfo->mode ); return SNMP_ERR_GENERR; } printf("bitrate - return\n"); return SNMP_ERR_NOERROR; }