/** 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; }
int write_snmpNotifyTag(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { static char *tmpvar; struct snmpNotifyTable_data *StorageTmp = NULL; static size_t tmplen; size_t newlen = name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + 3 - 1); DEBUGMSGTL(("snmpNotifyTable", "write_snmpNotifyTag entering action=%d... \n", action)); if (action != RESERVE1 && (StorageTmp = (struct snmpNotifyTable_data *) header_complex((struct header_complex_index *) snmpNotifyTableStorage, NULL, &name[sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) { if ((StorageTmp = StorageNew) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ } switch (action) { case RESERVE1: if (var_val_type != ASN_OCTET_STR) { return SNMP_ERR_WRONGTYPE; } if (var_val_len > 255) { return SNMP_ERR_WRONGLENGTH; } if (!snmpTagValid((char *) var_val, var_val_len)) { return SNMP_ERR_WRONGVALUE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ tmpvar = StorageTmp->snmpNotifyTag; tmplen = StorageTmp->snmpNotifyTagLen; StorageTmp->snmpNotifyTag = (char*)calloc(1, var_val_len + 1); if (NULL == StorageTmp->snmpNotifyTag) return SNMP_ERR_RESOURCEUNAVAILABLE; break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: memcpy(StorageTmp->snmpNotifyTag, var_val, var_val_len); StorageTmp->snmpNotifyTagLen = var_val_len; break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->snmpNotifyTag); StorageTmp->snmpNotifyTag = tmpvar; StorageTmp->snmpNotifyTagLen = tmplen; tmpvar = NULL; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
int write_snmpNotifyRowStatus(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { struct snmpNotifyTable_data *StorageTmp = NULL; static struct snmpNotifyTable_data *StorageDel; size_t newlen = name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + 3 - 1); static int old_value; int set_value = *((long *) var_val); static netsnmp_variable_list *vars, *vp; struct header_complex_index *hciptr; DEBUGMSGTL(("snmpNotifyTable", "write_snmpNotifyRowStatus entering action=%d... \n", action)); StorageTmp = (struct snmpNotifyTable_data *) header_complex((struct header_complex_index *) snmpNotifyTableStorage, NULL, &name[sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER || var_val == NULL) { return SNMP_ERR_WRONGTYPE; } if (var_val_len != sizeof(long)) { return SNMP_ERR_WRONGLENGTH; } if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) { return SNMP_ERR_WRONGVALUE; } if (StorageTmp == NULL) { /* * create the row now? */ /* * ditch illegal values now */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } } else { /* * row exists. Check for a valid state change */ if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) { /* * can't create a row that exists */ return SNMP_ERR_INCONSISTENTVALUE; } /* * XXX: interaction with row storage type needed */ } /* * memory reseveration, final preparation... */ if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * creation */ vars = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0); /* snmpNotifyName */ if (header_complex_parse_oid (& (name [sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { /* * XXX: free, zero vars */ snmp_free_var(vars); return SNMP_ERR_INCONSISTENTNAME; } vp = vars; StorageNew = SNMP_MALLOC_STRUCT(snmpNotifyTable_data); if (StorageNew == NULL) { return SNMP_ERR_RESOURCEUNAVAILABLE; } StorageNew->snmpNotifyName = (char*)calloc( 1, vp->val_len + 1 ); if (StorageNew->snmpNotifyName == NULL) { return SNMP_ERR_RESOURCEUNAVAILABLE; } memcpy(StorageNew->snmpNotifyName, vp->val.string, vp->val_len); StorageNew->snmpNotifyNameLen = vp->val_len; vp = vp->next_variable; /* * default values */ StorageNew->snmpNotifyStorageType = ST_NONVOLATILE; StorageNew->snmpNotifyType = SNMPNOTIFYTYPE_TRAP; StorageNew->snmpNotifyTagLen = 0; StorageNew->snmpNotifyTag = (char *) calloc(sizeof(char), 1); if (StorageNew->snmpNotifyTag == NULL) { return SNMP_ERR_RESOURCEUNAVAILABLE; } StorageNew->snmpNotifyRowStatus = set_value; snmp_free_var(vars); } break; case RESERVE2: break; case FREE: if (StorageNew != NULL) { SNMP_FREE(StorageNew->snmpNotifyTag); SNMP_FREE(StorageNew->snmpNotifyName); free(StorageNew); StorageNew = NULL; } break; case ACTION: if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * row creation, so add it */ if (StorageNew != NULL) { snmpNotifyTable_add(StorageNew); } } else if (set_value != RS_DESTROY) { /* * set the flag? */ if (StorageTmp == NULL) return SNMP_ERR_GENERR; /* should never ever get here */ old_value = StorageTmp->snmpNotifyRowStatus; StorageTmp->snmpNotifyRowStatus = *((long *) var_val); } else { /* * destroy... extract it for now */ if (StorageTmp) { hciptr = header_complex_find_entry(snmpNotifyTableStorage, StorageTmp); StorageDel = (struct snmpNotifyTable_data *) header_complex_extract_entry((struct header_complex_index **) &snmpNotifyTableStorage, hciptr); } } break; case UNDO: /* * Back out any changes made in the ACTION case */ if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * row creation, so remove it again */ hciptr = header_complex_find_entry(snmpNotifyTableStorage, StorageNew); StorageDel = (struct snmpNotifyTable_data *) header_complex_extract_entry((struct header_complex_index **) &snmpNotifyTableStorage, hciptr); /* * XXX: free it */ } else if (StorageDel != NULL) { /* * row deletion, so add it again */ snmpNotifyTable_add(StorageDel); } else if (set_value != RS_DESTROY) { if (StorageTmp) StorageTmp->snmpNotifyRowStatus = old_value; } break; case COMMIT: if (StorageDel != NULL) { SNMP_FREE(StorageDel->snmpNotifyTag); SNMP_FREE(StorageDel->snmpNotifyName); free(StorageDel); StorageDel = NULL; } if (StorageTmp && StorageTmp->snmpNotifyRowStatus == RS_CREATEANDGO) { StorageTmp->snmpNotifyRowStatus = RS_ACTIVE; StorageNew = NULL; } else if (StorageTmp && StorageTmp->snmpNotifyRowStatus == RS_CREATEANDWAIT) { StorageTmp->snmpNotifyRowStatus = RS_NOTINSERVICE; StorageNew = NULL; } snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
int write_expObjectDeltaDiscontinuityID(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { static oid *tmpvar; struct expObjectTable_data *StorageTmp = NULL; static size_t tmplen; size_t newlen = name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) + 3 - 1); DEBUGMSGTL(("expObjectTable", "write_expObjectDeltaDiscontinuityID entering action=%d... \n", action)); if ((StorageTmp = header_complex(expObjectTableStorage, NULL, &name[sizeof(expObjectTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ switch (action) { case RESERVE1: if (var_val_type != ASN_OBJECT_ID) { snmp_log(LOG_ERR, "write to expObjectDeltaDiscontinuityID not ASN_OBJECT_ID\n"); return SNMP_ERR_WRONGTYPE; } if (StorageTmp->storageType != ST_NONVOLATILE) return SNMP_ERR_NOTWRITABLE; break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->expObjectDeltaDiscontinuityID; tmplen = StorageTmp->expObjectDeltaDiscontinuityIDLen; StorageTmp->expObjectDeltaDiscontinuityID = netsnmp_memdup(var_val, var_val_len); StorageTmp->expObjectDeltaDiscontinuityIDLen = var_val_len / sizeof(oid); break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->expObjectDeltaDiscontinuityID); StorageTmp->expObjectDeltaDiscontinuityID = tmpvar; StorageTmp->expObjectDeltaDiscontinuityIDLen = tmplen; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ /* * XXX: if the valueID has actually changed, shouldn't we dump any * previous values, as these are from a different object? */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
int write_expObjectDiscontinuityIDType(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { static int tmpvar; struct expObjectTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) + 3 - 1); DEBUGMSGTL(("expObjectTable", "write_expObjectDiscontinuityIDWildcard entering action=%d... \n", action)); if ((StorageTmp = header_complex(expObjectTableStorage, NULL, &name[sizeof(expObjectTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to expObjectDiscontinuityIDType not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } if (StorageTmp->storageType != ST_NONVOLATILE) return SNMP_ERR_NOTWRITABLE; break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in long_ret for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->expObjectDiscontinuityIDType; StorageTmp->expObjectDiscontinuityIDType = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->expObjectDiscontinuityIDType = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
int write_snmpNotifyFilterProfileRowStatus(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { struct snmpNotifyFilterProfileTable_data *StorageTmp = NULL; static struct snmpNotifyFilterProfileTable_data *StorageDel; size_t newlen = name_len - (sizeof(snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + 3 - 1); static int old_value; int set_value = *((long *) var_val); netsnmp_variable_list *vars; struct header_complex_index *hciptr; DEBUGMSGTL(("snmpNotifyFilterProfileTable", "write_snmpNotifyFilterProfileRowStatus entering action=%d... \n", action)); StorageTmp = (struct snmpNotifyFilterProfileTable_data *) header_complex((struct header_complex_index *) snmpNotifyFilterProfileTableStorage, NULL, &name[sizeof (snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER || var_val == NULL) { return SNMP_ERR_WRONGTYPE; } if (var_val_len != sizeof(long)) { return SNMP_ERR_WRONGLENGTH; } if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) { return SNMP_ERR_WRONGVALUE; } /* * stage one: test validity */ if (StorageTmp == NULL) { /* * create the row now? */ /* * ditch illegal values now */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } } else { /* * row exists. Check for a valid state change */ if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) { /* * can't create a row that exists */ return SNMP_ERR_INCONSISTENTVALUE; } if ((set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) && StorageTmp->snmpNotifyFilterProfileNameLen == 0) { /* * can't activate row without a profile name */ return SNMP_ERR_INCONSISTENTVALUE; } /* * XXX: interaction with row storage type needed */ } /* * memory reseveration, final preparation... */ if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * creation */ vars = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0); if (header_complex_parse_oid (& (name [sizeof(snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { snmp_free_var(vars); return SNMP_ERR_INCONSISTENTNAME; } StorageNew = SNMP_MALLOC_STRUCT(snmpNotifyFilterProfileTable_data); if (StorageNew == NULL) return SNMP_ERR_GENERR; memdup((u_char **) & (StorageNew->snmpTargetParamsName), vars->val.string, vars->val_len); StorageNew->snmpTargetParamsNameLen = vars->val_len; StorageNew->snmpNotifyFilterProfileStorType = ST_NONVOLATILE; StorageNew->snmpNotifyFilterProfileRowStatus = RS_NOTREADY; snmp_free_var(vars); } break; case RESERVE2: break; case FREE: /* * XXX: free, zero vars */ /* * Release any resources that have been allocated */ if (StorageNew != NULL) { SNMP_FREE(StorageNew->snmpTargetParamsName); SNMP_FREE(StorageNew->snmpNotifyFilterProfileName); free(StorageNew); StorageNew = NULL; } break; case ACTION: /* * The variable has been stored in set_value for you to * use, and you have just been asked to do something with * it. Note that anything done here must be reversable in * the UNDO case */ if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * row creation, so add it */ if (StorageNew != NULL) snmpNotifyFilterProfileTable_add(StorageNew); /* * XXX: ack, and if it is NULL? */ } else if (set_value != RS_DESTROY) { /* * set the flag? */ if (StorageTmp == NULL) return SNMP_ERR_GENERR; /* should never ever get here */ old_value = StorageTmp->snmpNotifyFilterProfileRowStatus; StorageTmp->snmpNotifyFilterProfileRowStatus = *((long *) var_val); } else { /* * destroy... extract it for now */ if (StorageTmp) { hciptr = header_complex_find_entry (snmpNotifyFilterProfileTableStorage, StorageTmp); StorageDel = (struct snmpNotifyFilterProfileTable_data *) header_complex_extract_entry((struct header_complex_index **) &snmpNotifyFilterProfileTableStorage, hciptr); } } break; case UNDO: /* * Back out any changes made in the ACTION case */ if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT)) { /* * row creation, so remove it again */ hciptr = header_complex_find_entry (snmpNotifyFilterProfileTableStorage, StorageNew); StorageDel = (struct snmpNotifyFilterProfileTable_data *) header_complex_extract_entry((struct header_complex_index **) &snmpNotifyFilterProfileTableStorage, hciptr); /* * XXX: free it */ } else if (StorageDel != NULL) { /* * row deletion, so add it again */ snmpNotifyFilterProfileTable_add(StorageDel); StorageDel = NULL; } else if (set_value != RS_DESTROY) { if (StorageTmp) StorageTmp->snmpNotifyFilterProfileRowStatus = old_value; } break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ if (StorageDel != NULL) { SNMP_FREE(StorageDel->snmpTargetParamsName); SNMP_FREE(StorageDel->snmpNotifyFilterProfileName); free(StorageDel); StorageDel = NULL; } if (StorageTmp && set_value == RS_CREATEANDGO) { if (StorageTmp->snmpNotifyFilterProfileNameLen) StorageTmp->snmpNotifyFilterProfileRowStatus = RS_ACTIVE; StorageNew = NULL; } else if (StorageTmp && set_value == RS_CREATEANDWAIT) { if (StorageTmp->snmpNotifyFilterProfileNameLen) StorageTmp->snmpNotifyFilterProfileRowStatus = RS_NOTINSERVICE; StorageNew = NULL; } snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
int write_expObjectEntryStatus(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { struct expObjectTable_data *StorageTmp = NULL; static struct expObjectTable_data *StorageNew, *StorageDel; size_t newlen = name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) + 3 - 1); static int old_value; int set_value; static netsnmp_variable_list *vars, *vp; struct header_complex_index *hciptr; StorageTmp = header_complex(expObjectTableStorage, NULL, &name[sizeof(expObjectTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); if (var_val_type != ASN_INTEGER || var_val == NULL) { snmp_log(LOG_ERR, "write to expObjectEntryStatus not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } set_value = *((long *) var_val); /* * check legal range, and notReady is reserved for us, not a user */ if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) return SNMP_ERR_INCONSISTENTVALUE; switch (action) { case RESERVE1: /* * stage one: test validity */ if (StorageTmp == NULL) { /* * create the row now? */ /* * ditch illegal values now */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) return SNMP_ERR_INCONSISTENTVALUE; /* * destroying a non-existent row is actually legal */ if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } /* * illegal creation values */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } } else { /* * row exists. Check for a valid state change */ if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) { /* * can't create a row that exists */ return SNMP_ERR_INCONSISTENTVALUE; } if (StorageTmp->expObjectEntryStatus == RS_ACTIVE && set_value != RS_DESTROY) { /* * "Once made active an entry may not be modified except to * delete it." XXX: doesn't this in fact apply to ALL * columns of the table and not just this one? */ return SNMP_ERR_INCONSISTENTVALUE; } if (StorageTmp->storageType != ST_NONVOLATILE) return SNMP_ERR_NOTWRITABLE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ if (StorageTmp == NULL) { /* * creation */ vars = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* expExpressionOwner */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* expExpressionName */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, NULL, 0); /* expObjectIndex */ if (header_complex_parse_oid (& (name [sizeof(expObjectTable_variables_oid) / sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { /* * XXX: free, zero vars */ return SNMP_ERR_INCONSISTENTNAME; } vp = vars; StorageNew = create_expObjectTable_data(); StorageNew->expExpressionOwner = malloc(vp->val_len + 1); memcpy(StorageNew->expExpressionOwner, vp->val.string, vp->val_len); StorageNew->expExpressionOwner[vp->val_len] = '\0'; StorageNew->expExpressionOwnerLen = vp->val_len; vp = vp->next_variable; StorageNew->expExpressionName = malloc(vp->val_len + 1); memcpy(StorageNew->expExpressionName, vp->val.string, vp->val_len); StorageNew->expExpressionName[vp->val_len] = '\0'; StorageNew->expExpressionNameLen = vp->val_len; vp = vp->next_variable; StorageNew->expObjectIndex = *vp->val.integer; StorageNew->expObjectEntryStatus = set_value; } break; case FREE: /* * XXX: free, zero vars */ /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in set_value for you to * use, and you have just been asked to do something with * it. Note that anything done here must be reversable in * the UNDO case */ if (StorageTmp == NULL) { /* * row creation, so add it */ if (StorageNew != NULL) expObjectTable_add(StorageNew); /* * XXX: ack, and if it is NULL? */ } else if (set_value != RS_DESTROY) { /* * set the flag? */ old_value = StorageTmp->expObjectEntryStatus; StorageTmp->expObjectEntryStatus = *((long *) var_val); } else { /* * destroy... extract it for now */ hciptr = header_complex_find_entry(expObjectTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&expObjectTableStorage, hciptr); } break; case UNDO: /* * Back out any changes made in the ACTION case */ if (StorageTmp == NULL) { /* * row creation, so remove it again */ hciptr = header_complex_find_entry(expObjectTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&expObjectTableStorage, hciptr); /* * XXX: free it */ } else if (StorageDel != NULL) { /* * row deletion, so add it again */ expObjectTable_add(StorageDel); } else { StorageTmp->expObjectEntryStatus = old_value; } break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ if (StorageDel != NULL) { StorageDel = 0; /* * XXX: free it, its dead */ } else { if (StorageTmp && StorageTmp->expObjectEntryStatus == RS_CREATEANDGO) { StorageTmp->expObjectEntryStatus = RS_ACTIVE; } else if (StorageTmp && StorageTmp->expObjectEntryStatus == RS_CREATEANDWAIT) { StorageTmp->expObjectEntryStatus = RS_NOTINSERVICE; } } snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
int write_snmpNotifyFilterProfileStorType(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { static int tmpvar; long value = *((long *) var_val); struct snmpNotifyFilterProfileTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + 3 - 1); DEBUGMSGTL(("snmpNotifyFilterProfileTable", "write_snmpNotifyFilterProfileStorType entering action=%d... \n", action)); if (action != RESERVE1 && (StorageTmp = (struct snmpNotifyFilterProfileTable_data *) header_complex((struct header_complex_index *) snmpNotifyFilterProfileTableStorage, NULL, &name[sizeof (snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) { if ((StorageTmp = StorageNew) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ } switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { return SNMP_ERR_WRONGTYPE; } if (var_val_len != sizeof(long)) { return SNMP_ERR_WRONGLENGTH; } if (value != SNMP_STORAGE_OTHER && value != SNMP_STORAGE_VOLATILE && value != SNMP_STORAGE_NONVOLATILE) { return SNMP_ERR_WRONGVALUE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in long_ret for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->snmpNotifyFilterProfileStorType; StorageTmp->snmpNotifyFilterProfileStorType = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->snmpNotifyFilterProfileStorType = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
int write_mteObjectsEntryStatus(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { struct mteObjectsTable_data *StorageTmp = NULL; static struct mteObjectsTable_data *StorageNew, *StorageDel; size_t newlen = name_len - (sizeof(mteObjectsTable_variables_oid) / sizeof(oid) + 3 - 1); static int old_value; int set_value; static netsnmp_variable_list *vars, *vp; struct header_complex_index *hciptr; StorageTmp = header_complex(mteObjectsTableStorage, NULL, &name[sizeof(mteObjectsTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); if (var_val_type != ASN_INTEGER || var_val == NULL) { snmp_log(LOG_ERR, "write to mteObjectsEntryStatus not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } if (StorageTmp && StorageTmp->storagetype == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } set_value = *((long *) var_val); /* * check legal range, and notReady is reserved for us, not a user */ if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) return SNMP_ERR_INCONSISTENTVALUE; switch (action) { case RESERVE1: /* * stage one: test validity */ if (StorageTmp == NULL) { /* * create the row now? */ /* * ditch illegal values now */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) return SNMP_ERR_INCONSISTENTVALUE; /* * destroying a non-existent row is actually legal */ if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } /* * illegal creation values */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } } else { /* * row exists. Check for a valid state change */ if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) { /* * can't create a row that exists */ return SNMP_ERR_INCONSISTENTVALUE; } /* * XXX: interaction with row storage type needed */ } break; case RESERVE2: /* * memory reseveration, final preparation... */ if (StorageTmp == NULL) { /* * creation */ vars = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* mteOwner */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* mteObjectsName */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, NULL, 0); /* mteObjectsIndex */ if (header_complex_parse_oid (& (name [sizeof(mteObjectsTable_variables_oid) / sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { /* * XXX: free, zero vars */ return SNMP_ERR_INCONSISTENTNAME; } vp = vars; StorageNew = SNMP_MALLOC_STRUCT(mteObjectsTable_data); if (StorageNew == NULL) return SNMP_ERR_GENERR; StorageNew->mteOwner = netsnmp_strdup_and_null(vp->val.string, vp->val_len); StorageNew->mteOwnerLen = vp->val_len; vp = vp->next_variable; StorageNew->mteObjectsName = netsnmp_strdup_and_null(vp->val.string, vp->val_len); StorageNew->mteObjectsNameLen = vp->val_len; vp = vp->next_variable; StorageNew->mteObjectsIndex = *(vp->val.integer); /* * XXX: fill in default row values here into StorageNew */ StorageNew->mteObjectsID = calloc(1, sizeof(oid) * sizeof(2)); /* 0.0 */ StorageNew->mteObjectsIDLen = 2; StorageNew->mteObjectsIDWildcard = MTEOBJECTSIDWILDCARD_FALSE; StorageNew->mteObjectsEntryStatus = set_value; /* * XXX: free, zero vars, no longer needed? */ } break; case FREE: /* * XXX: free, zero vars */ /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in set_value for you to * use, and you have just been asked to do something with * it. Note that anything done here must be reversable in * the UNDO case */ if (StorageTmp == NULL) { /* * row creation, so add it */ if (StorageNew != NULL) mteObjectsTable_add(StorageNew); /* * XXX: ack, and if it is NULL? */ } else if (set_value != RS_DESTROY) { /* * set the flag? */ old_value = StorageTmp->mteObjectsEntryStatus; StorageTmp->mteObjectsEntryStatus = *((long *) var_val); } else { /* * destroy... extract it for now */ hciptr = header_complex_find_entry(mteObjectsTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&mteObjectsTableStorage, hciptr); } break; case UNDO: /* * Back out any changes made in the ACTION case */ if (StorageTmp == NULL) { /* * row creation, so remove it again */ hciptr = header_complex_find_entry(mteObjectsTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&mteObjectsTableStorage, hciptr); /* * XXX: free it */ } else if (StorageDel != NULL) { /* * row deletion, so add it again */ mteObjectsTable_add(StorageDel); } else { StorageTmp->mteObjectsEntryStatus = old_value; } break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ if (StorageDel != NULL) { StorageDel = 0; /* * XXX: free it, its dead */ } else { if (StorageTmp && StorageTmp->mteObjectsEntryStatus == RS_CREATEANDGO) { StorageTmp->mteObjectsEntryStatus = RS_ACTIVE; } else if (StorageTmp && StorageTmp->mteObjectsEntryStatus == RS_CREATEANDWAIT) { StorageTmp->mteObjectsEntryStatus = RS_NOTINSERVICE; } } snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
int write_mteObjectsID(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { static oid *tmpvar; struct mteObjectsTable_data *StorageTmp = NULL; static size_t tmplen; size_t newlen = name_len - (sizeof(mteObjectsTable_variables_oid) / sizeof(oid) + 3 - 1); DEBUGMSGTL(("mteObjectsTable", "write_mteObjectsID entering action=%d... \n", action)); if ((StorageTmp = header_complex(mteObjectsTableStorage, NULL, &name[sizeof(mteObjectsTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storagetype == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_OBJECT_ID) { snmp_log(LOG_ERR, "write to mteObjectsID not ASN_OBJECT_ID\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->mteObjectsID; tmplen = StorageTmp->mteObjectsIDLen; memdup((u_char **) & StorageTmp->mteObjectsID, var_val, var_val_len); StorageTmp->mteObjectsIDLen = var_val_len / sizeof(oid); break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->mteObjectsID); StorageTmp->mteObjectsID = tmpvar; StorageTmp->mteObjectsIDLen = tmplen; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; }
/** handles requests for the mteObjectsTable table */ int mteObjectsTable_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 mteObject *entry; char mteOwner[MTE_STR1_LEN+1]; char mteOName[MTE_STR1_LEN+1]; long ret; DEBUGMSGTL(("disman:event:mib", "ObjTable 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 mteObject *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); if (!entry) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } switch (tinfo->colnum) { case COLUMN_MTEOBJECTSID: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *) entry->mteObjectID, entry->mteObjectID_len*sizeof(oid)); break; case COLUMN_MTEOBJECTSIDWILDCARD: ret = (entry->flags & MTE_OBJECT_FLAG_WILD ) ? TV_TRUE : TV_FALSE; snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret); break; case COLUMN_MTEOBJECTSENTRYSTATUS: ret = (entry->flags & MTE_OBJECT_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) { entry = (struct mteObject *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEOBJECTSID: ret = netsnmp_check_vb_oid( request->requestvb ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } /* * Can't modify the OID of an active row * (an unnecessary restriction, IMO) */ if (entry && entry->flags & MTE_OBJECT_FLAG_ACTIVE ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_NOERROR; } break; case COLUMN_MTEOBJECTSIDWILDCARD: ret = netsnmp_check_vb_truthvalue( request->requestvb ); if (ret != SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } /* * Can't modify the wildcarding of an active row * (an unnecessary restriction, IMO) */ if (entry && entry->flags & MTE_OBJECT_FLAG_ACTIVE ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_NOERROR; } break; case COLUMN_MTEOBJECTSENTRYSTATUS: 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_OBJECT_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) { tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEOBJECTSENTRYSTATUS: 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(mteOName, 0, sizeof(mteOName)); memcpy(mteOName, tinfo->indexes->next_variable->val.string, tinfo->indexes->next_variable->val_len); ret = *tinfo->indexes->next_variable->next_variable->val.integer; row = mteObjects_createEntry(mteOwner, mteOName, ret, 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) { tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEOBJECTSENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Tidy up after a failed row creation request */ entry = (struct mteObject *) netsnmp_tdata_extract_entry(request); if (entry && !(entry->flags & MTE_OBJECT_FLAG_VALID)) { row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); mteObjects_removeEntry( row ); } } } } break; case MODE_SET_ACTION: for (request = requests; request; request = request->next) { entry = (struct mteObject *) 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) { entry = (struct mteObject *) netsnmp_tdata_extract_entry(request); tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_MTEOBJECTSID: memset(entry->mteObjectID, 0, sizeof(entry->mteObjectID)); memcpy(entry->mteObjectID, request->requestvb->val.objid, request->requestvb->val_len); entry->mteObjectID_len = request->requestvb->val_len/sizeof(oid); break; case COLUMN_MTEOBJECTSIDWILDCARD: if (*request->requestvb->val.integer == TV_TRUE) entry->flags |= MTE_OBJECT_FLAG_WILD; else entry->flags &= ~MTE_OBJECT_FLAG_WILD; break; case COLUMN_MTEOBJECTSENTRYSTATUS: switch (*request->requestvb->val.integer) { case RS_ACTIVE: entry->flags |= MTE_OBJECT_FLAG_ACTIVE; break; case RS_CREATEANDGO: entry->flags |= MTE_OBJECT_FLAG_VALID; entry->flags |= MTE_OBJECT_FLAG_ACTIVE; break; case RS_CREATEANDWAIT: entry->flags |= MTE_OBJECT_FLAG_VALID; break; case RS_DESTROY: row = (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request); mteObjects_removeEntry(row); } } } /** set up to save persistent store */ snmp_store_needed(NULL); break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } 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; }