/** handles requests for the nsVacmAccessTable table */ int nsVacmAccessTable_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; netsnmp_variable_list *idx; struct vacm_accessEntry *entry; char atype[20]; int viewIdx, ret; char *gName, *cPrefix; int model, level; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { entry = (struct vacm_accessEntry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); /* Extract the authType token from the list of indexes */ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable; memset(atype, 0, sizeof(atype)); memcpy(atype, (char *)idx->val.string, idx->val_len); viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype); DEBUGMSGTL(("nsVacm", "GET %s (%d)\n", idx->val.string, viewIdx)); if (!entry || viewIdx < 0) continue; switch (table_info->colnum) { case COLUMN_NSVACMCONTEXTMATCH: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->contextMatch); break; case COLUMN_NSVACMVIEWNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)entry->views[ viewIdx ], strlen(entry->views[ viewIdx ])); break; case COLUMN_VACMACCESSSTORAGETYPE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->storageType); break; case COLUMN_NSVACMACCESSSTATUS: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->status); break; } } break; #ifndef NETSNMP_NO_WRITE_SUPPORT /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { entry = (struct vacm_accessEntry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); ret = SNMP_ERR_NOERROR; switch (table_info->colnum) { case COLUMN_NSVACMCONTEXTMATCH: ret = netsnmp_check_vb_int_range(request->requestvb, 1, 2); break; case COLUMN_NSVACMVIEWNAME: ret = netsnmp_check_vb_type_and_max_size(request->requestvb, ASN_OCTET_STR, VACM_MAX_STRING); break; case COLUMN_VACMACCESSSTORAGETYPE: ret = netsnmp_check_vb_storagetype(request->requestvb, (/*entry ? entry->storageType :*/ SNMP_STORAGE_NONE)); break; case COLUMN_NSVACMACCESSSTATUS: /* * The usual 'check_vb_rowstatus' call is too simplistic * to be used here. Because we're implementing a table * within an existing table, it's quite possible for a * the vacmAccessTable entry to exist, even if this is * a "new" nsVacmAccessEntry. * * We can check that the value being assigned is suitable * for a RowStatus syntax object, but the transition * checks need to be done explicitly. */ ret = netsnmp_check_vb_rowstatus_value(request->requestvb); if ( ret != SNMP_ERR_NOERROR ) break; /* * Extract the authType token from the list of indexes */ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable; memset(atype, 0, sizeof(atype)); memcpy(atype, (char *)idx->val.string, idx->val_len); viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype); if ( viewIdx < 0 ) { ret = SNMP_ERR_NOCREATION; break; } switch ( *request->requestvb->val.integer ) { case RS_ACTIVE: case RS_NOTINSERVICE: /* Check that this particular view is already set */ if ( !entry || !entry->views[viewIdx][0] ) ret = SNMP_ERR_INCONSISTENTVALUE; break; case RS_CREATEANDWAIT: case RS_CREATEANDGO: /* Check that this particular view is not yet set */ if ( entry && entry->views[viewIdx][0] ) ret = SNMP_ERR_INCONSISTENTVALUE; break; } break; } /* switch(colnum) */ if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } } break; case MODE_SET_RESERVE2: for (request = requests; request; request = request->next) { entry = (struct vacm_accessEntry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case COLUMN_NSVACMACCESSSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: if (!entry) { idx = table_info->indexes; gName = (char*)idx->val.string; idx = idx->next_variable; cPrefix = (char*)idx->val.string; idx = idx->next_variable; model = *idx->val.integer; idx = idx->next_variable; level = *idx->val.integer; entry = vacm_createAccessEntry( gName, cPrefix, model, level ); entry->storageType = ST_NONVOLATILE; netsnmp_insert_iterator_context(request, (void*)entry); } } } } break; case MODE_SET_FREE: case MODE_SET_UNDO: /* XXX - TODO */ break; case MODE_SET_ACTION: /* ??? Empty ??? */ break; case MODE_SET_COMMIT: for (request = requests; request; request = request->next) { entry = (struct vacm_accessEntry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if ( !entry ) continue; /* Shouldn't happen */ /* Extract the authType token from the list of indexes */ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable; memset(atype, 0, sizeof(atype)); memcpy(atype, (char *)idx->val.string, idx->val_len); viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype); if (viewIdx < 0) continue; switch (table_info->colnum) { case COLUMN_NSVACMCONTEXTMATCH: entry->contextMatch = *request->requestvb->val.integer; break; case COLUMN_NSVACMVIEWNAME: memset( entry->views[viewIdx], 0, VACMSTRINGLEN ); memcpy( entry->views[viewIdx], request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_VACMACCESSSTORAGETYPE: entry->storageType = *request->requestvb->val.integer; break; case COLUMN_NSVACMACCESSSTATUS: switch (*request->requestvb->val.integer) { case RS_DESTROY: memset( entry->views[viewIdx], 0, VACMSTRINGLEN ); break; } break; } } break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } return SNMP_ERR_NOERROR; }
/** handles requests for the mteTriggerThresholdTable table */ int mteTriggerThresholdTable_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 *tinfo; struct mteTrigger *entry; int ret; DEBUGMSGTL(("disman:event:mib", "Threshold Table handler (%d)\n", reqinfo->mode)); switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); /* * The mteTriggerThresholdTable should only contains entries for * rows where the mteTriggerTest 'threshold(2)' bit is set. * So skip entries where this isn't the case. */ if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD )) continue; switch (tinfo->colnum) { case COLUMN_MTETRIGGERTHRESHOLDSTARTUP: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->mteTThStartup); break; case COLUMN_MTETRIGGERTHRESHOLDRISING: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->mteTThRiseValue); break; case COLUMN_MTETRIGGERTHRESHOLDFALLING: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->mteTThFallValue); break; case COLUMN_MTETRIGGERTHRESHOLDDELTARISING: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->mteTThDRiseValue); break; case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLING: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->mteTThDFallValue); break; case COLUMN_MTETRIGGERTHRESHOLDOBJECTSOWNER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThObjOwner, strlen(entry->mteTThObjOwner)); break; case COLUMN_MTETRIGGERTHRESHOLDOBJECTS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThObjects, strlen(entry->mteTThObjects)); break; case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENTOWNER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThRiseOwner, strlen(entry->mteTThRiseOwner)); break; case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENT: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThRiseEvent, strlen(entry->mteTThRiseEvent)); break; case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENTOWNER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThFallOwner, strlen(entry->mteTThFallOwner)); break; case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENT: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThFallEvent, strlen(entry->mteTThFallEvent)); break; case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENTOWNER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThDRiseOwner, strlen(entry->mteTThDRiseOwner)); break; case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENT: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThDRiseEvent, strlen(entry->mteTThDRiseEvent)); break; case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENTOWNER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThDFallOwner, strlen(entry->mteTThDFallOwner)); break; case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENT: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteTThDFallEvent, strlen(entry->mteTThDFallEvent)); break; } } break; #ifndef NETSNMP_NO_WRITE_SUPPORT /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); /* * Since the mteTriggerThresholdTable only contains entries for * rows where the mteTriggerTest 'threshold(2)' bit is set, * strictly speaking we should reject assignments where * this isn't the case. * But SET requests that include an assignment of the * 'threshold(2)' bit at the same time are valid, so would * need to be accepted. Unfortunately, this assignment * is only applied in the COMMIT pass, so it's difficult * to detect whether this holds or not. * * Let's fudge things for now, by processing assignments * even if the 'threshold(2)' bit isn't set. */ switch (tinfo->colnum) { case COLUMN_MTETRIGGERTHRESHOLDSTARTUP: ret = netsnmp_check_vb_int_range(request->requestvb, MTE_THRESH_START_RISE, MTE_THRESH_START_RISEFALL ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGERTHRESHOLDRISING: case COLUMN_MTETRIGGERTHRESHOLDFALLING: case COLUMN_MTETRIGGERTHRESHOLDDELTARISING: case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLING: ret = netsnmp_check_vb_int(request->requestvb); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGERTHRESHOLDOBJECTSOWNER: case COLUMN_MTETRIGGERTHRESHOLDOBJECTS: case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENTOWNER: case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENT: case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENTOWNER: case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENT: case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENTOWNER: case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENT: case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENTOWNER: case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENT: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, MTE_STR1_LEN); 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; } /* * The Event MIB is somewhat ambiguous as to whether the * various trigger table entries can be modified once the * main mteTriggerTable entry has been marked 'active'. * But it's clear from discussion on the DisMan mailing * list is that the intention is not. * * So check for whether this row is already active, * and reject *all* SET requests if it is. */ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); if (entry && entry->flags & MTE_TRIGGER_FLAG_ACTIVE ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_NOERROR; } } break; case MODE_SET_RESERVE2: case MODE_SET_FREE: case MODE_SET_UNDO: break; case MODE_SET_ACTION: for (request = requests; request; request = request->next) { entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); if (!entry) { /* * New rows must be created via the RowStatus column * (in the main mteTriggerTable) */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); /* or inconsistentName? */ return SNMP_ERR_NOERROR; } } break; case MODE_SET_COMMIT: /* * All these assignments are "unfailable", so it's * (reasonably) safe to apply them in the Commit phase */ for (request = requests; request; request = request->next) { entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTETRIGGERTHRESHOLDSTARTUP: entry->mteTThStartup = *request->requestvb->val.integer; break; case COLUMN_MTETRIGGERTHRESHOLDRISING: entry->mteTThRiseValue = *request->requestvb->val.integer; break; case COLUMN_MTETRIGGERTHRESHOLDFALLING: entry->mteTThFallValue = *request->requestvb->val.integer; break; case COLUMN_MTETRIGGERTHRESHOLDDELTARISING: entry->mteTThDRiseValue = *request->requestvb->val.integer; break; case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLING: entry->mteTThDFallValue = *request->requestvb->val.integer; break; case COLUMN_MTETRIGGERTHRESHOLDOBJECTSOWNER: memset(entry->mteTThObjOwner, 0, sizeof(entry->mteTThObjOwner)); memcpy(entry->mteTThObjOwner, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDOBJECTS: memset(entry->mteTThObjects, 0, sizeof(entry->mteTThObjects)); memcpy(entry->mteTThObjects, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENTOWNER: memset(entry->mteTThRiseOwner, 0, sizeof(entry->mteTThRiseOwner)); memcpy(entry->mteTThRiseOwner, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENT: memset(entry->mteTThRiseEvent, 0, sizeof(entry->mteTThRiseEvent)); memcpy(entry->mteTThRiseEvent, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENTOWNER: memset(entry->mteTThFallOwner, 0, sizeof(entry->mteTThFallOwner)); memcpy(entry->mteTThFallOwner, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENT: memset(entry->mteTThFallEvent, 0, sizeof(entry->mteTThFallEvent)); memcpy(entry->mteTThFallEvent, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENTOWNER: memset(entry->mteTThDRiseOwner, 0, sizeof(entry->mteTThDRiseOwner)); memcpy(entry->mteTThDRiseOwner, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENT: memset(entry->mteTThDRiseEvent, 0, sizeof(entry->mteTThDRiseEvent)); memcpy(entry->mteTThDRiseEvent, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENTOWNER: memset(entry->mteTThDFallOwner, 0, sizeof(entry->mteTThDFallOwner)); memcpy(entry->mteTThDFallOwner, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENT: memset(entry->mteTThDFallEvent, 0, sizeof(entry->mteTThDFallEvent)); memcpy(entry->mteTThDFallEvent, request->requestvb->val.string, request->requestvb->val_len); break; } } break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } return SNMP_ERR_NOERROR; }
/** handles requests for the mteEventTable table */ int mteEventTable_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 *tinfo; netsnmp_tdata_row *row; struct mteEvent *entry; char mteOwner[MTE_STR1_LEN+1]; char mteEName[MTE_STR1_LEN+1]; long ret; DEBUGMSGTL(("disman:event:mib", "Event Table handler (%d)\n", reqinfo->mode)); switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); if (!entry || !(entry->flags & MTE_EVENT_FLAG_VALID)) continue; switch (tinfo->colnum) { case COLUMN_MTEEVENTCOMMENT: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->mteEventComment, strlen(entry->mteEventComment)); break; case COLUMN_MTEEVENTACTIONS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, &entry->mteEventActions, 1); break; case COLUMN_MTEEVENTENABLED: ret = (entry->flags & MTE_EVENT_FLAG_ENABLED ) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_MTEEVENTENTRYSTATUS: ret = (entry->flags & MTE_EVENT_FLAG_ACTIVE ) ? RS_ACTIVE : RS_NOTINSERVICE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; } } break; #ifndef NETSNMP_NO_WRITE_SUPPORT /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEEVENTCOMMENT: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, MTE_STR1_LEN); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } /* * Can't modify the comment of an active row * (No good reason for this, but that's what the MIB says!) */ if (entry && entry->flags & MTE_EVENT_FLAG_ACTIVE ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_NOERROR; } break; case COLUMN_MTEEVENTACTIONS: ret = netsnmp_check_vb_type_and_size( request->requestvb, ASN_OCTET_STR, 1); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } /* * Can't modify the event types of an active row * (A little more understandable perhaps, * but still an unnecessary restriction IMO) */ if (entry && entry->flags & MTE_EVENT_FLAG_ACTIVE ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_NOERROR; } break; case COLUMN_MTEEVENTENABLED: ret = netsnmp_check_vb_truthvalue(request->requestvb); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } /* * The published version of the Event MIB forbids * enabling (or disabling) an active row, which * would make this object completely pointless! * Fortunately this ludicrous decision has since been corrected. */ break; case COLUMN_MTEEVENTENTRYSTATUS: ret = netsnmp_check_vb_rowstatus(request->requestvb, (entry ? RS_ACTIVE : RS_NONEXISTENT)); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } /* An active row can only be deleted */ if (entry && entry->flags & MTE_EVENT_FLAG_ACTIVE && *request->requestvb->val.integer == RS_NOTINSERVICE ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); 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; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEEVENTENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Create an (empty) new row structure */ memset(mteOwner, 0, sizeof(mteOwner)); memcpy(mteOwner, tinfo->indexes->val.string, tinfo->indexes->val_len); memset(mteEName, 0, sizeof(mteEName)); memcpy(mteEName, tinfo->indexes->next_variable->val.string, tinfo->indexes->next_variable->val_len); row = mteEvent_createEntry(mteOwner, mteEName, 0); if (!row) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } netsnmp_insert_tdata_row( request, row ); } } } break; case MODE_SET_FREE: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEEVENTENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Tidy up after a failed row creation request */ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); if (entry && !(entry->flags & MTE_EVENT_FLAG_VALID)) { row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); mteEvent_removeEntry( row ); } } } } break; case MODE_SET_ACTION: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); if (!entry) { /* * New rows must be created via the RowStatus column */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); /* or inconsistentName? */ return SNMP_ERR_NOERROR; } } break; case MODE_SET_UNDO: break; case MODE_SET_COMMIT: /* * All these assignments are "unfailable", so it's * (reasonably) safe to apply them in the Commit phase */ for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEEVENTCOMMENT: memset(entry->mteEventComment, 0, sizeof(entry->mteEventComment)); memcpy(entry->mteEventComment, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTEEVENTACTIONS: entry->mteEventActions = request->requestvb->val.string[0]; break; case COLUMN_MTEEVENTENABLED: if (*request->requestvb->val.integer == TV_TRUE) entry->flags |= MTE_EVENT_FLAG_ENABLED; else entry->flags &= ~MTE_EVENT_FLAG_ENABLED; break; case COLUMN_MTEEVENTENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_ACTIVE: entry->flags |= MTE_EVENT_FLAG_ACTIVE; break; case RS_CREATEANDGO: entry->flags |= MTE_EVENT_FLAG_ACTIVE; /* fall-through */ case RS_CREATEANDWAIT: entry->flags |= MTE_EVENT_FLAG_VALID; entry->session = netsnmp_iquery_pdu_session(reqinfo->asp->pdu); break; case RS_DESTROY: row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); mteEvent_removeEntry(row); } } } break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } DEBUGMSGTL(("disman:event:mib", "Table handler, done\n")); return SNMP_ERR_NOERROR; }
/** handles requests for the tlstmCertToTSNTable table */ static int tlstmCertToTSNTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { oid tsnm[] = { SNMP_TLS_TM_BASE, 1, 1, 0 }; static const int tsnm_pos = OID_LENGTH(tsnm) - 1; netsnmp_request_info *request = NULL; netsnmp_table_request_info *info; netsnmp_tdata *table; netsnmp_tdata_row *row; certToTSN_entry *entry; int ret = SNMP_ERR_NOERROR; DEBUGMSGTL(("tlstmCertToSN:handler", "Processing request (mode %s (%d))\n", se_find_label_in_slist("agent_mode", reqinfo->mode), reqinfo->mode)); switch (reqinfo->mode) { /** ######################################################### GET ##### * * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); netsnmp_assert(entry && info); switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: { /* * build SnmpTLSFingerprint */ u_char bin[42], *ptr = bin; size_t len = sizeof(bin); int rc; rc = netsnmp_tls_fingerprint_build(entry->hashType, entry->fingerprint, &ptr, &len, 0); if (SNMPERR_SUCCESS != rc) netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); else snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, bin, len); } break; /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */ case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: tsnm[tsnm_pos] = entry->mapType; snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, tsnm, sizeof(tsnm)); break; /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */ case COL_SNMPTLSTMCERTTOTSN_DATA: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->data, entry->data_len); break; /* case COL_SNMPTLSTMCERTTOTSN_DATA */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->storageType); break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->rowStatus); break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); break; } /* switch colnum */ } /* for requests */ break; /* case MODE_GET */ /* * Write-support */ /** #################################################### RESERVE1 ##### * * In RESERVE1 we are just checking basic ASN.1 size/type restrictions. * You probably don't need to change any of this code. Don't change any * of the column values here. Save that for the ACTION phase. * * The next phase is RESERVE2 or FREE. */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { netsnmp_assert(request->processed == 0); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); if ((NULL != entry) && (ST_READONLY == entry->storageType)) { ret = SNMP_ERR_NOTWRITABLE; break; } switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OCTET_STR, sizeof(entry->fingerprint)); /** check len/algorithm MIB requirements */ if (ret == SNMP_ERR_NOERROR) ret = netsnmp_cert_check_vb_fingerprint(request->requestvb); break; /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */ case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OBJECT_ID, SNMPTLSTMCERTTOTSN_MAPTYPE_MAX_SIZE); if (ret == SNMP_ERR_NOERROR) { if (_oid2type(request->requestvb->val.objid, request->requestvb->val_len) > TSNM_tlstmCert_MAX) ret = SNMP_ERR_WRONGVALUE; } break; /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */ case COL_SNMPTLSTMCERTTOTSN_DATA: ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OCTET_STR, sizeof(entry->data)); break; /* case COL_SNMPTLSTMCERTTOTSN_DATA */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: ret = netsnmp_check_vb_storagetype (request->requestvb,(entry ? entry->storageType : ST_NONE)); break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: ret = netsnmp_check_vb_rowstatus_with_storagetype (request->requestvb, (entry ? entry->rowStatus :RS_NONEXISTENT), (entry ? entry->storageType :ST_NONE)); break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ default: ret = SNMP_ERR_NOTWRITABLE; } /* switch colnum */ if (ret != SNMP_ERR_NOERROR) break; } /* for requests */ break; /* case MODE_SET_RESERVE1 */ /** #################################################### RESERVE2 ##### * * RESERVE2 is for checking additional restrictions from the MIB. * Since these restrictions are often in the description of the object, * mib2c can't generate code. It's possible that you need to add * additional checks here. However, don't change any of the column * values here. Save that for the ACTION phase. * * The next phase is ACTION or FREE. */ case MODE_SET_RESERVE2: for (request = requests; request; request = request->next) { netsnmp_assert(request->processed == 0); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); table = netsnmp_tdata_extract_table(request); info = netsnmp_extract_table_info(request); /* * if no row, create one */ if (!entry) { row = tlstmCertToTSNTable_createEntry (table,*info->indexes->val.integer); if (!row) { ret = SNMP_ERR_RESOURCEUNAVAILABLE; break; } entry = row->data; _allocUndo(entry); if (!entry->undo) { tlstmCertToTSNTable_removeEntry(table, row); row = NULL; ret = SNMP_ERR_RESOURCEUNAVAILABLE; break; } entry->undo->fate = FATE_NEWLY_CREATED; /** associate row with requests */ netsnmp_insert_tdata_row(request, row); } /** allocate undo structure, if needed */ if (!entry->undo) { _allocUndo(entry); if (!entry->undo) { ret = SNMP_ERR_RESOURCEUNAVAILABLE; break; } } /* * save request ptr for column. if we already * have a value, bail. */ if (entry->undo->req[info->colnum]) { DEBUGMSGT(("tlstmCertToSN:reserve2", "multiple sets to col %d in request\n", info->colnum)); if (FATE_NEWLY_CREATED == entry->undo->fate) ret = SNMP_ERR_INCONSISTENTNAME; else ret = SNMP_ERR_INCONSISTENTVALUE; break; } entry->undo->req[info->colnum] = request; if (ret != SNMP_ERR_NOERROR) break; } /* for requests */ if (ret == SNMP_ERR_NOERROR) { /** make sure rowstatus is used to create rows */ for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); if ((entry->undo->fate != FATE_NEWLY_CREATED) || (entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS])) continue; ret = SNMP_ERR_INCONSISTENTNAME; break; } /* creation for requests */ } /* no error */ break; /* case MODE_SET_RESERVE2 */ /** ######################################################## FREE ##### * * FREE is for cleaning up after a failed request (during either * RESERVE1 or RESERVE2). So any allocated resources need to be * released. * * This the final phase for this path in the state machine. */ case MODE_SET_FREE: /* * release undo resources * remove any newly created rows */ for (request = requests; request; request = request->next) { table = netsnmp_tdata_extract_table(request); row = netsnmp_tdata_extract_row(request); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); if (!entry || !entry->undo) continue; /** disassociate row with requests */ netsnmp_remove_tdata_row(request, row); if (FATE_NEWLY_CREATED == entry->undo->fate) tlstmCertToTSNTable_removeEntry(table, row); else _freeUndo(entry); } break; /* case MODE_SET_FREE */ /** ###################################################### ACTION ##### * * In the ACTION phase, we perform any sets that can be undone. * (Save anything that can't be undone for the COMMIT phase.) * * After individual columns have been done, you should check that the * row as a whole is consistent. * * The next phase is UNDO or COMMIT. */ case MODE_SET_ACTION: for (request = requests; request; request = request->next) { entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); /** reserve2 should enforce this */ netsnmp_assert(request == entry->undo->req[info->colnum]); /* * for each col, save old value and the set new value */ switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: { u_char *tmp = (u_char*)entry->fingerprint; u_int size = sizeof(entry->fingerprint); netsnmp_variable_list *vb = request->requestvb; memcpy(entry->undo->fingerprint, entry->fingerprint, sizeof(entry->fingerprint)); entry->undo->fingerprint_len = entry->fingerprint_len; entry->undo->hashType = entry->hashType; memset(entry->fingerprint, 0, sizeof(entry->fingerprint)); (void)netsnmp_tls_fingerprint_parse(vb->val.string, vb->val_len, (char**)&tmp, &size, 0, &entry->hashType); entry->fingerprint_len = size; if (0 == entry->fingerprint_len) ret = SNMP_ERR_GENERR; } break; /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */ case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: entry->undo->mapType = entry->mapType; entry->mapType = _oid2type(request->requestvb->val.objid, request->requestvb->val_len); break; /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */ case COL_SNMPTLSTMCERTTOTSN_DATA: memcpy(entry->undo->data, entry->data, sizeof(entry->data)); entry->undo->data_len = entry->data_len; memset(entry->data, 0, sizeof(entry->data)); memcpy(entry->data, request->requestvb->val.string, request->requestvb->val_len); entry->data_len = request->requestvb->val_len; break; /* case COL_SNMPTLSTMCERTTOTSN_DATA */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: entry->undo->storageType = entry->storageType; entry->storageType = *request->requestvb->val.integer; break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: entry->undo->rowStatus = entry->rowStatus; entry->rowStatus = *request->requestvb->val.integer; break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ } /* switch colnum */ } /* set values for requests */ if (ret != SNMP_ERR_NOERROR) break; /* skip consistency if we've already got error */ /* * All columns now have their final values set. check the * internal consistency of each row. */ for (request = requests; request; request = request->next) { entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); if (entry->undo->is_consistent != -1) continue; /* already checked */ /** assume consistency */ entry->undo->is_consistent = 1; /* * per mib, can't have empty fingerprint and must * have data if indicated by map type. */ if (0 == entry->fingerprint_len) { DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent", "fingerprint must not be empty\n")); entry->undo->is_consistent = 0; } else if ((TSNM_tlstmCertSpecified == entry->mapType) && (0 == entry->data_len)) { DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent", "must specify Data for CertSpecified identity\n")); entry->undo->is_consistent = 0; } if ((RS_IS_ACTIVE(entry->rowStatus)) && ((!entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]) || (RS_IS_ACTIVE(entry->undo->rowStatus)))) { /* * per mib, can't modify these while row active */ char _cols[3] = { COL_SNMPTLSTMCERTTOTSN_FINGERPRINT, COL_SNMPTLSTMCERTTOTSN_MAPTYPE, COL_SNMPTLSTMCERTTOTSN_DATA }; int i; for (i=0; i < 3; ++i ) { if (!entry->undo->req[i]) continue; DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent", "can't modify row %d while active\n", _cols[i])); entry->undo->is_consistent = 0; ret = SNMP_ERR_NOTWRITABLE; request= entry->undo->req[i]; break; } } else if (RS_IS_GOING_ACTIVE(entry->rowStatus)) { /* * if going active, inconsistency is fatal */ if (!entry->undo->is_consistent) { netsnmp_assert(entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]); if (FATE_NEWLY_CREATED == entry->undo->fate) ret = SNMP_ERR_INCONSISTENTNAME; else ret = SNMP_ERR_INCONSISTENTVALUE; request = entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]; } } else if (RS_DESTROY == entry->rowStatus) { /* * can't destroy active row */ if (RS_IS_ACTIVE(entry->undo->rowStatus)) { DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent", "can't destroy active row\n")); netsnmp_assert(entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]); ret = SNMP_ERR_INCONSISTENTVALUE; request = entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]; } } if (ret != SNMP_ERR_NOERROR) break; } /* consistency for requests */ break; /* case MODE_SET_ACTION */ /** ######################################################## UNDO ##### * * UNDO is for cleaning up any failed requests that went through the * ACTION phase. * * This the final phase for this path in the state machine. */ case MODE_SET_UNDO: for (request = requests; request; request = request->next) { row = netsnmp_tdata_extract_row(request); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); /* * skip newly created rows, as we're going to delete * them below anyways */ if (FATE_NEWLY_CREATED == entry->undo->fate) continue; /* * restore values */ switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: memcpy(entry->fingerprint, entry->undo->fingerprint, sizeof(entry->fingerprint)); entry->fingerprint_len = entry->undo->fingerprint_len; entry->hashType = entry->undo->hashType; break; /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */ case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: entry->mapType = entry->undo->mapType; break; /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */ case COL_SNMPTLSTMCERTTOTSN_DATA: memcpy(entry->data, entry->undo->data, sizeof(entry->data)); entry->data_len = entry->undo->data_len; break; /* case COL_SNMPTLSTMCERTTOTSN_DATA */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: entry->storageType = entry->undo->storageType; break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: entry->rowStatus = entry->undo->rowStatus; break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ } /* switch colnum */ } /* for requests */ /* * release undo data * or remove any newly created rows */ for (request = requests; request; request = request->next) { table = netsnmp_tdata_extract_table(request); row = netsnmp_tdata_extract_row(request); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); if (!entry || !entry->undo) continue; /** disassociate row with requests */ netsnmp_remove_tdata_row(request, row); if (FATE_NEWLY_CREATED == entry->undo->fate) tlstmCertToTSNTable_removeEntry(table, row); else _freeUndo(entry); } /* for requests */ break; /* case MODE_SET_UNDO */ /** ###################################################### COMMIT ##### * * COMMIT is the final success state, when all changes are finalized. * There is not recovery state should something faile here. * * This the final phase for this path in the state machine. */ case MODE_SET_COMMIT: for (request = requests; request; request = request->next) { row = netsnmp_tdata_extract_row(request); table = netsnmp_tdata_extract_table(request); info = netsnmp_extract_table_info(request); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); if ((RS_NOTREADY == entry->rowStatus) && entry->undo->is_consistent) entry->rowStatus = RS_NOTINSERVICE; else if ((RS_NOTINSERVICE == entry->rowStatus) && (0 == entry->undo->is_consistent)) entry->rowStatus = RS_NOTREADY; /** release undo data for requests with no rowstatus */ if (entry->undo && !entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]) { _freeUndo(entry); if ((0 == entry->map_flags) && (entry->rowStatus == RS_ACTIVE)) _cert_map_add(entry); else if ((0 != entry->map_flags) && (entry->rowStatus == RS_DESTROY)) _cert_map_remove(entry); } switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: switch (entry->rowStatus) { case RS_CREATEANDGO: /** Fall-through */ case RS_ACTIVE: netsnmp_assert(entry->undo->is_consistent); entry->rowStatus = RS_ACTIVE; if (0 == entry->map_flags) _cert_map_add(entry); break; case RS_CREATEANDWAIT: /** Fall-through */ case RS_NOTINSERVICE: /** simply set status based on consistency */ if (entry->undo->is_consistent) entry->rowStatus = RS_NOTINSERVICE; else entry->rowStatus = RS_NOTREADY; if (0 != entry->map_flags) _cert_map_remove(entry); break; case RS_DESTROY: /** remove from cert map */ if (0 != entry->map_flags) _cert_map_remove(entry); /** disassociate row with requests */ netsnmp_remove_tdata_row(request, row); tlstmCertToTSNTable_removeEntry(table, row); row = NULL; entry = NULL; } /** release undo data */ _freeUndo(entry); break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: if (RS_ACTIVE == entry->rowStatus) _cert_map_tweak_storage(entry); break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: case COL_SNMPTLSTMCERTTOTSN_DATA: break; } /* switch colnum */ } /* for requests */ /** update last changed */ _last_changed = netsnmp_get_agent_uptime(); /** set up to save persistent store */ snmp_store_needed(NULL); break; /* case MODE_SET_COMMIT */ } /* switch (reqinfo->mode) */ if (ret != SNMP_ERR_NOERROR) netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; }
/** handles requests for the expExpressionTable table */ int expExpressionTable_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 *tinfo; netsnmp_tdata_row *row; struct expExpression *entry; char expOwner[EXP_STR1_LEN+1]; char expName[ EXP_STR1_LEN+1]; long ret; DEBUGMSGTL(("disman:expr:mib", "Expression Table handler (%d)\n", reqinfo->mode)); switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct expExpression *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); if (!entry || !(entry->flags & EXP_FLAG_VALID)) continue; switch (tinfo->colnum) { case COLUMN_EXPEXPRESSION: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char*)entry->expExpression, strlen(entry->expExpression)); break; case COLUMN_EXPEXPRESSIONVALUETYPE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->expValueType); break; case COLUMN_EXPEXPRESSIONCOMMENT: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char*)entry->expComment, strlen(entry->expComment)); break; case COLUMN_EXPEXPRESSIONDELTAINTERVAL: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->expDeltaInterval); break; case COLUMN_EXPEXPRESSIONPREFIX: /* * XXX - Need to search expObjectTable for a suitable OID */ /* * Empty OIDs (len=0) are converted into .0.0 * by the SNMP library automatically :-( */ if ( entry->expPrefix_len ) { snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *) entry->expPrefix, entry->expPrefix_len*sizeof(oid)); } else { /* XXX - possibly not needed */ request->requestvb->type = ASN_OBJECT_ID; request->requestvb->val_len = 0; } break; case COLUMN_EXPEXPRESSIONERRORS: snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER, entry->expErrorCount); break; case COLUMN_EXPEXPRESSIONENTRYSTATUS: /* What would indicate 'notReady' ? */ ret = (entry->flags & EXP_FLAG_ACTIVE) ? RS_ACTIVE : RS_NOTINSERVICE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; } } break; /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct expExpression *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_EXPEXPRESSION: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, EXP_STR3_LEN); /* XXX - check new expression is syntactically valid */ if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_EXPEXPRESSIONVALUETYPE: ret = netsnmp_check_vb_int_range(request->requestvb, 1, 8); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_EXPEXPRESSIONCOMMENT: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, EXP_STR2_LEN); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_EXPEXPRESSIONDELTAINTERVAL: ret = netsnmp_check_vb_int_range(request->requestvb, 0, 86400); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_EXPEXPRESSIONENTRYSTATUS: ret = netsnmp_check_vb_rowstatus(request->requestvb, (entry ? RS_ACTIVE : RS_NONEXISTENT)); 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; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_EXPEXPRESSIONENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Create an (empty) new row structure */ memset(expOwner, 0, sizeof(expOwner)); memcpy(expOwner, tinfo->indexes->val.string, tinfo->indexes->val_len); memset(expName, 0, sizeof(expName)); memcpy(expName, tinfo->indexes->next_variable->val.string, tinfo->indexes->next_variable->val_len); row = expExpression_createRow(expOwner, expName, 0); if (!row) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } netsnmp_insert_tdata_row( request, row ); } } } break; case MODE_SET_FREE: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_EXPEXPRESSIONENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Tidy up after a failed row creation request */ entry = (struct expExpression *) netsnmp_tdata_extract_entry(request); if (entry && !(entry->flags & EXP_FLAG_VALID)) { row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); expExpression_removeEntry( row ); } } } } break; case MODE_SET_ACTION: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); entry = (struct expExpression *) netsnmp_tdata_extract_entry(request); if (!entry) { /* * New rows must be created via the RowStatus column */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); /* or inconsistentName? */ return SNMP_ERR_NOERROR; } } break; case MODE_SET_UNDO: break; case MODE_SET_COMMIT: /* * All these assignments are "unfailable", so it's * (reasonably) safe to apply them in the Commit phase */ for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct expExpression *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_EXPEXPRESSION: memset(entry->expExpression, 0, EXP_STR3_LEN+1); memcpy(entry->expExpression, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_EXPEXPRESSIONVALUETYPE: entry->expValueType = *request->requestvb->val.integer; break; case COLUMN_EXPEXPRESSIONCOMMENT: memset(entry->expComment, 0, EXP_STR2_LEN+1); memcpy(entry->expComment, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_EXPEXPRESSIONDELTAINTERVAL: entry->expDeltaInterval = *request->requestvb->val.integer; break; case COLUMN_EXPEXPRESSIONENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_ACTIVE: entry->flags |= EXP_FLAG_ACTIVE; expExpression_enable( entry ); break; case RS_NOTINSERVICE: entry->flags &= ~EXP_FLAG_ACTIVE; expExpression_disable( entry ); break; case RS_CREATEANDGO: entry->flags |= EXP_FLAG_ACTIVE; entry->flags |= EXP_FLAG_VALID; entry->session = netsnmp_iquery_pdu_session(reqinfo->asp->pdu); expExpression_enable( entry ); break; case RS_CREATEANDWAIT: entry->flags |= EXP_FLAG_VALID; entry->session = netsnmp_iquery_pdu_session(reqinfo->asp->pdu); break; case RS_DESTROY: row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); expExpression_removeEntry(row); } } } break; } DEBUGMSGTL(("disman:expr:mib", "Expression Table handler - done \n")); return SNMP_ERR_NOERROR; }
/* neIeee8021QBridgeVlanCurrentTable table mapper */ int neIeee8021QBridgeVlanCurrentTable_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; neIeee8021QBridgeVlanCurrentEntry_t *table_entry; register ieee8021QBridgeVlanCurrentEntry_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 = (ieee8021QBridgeVlanCurrentEntry_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 NEIEEE8021QBRIDGEVLANCURRENTADMINFLAGS: snmp_set_var_typed_value (request->requestvb, ASN_OCTET_STR, (u_char*) table_entry->au8AdminFlags, table_entry->u16AdminFlags_len); break; case NEIEEE8021QBRIDGEVLANCURRENTOPERSTATE: snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, table_entry->i32OperState); break; case NEIEEE8021QBRIDGEVLANCURRENTLEARNT: snmp_set_var_typed_value (request->requestvb, ASN_OCTET_STR, (u_char*) table_entry->pu8Learnt, table_entry->u16Learnt_len); break; case NEIEEE8021QBRIDGEVLANCURRENTIFINDEX: snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, table_entry->u32IfIndex); 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 = (ieee8021QBridgeVlanCurrentEntry_t*) netsnmp_extract_iterator_context (request); table_info = netsnmp_extract_table_info (request); table_entry = &poEntry->oNe; switch (table_info->colnum) { case NEIEEE8021QBRIDGEVLANCURRENTADMINFLAGS: 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 = (ieee8021QBridgeVlanCurrentEntry_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 NEIEEE8021QBRIDGEVLANCURRENTADMINFLAGS: 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 = (ieee8021QBridgeVlanCurrentEntry_t*) netsnmp_extract_iterator_context (request); table_info = netsnmp_extract_table_info (request); table_entry = &poEntry->oNe; switch (table_info->colnum) { case NEIEEE8021QBRIDGEVLANCURRENTADMINFLAGS: 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 = (ieee8021QBridgeVlanCurrentEntry_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 NEIEEE8021QBRIDGEVLANCURRENTADMINFLAGS: 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; }
/** handles requests for the mteEventNotificationTable table */ int mteEventNotificationTable_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 *tinfo; struct mteEvent *entry; int ret; DEBUGMSGTL(("disman:event:mib", "Notification Table handler (%d)\n", reqinfo->mode)); switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); /* * The mteEventNotificationTable should only contains entries * for rows where the mteEventActions 'notification(0)' bit * is set. So skip entries where this isn't the case. */ if (!entry || !(entry->mteEventActions & MTE_EVENT_NOTIFICATION)) continue; switch (tinfo->colnum) { case COLUMN_MTEEVENTNOTIFICATION: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *) entry->mteNotification, entry->mteNotification_len*sizeof(oid)); break; case COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteNotifyOwner, strlen(entry->mteNotifyOwner)); break; case COLUMN_MTEEVENTNOTIFICATIONOBJECTS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteNotifyObjects, strlen(entry->mteNotifyObjects)); break; } } break; /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { tinfo = netsnmp_extract_table_info(request); /* * Since the mteEventNotificationTable only contains entries * for rows where the mteEventActions 'notification(0)' * bit is set, strictly speaking we should reject * assignments where this isn't the case. * But SET requests that include an assignment of the * 'notification(0)' bit at the same time are valid, * so would need to be accepted. Unfortunately, this * assignment is only applied in the COMMIT pass, so * it's difficult to detect whether this holds or not. * * Let's fudge things for now, by processing assignments * even if the 'notification(0)' bit isn't set. */ switch (tinfo->colnum) { case COLUMN_MTEEVENTNOTIFICATION: ret = netsnmp_check_vb_oid( request->requestvb ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER: case COLUMN_MTEEVENTNOTIFICATIONOBJECTS: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, MTE_STR1_LEN); 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; } /* * The Event MIB is somewhat ambiguous as to whether * mteEventNotificationTable (and mteEventSetTable) * entries can be modified once the main mteEventTable * entry has been marked 'active'. * But it's clear from discussion on the DisMan mailing * list is that the intention is not. * * So check for whether this row is already active, * and reject *all* SET requests if it is. */ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); if (entry && entry->flags & MTE_EVENT_FLAG_ACTIVE ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_NOERROR; } } break; case MODE_SET_RESERVE2: case MODE_SET_FREE: case MODE_SET_UNDO: break; case MODE_SET_ACTION: for (request = requests; request; request = request->next) { entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); if (!entry) { /* * New rows must be created via the RowStatus column * (in the main mteEventTable) */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); /* or inconsistentName? */ return SNMP_ERR_NOERROR; } } break; case MODE_SET_COMMIT: /* * All these assignments are "unfailable", so it's * (reasonably) safe to apply them in the Commit phase */ for (request = requests; request; request = request->next) { entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEEVENTNOTIFICATION: memset(entry->mteNotification, 0, sizeof(entry->mteNotification)); memcpy(entry->mteNotification, request->requestvb->val.objid, request->requestvb->val_len); entry->mteNotification_len = request->requestvb->val_len/sizeof(oid); break; case COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER: memset(entry->mteNotifyOwner, 0, sizeof(entry->mteNotifyOwner)); memcpy(entry->mteNotifyOwner, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTEEVENTNOTIFICATIONOBJECTS: memset(entry->mteNotifyObjects, 0, sizeof(entry->mteNotifyObjects)); memcpy(entry->mteNotifyObjects, request->requestvb->val.string, request->requestvb->val_len); break; } } break; } return SNMP_ERR_NOERROR; }
/** handles requests for the mteEventSetTable table */ int mteEventSetTable_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 *tinfo; struct mteEvent *entry; int ret; DEBUGMSGTL (("disman:event:mib", "Set Table handler (%d)\n", reqinfo->mode)); switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteEvent *) netsnmp_tdata_extract_entry (request); tinfo = netsnmp_extract_table_info (request); /* * The mteEventSetTable should only contains entries for * rows where the mteEventActions 'set(1)' bit is set. * So skip entries where this isn't the case. */ if (!entry || !(entry->mteEventActions & MTE_EVENT_SET)) continue; switch (tinfo->colnum) { case COLUMN_MTEEVENTSETOBJECT: snmp_set_var_typed_value (request->requestvb, ASN_OBJECT_ID, (u_char *) entry->mteSetOID, entry->mteSetOID_len * sizeof (oid)); break; case COLUMN_MTEEVENTSETOBJECTWILDCARD: ret = (entry->flags & MTE_SET_FLAG_OBJWILD) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, ret); break; case COLUMN_MTEEVENTSETVALUE: snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, entry->mteSetValue); break; case COLUMN_MTEEVENTSETTARGETTAG: snmp_set_var_typed_value (request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteSetTarget, strlen (entry->mteSetTarget)); break; case COLUMN_MTEEVENTSETCONTEXTNAME: snmp_set_var_typed_value (request->requestvb, ASN_OCTET_STR, (u_char *) entry->mteSetContext, strlen (entry->mteSetContext)); break; case COLUMN_MTEEVENTSETCONTEXTNAMEWILDCARD: ret = (entry->flags & MTE_SET_FLAG_CTXWILD) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, ret); break; } } break; #ifndef NETSNMP_NO_WRITE_SUPPORT /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info (request); /* * Since the mteEventSetTable only contains entries for * rows where the mteEventActions 'set(1)' bit is set, * strictly speaking we should reject assignments where * this isn't the case. * But SET requests that include an assignment of the * 'set(1)' bit at the same time are valid, so would * need to be accepted. Unfortunately, this assignment * is only applied in the COMMIT pass, so it's difficult * to detect whether this holds or not. * * Let's fudge things for now, by processing assignments * even if the 'set(1)' bit isn't set. */ switch (tinfo->colnum) { case COLUMN_MTEEVENTSETOBJECT: ret = netsnmp_check_vb_oid (request->requestvb); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error (reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTEEVENTSETOBJECTWILDCARD: case COLUMN_MTEEVENTSETCONTEXTNAMEWILDCARD: ret = netsnmp_check_vb_truthvalue (request->requestvb); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error (reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTEEVENTSETVALUE: ret = netsnmp_check_vb_int (request->requestvb); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error (reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTEEVENTSETTARGETTAG: case COLUMN_MTEEVENTSETCONTEXTNAME: ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OCTET_STR, MTE_STR2_LEN); 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; } /* * The Event MIB is somewhat ambiguous as to whether * mteEventSetTable (and mteEventNotificationTable) * entries can be modified once the main mteEventTable * entry has been marked 'active'. * But it's clear from discussion on the DisMan mailing * list is that the intention is not. * * So check for whether this row is already active, * and reject *all* SET requests if it is. */ entry = (struct mteEvent *) netsnmp_tdata_extract_entry (request); if (entry && entry->flags & MTE_EVENT_FLAG_ACTIVE) { netsnmp_set_request_error (reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_NOERROR; } } break; case MODE_SET_RESERVE2: case MODE_SET_FREE: case MODE_SET_UNDO: break; case MODE_SET_ACTION: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteEvent *) netsnmp_tdata_extract_entry (request); if (!entry) { /* * New rows must be created via the RowStatus column * (in the main mteEventTable) */ netsnmp_set_request_error (reqinfo, request, SNMP_ERR_NOCREATION); /* or inconsistentName? */ return SNMP_ERR_NOERROR; } } break; case MODE_SET_COMMIT: /* * All these assignments are "unfailable", so it's * (reasonably) safe to apply them in the Commit phase */ for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteEvent *) netsnmp_tdata_extract_entry (request); tinfo = netsnmp_extract_table_info (request); switch (tinfo->colnum) { case COLUMN_MTEEVENTSETOBJECT: memset (entry->mteSetOID, 0, sizeof (entry->mteSetOID)); memcpy (entry->mteSetOID, request->requestvb->val.objid, request->requestvb->val_len); entry->mteSetOID_len = request->requestvb->val_len / sizeof (oid); break; case COLUMN_MTEEVENTSETOBJECTWILDCARD: if (*request->requestvb->val.integer == TV_TRUE) entry->flags |= MTE_SET_FLAG_OBJWILD; else entry->flags &= ~MTE_SET_FLAG_OBJWILD; break; case COLUMN_MTEEVENTSETVALUE: entry->mteSetValue = *request->requestvb->val.integer; break; case COLUMN_MTEEVENTSETTARGETTAG: memset (entry->mteSetTarget, 0, sizeof (entry->mteSetTarget)); memcpy (entry->mteSetTarget, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTEEVENTSETCONTEXTNAME: memset (entry->mteSetContext, 0, sizeof (entry->mteSetContext)); memcpy (entry->mteSetContext, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTEEVENTSETCONTEXTNAMEWILDCARD: if (*request->requestvb->val.integer == TV_TRUE) entry->flags |= MTE_SET_FLAG_CTXWILD; else entry->flags &= ~MTE_SET_FLAG_CTXWILD; break; } } break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } return SNMP_ERR_NOERROR; }
/** handles requests for the schedTable table */ int schedTable_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 *tinfo; netsnmp_tdata_row *row; struct schedTable_entry *entry; int recalculate = 0; size_t len; char *cp; char owner[SCHED_STR1_LEN+1]; char name[ SCHED_STR1_LEN+1]; int ret; DEBUGMSGTL(("disman:schedule:mib", "Schedule handler (%d)\n", reqinfo->mode)); switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct schedTable_entry *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info( request); switch (tinfo->colnum) { case COLUMN_SCHEDDESCR: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->schedDescr, strlen(entry->schedDescr)); break; case COLUMN_SCHEDINTERVAL: snmp_set_var_typed_integer(request->requestvb, ASN_UNSIGNED, entry->schedInterval); break; case COLUMN_SCHEDWEEKDAY: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, &entry->schedWeekDay, sizeof(entry->schedWeekDay)); break; case COLUMN_SCHEDMONTH: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->schedMonth, sizeof(entry->schedMonth)); break; case COLUMN_SCHEDDAY: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->schedDay, sizeof(entry->schedDay)); break; case COLUMN_SCHEDHOUR: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->schedHour, sizeof(entry->schedHour)); break; case COLUMN_SCHEDMINUTE: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->schedMinute, sizeof(entry->schedMinute)); break; case COLUMN_SCHEDCONTEXTNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->schedContextName, strlen(entry->schedContextName)); break; case COLUMN_SCHEDVARIABLE: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)entry->schedVariable, entry->schedVariable_len*sizeof(oid)); break; case COLUMN_SCHEDVALUE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->schedValue); break; case COLUMN_SCHEDTYPE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->schedType); break; case COLUMN_SCHEDADMINSTATUS: ret = (entry->flags & SCHEDULE_FLAG_ENABLED ) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_SCHEDOPERSTATUS: ret = (entry->flags & SCHEDULE_FLAG_ENABLED ) ? TV_TRUE : TV_FALSE; /* * Check for one-shot entries that have already fired */ if ((entry->schedType == SCHED_TYPE_ONESHOT) && (entry->schedLastRun != 0 )) ret = 3; /* finished(3) */ snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_SCHEDFAILURES: snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER, entry->schedFailures); break; case COLUMN_SCHEDLASTFAILURE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->schedLastFailure); break; case COLUMN_SCHEDLASTFAILED: /* * Convert 'schedLastFailed' timestamp * into DateAndTime string */ cp = (char *) date_n_time( &entry->schedLastFailed, &len ); snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, cp, len); break; case COLUMN_SCHEDSTORAGETYPE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->schedStorageType); break; case COLUMN_SCHEDROWSTATUS: ret = (entry->flags & SCHEDULE_FLAG_ACTIVE ) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_SCHEDTRIGGERS: snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER, entry->schedTriggers); break; } } break; /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct schedTable_entry *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info( request); switch (tinfo->colnum) { case COLUMN_SCHEDDESCR: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, SCHED_STR2_LEN); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDINTERVAL: ret = netsnmp_check_vb_uint( request->requestvb ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDWEEKDAY: ret = netsnmp_check_vb_type_and_size( request->requestvb, ASN_OCTET_STR, 1); /* XXX - check for bit(7) set */ if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDMONTH: ret = netsnmp_check_vb_type_and_size( /* max_size ?? */ request->requestvb, ASN_OCTET_STR, 2); /* XXX - check for bit(12)-bit(15) set */ if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDDAY: ret = netsnmp_check_vb_type_and_size( /* max_size ?? */ request->requestvb, ASN_OCTET_STR, 4+4); /* XXX - check for bit(62) or bit(63) set */ if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDHOUR: ret = netsnmp_check_vb_type_and_size( /* max_size ?? */ request->requestvb, ASN_OCTET_STR, 3); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDMINUTE: ret = netsnmp_check_vb_type_and_size( /* max_size ?? */ request->requestvb, ASN_OCTET_STR, 8); /* XXX - check for bit(60)-bit(63) set */ if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDCONTEXTNAME: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, SCHED_STR1_LEN); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDVARIABLE: ret = netsnmp_check_vb_oid( request->requestvb ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDVALUE: ret = netsnmp_check_vb_int( request->requestvb ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDTYPE: ret = netsnmp_check_vb_int_range( request->requestvb, SCHED_TYPE_PERIODIC, SCHED_TYPE_ONESHOT ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDADMINSTATUS: ret = netsnmp_check_vb_truthvalue( request->requestvb ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDSTORAGETYPE: ret = netsnmp_check_vb_int_range( request->requestvb, ST_NONE, ST_READONLY ); /* XXX - check valid/consistent assignments */ if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_SCHEDROWSTATUS: ret = netsnmp_check_vb_rowstatus( request->requestvb, (entry ? RS_ACTIVE: RS_NONEXISTENT)); /* XXX - check consistency assignments */ 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; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_SCHEDROWSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Create an (empty) new row structure */ memset(owner, 0, SCHED_STR1_LEN+1); memset(name, 0, SCHED_STR1_LEN+1); memcpy(owner, tinfo->indexes->val.string, tinfo->indexes->val_len); memcpy(name, tinfo->indexes->next_variable->val.string, tinfo->indexes->next_variable->val_len); row = schedTable_createEntry(owner, name); if (!row) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } netsnmp_insert_tdata_row(request, row); } } } break; case MODE_SET_FREE: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_SCHEDROWSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Tidy up after a failed row creation request */ entry = (struct schedTable_entry *) netsnmp_tdata_extract_entry(request); if (entry && !(entry->flags & SCHEDULE_FLAG_VALID)) { row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); schedTable_removeEntry(row); } } } } break; case MODE_SET_ACTION: for (request = requests; request; request = request->next) { entry = (struct schedTable_entry *) netsnmp_tdata_extract_entry(request); if (!entry) { /* * New rows must be created via the RowStatus column */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); /* or inconsistentName? */ return SNMP_ERR_NOERROR; } } break; case MODE_SET_UNDO: break; case MODE_SET_COMMIT: /* * All these assignments are "unfailable", so it's * (reasonably) safe to apply them in the Commit phase */ entry = NULL; for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct schedTable_entry *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info( request); switch (tinfo->colnum) { case COLUMN_SCHEDDESCR: memset(entry->schedDescr, 0, sizeof(entry->schedDescr)); memcpy(entry->schedDescr, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_SCHEDINTERVAL: entry->schedInterval = *request->requestvb->val.integer; recalculate = 1; break; case COLUMN_SCHEDWEEKDAY: entry->schedWeekDay = request->requestvb->val.string[0]; recalculate = 1; break; case COLUMN_SCHEDMONTH: entry->schedMonth[0] = request->requestvb->val.string[0]; entry->schedMonth[1] = request->requestvb->val.string[1]; recalculate = 1; break; case COLUMN_SCHEDDAY: memset(entry->schedDay, 0, sizeof(entry->schedDay)); memcpy(entry->schedDay, request->requestvb->val.string, request->requestvb->val_len); recalculate = 1; break; case COLUMN_SCHEDHOUR: entry->schedHour[0] = request->requestvb->val.string[0]; entry->schedHour[1] = request->requestvb->val.string[1]; entry->schedHour[2] = request->requestvb->val.string[2]; recalculate = 1; break; case COLUMN_SCHEDMINUTE: memset(entry->schedMinute, 0, sizeof(entry->schedMinute)); memcpy(entry->schedMinute, request->requestvb->val.string, request->requestvb->val_len); recalculate = 1; break; case COLUMN_SCHEDCONTEXTNAME: memset(entry->schedContextName, 0, sizeof(entry->schedContextName)); memcpy(entry->schedContextName, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_SCHEDVARIABLE: memset(entry->schedVariable, 0, sizeof(entry->schedVariable)); memcpy(entry->schedVariable, request->requestvb->val.string, request->requestvb->val_len); entry->schedVariable_len = request->requestvb->val_len/sizeof(oid); break; case COLUMN_SCHEDVALUE: entry->schedValue = *request->requestvb->val.integer; break; case COLUMN_SCHEDTYPE: entry->schedType = *request->requestvb->val.integer; break; case COLUMN_SCHEDADMINSTATUS: if (*request->requestvb->val.integer == TV_TRUE) entry->flags |= SCHEDULE_FLAG_ENABLED; else entry->flags &= ~SCHEDULE_FLAG_ENABLED; break; case COLUMN_SCHEDSTORAGETYPE: entry->schedStorageType = *request->requestvb->val.integer; break; case COLUMN_SCHEDROWSTATUS: switch (*request->requestvb->val.integer) { case RS_ACTIVE: entry->flags |= SCHEDULE_FLAG_ACTIVE; break; case RS_CREATEANDGO: entry->flags |= SCHEDULE_FLAG_ACTIVE; entry->flags |= SCHEDULE_FLAG_VALID; entry->session = netsnmp_iquery_pdu_session(reqinfo->asp->pdu); break; case RS_CREATEANDWAIT: entry->flags |= SCHEDULE_FLAG_VALID; entry->session = netsnmp_iquery_pdu_session(reqinfo->asp->pdu); break; case RS_DESTROY: row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); schedTable_removeEntry(row); } recalculate = 1; break; } } if (recalculate) { netsnmp_assert(entry); sched_nextTime(entry); } break; } return SNMP_ERR_NOERROR; }
/******************************************************************************* 函数名称 : mib_historyControlTable_handler 功能描述 : handles requests for the historyControlTable table 输入参数 : 输出参数 : 返 回 值 : -------------------------------------------------------------------------------- 最近一次修改记录 : 修改作者 : 修改目的 : 修改日期 : *******************************************************************************/ static int mib_historyControlTable_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_req_info; struct historyControlTable_entry *table_entry; int ret; switch (reqinfo->mode) { /* * 这里的GET操作已经覆盖了GET_NEXT操作 */ case MODE_GET: for (request=requests; request; request=request->next) { table_entry = (struct historyControlTable_entry *) netsnmp_extract_iterator_context(request); table_req_info = netsnmp_extract_table_info(request); if(NULL == table_req_info) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOACCESS); continue; } switch (table_req_info->colnum) { case COLUMN_HISTORYCONTROLINDEX: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, htonl(table_entry->historyControlIndex)); break; case COLUMN_HISTORYCONTROLDATASOURCE: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_value( request->requestvb, ASN_OBJECT_ID, (u_char*)table_entry->historyControlDataSource, table_entry->historyControlDataSource_len); break; case COLUMN_HISTORYCONTROLBUCKETSREQUESTED: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, htonl(table_entry->historyControlBucketsRequested)); break; case COLUMN_HISTORYCONTROLBUCKETSGRANTED: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, htonl(table_entry->historyControlBucketsGranted)); break; case COLUMN_HISTORYCONTROLINTERVAL: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, htonl(table_entry->historyControlInterval)); break; case COLUMN_HISTORYCONTROLOWNER: 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->historyControlOwner, table_entry->historyControlOwner_len); break; case COLUMN_HISTORYCONTROLSTATUS: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, htonl(table_entry->historyControlStatus)); break; default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); break; } } break; /* * SET 操作 */ case MODE_SET_RESERVE1: /* SET第一阶段,检查参数类型 */ for (request=requests; request; request=request->next) { table_entry = (struct historyControlTable_entry *) netsnmp_extract_iterator_context(request); table_req_info = netsnmp_extract_table_info(request); if(NULL == table_req_info) { netsnmp_set_request_error( reqinfo, request, SNMP_ERR_NOACCESS ); return SNMP_ERR_NOERROR; } switch (table_req_info->colnum) { case COLUMN_HISTORYCONTROLDATASOURCE: /* or possibly 'netsnmp_check_vb_type_and_size' */ ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OBJECT_ID, sizeof(table_entry->historyControlDataSource)); if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error( reqinfo, request, ret ); return SNMP_ERR_NOERROR; } break; case COLUMN_HISTORYCONTROLBUCKETSREQUESTED: /* or possibly 'netsnmp_check_vb_int_range' */ ret = netsnmp_check_vb_int( request->requestvb ); if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error( reqinfo, request, ret ); return SNMP_ERR_NOERROR; } break; case COLUMN_HISTORYCONTROLINTERVAL: /* or possibly 'netsnmp_check_vb_int_range' */ ret = netsnmp_check_vb_int( request->requestvb ); if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error( reqinfo, request, ret ); return SNMP_ERR_NOERROR; } break; case COLUMN_HISTORYCONTROLOWNER: /* or possibly 'netsnmp_check_vb_type_and_size' */ ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, sizeof(table_entry->historyControlOwner)); if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error( reqinfo, request, ret ); return SNMP_ERR_NOERROR; } break; case COLUMN_HISTORYCONTROLSTATUS: /* or possibly 'netsnmp_check_vb_int_range' */ ret = netsnmp_check_vb_int( request->requestvb ); 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: /* 出错处理,MODE_SET_RESERVE1或MODE_SET_RESERVE2出错时调用。 需要释放第一阶段和第二阶段分配的内存 */ for (request=requests; request; request=request->next) { table_entry = (struct historyControlTable_entry *) netsnmp_extract_iterator_context(request); table_req_info = netsnmp_extract_table_info( request); switch (table_req_info->colnum) { case COLUMN_HISTORYCONTROLDATASOURCE: case COLUMN_HISTORYCONTROLBUCKETSREQUESTED: case COLUMN_HISTORYCONTROLINTERVAL: case COLUMN_HISTORYCONTROLOWNER: case COLUMN_HISTORYCONTROLSTATUS: if ( table_entry && table_entry->new_record ) { mib_historyControlTable_removeEntry(table_entry ); (void)netsnmp_remove_iterator_context(request); } break; } } break; case MODE_SET_ACTION: /* SET第三阶段,执行设置值的具体动作 */ for (request=requests; request; request=request->next) { table_entry = (struct historyControlTable_entry *) netsnmp_extract_iterator_context(request); table_req_info = netsnmp_extract_table_info(request); switch (table_req_info->colnum) { case COLUMN_HISTORYCONTROLDATASOURCE: memcpy( table_entry->old_historyControlDataSource, table_entry->historyControlDataSource, sizeof(table_entry->historyControlDataSource)); table_entry->old_historyControlDataSource_len = table_entry->historyControlDataSource_len; memset( table_entry->historyControlDataSource, 0, sizeof(table_entry->historyControlDataSource)); memcpy( table_entry->historyControlDataSource, request->requestvb->val.string, request->requestvb->val_len); table_entry->historyControlDataSource_len = request->requestvb->val_len; break; case COLUMN_HISTORYCONTROLBUCKETSREQUESTED: table_entry->old_historyControlBucketsRequested = table_entry->historyControlBucketsRequested; table_entry->historyControlBucketsRequested = *request->requestvb->val.integer; break; case COLUMN_HISTORYCONTROLINTERVAL: table_entry->old_historyControlInterval = table_entry->historyControlInterval; table_entry->historyControlInterval = *request->requestvb->val.integer; break; case COLUMN_HISTORYCONTROLOWNER: memcpy( table_entry->old_historyControlOwner, table_entry->historyControlOwner, sizeof(table_entry->historyControlOwner)); table_entry->old_historyControlOwner_len = table_entry->historyControlOwner_len; memset( table_entry->historyControlOwner, 0, sizeof(table_entry->historyControlOwner)); memcpy( table_entry->historyControlOwner, request->requestvb->val.string, request->requestvb->val_len); table_entry->historyControlOwner_len = request->requestvb->val_len; break; case COLUMN_HISTORYCONTROLSTATUS: table_entry->old_historyControlStatus = table_entry->historyControlStatus; table_entry->historyControlStatus = *request->requestvb->val.integer; break; } } break; case MODE_SET_COMMIT: /* SET第四阶段,提交设置的值,并释放第三阶段的内存 */ for (request=requests; request; request=request->next) { table_entry = (struct historyControlTable_entry *) netsnmp_extract_iterator_context(request); table_req_info = netsnmp_extract_table_info( request); switch (table_req_info->colnum) { case COLUMN_HISTORYCONTROLDATASOURCE: case COLUMN_HISTORYCONTROLBUCKETSREQUESTED: case COLUMN_HISTORYCONTROLINTERVAL: case COLUMN_HISTORYCONTROLOWNER: case COLUMN_HISTORYCONTROLSTATUS: if ( table_entry && table_entry->new_record ) { mib_historyControlTable_removeEntry( table_entry ); (void)netsnmp_remove_iterator_context(request); } } } break; case MODE_SET_UNDO: /* 出错处理,MODE_SET_ACTION出错时调用 需要释放第三阶段分配的内存 */ for (request=requests; request; request=request->next) { table_entry = (struct historyControlTable_entry *) netsnmp_extract_iterator_context(request); table_req_info = netsnmp_extract_table_info( request); switch (table_req_info->colnum) { case COLUMN_HISTORYCONTROLDATASOURCE: if ( table_entry && table_entry->new_record ) { mib_historyControlTable_removeEntry( table_entry ); (void)netsnmp_remove_iterator_context(request); } else if (table_entry) { memcpy( table_entry->historyControlDataSource, table_entry->old_historyControlDataSource, sizeof(table_entry->historyControlDataSource)); memset( table_entry->old_historyControlDataSource, 0, sizeof(table_entry->historyControlDataSource)); table_entry->historyControlDataSource_len = table_entry->old_historyControlDataSource_len; } break; case COLUMN_HISTORYCONTROLBUCKETSREQUESTED: if ( table_entry && table_entry->new_record ) { mib_historyControlTable_removeEntry( table_entry ); (void)netsnmp_remove_iterator_context(request); } else if (table_entry) { table_entry->historyControlBucketsRequested = table_entry->old_historyControlBucketsRequested; table_entry->old_historyControlBucketsRequested = 0; } break; case COLUMN_HISTORYCONTROLINTERVAL: if ( table_entry && table_entry->new_record ) { mib_historyControlTable_removeEntry( table_entry ); (void)netsnmp_remove_iterator_context(request); } else if (table_entry) { table_entry->historyControlInterval = table_entry->old_historyControlInterval; table_entry->old_historyControlInterval = 0; } break; case COLUMN_HISTORYCONTROLOWNER: if ( table_entry && table_entry->new_record ) { mib_historyControlTable_removeEntry( table_entry ); (void)netsnmp_remove_iterator_context(request); } else if (table_entry) { memcpy( table_entry->historyControlOwner, table_entry->old_historyControlOwner, sizeof(table_entry->historyControlOwner)); memset( table_entry->old_historyControlOwner, 0, sizeof(table_entry->historyControlOwner)); table_entry->historyControlOwner_len = table_entry->old_historyControlOwner_len; } break; case COLUMN_HISTORYCONTROLSTATUS: if ( table_entry && table_entry->new_record ) { mib_historyControlTable_removeEntry( table_entry ); (void)netsnmp_remove_iterator_context(request); } else if (table_entry) { table_entry->historyControlStatus = table_entry->old_historyControlStatus; table_entry->old_historyControlStatus = 0; } break; } } break; } return SNMP_ERR_NOERROR; }
/** handles requests for the mteTriggerTable table */ int mteTriggerTable_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 *tinfo; netsnmp_tdata_row *row; struct mteTrigger *entry; char mteOwner[MTE_STR1_LEN+1]; char mteTName[MTE_STR1_LEN+1]; long ret; DEBUGMSGTL(("disman:event:mib", "Trigger Table handler (%d)\n", reqinfo->mode)); switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTETRIGGERCOMMENT: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->mteTriggerComment, strlen(entry->mteTriggerComment)); break; case COLUMN_MTETRIGGERTEST: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, &entry->mteTriggerTest, 1); break; case COLUMN_MTETRIGGERSAMPLETYPE: ret = (entry->flags & MTE_TRIGGER_FLAG_DELTA ) ? MTE_SAMPLE_DELTA : MTE_SAMPLE_ABSOLUTE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_MTETRIGGERVALUEID: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *) entry->mteTriggerValueID, entry->mteTriggerValueID_len*sizeof(oid)); break; case COLUMN_MTETRIGGERVALUEIDWILDCARD: ret = (entry->flags & MTE_TRIGGER_FLAG_VWILD ) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_MTETRIGGERTARGETTAG: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->mteTriggerTarget, strlen(entry->mteTriggerTarget)); break; case COLUMN_MTETRIGGERCONTEXTNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->mteTriggerContext, strlen(entry->mteTriggerContext)); break; case COLUMN_MTETRIGGERCONTEXTNAMEWILDCARD: ret = (entry->flags & MTE_TRIGGER_FLAG_CWILD ) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_MTETRIGGERFREQUENCY: snmp_set_var_typed_integer(request->requestvb, ASN_UNSIGNED, entry->mteTriggerFrequency); break; case COLUMN_MTETRIGGEROBJECTSOWNER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->mteTriggerOOwner, strlen(entry->mteTriggerOOwner)); break; case COLUMN_MTETRIGGEROBJECTS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->mteTriggerObjects, strlen(entry->mteTriggerObjects)); break; case COLUMN_MTETRIGGERENABLED: ret = (entry->flags & MTE_TRIGGER_FLAG_ENABLED ) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_MTETRIGGERENTRYSTATUS: ret = (entry->flags & MTE_TRIGGER_FLAG_ACTIVE ) ? RS_ACTIVE : RS_NOTINSERVICE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; } } break; #ifndef NETSNMP_NO_WRITE_SUPPORT /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTETRIGGERCOMMENT: case COLUMN_MTETRIGGERTARGETTAG: case COLUMN_MTETRIGGERCONTEXTNAME: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, MTE_STR2_LEN); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGERTEST: ret = netsnmp_check_vb_type_and_size( request->requestvb, ASN_OCTET_STR, 1); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGERSAMPLETYPE: ret = netsnmp_check_vb_int_range(request->requestvb, MTE_SAMPLE_ABSOLUTE, MTE_SAMPLE_DELTA); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGERVALUEID: ret = netsnmp_check_vb_oid(request->requestvb); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGERVALUEIDWILDCARD: case COLUMN_MTETRIGGERCONTEXTNAMEWILDCARD: case COLUMN_MTETRIGGERENABLED: ret = netsnmp_check_vb_truthvalue(request->requestvb); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGERFREQUENCY: ret = netsnmp_check_vb_uint(request->requestvb); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGEROBJECTSOWNER: case COLUMN_MTETRIGGEROBJECTS: ret = netsnmp_check_vb_type_and_max_size( request->requestvb, ASN_OCTET_STR, MTE_STR1_LEN); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } break; case COLUMN_MTETRIGGERENTRYSTATUS: ret = netsnmp_check_vb_rowstatus(request->requestvb, (entry ? RS_ACTIVE : RS_NONEXISTENT)); 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; } /* * Once a row has been made active, it cannot be * modified except to delete it. There's no good * reason for this, but that's what the MIB says. * * The published version of the Event MIB even forbids * enabling (or disabling) an active row, which * would make this object completely pointless! * Fortunately this ludicrous decision has since been corrected. */ if (entry && entry->flags & MTE_TRIGGER_FLAG_ACTIVE ) { /* check for the acceptable assignments */ if ((tinfo->colnum == COLUMN_MTETRIGGERENABLED) || (tinfo->colnum == COLUMN_MTETRIGGERENTRYSTATUS && *request->requestvb->val.integer != RS_NOTINSERVICE)) continue; /* Otherwise, reject this request */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_NOERROR; } } break; case MODE_SET_RESERVE2: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTETRIGGERENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Create an (empty) new row structure */ memset(mteOwner, 0, sizeof(mteOwner)); memcpy(mteOwner, tinfo->indexes->val.string, tinfo->indexes->val_len); memset(mteTName, 0, sizeof(mteTName)); memcpy(mteTName, tinfo->indexes->next_variable->val.string, tinfo->indexes->next_variable->val_len); row = mteTrigger_createEntry(mteOwner, mteTName, 0); if (!row) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } netsnmp_insert_tdata_row( request, row ); } } } break; case MODE_SET_FREE: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTETRIGGERENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Tidy up after a failed row creation request */ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); if (entry && !(entry->flags & MTE_TRIGGER_FLAG_VALID)) { row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); mteTrigger_removeEntry( row ); } } } } break; case MODE_SET_ACTION: for (request = requests; request; request = request->next) { if (request->processed) continue; tinfo = netsnmp_extract_table_info(request); entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); if (!entry) { /* * New rows must be created via the RowStatus column */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); /* or inconsistentName? */ return SNMP_ERR_NOERROR; } } break; case MODE_SET_UNDO: break; case MODE_SET_COMMIT: /* * All these assignments are "unfailable", so it's * (reasonably) safe to apply them in the Commit phase */ for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTETRIGGERCOMMENT: memset(entry->mteTriggerComment, 0, sizeof(entry->mteTriggerComment)); memcpy(entry->mteTriggerComment, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERTEST: entry->mteTriggerTest = request->requestvb->val.string[0]; break; case COLUMN_MTETRIGGERSAMPLETYPE: if (*request->requestvb->val.integer == MTE_SAMPLE_DELTA) entry->flags |= MTE_TRIGGER_FLAG_DELTA; else entry->flags &= ~MTE_TRIGGER_FLAG_DELTA; break; case COLUMN_MTETRIGGERVALUEID: memset(entry->mteTriggerValueID, 0, sizeof(entry->mteTriggerValueID)); memcpy(entry->mteTriggerValueID, request->requestvb->val.string, request->requestvb->val_len); entry->mteTriggerValueID_len = request->requestvb->val_len/sizeof(oid); break; case COLUMN_MTETRIGGERVALUEIDWILDCARD: if (*request->requestvb->val.integer == TV_TRUE) entry->flags |= MTE_TRIGGER_FLAG_VWILD; else entry->flags &= ~MTE_TRIGGER_FLAG_VWILD; break; case COLUMN_MTETRIGGERTARGETTAG: memset(entry->mteTriggerTarget, 0, sizeof(entry->mteTriggerTarget)); memcpy(entry->mteTriggerTarget, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERCONTEXTNAME: memset(entry->mteTriggerContext, 0, sizeof(entry->mteTriggerContext)); memcpy(entry->mteTriggerContext, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERCONTEXTNAMEWILDCARD: if (*request->requestvb->val.integer == TV_TRUE) entry->flags |= MTE_TRIGGER_FLAG_CWILD; else entry->flags &= ~MTE_TRIGGER_FLAG_CWILD; break; case COLUMN_MTETRIGGERFREQUENCY: entry->mteTriggerFrequency = *request->requestvb->val.integer; break; case COLUMN_MTETRIGGEROBJECTSOWNER: memset(entry->mteTriggerOOwner, 0, sizeof(entry->mteTriggerOOwner)); memcpy(entry->mteTriggerOOwner, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGEROBJECTS: memset(entry->mteTriggerObjects, 0, sizeof(entry->mteTriggerObjects)); memcpy(entry->mteTriggerObjects, request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_MTETRIGGERENABLED: if (*request->requestvb->val.integer == TV_TRUE) entry->flags |= MTE_TRIGGER_FLAG_ENABLED; else entry->flags &= ~MTE_TRIGGER_FLAG_ENABLED; break; case COLUMN_MTETRIGGERENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_ACTIVE: entry->flags |= MTE_TRIGGER_FLAG_ACTIVE; mteTrigger_enable( entry ); break; case RS_CREATEANDGO: entry->flags |= MTE_TRIGGER_FLAG_ACTIVE; entry->flags |= MTE_TRIGGER_FLAG_VALID; entry->session = netsnmp_iquery_pdu_session(reqinfo->asp->pdu); mteTrigger_enable( entry ); break; case RS_CREATEANDWAIT: entry->flags |= MTE_TRIGGER_FLAG_VALID; entry->session = netsnmp_iquery_pdu_session(reqinfo->asp->pdu); break; case RS_DESTROY: row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); mteTrigger_removeEntry(row); } break; } } /** set up to save persistent store */ snmp_store_needed(NULL); break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } return SNMP_ERR_NOERROR; }