diff options
Diffstat (limited to 'agent/mibgroup/disman/mteTriggerTable.c')
-rw-r--r-- | agent/mibgroup/disman/mteTriggerTable.c | 3814 |
1 files changed, 3814 insertions, 0 deletions
diff --git a/agent/mibgroup/disman/mteTriggerTable.c b/agent/mibgroup/disman/mteTriggerTable.c new file mode 100644 index 0000000..a2306f7 --- /dev/null +++ b/agent/mibgroup/disman/mteTriggerTable.c @@ -0,0 +1,3814 @@ +/* + * This file was generated by mib2c and is intended for use as + * a mib module for the ucd-snmp snmpd agent. + */ + + +/* + * This should always be included first before anything else + */ +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-features.h> +#if HAVE_STDLIB_H +#include <stdlib.h> +#endif +#if HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +netsnmp_feature_require(mib_snprint_variable) +netsnmp_feature_require(tdomain_support) +netsnmp_feature_require(check_vb_uint) +netsnmp_feature_require(string_time_to_secs) +#ifndef NETSNMP_NO_WRITE_SUPPORT +netsnmp_feature_require(header_complex_find_entry) +#endif /* NETSNMP_NO_WRITE_SUPPORT */ + +/* + * minimal include directives + */ +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +#include "header_complex.h" +#include "mteTriggerTable.h" +#include "mteTriggerBooleanTable.h" +#include "mteTriggerDeltaTable.h" +#include "mteTriggerExistenceTable.h" +#include "mteTriggerThresholdTable.h" +#include "mteEventTable.h" +#include "mteObjectsTable.h" + +/* + * mteTriggerTable_variables_oid: + * this is the top level oid that we want to register under. This + * is essentially a prefix, with the suffix appearing in the + * variable below. + */ + +/* + * trap definitions + */ +oid mteTriggerFired[] = { 1, 3, 6, 1, 2, 1, 88, 2, 0, 1 }; +oid mteTriggerRising[] = { 1, 3, 6, 1, 2, 1, 88, 2, 0, 2 }; +oid mteTriggerFalling[] = { 1, 3, 6, 1, 2, 1, 88, 2, 0, 3 }; +oid mteTriggerFailure[] = { 1, 3, 6, 1, 2, 1, 88, 2, 0, 4 }; +oid mteEventSetFailure[] = { 1, 3, 6, 1, 2, 1, 88, 2, 0, 5 }; + +/* + * trap objects + */ +oid mteHotTrigger[] = { 1, 3, 6, 1, 2, 1, 88, 2, 1, 1 }; +oid mteHotTargetName[] = { 1, 3, 6, 1, 2, 1, 88, 2, 1, 2 }; +oid mteHotContextName[] = { 1, 3, 6, 1, 2, 1, 88, 2, 1, 3 }; +oid mteHotOID[] = { 1, 3, 6, 1, 2, 1, 88, 2, 1, 4 }; +oid mteHotValue[] = { 1, 3, 6, 1, 2, 1, 88, 2, 1, 5 }; +oid mteFailedReason[] = { 1, 3, 6, 1, 2, 1, 88, 2, 1, 6 }; + +/* + * For discontinuity checking. + */ +oid sysUpTimeInstance[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 }; + +oid mteTriggerTable_variables_oid[] = + { 1, 3, 6, 1, 2, 1, 88, 1, 2, 2 }; + + +/* + * variable2 mteTriggerTable_variables: + * this variable defines function callbacks and type return information + * for the mteTriggerTable mib section + */ + + +#ifndef NETSNMP_NO_WRITE_SUPPORT +struct variable2 mteTriggerTable_variables[] = { + /* + * magic number , variable type , ro/rw , callback fn , L, oidsuffix + */ +#define MTETRIGGERCOMMENT 5 + {MTETRIGGERCOMMENT, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 3}}, +#define MTETRIGGERTEST 6 + {MTETRIGGERTEST, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 4}}, +#define MTETRIGGERSAMPLETYPE 7 + {MTETRIGGERSAMPLETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 5}}, +#define MTETRIGGERVALUEID 8 + {MTETRIGGERVALUEID, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 6}}, +#define MTETRIGGERVALUEIDWILDCARD 9 + {MTETRIGGERVALUEIDWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 7}}, +#define MTETRIGGERTARGETTAG 10 + {MTETRIGGERTARGETTAG, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 8}}, +#define MTETRIGGERCONTEXTNAME 11 + {MTETRIGGERCONTEXTNAME, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 9}}, +#define MTETRIGGERCONTEXTNAMEWILDCARD 12 + {MTETRIGGERCONTEXTNAMEWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 10}}, +#define MTETRIGGERFREQUENCY 13 + {MTETRIGGERFREQUENCY, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 11}}, +#define MTETRIGGEROBJECTSOWNER 14 + {MTETRIGGEROBJECTSOWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 12}}, +#define MTETRIGGEROBJECTS 15 + {MTETRIGGEROBJECTS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 13}}, +#define MTETRIGGERENABLED 16 + {MTETRIGGERENABLED, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 14}}, +#define MTETRIGGERENTRYSTATUS 17 + {MTETRIGGERENTRYSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_mteTriggerTable, 2, {1, 15}}, +}; +#else /* !NETSNMP_NO_WRITE_SUPPORT */ +struct variable2 mteTriggerTable_variables[] = { + /* + * magic number , variable type , ro/rw , callback fn , L, oidsuffix + */ +#define MTETRIGGERCOMMENT 5 + {MTETRIGGERCOMMENT, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 3}}, +#define MTETRIGGERTEST 6 + {MTETRIGGERTEST, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 4}}, +#define MTETRIGGERSAMPLETYPE 7 + {MTETRIGGERSAMPLETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 5}}, +#define MTETRIGGERVALUEID 8 + {MTETRIGGERVALUEID, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 6}}, +#define MTETRIGGERVALUEIDWILDCARD 9 + {MTETRIGGERVALUEIDWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 7}}, +#define MTETRIGGERTARGETTAG 10 + {MTETRIGGERTARGETTAG, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 8}}, +#define MTETRIGGERCONTEXTNAME 11 + {MTETRIGGERCONTEXTNAME, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 9}}, +#define MTETRIGGERCONTEXTNAMEWILDCARD 12 + {MTETRIGGERCONTEXTNAMEWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 10}}, +#define MTETRIGGERFREQUENCY 13 + {MTETRIGGERFREQUENCY, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 11}}, +#define MTETRIGGEROBJECTSOWNER 14 + {MTETRIGGEROBJECTSOWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 12}}, +#define MTETRIGGEROBJECTS 15 + {MTETRIGGEROBJECTS, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 13}}, +#define MTETRIGGERENABLED 16 + {MTETRIGGERENABLED, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 14}}, +#define MTETRIGGERENTRYSTATUS 17 + {MTETRIGGERENTRYSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_mteTriggerTable, 2, {1, 15}}, +}; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + +/* + * (L = length of the oidsuffix) + */ + + +/* + * global storage of our data, saved in and configured by header_complex() + */ +struct header_complex_index *mteTriggerTableStorage = NULL; + +netsnmp_session *mte_callback_sess = NULL; +extern int callback_master_num; + +/* + * init_mteTriggerTable(): + * Initialization routine. This is called when the agent starts up. + * At a minimum, registration of your variables should take place here. + */ +void +init_mteTriggerTable(void) +{ + DEBUGMSGTL(("mteTriggerTable", "initializing... ")); + +#ifndef NETSNMP_TRANSPORT_CALLBACK_DOMAIN + snmp_log(LOG_WARNING,"mteTriggerTable has been disabled because " + "the callback transport is not available.\n"); + return; +#endif + + /* + * register ourselves with the agent to handle our mib tree + */ + REGISTER_MIB("mteTriggerTable", mteTriggerTable_variables, variable2, + mteTriggerTable_variables_oid); + + + /* + * register our config handler(s) to deal with registrations + */ + snmpd_register_config_handler("mteTriggerTable", parse_mteTriggerTable, + NULL, NULL); + + snmpd_register_config_handler("monitor", parse_simple_monitor, NULL, + "[options] monitor_expression [see \"man snmpd.conf\"]"); + snmpd_register_config_handler("defaultMonitors", + parse_default_monitors, NULL, "yes|no"); + + /* + * we need to be called back later to store our data + */ + snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, + store_mteTriggerTable, NULL); + + + /* + * place any other initialization junk you need here + */ + se_add_pair_to_slist("mteBooleanOperators", strdup("!="), + MTETRIGGERBOOLEANCOMPARISON_UNEQUAL); + se_add_pair_to_slist("mteBooleanOperators", strdup("=="), + MTETRIGGERBOOLEANCOMPARISON_EQUAL); + se_add_pair_to_slist("mteBooleanOperators", strdup("<"), + MTETRIGGERBOOLEANCOMPARISON_LESS); + se_add_pair_to_slist("mteBooleanOperators", strdup("<="), + MTETRIGGERBOOLEANCOMPARISON_LESSOREQUAL); + se_add_pair_to_slist("mteBooleanOperators", strdup(">"), + MTETRIGGERBOOLEANCOMPARISON_GREATER); + se_add_pair_to_slist("mteBooleanOperators", strdup(">="), + MTETRIGGERBOOLEANCOMPARISON_GREATEROREQUAL); + + DEBUGMSGTL(("mteTriggerTable", "done.\n")); +} + +struct mteTriggerTable_data * +create_mteTriggerTable_data(void) +{ + struct mteTriggerTable_data *StorageNew; + + StorageNew = SNMP_MALLOC_STRUCT(mteTriggerTable_data); + + /* + * fill in default row values here into StorageNew + */ + /* + * fill in values for all tables (even if not + * appropriate), since its easier to do here than anywhere + * else + */ + StorageNew->mteTriggerComment = strdup(""); + StorageNew->mteTriggerTest = strdup(""); + StorageNew->mteTriggerTest[0] |= (char) MTETRIGGERTEST_BOOLEAN; + StorageNew->mteTriggerTestLen = 1; + StorageNew->mteTriggerSampleType = MTETRIGGERSAMPLETYPE_ABSOLUTEVALUE; + StorageNew->mteTriggerValueID = calloc(1, sizeof(oid) * sizeof(2)); /* 0.0 */ + StorageNew->mteTriggerValueIDLen = 2; + StorageNew->mteTriggerValueIDWildcard = + MTETRIGGERVALUEIDWILDCARD_FALSE; + StorageNew->mteTriggerTargetTag = strdup(""); + StorageNew->mteTriggerContextName = strdup(""); + StorageNew->mteTriggerContextNameWildcard = + MTETRIGGERCONTEXTNAMEWILDCARD_FALSE; + StorageNew->mteTriggerFrequency = 600; + StorageNew->mteTriggerObjectsOwner = strdup(""); + StorageNew->mteTriggerObjects = strdup(""); + StorageNew->mteTriggerEnabled = MTETRIGGERENABLED_FALSE; + memdup((unsigned char **) + &(StorageNew->mteTriggerDeltaDiscontinuityID), + (unsigned char *) sysUpTimeInstance, sizeof(sysUpTimeInstance)); + StorageNew->mteTriggerDeltaDiscontinuityIDLen = + sizeof(sysUpTimeInstance) / sizeof(oid); + StorageNew->mteTriggerDeltaDiscontinuityIDWildcard = TV_FALSE; + StorageNew->mteTriggerDeltaDiscontinuityIDType = + MTETRIGGERDELTADISCONTINUITYIDTYPE_TIMETICKS; + StorageNew->mteTriggerExistenceTest = strdup(""); + StorageNew->mteTriggerExistenceTest[0] = + (char) (MTETRIGGEREXISTENCETEST_PRESENT | + MTETRIGGEREXISTENCETEST_ABSENT); + StorageNew->mteTriggerExistenceTestLen = 1; + StorageNew->mteTriggerExistenceStartup = strdup(""); + StorageNew->mteTriggerExistenceStartup[0] = + (char) (MTETRIGGEREXISTENCESTARTUP_PRESENT); + StorageNew->mteTriggerExistenceStartupLen = 1; + StorageNew->mteTriggerExistenceObjectsOwner = strdup(""); + StorageNew->mteTriggerExistenceObjects = strdup(""); + StorageNew->mteTriggerExistenceEventOwner = strdup(""); + StorageNew->mteTriggerExistenceEvent = strdup(""); + StorageNew->mteTriggerBooleanComparison = + MTETRIGGERBOOLEANCOMPARISON_UNEQUAL; + StorageNew->mteTriggerBooleanStartup = MTETRIGGERBOOLEANSTARTUP_TRUE; + StorageNew->mteTriggerBooleanObjectsOwner = strdup(""); + StorageNew->mteTriggerBooleanObjects = strdup(""); + StorageNew->mteTriggerBooleanEventOwner = strdup(""); + StorageNew->mteTriggerBooleanEvent = strdup(""); + StorageNew->mteTriggerThresholdStartup = + MTETRIGGERTHRESHOLDSTARTUP_RISINGORFALLING; + StorageNew->mteTriggerThresholdObjectsOwner = strdup(""); + StorageNew->mteTriggerThresholdObjects = strdup(""); + StorageNew->mteTriggerThresholdRisingEventOwner = strdup(""); + StorageNew->mteTriggerThresholdRisingEvent = strdup(""); + StorageNew->mteTriggerThresholdFallingEventOwner = strdup(""); + StorageNew->mteTriggerThresholdFallingEvent = strdup(""); + StorageNew->mteTriggerThresholdDeltaRisingEventOwner = strdup(""); + StorageNew->mteTriggerThresholdDeltaRisingEvent = strdup(""); + StorageNew->mteTriggerThresholdDeltaFallingEventOwner = strdup(""); + StorageNew->mteTriggerThresholdDeltaFallingEvent = strdup(""); + StorageNew->lastboolresult = -1; + StorageNew->storageType = ST_NONVOLATILE; + StorageNew->prevDiscoTicks = 0; + StorageNew->prevUptimeTicks = 0; + return StorageNew; +} + +/* + * mteTriggerTable_add(): adds a structure node to our data set + */ +int +mteTriggerTable_add(struct mteTriggerTable_data *thedata) +{ + netsnmp_variable_list *vars = NULL; + + + DEBUGMSGTL(("mteTriggerTable", "adding data... ")); + /* + * add the index variables to the varbind list, which is + * used by header_complex to index the data + */ + + + snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->mteOwner, thedata->mteOwnerLen); /* mteOwner */ + snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, (char *) thedata->mteTriggerName, thedata->mteTriggerNameLen); /* mteTriggerName */ + + + + header_complex_add_data(&mteTriggerTableStorage, vars, thedata); + DEBUGMSGTL(("mteTriggerTable", "registered an entry\n")); + + + DEBUGMSGTL(("mteTriggerTable", "done.\n")); + return SNMPERR_SUCCESS; +} + + +#define MTE_PROCESS_LINE(line) \ + snprintf(buf, SPRINT_MAX_LEN, "-u %s %s", mte_default_user, line); \ + parse_simple_monitor("monitor", buf); + +void +parse_default_monitors(const char *token, char *line) +{ + char buf[SPRINT_MAX_LEN]; + char *mte_default_user = + netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_INTERNAL_SECNAME); + + if (strncmp(line, "yes", 3) == 0) { + + DEBUGMSGTL(("mteTriggerTable", "registering default monitors\n")); + + if (mte_default_user == NULL) { + config_perror + ("You must specify a user name first using the agentSecName token\n"); + return; + } + + /* + * we don't include many additional objects here as most of + * the error messages are complete with the needed + * information + */ + MTE_PROCESS_LINE + ("-o prNames -o prErrMessage \"process table\" prErrorFlag != 0"); + MTE_PROCESS_LINE + ("-o memErrorName -o memSwapErrorMsg \"memory\" memSwapError != 0"); + MTE_PROCESS_LINE + ("-o extNames -o extOutput \"extTable\" extResult != 0"); + MTE_PROCESS_LINE + ("-o dskPath -o dskErrorMsg \"dskTable\" dskErrorFlag != 0"); + MTE_PROCESS_LINE + ("-o laNames -o laErrMessage \"laTable\" laErrorFlag != 0"); + MTE_PROCESS_LINE + ("-o fileName -o fileErrorMsg \"fileTable\" fileErrorFlag != 0"); + /* + * this one is not *all* that useful, because the error is + * only kept for 30 seconds at most. Maybe scan it every 30 + * seconds, but I'm not doing so without seeking other peoples + * opinions first. + */ + MTE_PROCESS_LINE + ("-o snmperrErrMessage \"snmperrs\" snmperrErrorFlag != 0"); + } +} + +static int monitor_call_count = 0; +void +parse_simple_monitor(const char *token, char *line) +{ + char buf[SPRINT_MAX_LEN], *cp, eventname[64]; + oid obuf[MAX_OID_LEN]; + size_t obufLen; + struct mteTriggerTable_data *StorageNew; + + monitor_call_count++; + eventname[0] = '\0'; + + StorageNew = create_mteTriggerTable_data(); + StorageNew->storageType = ST_READONLY; + StorageNew->mteTriggerEnabled = MTETRIGGERENABLED_TRUE; + StorageNew->mteTriggerEntryStatus = RS_ACTIVE; + StorageNew->mteTriggerValueIDWildcard = MTETRIGGERVALUEIDWILDCARD_TRUE; + StorageNew->mteTriggerBooleanStartup = MTETRIGGERBOOLEANSTARTUP_TRUE; + StorageNew->mteTriggerThresholdStartup = + MTETRIGGERTHRESHOLDSTARTUP_RISINGORFALLING; + StorageNew->mteTriggerExistenceTest[0] = 0; + + /* + * owner = snmpd.conf, why not? + */ + StorageNew->mteOwner = strdup("snmpd.conf"); + StorageNew->mteOwnerLen = strlen(StorageNew->mteOwner); + StorageNew->pdu_version = SNMP_VERSION_3; + StorageNew->pdu_securityModel = SNMP_SEC_MODEL_USM; + StorageNew->pdu_securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; + + cp = line; + + while (cp && *cp == '-') { + cp = copy_nword(cp, buf, sizeof(buf)); + switch (buf[1]) { + case 't': + /* + * Threshold toggle + */ + StorageNew->mteTriggerTest[0] = MTETRIGGERTEST_THRESHOLD; + break; + case 'i': + /* + * Single instance + */ + StorageNew->mteTriggerValueIDWildcard = MTETRIGGERVALUEIDWILDCARD_FALSE; + break; + case 'r': + if (cp) { + int freq; + cp = copy_nword(cp, buf, sizeof(buf)); + freq = netsnmp_string_time_to_secs(buf); + if (freq == -1) { + config_perror("Invalid -r value\n"); + /* + * XXX: free StorageNew + */ + return; + } + StorageNew->mteTriggerFrequency = (unsigend long) freq; + } else { + config_perror("No parameter after -r given\n"); + /* + * XXX: free StorageNew + */ + return; + } + break; + case 'u': + if (cp) { + cp = copy_nword(cp, buf, sizeof(buf)); + StorageNew->pdu_securityName = strdup(buf); + StorageNew->pdu_securityNameLen = strlen(buf); + } else { + config_perror("No parameter after -u given\n"); + /* + * XXX: free StorageNew + */ + return; + } + break; + case 'e': + if (cp) { + cp = copy_nword(cp, eventname, sizeof(eventname)); + } else { + config_perror("No parameter after -e given\n"); + /* + * XXX: free StorageNew + */ + return; + } + break; + case 'o': + /* + * oid + */ + cp = copy_nword(cp, buf, sizeof(buf)); + obufLen = MAX_OID_LEN; + if (!snmp_parse_oid(buf, obuf, &obufLen)) { + netsnmp_config_error("unable to parse oid: %s", buf); + /* + * XXX: free StorageNew + */ + return; + } + sprintf(buf, "snmpd.conf%d", monitor_call_count); + mte_add_object_to_table("snmpd.conf", buf, obuf, obufLen, 1); + + if (StorageNew->mteTriggerObjectsOwnerLen == 0) { + SNMP_FREE(StorageNew->mteTriggerObjectsOwner); + StorageNew->mteTriggerObjectsOwner = strdup("snmpd.conf"); + StorageNew->mteTriggerObjectsOwnerLen = + strlen("snmpd.conf"); + } + + if (StorageNew->mteTriggerObjectsLen == 0) { + SNMP_FREE(StorageNew->mteTriggerObjects); + StorageNew->mteTriggerObjects = strdup(buf); + StorageNew->mteTriggerObjectsLen = strlen(buf); + } + break; + } + } + + if (StorageNew->pdu_securityNameLen == 0) { + char *mte_default_user = + netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_INTERNAL_SECNAME); + if (mte_default_user) { + StorageNew->pdu_securityName = strdup(mte_default_user); + StorageNew->pdu_securityNameLen = strlen(mte_default_user); + } else { + config_perror("-u USER parameter required\n"); + /* + * XXX: free StorageNew + */ + return; + } + } + + /* + * name + */ + cp = copy_nword(cp, buf, sizeof(buf)); + if (!cp) { + config_perror("illegal monitor: no name specified"); + /* + * XXX: free StorageNew + */ + return; + } + + StorageNew->mteTriggerName = strdup(buf); + StorageNew->mteTriggerNameLen = strlen(StorageNew->mteTriggerName); + + /* + * oid + */ + cp = copy_nword(cp, buf, sizeof(buf)); + obufLen = MAX_OID_LEN; + if (!snmp_parse_oid(buf, obuf, &obufLen)) { + netsnmp_config_error("unable to parse oid: %s", buf); + /* + * XXX: free StorageNew + */ + return; + } + if (StorageNew->mteTriggerValueID) + free(StorageNew->mteTriggerValueID); + StorageNew->mteTriggerValueID = snmp_duplicate_objid(obuf, obufLen); + StorageNew->mteTriggerValueIDLen = obufLen; + + if (StorageNew->mteTriggerTest[0] == MTETRIGGERTEST_THRESHOLD) { + /* + * it's a threshold + * grab 'low' and 'high' params + */ + if (!cp) { + config_perror("no lower threshold value specified"); + } + cp = copy_nword(cp, buf, sizeof(buf)); + StorageNew->mteTriggerThresholdFalling = strtol(buf, NULL, 0); + + if (!cp) { + config_perror("no upper threshold value specified"); + } + cp = copy_nword(cp, buf, sizeof(buf)); + StorageNew->mteTriggerThresholdRising = strtol(buf, NULL, 0); + } else { + /* + * if nothing beyond here, it's an existence test + */ + if (!cp) { + StorageNew->mteTriggerTest[0] = (u_char)MTETRIGGERTEST_EXISTENCE; + if (eventname[0] != '\0') { + StorageNew->mteTriggerExistenceEventOwner = + strdup("snmpd.conf"); + StorageNew->mteTriggerExistenceEventOwnerLen = + strlen(StorageNew->mteTriggerExistenceEventOwner); + StorageNew->mteTriggerExistenceEvent = + strdup(eventname); + StorageNew->mteTriggerExistenceEventLen = + strlen(eventname); + } + mteTriggerTable_add(StorageNew); + return; + } + + /* + * assume boolean (need to deal with threshold statements) + */ + cp = copy_nword(cp, buf, sizeof(buf)); + if ((StorageNew->mteTriggerBooleanComparison = + se_find_value_in_slist("mteBooleanOperators", buf)) == -1) { + config_perror("illegal boolean operator"); + return; + } + + /* + * XXX: add threshold + */ + StorageNew->mteTriggerTest[0] = MTETRIGGERTEST_BOOLEAN; + if (!cp) { + config_perror("no comparison value specified"); + /* + * XXX: free StorageNew + */ + return; + } + + cp = copy_nword(cp, buf, sizeof(buf)); + StorageNew->mteTriggerBooleanValue = strtol(buf, NULL, 0); + + if (eventname[0] != '\0') { + StorageNew->mteTriggerBooleanEventOwner = + strdup("snmpd.conf"); + StorageNew->mteTriggerBooleanEventOwnerLen = + strlen(StorageNew->mteTriggerBooleanEventOwner); + StorageNew->mteTriggerBooleanEvent = + strdup(eventname); + StorageNew->mteTriggerBooleanEventLen = + strlen(eventname); + } + } + mteTriggerTable_add(StorageNew); + mte_enable_trigger(StorageNew); + + DEBUGMSGTL(("mteTriggerTable", "added simple monitor: %s\n", + StorageNew->mteTriggerName)); +} /* parse_simple_monitor */ + + +/* + * parse_mteTriggerTable(): + * parses .conf file entries needed to configure the mib. + */ +void +parse_mteTriggerTable(const char *token, char *line) +{ + size_t tmpint; + oid *tmpoid = NULL; + struct mteTriggerTable_data *StorageTmp = + SNMP_MALLOC_STRUCT(mteTriggerTable_data); + + DEBUGMSGTL(("mteTriggerTable", "parsing config... ")); + + if (StorageTmp == NULL) { + config_perror("malloc failure"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->mteOwner, + &StorageTmp->mteOwnerLen); + if (StorageTmp->mteOwner == NULL) { + config_perror("invalid specification for mteOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerName, + &StorageTmp->mteTriggerNameLen); + if (StorageTmp->mteTriggerName == NULL) { + config_perror("invalid specification for mteTriggerName"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerComment, + &StorageTmp->mteTriggerCommentLen); + if (StorageTmp->mteTriggerComment == NULL) { + config_perror("invalid specification for mteTriggerComment"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerTest, + &StorageTmp->mteTriggerTestLen); + if (StorageTmp->mteTriggerTest == NULL) { + config_perror("invalid specification for mteTriggerTest"); + return; + } + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerSampleType, &tmpint); + + line = + read_config_read_data(ASN_OBJECT_ID, line, + &StorageTmp->mteTriggerValueID, + &StorageTmp->mteTriggerValueIDLen); + if (StorageTmp->mteTriggerValueID == NULL) { + config_perror("invalid specification for mteTriggerValueID"); + return; + } + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerValueIDWildcard, + &tmpint); + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerTargetTag, + &StorageTmp->mteTriggerTargetTagLen); + if (StorageTmp->mteTriggerTargetTag == NULL) { + config_perror("invalid specification for mteTriggerTargetTag"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerContextName, + &StorageTmp->mteTriggerContextNameLen); + if (StorageTmp->mteTriggerContextName == NULL) { + config_perror("invalid specification for mteTriggerContextName"); + return; + } + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerContextNameWildcard, + &tmpint); + + line = + read_config_read_data(ASN_UNSIGNED, line, + &StorageTmp->mteTriggerFrequency, &tmpint); + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerObjectsOwner, + &StorageTmp->mteTriggerObjectsOwnerLen); + if (StorageTmp->mteTriggerObjectsOwner == NULL) { + config_perror("invalid specification for mteTriggerObjectsOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerObjects, + &StorageTmp->mteTriggerObjectsLen); + if (StorageTmp->mteTriggerObjects == NULL) { + config_perror("invalid specification for mteTriggerObjects"); + return; + } + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerEnabled, &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerEntryStatus, &tmpint); + + /* + * delta table + */ + line = + read_config_read_data(ASN_OBJECT_ID, line, + &StorageTmp->mteTriggerDeltaDiscontinuityID, + &StorageTmp-> + mteTriggerDeltaDiscontinuityIDLen); + if (StorageTmp->mteTriggerDeltaDiscontinuityID == NULL) { + config_perror + ("invalid specification for mteTriggerDeltaDiscontinuityID"); + return; + } + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp-> + mteTriggerDeltaDiscontinuityIDWildcard, + &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp-> + mteTriggerDeltaDiscontinuityIDType, &tmpint); + + /* + * existence table + */ + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerExistenceTest, + &StorageTmp->mteTriggerExistenceTestLen); + if (StorageTmp->mteTriggerExistenceTest == NULL) { + config_perror("invalid specification for mteTriggerExistenceTest"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerExistenceStartup, + &StorageTmp->mteTriggerExistenceStartupLen); + if (StorageTmp->mteTriggerExistenceStartup == NULL) { + config_perror + ("invalid specification for mteTriggerExistenceStartup"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerExistenceObjectsOwner, + &StorageTmp-> + mteTriggerExistenceObjectsOwnerLen); + if (StorageTmp->mteTriggerExistenceObjectsOwner == NULL) { + config_perror + ("invalid specification for mteTriggerExistenceObjectsOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerExistenceObjects, + &StorageTmp->mteTriggerExistenceObjectsLen); + if (StorageTmp->mteTriggerExistenceObjects == NULL) { + config_perror + ("invalid specification for mteTriggerExistenceObjects"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerExistenceEventOwner, + &StorageTmp-> + mteTriggerExistenceEventOwnerLen); + if (StorageTmp->mteTriggerExistenceEventOwner == NULL) { + config_perror + ("invalid specification for mteTriggerExistenceEventOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerExistenceEvent, + &StorageTmp->mteTriggerExistenceEventLen); + if (StorageTmp->mteTriggerExistenceEvent == NULL) { + config_perror + ("invalid specification for mteTriggerExistenceEvent"); + return; + } + + /* + * boolean table + */ + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerBooleanComparison, + &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerBooleanValue, + &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerBooleanStartup, + &tmpint); + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerBooleanObjectsOwner, + &StorageTmp-> + mteTriggerBooleanObjectsOwnerLen); + if (StorageTmp->mteTriggerBooleanObjectsOwner == NULL) { + config_perror + ("invalid specification for mteTriggerBooleanObjectsOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerBooleanObjects, + &StorageTmp->mteTriggerBooleanObjectsLen); + if (StorageTmp->mteTriggerBooleanObjects == NULL) { + config_perror + ("invalid specification for mteTriggerBooleanObjects"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerBooleanEventOwner, + &StorageTmp->mteTriggerBooleanEventOwnerLen); + if (StorageTmp->mteTriggerBooleanEventOwner == NULL) { + config_perror + ("invalid specification for mteTriggerBooleanEventOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerBooleanEvent, + &StorageTmp->mteTriggerBooleanEventLen); + if (StorageTmp->mteTriggerBooleanEvent == NULL) { + config_perror("invalid specification for mteTriggerBooleanEvent"); + return; + } + + /* + * threshold table + */ + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerThresholdStartup, + &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerThresholdRising, + &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerThresholdFalling, + &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerThresholdDeltaRising, + &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->mteTriggerThresholdDeltaFalling, + &tmpint); + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerThresholdObjectsOwner, + &StorageTmp-> + mteTriggerThresholdObjectsOwnerLen); + if (StorageTmp->mteTriggerThresholdObjectsOwner == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdObjectsOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerThresholdObjects, + &StorageTmp->mteTriggerThresholdObjectsLen); + if (StorageTmp->mteTriggerThresholdObjects == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdObjects"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp-> + mteTriggerThresholdRisingEventOwner, + &StorageTmp-> + mteTriggerThresholdRisingEventOwnerLen); + if (StorageTmp->mteTriggerThresholdRisingEventOwner == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdRisingEventOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerThresholdRisingEvent, + &StorageTmp-> + mteTriggerThresholdRisingEventLen); + if (StorageTmp->mteTriggerThresholdRisingEvent == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdRisingEvent"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp-> + mteTriggerThresholdFallingEventOwner, + &StorageTmp-> + mteTriggerThresholdFallingEventOwnerLen); + if (StorageTmp->mteTriggerThresholdFallingEventOwner == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdFallingEventOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->mteTriggerThresholdFallingEvent, + &StorageTmp-> + mteTriggerThresholdFallingEventLen); + if (StorageTmp->mteTriggerThresholdFallingEvent == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdFallingEvent"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp-> + mteTriggerThresholdDeltaRisingEventOwner, + &StorageTmp-> + mteTriggerThresholdDeltaRisingEventOwnerLen); + if (StorageTmp->mteTriggerThresholdDeltaRisingEventOwner == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdDeltaRisingEventOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp-> + mteTriggerThresholdDeltaRisingEvent, + &StorageTmp-> + mteTriggerThresholdDeltaRisingEventLen); + if (StorageTmp->mteTriggerThresholdDeltaRisingEvent == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdDeltaRisingEvent"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp-> + mteTriggerThresholdDeltaFallingEventOwner, + &StorageTmp-> + mteTriggerThresholdDeltaFallingEventOwnerLen); + if (StorageTmp->mteTriggerThresholdDeltaFallingEventOwner == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdDeltaFallingEventOwner"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp-> + mteTriggerThresholdDeltaFallingEvent, + &StorageTmp-> + mteTriggerThresholdDeltaFallingEventLen); + if (StorageTmp->mteTriggerThresholdDeltaFallingEvent == NULL) { + config_perror + ("invalid specification for mteTriggerThresholdDeltaFallingEvent"); + return; + } + + /* + * local internal variables + */ + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->have_copied_auth_info, &tmpint); + if (StorageTmp->have_copied_auth_info) { + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->pdu_version, &tmpint); + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->pdu_securityModel, &tmpint); + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->pdu_securityLevel, &tmpint); + line = + read_config_read_data(ASN_OBJECT_ID, line, &tmpoid, &tmpint); + if (!netsnmp_tdomain_support + (tmpoid, tmpint, &StorageTmp->pdu_tDomain, + &StorageTmp->pdu_tDomainLen)) { + config_perror + ("unsupported transport domain for mteTriggerEntry"); + return; + } + if (tmpoid != NULL) { + free(tmpoid); + } + + /* + * can be NULL? Yes. + */ + line = read_config_read_data(ASN_OCTET_STR, line, + &(StorageTmp->pdu_transport), + &StorageTmp->pdu_transportLen); + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->pdu_community, + &StorageTmp->pdu_community_len); + if (StorageTmp->pdu_community == NULL) { + config_perror("invalid specification for pdu_community"); + return; + } + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->pdu_securityName, + &StorageTmp->pdu_securityNameLen); + if (StorageTmp->pdu_securityName == NULL) { + config_perror("invalid specification for pdu_securityName"); + return; + } + } + StorageTmp->storageType = ST_NONVOLATILE; /* the only type stored */ + + mteTriggerTable_add(StorageTmp); + + /* + * technically this is too early + */ + if (StorageTmp->mteTriggerEnabled == MTETRIGGERENABLED_TRUE && + StorageTmp->mteTriggerEntryStatus == RS_ACTIVE) + mte_enable_trigger(StorageTmp); + + DEBUGMSGTL(("mteTriggerTable", "done.\n")); +} /* parse_mteTriggerTable */ + + +/* + * store_mteTriggerTable(): + * stores .conf file entries needed to configure the mib. + */ +int +store_mteTriggerTable(int majorID, int minorID, void *serverarg, + void *clientarg) +{ + char line[SNMP_MAXBUF]; + char *cptr; + size_t tmpint; + struct mteTriggerTable_data *StorageTmp; + struct header_complex_index *hcindex; + + DEBUGMSGTL(("mteTriggerTable", "storing data... ")); + + for (hcindex = mteTriggerTableStorage; hcindex != NULL; + hcindex = hcindex->next) { + StorageTmp = (struct mteTriggerTable_data *) hcindex->data; + + + if (StorageTmp->storageType == ST_NONVOLATILE) { + + memset(line, 0, sizeof(line)); + strcat(line, "mteTriggerTable "); + cptr = line + strlen(line); + + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteOwner, + &StorageTmp->mteOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteTriggerName, + &StorageTmp->mteTriggerNameLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteTriggerComment, + &StorageTmp->mteTriggerCommentLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteTriggerTest, + &StorageTmp->mteTriggerTestLen); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->mteTriggerSampleType, + &tmpint); + cptr = + read_config_store_data(ASN_OBJECT_ID, cptr, + &StorageTmp->mteTriggerValueID, + &StorageTmp->mteTriggerValueIDLen); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerValueIDWildcard, &tmpint); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteTriggerTargetTag, + &StorageTmp-> + mteTriggerTargetTagLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteTriggerContextName, + &StorageTmp-> + mteTriggerContextNameLen); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerContextNameWildcard, + &tmpint); + cptr = + read_config_store_data(ASN_UNSIGNED, cptr, + &StorageTmp->mteTriggerFrequency, + &tmpint); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteTriggerObjectsOwner, + &StorageTmp-> + mteTriggerObjectsOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteTriggerObjects, + &StorageTmp->mteTriggerObjectsLen); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->mteTriggerEnabled, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->mteTriggerEntryStatus, + &tmpint); + + /* + * delta table + */ + cptr = + read_config_store_data(ASN_OBJECT_ID, cptr, + &StorageTmp-> + mteTriggerDeltaDiscontinuityID, + &StorageTmp-> + mteTriggerDeltaDiscontinuityIDLen); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerDeltaDiscontinuityIDWildcard, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerDeltaDiscontinuityIDType, + &tmpint); + + /* + * existence table + */ + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerExistenceTest, + &StorageTmp-> + mteTriggerExistenceTestLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerExistenceStartup, + &StorageTmp-> + mteTriggerExistenceStartupLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerExistenceObjectsOwner, + &StorageTmp-> + mteTriggerExistenceObjectsOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerExistenceObjects, + &StorageTmp-> + mteTriggerExistenceObjectsLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerExistenceEventOwner, + &StorageTmp-> + mteTriggerExistenceEventOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerExistenceEvent, + &StorageTmp-> + mteTriggerExistenceEventLen); + + /* + * boolean table + */ + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerBooleanComparison, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->mteTriggerBooleanValue, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerBooleanStartup, &tmpint); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerBooleanObjectsOwner, + &StorageTmp-> + mteTriggerBooleanObjectsOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerBooleanObjects, + &StorageTmp-> + mteTriggerBooleanObjectsLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerBooleanEventOwner, + &StorageTmp-> + mteTriggerBooleanEventOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->mteTriggerBooleanEvent, + &StorageTmp-> + mteTriggerBooleanEventLen); + + /* + * threshold table + */ + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerThresholdStartup, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerThresholdRising, &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerThresholdFalling, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerThresholdDeltaRising, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + mteTriggerThresholdDeltaFalling, + &tmpint); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdObjectsOwner, + &StorageTmp-> + mteTriggerThresholdObjectsOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdObjects, + &StorageTmp-> + mteTriggerThresholdObjectsLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdRisingEventOwner, + &StorageTmp-> + mteTriggerThresholdRisingEventOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdRisingEvent, + &StorageTmp-> + mteTriggerThresholdRisingEventLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdFallingEventOwner, + &StorageTmp-> + mteTriggerThresholdFallingEventOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdFallingEvent, + &StorageTmp-> + mteTriggerThresholdFallingEventLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdDeltaRisingEventOwner, + &StorageTmp-> + mteTriggerThresholdDeltaRisingEventOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdDeltaRisingEvent, + &StorageTmp-> + mteTriggerThresholdDeltaRisingEventLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdDeltaFallingEventOwner, + &StorageTmp-> + mteTriggerThresholdDeltaFallingEventOwnerLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + mteTriggerThresholdDeltaFallingEvent, + &StorageTmp-> + mteTriggerThresholdDeltaFallingEventLen); + + /* + * local internal variables + */ + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->have_copied_auth_info, + &tmpint); + if (StorageTmp->have_copied_auth_info) { + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->pdu_version, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->pdu_securityModel, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->pdu_securityLevel, + &tmpint); + cptr = + read_config_store_data(ASN_OBJECT_ID, cptr, + (void *)(&StorageTmp->pdu_tDomain), + &StorageTmp->pdu_tDomainLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->pdu_transport, + &StorageTmp->pdu_transportLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->pdu_community, + &StorageTmp->pdu_community_len); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->pdu_securityName, + &StorageTmp-> + pdu_securityNameLen); + } + + snmpd_store_config(line); + } + } + DEBUGMSGTL(("mteTriggerTable", "done.\n")); + return SNMPERR_SUCCESS; +} + + + + +/* + * var_mteTriggerTable(): + * Handle this table separately from the scalar value case. + * The workings of this are basically the same as for var_mteTriggerTable above. + */ +unsigned char * +var_mteTriggerTable(struct variable *vp, + oid * name, + size_t * length, + int exact, + size_t * var_len, WriteMethod ** write_method) +{ + + + struct mteTriggerTable_data *StorageTmp = NULL; + + + DEBUGMSGTL(("mteTriggerTable", + "var_mteTriggerTable: Entering... \n")); + + /* set default value */ + *write_method = NULL; + + /* + * this assumes you have registered all your data properly + */ + if ((StorageTmp = + header_complex(mteTriggerTableStorage, vp, name, length, exact, + var_len, write_method)) == NULL) { +#ifndef NETSNMP_NO_WRITE_SUPPORT + if (vp->magic == MTETRIGGERENTRYSTATUS) + *write_method = write_mteTriggerEntryStatus; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + return NULL; + } + + + /* + * this is where we do the value assignments for the mib results. + */ + switch (vp->magic) { + + + case MTETRIGGERCOMMENT: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerComment; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = StorageTmp->mteTriggerCommentLen; + return (u_char *) StorageTmp->mteTriggerComment; + + case MTETRIGGERTEST: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerTest; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = StorageTmp->mteTriggerTestLen; + return (u_char *) StorageTmp->mteTriggerTest; + + case MTETRIGGERSAMPLETYPE: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerSampleType; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = sizeof(StorageTmp->mteTriggerSampleType); + return (u_char *) & StorageTmp->mteTriggerSampleType; + + case MTETRIGGERVALUEID: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerValueID; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = StorageTmp->mteTriggerValueIDLen * sizeof(oid); + return (u_char *) StorageTmp->mteTriggerValueID; + + case MTETRIGGERVALUEIDWILDCARD: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerValueIDWildcard; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = sizeof(StorageTmp->mteTriggerValueIDWildcard); + return (u_char *) & StorageTmp->mteTriggerValueIDWildcard; + + case MTETRIGGERTARGETTAG: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerTargetTag; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = StorageTmp->mteTriggerTargetTagLen; + return (u_char *) StorageTmp->mteTriggerTargetTag; + + case MTETRIGGERCONTEXTNAME: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerContextName; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = StorageTmp->mteTriggerContextNameLen; + return (u_char *) StorageTmp->mteTriggerContextName; + + case MTETRIGGERCONTEXTNAMEWILDCARD: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerContextNameWildcard; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = sizeof(StorageTmp->mteTriggerContextNameWildcard); + return (u_char *) & StorageTmp->mteTriggerContextNameWildcard; + + case MTETRIGGERFREQUENCY: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerFrequency; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = sizeof(StorageTmp->mteTriggerFrequency); + return (u_char *) & StorageTmp->mteTriggerFrequency; + + case MTETRIGGEROBJECTSOWNER: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerObjectsOwner; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = StorageTmp->mteTriggerObjectsOwnerLen; + return (u_char *) StorageTmp->mteTriggerObjectsOwner; + + case MTETRIGGEROBJECTS: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerObjects; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = StorageTmp->mteTriggerObjectsLen; + return (u_char *) StorageTmp->mteTriggerObjects; + + case MTETRIGGERENABLED: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerEnabled; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = sizeof(StorageTmp->mteTriggerEnabled); + return (u_char *) & StorageTmp->mteTriggerEnabled; + + case MTETRIGGERENTRYSTATUS: +#ifndef NETSNMP_NO_WRITE_SUPPORT + *write_method = write_mteTriggerEntryStatus; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + *var_len = sizeof(StorageTmp->mteTriggerEntryStatus); + return (u_char *) & StorageTmp->mteTriggerEntryStatus; + + + default: + ERROR_MSG(""); + } + return NULL; +} + + + +#ifndef NETSNMP_NO_WRITE_SUPPORT +int +write_mteTriggerComment(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 mteTriggerTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerComment entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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_OCTET_STR) { + snmp_log(LOG_ERR, + "write to mteTriggerComment not ASN_OCTET_STR\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 string 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->mteTriggerComment; + tmplen = StorageTmp->mteTriggerCommentLen; + memdup((u_char **) & StorageTmp->mteTriggerComment, var_val, + var_val_len); + StorageTmp->mteTriggerCommentLen = var_val_len; + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->mteTriggerComment); + StorageTmp->mteTriggerComment = tmpvar; + StorageTmp->mteTriggerCommentLen = 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; +} /* write_mteTriggerComment */ + + + +int +write_mteTriggerTest(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 mteTriggerTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerTest entering action=%d... \n", action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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_OCTET_STR) { + snmp_log(LOG_ERR, "write to mteTriggerTest not ASN_OCTET_STR\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 string 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->mteTriggerTest; + tmplen = StorageTmp->mteTriggerTestLen; + memdup((u_char **) & StorageTmp->mteTriggerTest, var_val, + var_val_len); + StorageTmp->mteTriggerTestLen = var_val_len; + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->mteTriggerTest); + StorageTmp->mteTriggerTest = tmpvar; + StorageTmp->mteTriggerTestLen = 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; +} /* write_mteTriggerTest */ + + + +int +write_mteTriggerSampleType(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 mteTriggerTable_data *StorageTmp = NULL; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerSampleType entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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 mteTriggerSampleType 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->mteTriggerSampleType; + StorageTmp->mteTriggerSampleType = *((long *) var_val); + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + StorageTmp->mteTriggerSampleType = 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; +} /* write_mteTriggerSampleType */ + + + +int +write_mteTriggerValueID(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 mteTriggerTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerValueID entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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 mteTriggerValueID 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->mteTriggerValueID; + tmplen = StorageTmp->mteTriggerValueIDLen; + memdup((u_char **) & StorageTmp->mteTriggerValueID, var_val, + var_val_len); + StorageTmp->mteTriggerValueIDLen = var_val_len / sizeof(oid); + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->mteTriggerValueID); + StorageTmp->mteTriggerValueID = tmpvar; + StorageTmp->mteTriggerValueIDLen = 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; +} /* write_mteTriggerValueID */ + + + +int +write_mteTriggerValueIDWildcard(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 mteTriggerTable_data *StorageTmp = NULL; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerValueIDWildcard entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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 mteTriggerValueIDWildcard 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->mteTriggerValueIDWildcard; + StorageTmp->mteTriggerValueIDWildcard = *((long *) var_val); + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + StorageTmp->mteTriggerValueIDWildcard = 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; +} /* write_mteTriggerValueIDWildcard */ + + + +int +write_mteTriggerTargetTag(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 mteTriggerTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerTargetTag entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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_OCTET_STR) { + snmp_log(LOG_ERR, + "write to mteTriggerTargetTag not ASN_OCTET_STR\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 string 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->mteTriggerTargetTag; + tmplen = StorageTmp->mteTriggerTargetTagLen; + memdup((u_char **) & StorageTmp->mteTriggerTargetTag, var_val, + var_val_len); + StorageTmp->mteTriggerTargetTagLen = var_val_len; + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->mteTriggerTargetTag); + StorageTmp->mteTriggerTargetTag = tmpvar; + StorageTmp->mteTriggerTargetTagLen = 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; +} /* write_mteTriggerTargetTag */ + + + +int +write_mteTriggerContextName(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 mteTriggerTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerContextName entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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_OCTET_STR) { + snmp_log(LOG_ERR, + "write to mteTriggerContextName not ASN_OCTET_STR\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 string 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->mteTriggerContextName; + tmplen = StorageTmp->mteTriggerContextNameLen; + memdup((u_char **) & StorageTmp->mteTriggerContextName, var_val, + var_val_len); + StorageTmp->mteTriggerContextNameLen = var_val_len; + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->mteTriggerContextName); + StorageTmp->mteTriggerContextName = tmpvar; + StorageTmp->mteTriggerContextNameLen = 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; +} /* write_mteTriggerContextName */ + + + +int +write_mteTriggerContextNameWildcard(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 mteTriggerTable_data *StorageTmp = NULL; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerContextNameWildcard entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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 mteTriggerContextNameWildcard 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->mteTriggerContextNameWildcard; + StorageTmp->mteTriggerContextNameWildcard = *((long *) var_val); + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + StorageTmp->mteTriggerContextNameWildcard = 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; +} /* write_mteTriggerContextNameWildcard */ + + + +int +write_mteTriggerFrequency(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 mteTriggerTable_data *StorageTmp = NULL; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerFrequency entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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_UNSIGNED) { + snmp_log(LOG_ERR, + "write to mteTriggerFrequency not ASN_UNSIGNED\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 ulong_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->mteTriggerFrequency; + StorageTmp->mteTriggerFrequency = *((unsigned long *) var_val); + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + StorageTmp->mteTriggerFrequency = 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! + */ + if (StorageTmp->mteTriggerEnabled == MTETRIGGERENABLED_TRUE && + StorageTmp->mteTriggerEntryStatus == RS_ACTIVE) + mte_enable_trigger(StorageTmp); + + snmp_store_needed(NULL); + break; + } + return SNMP_ERR_NOERROR; +} /* write_mteTriggerFrequency */ + + + +int +write_mteTriggerObjectsOwner(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 mteTriggerTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerObjectsOwner entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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_OCTET_STR) { + snmp_log(LOG_ERR, + "write to mteTriggerObjectsOwner not ASN_OCTET_STR\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 string 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->mteTriggerObjectsOwner; + tmplen = StorageTmp->mteTriggerObjectsOwnerLen; + memdup((u_char **) & StorageTmp->mteTriggerObjectsOwner, var_val, + var_val_len); + StorageTmp->mteTriggerObjectsOwnerLen = var_val_len; + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->mteTriggerObjectsOwner); + StorageTmp->mteTriggerObjectsOwner = tmpvar; + StorageTmp->mteTriggerObjectsOwnerLen = 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; +} /* write_mteTriggerObjectsOwner */ + + + +int +write_mteTriggerObjects(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 mteTriggerTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerObjects entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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_OCTET_STR) { + snmp_log(LOG_ERR, + "write to mteTriggerObjects not ASN_OCTET_STR\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 string 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->mteTriggerObjects; + tmplen = StorageTmp->mteTriggerObjectsLen; + memdup((u_char **) & StorageTmp->mteTriggerObjects, var_val, + var_val_len); + StorageTmp->mteTriggerObjectsLen = var_val_len; + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->mteTriggerObjects); + StorageTmp->mteTriggerObjects = tmpvar; + StorageTmp->mteTriggerObjectsLen = 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; +} /* write_mteTriggerObjects */ + + + +int +write_mteTriggerEnabled(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 mteTriggerTable_data *StorageTmp = NULL; + size_t newlen = + name_len - (sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("mteTriggerTable", + "write_mteTriggerEnabled entering action=%d... \n", + action)); + if ((StorageTmp = + header_complex(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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 mteTriggerEnabled 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->mteTriggerEnabled; + StorageTmp->mteTriggerEnabled = *((long *) var_val); + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + StorageTmp->mteTriggerEnabled = 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! + */ + if (StorageTmp->mteTriggerEnabled == MTETRIGGERENABLED_TRUE && + StorageTmp->mteTriggerEntryStatus == RS_ACTIVE) + mte_enable_trigger(StorageTmp); + else if (StorageTmp->mteTriggerEnabled == MTETRIGGERENABLED_FALSE) + mte_disable_trigger(StorageTmp); + + snmp_store_needed(NULL); + break; + } + return SNMP_ERR_NOERROR; +} /* write_mteTriggerEnabled */ + + + +int +write_mteTriggerEntryStatus(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 mteTriggerTable_data *StorageTmp = NULL; + static struct mteTriggerTable_data *StorageNew, *StorageDel; + size_t newlen = + name_len - (sizeof(mteTriggerTable_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(mteTriggerTableStorage, NULL, + &name[sizeof(mteTriggerTable_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 mteTriggerEntryStatus 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->mteTriggerEntryStatus == 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); /* mteOwner */ + snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0); /* mteTriggerName */ + + + + if (header_complex_parse_oid + (& + (name + [sizeof(mteTriggerTable_variables_oid) / sizeof(oid) + + 2]), newlen, vars) != SNMPERR_SUCCESS) { + /* + * XXX: free, zero vars + */ + return SNMP_ERR_INCONSISTENTNAME; + } + vp = vars; + + + StorageNew = create_mteTriggerTable_data(); + + StorageNew->mteOwner = malloc(vp->val_len + 1); + memcpy(StorageNew->mteOwner, vp->val.string, vp->val_len); + StorageNew->mteOwner[vp->val_len] = '\0'; + StorageNew->mteOwnerLen = vp->val_len; + + vp = vp->next_variable; + StorageNew->mteTriggerName = malloc(vp->val_len + 1); + memcpy(StorageNew->mteTriggerName, vp->val.string, + vp->val_len); + StorageNew->mteTriggerName[vp->val_len] = '\0'; + StorageNew->mteTriggerNameLen = vp->val_len; + + vp = vp->next_variable; + + StorageNew->mteTriggerEntryStatus = 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) + mteTriggerTable_add(StorageNew); + /* + * XXX: ack, and if it is NULL? + */ + } else if (set_value != RS_DESTROY) { + /* + * set the flag? + */ + old_value = StorageTmp->mteTriggerEntryStatus; + StorageTmp->mteTriggerEntryStatus = *((long *) var_val); + } else { + /* + * destroy... extract it for now + */ + hciptr = + header_complex_find_entry(mteTriggerTableStorage, + StorageTmp); + StorageDel = + header_complex_extract_entry(&mteTriggerTableStorage, + 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(mteTriggerTableStorage, + StorageTmp); + StorageDel = + header_complex_extract_entry(&mteTriggerTableStorage, + hciptr); + /* + * XXX: free it + */ + } else if (StorageDel != NULL) { + /* + * row deletion, so add it again + */ + mteTriggerTable_add(StorageDel); + } else { + StorageTmp->mteTriggerEntryStatus = 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) { + mte_disable_trigger(StorageDel); + StorageDel = 0; + /* + * XXX: free it, its dead + */ + } else { + if (StorageTmp + && StorageTmp->mteTriggerEntryStatus == RS_CREATEANDGO) { + StorageTmp->mteTriggerEntryStatus = RS_ACTIVE; + } else if (StorageTmp && + StorageTmp->mteTriggerEntryStatus == + RS_CREATEANDWAIT) { + StorageTmp->mteTriggerEntryStatus = RS_NOTINSERVICE; + } + } + if (StorageTmp && + StorageTmp->mteTriggerEntryStatus == RS_ACTIVE && + !StorageTmp->have_copied_auth_info) { + + netsnmp_agent_session *asp = + netsnmp_get_current_agent_session(); + netsnmp_pdu *pdu = NULL; + + if (!asp) { + snmp_log(LOG_ERR, + "snmpTriggerTable: can't get master session for authentication params\n"); + } else { + pdu = asp->orig_pdu; + if (!pdu) { + snmp_log(LOG_ERR, + "snmpTriggerTable: can't get master pdu for authentication params\n"); + } + } + + if (pdu) { + DEBUGMSGTL(("mteTriggerTest", "copying PDU auth info\n")); + StorageTmp->pdu_version = pdu->version; + StorageTmp->pdu_securityModel = pdu->securityModel; + StorageTmp->pdu_securityLevel = pdu->securityLevel; + StorageTmp->pdu_tDomain = pdu->tDomain; + StorageTmp->pdu_tDomainLen = pdu->tDomainLen; + if (pdu->transport_data != NULL) { + StorageTmp->pdu_transport = + malloc(pdu->transport_data_length); + memcpy(StorageTmp->pdu_transport, pdu->transport_data, + pdu->transport_data_length); + } + StorageTmp->pdu_transportLen = pdu->transport_data_length; + if (pdu->community) { + StorageTmp->pdu_community = + calloc(1, pdu->community_len + 1); + memcpy(StorageTmp->pdu_community, pdu->community, + pdu->community_len); + StorageTmp->pdu_community_len = pdu->community_len; + } else { + StorageTmp->pdu_community = NULL; + StorageTmp->pdu_community_len = 0; + } + if (pdu->securityName) { + StorageTmp->pdu_securityName = + calloc(1, pdu->securityNameLen + 1); + memcpy(StorageTmp->pdu_securityName, pdu->securityName, + pdu->securityNameLen); + StorageTmp->pdu_securityNameLen = pdu->securityNameLen; + } else { + StorageTmp->pdu_securityName = NULL; + StorageTmp->pdu_securityNameLen = 0; + } + StorageTmp->have_copied_auth_info = 1; + } + } + + if (StorageTmp && + StorageTmp->mteTriggerEnabled == MTETRIGGERENABLED_TRUE && + StorageTmp->mteTriggerEntryStatus == RS_ACTIVE) + mte_enable_trigger(StorageTmp); + snmp_store_needed(NULL); + break; + } + return SNMP_ERR_NOERROR; +} /* write_mteTriggerEntryStatus */ + +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + + + +/* + * send trap + */ +void +send_mte_trap(struct mteTriggerTable_data *item, + oid * trap_oid, size_t trap_oid_len, + oid * name_oid, size_t name_oid_len, + long *value, const char *objowner, const char *objname, + const char *reason) +{ + static oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; /* snmpTrapIOD.0 */ + + netsnmp_variable_list *var_list = NULL; + + /* + * snmpTrap oid + */ + snmp_varlist_add_variable(&var_list, objid_snmptrap, + sizeof(objid_snmptrap) / sizeof(oid), + ASN_OBJECT_ID, (u_char *) trap_oid, + trap_oid_len * sizeof(oid)); + + /* + * mteHotTrigger + */ + snmp_varlist_add_variable(&var_list, mteHotTrigger, + sizeof(mteHotTrigger) / sizeof(oid), + ASN_OCTET_STR, + (u_char *) item->mteTriggerName, + item->mteTriggerNameLen); + + /* + * mteHotTargetName + */ + snmp_varlist_add_variable(&var_list, mteHotTargetName, sizeof(mteHotTargetName) / sizeof(oid), ASN_OCTET_STR, (u_char *) item->mteTriggerTargetTag, /*XXX: targetName,not tag */ + item->mteTriggerTargetTagLen); /*XXX */ + + /* + * mteHotContextName + */ + snmp_varlist_add_variable(&var_list, mteHotContextName, + sizeof(mteHotContextName) / sizeof(oid), + ASN_OCTET_STR, + (u_char *) item->mteTriggerContextName, + item->mteTriggerContextNameLen); + + snmp_varlist_add_variable(&var_list, mteHotOID, + sizeof(mteHotOID) / sizeof(oid), + ASN_OBJECT_ID, (u_char *) name_oid, + sizeof(oid) * name_oid_len); + + if (trap_oid == mteTriggerFailure || trap_oid == mteEventSetFailure) { + /* + * mteFailedReason + */ + snmp_varlist_add_variable(&var_list, mteFailedReason, + sizeof(mteFailedReason) / sizeof(oid), + ASN_INTEGER, (u_char *) value, + sizeof(value)); + } else { + /* + * mteHotValue + */ + snmp_varlist_add_variable(&var_list, mteHotValue, + sizeof(mteHotValue) / sizeof(oid), + ASN_INTEGER, (u_char *) value, + sizeof(value)); + } + + /* + * add in traps from main table + */ + mte_add_objects(var_list, item, item->mteTriggerObjectsOwner, + item->mteTriggerObjects, + name_oid + item->mteTriggerValueIDLen, + name_oid_len - item->mteTriggerValueIDLen); + /* + * add in traps from sub table + */ + mte_add_objects(var_list, item, objowner, objname, + name_oid + item->mteTriggerValueIDLen, + name_oid_len - item->mteTriggerValueIDLen); + + /* + * XXX: stuff based on event table + */ + DEBUGMSGTL(("mteTriggerTest:send_mte_trap", "sending the trap (%s): ", + reason)); + DEBUGMSGOID(("mteTriggerTest:send_mte_trap", name_oid, name_oid_len)); + DEBUGMSG(("mteTriggerTest:send_mte_trap", " = %ld\n", *value)); + + send_v2trap(var_list); + snmp_free_varbind(var_list); +} /* send_mte_trap */ + + +void +last_state_clean(void *data) +{ + struct last_state *cleanme = (struct last_state *) data; + SNMP_FREE(cleanme->value); + SNMP_FREE(cleanme); +} + + +/* + * retrieves requested info in pdu from the current target + */ +netsnmp_pdu * +mte_get_response(struct mteTriggerTable_data *item, netsnmp_pdu *pdu) +{ + netsnmp_pdu *response = NULL; + int status = 0; + char buf[SPRINT_MAX_LEN]; + + /* + * local agent check + */ + pdu->errstat = SNMPERR_SUCCESS; + pdu->errindex = 0; + pdu->version = item->pdu_version; + pdu->securityModel = item->pdu_securityModel; + pdu->securityLevel = item->pdu_securityLevel; + pdu->tDomain = item->pdu_tDomain; + pdu->tDomainLen = item->pdu_tDomainLen; + memdup((u_char **) & pdu->transport_data, item->pdu_transport, + item->pdu_transportLen); + pdu->transport_data_length = item->pdu_transportLen; + memdup(&pdu->community, item->pdu_community, item->pdu_community_len); + pdu->community_len = item->pdu_community_len; + memdup((u_char **) & pdu->contextName, item->mteTriggerContextName, + item->mteTriggerContextNameLen); + pdu->contextNameLen = item->mteTriggerContextNameLen; + memdup((u_char **) & pdu->securityName, item->pdu_securityName, + item->pdu_securityNameLen); + pdu->securityNameLen = item->pdu_securityNameLen; + DEBUGMSGTL(("mteTriggerTable", + "accessing locally with secName \"%s\" community \"%s\"\n", + item->pdu_securityName ? (char *) item-> + pdu_securityName : "[NIL]", + item->pdu_community ? (char *) item-> + pdu_community : "[NIL]")); + + if (item->mteTriggerTargetTagLen == 0) { + /* + * send to the local agent + */ + + if (mte_callback_sess == NULL) + mte_callback_sess = netsnmp_query_get_default_session(); + if (!mte_callback_sess) + return NULL; + + status = snmp_synch_response(mte_callback_sess, pdu, &response); + + if (status != SNMP_ERR_NOERROR || + response->errstat != SNMP_ERR_NOERROR) { + /* + * xxx + */ + char *errstr; + snmp_error(mte_callback_sess, 0, 0, &errstr); + if (response) { + DEBUGMSGTL(("mteTriggerTable", + "Error received: status=%d, sess_error=%s, pduerr=%d/%s, pdu version=%d\n", + status, errstr, + response->errstat, + snmp_api_errstring(response->errstat), + response->version)); + } else { + DEBUGMSGTL(("mteTriggerTable", + "Error received: status=%d, sess_error=%s [no response pointer]\n", + status, errstr)); + } + if (errstr) + free(errstr); + return NULL; /* XXX: proper failure, trap sent, etc */ + } + } else { + /* + * remote target list + */ + /* + * XXX + */ + } + if (response->variables) + snprint_variable(buf, sizeof(buf), response->variables->name, + response->variables->name_length, + response->variables); + else + strcpy(buf, "empty"); + buf[sizeof(buf) - 1] = '\0'; + DEBUGMSGTL(("mteTriggerTable", "got a variables: %s\n", buf)); + return response; +} /* mte_get_response */ + + +/* + * Return 1 if `type' is an integer type; specifically, to quote RFC 2981, + * p. 13, "anything that ends up encoded for transmission (that is, in BER, + * not ASN.1) as an integer". Return 0 for all other types. + */ + +int +mte_is_integer_type(unsigned char type) +{ + switch (type) { + case ASN_INTEGER: + case ASN_COUNTER: + case ASN_GAUGE: + case ASN_TIMETICKS: + case ASN_UINTEGER: + case ASN_COUNTER64: +#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES + case ASN_OPAQUE_COUNTER64: + case ASN_OPAQUE_U64: + case ASN_OPAQUE_I64: +#endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ + return 1; + default: + return 0; + } +} + + +/* + * Return 0 if the discontinuity object was checked and no discontinuity has + * occurred, 1 if the discontinuity object was checked and a discontinuity + * has occurred or -1 if the discontinuity object is not accessible. + */ + +int +mte_discontinuity_occurred(struct mteTriggerTable_data *item) +{ + netsnmp_pdu *pdu = NULL, *response = NULL; + unsigned long discoTicks = 0; /* cool var name */ + + if (item->mteTriggerDeltaDiscontinuityIDLen == 0 || + (snmp_oid_compare(item->mteTriggerDeltaDiscontinuityID, + item->mteTriggerDeltaDiscontinuityIDLen, + sysUpTimeInstance, + sizeof(sysUpTimeInstance) / sizeof(oid)) == 0)) { + DEBUGMSGTL(("mte_disco", + "discoID either zero-length or sysUpTimeInstance\n")); + } else { + if (item->mteTriggerValueIDWildcard == TV_TRUE) { + pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); + } else { + pdu = snmp_pdu_create(SNMP_MSG_GET); + } + snmp_add_null_var(pdu, item->mteTriggerDeltaDiscontinuityID, + item->mteTriggerDeltaDiscontinuityIDLen); + response = mte_get_response(item, pdu); + if (response == NULL) { + /* + * XXX: send a mteTriggerFailure notification with the appropriate + * error code here. + */ + /* + * "If the object identified is not accessible the sample attempt is in + * error, with the error code as from an SNMP request." + */ + DEBUGMSGTL(("mte_disco", "failure (auth?) getting discoID\n")); + return -1; + } else { + if (item->mteTriggerDeltaDiscontinuityIDType == + MTETRIGGERDELTADISCONTINUITYIDTYPE_TIMETICKS || + item->mteTriggerDeltaDiscontinuityIDType == + MTETRIGGERDELTADISCONTINUITYIDTYPE_TIMESTAMP) { + if (response->errstat == SNMPERR_SUCCESS) { + if (response->variables != NULL && + response->variables->type == ASN_TIMETICKS) { + DEBUGMSGTL(("mte_disco", + "got ASN_TIMETICKS-valued variable\n")); + discoTicks = + *((unsigned long *) response->variables->val. + integer); + if (item->prevDiscoTicks != 0) { + if (discoTicks != item->prevDiscoTicks) { + /* + * Danger Will Robinson: there has been a discontinuity! + */ + DEBUGMSGTL(("mte_disco", + "a discontinuity has occurred\n")); + item->prevDiscoTicks = discoTicks; + snmp_free_pdu(response); + return 1; + } + } + item->prevDiscoTicks = discoTicks; + } else { + /* + * XXX: send a mteTriggerFailure notification with the + * appropriate error code here. + */ + if (response->variables != NULL && + (response->variables->type == SNMP_NOSUCHOBJECT + || response->variables->type == + SNMP_NOSUCHINSTANCE + || response->variables->type == + SNMP_ENDOFMIBVIEW)) { + /* + * noSuchName I guess. + */ + } else { + /* + * badType. + */ + } + DEBUGMSGTL(("mte_disco", + "failure getting discoID\n")); + snmp_free_pdu(response); + return -1; + } + } else { + /* + * XXX: send a mteTriggerFailure notification with the appropriate + * error code (just use response->errstat) here. + */ + DEBUGMSGTL(("mte_disco", "failure getting discoID\n")); + snmp_free_pdu(response); + return -1; + } + } else { + /* + * Don't handle dateAndTime type queries yet. + */ + DEBUGMSGTL(("mte_disco", + "dateAndTime query UNIMPLEMENTED\n")); + } + snmp_free_pdu(response); + } + } + + /* + * "...if this object does not point to sysUpTime discontinuity checking + * MUST still check sysUpTime for an overall discontinuity." + */ + if (snmp_oid_compare(item->mteTriggerDeltaDiscontinuityID, + item->mteTriggerDeltaDiscontinuityIDLen, + sysUpTimeInstance, + sizeof(sysUpTimeInstance) / sizeof(oid)) != 0) { + DEBUGMSGTL(("mte_disco", "discoID != sysUpTimeInstance\n")); + /* + * At the moment we only support checking the local system so there's no + * point doing anything extra here. + */ + } + + /* + * Well if we got all the way to here, then there has been neither a + * discontinuity nor an error. + */ + DEBUGMSGTL(("mte_disco", "no discontinuity\n")); + return 0; +} /* mte_discontinuity_occurred */ + + +void +mte_run_trigger(unsigned int clientreg, void *clientarg) +{ + + struct mteTriggerTable_data *item = + (struct mteTriggerTable_data *) clientarg; + netsnmp_pdu *pdu = NULL, *response = NULL; + char buf[SPRINT_MAX_LEN]; + int msg_type = SNMP_MSG_GET, disco; + + oid *next_oid; + size_t next_oid_len; + long *value, *old_value, x; + struct last_state *laststate; + char lastbool = 0, boolresult = 0, lastthresh = 0; + + if (!item) { + /* + * ack + */ + snmp_alarm_unregister(clientreg); + return; + } + DEBUGMSGTL(("mteTriggertable", "Running trigger for %s/%s\n", + item->mteOwner, item->mteTriggerName)); + + next_oid = item->mteTriggerValueID; + next_oid_len = item->mteTriggerValueIDLen; + if (item->mteTriggerValueIDWildcard == TV_TRUE) + msg_type = SNMP_MSG_GETNEXT; + + item->hc_storage_old = item->hc_storage; + item->hc_storage = NULL; + do { + pdu = snmp_pdu_create(msg_type); + snmp_add_null_var(pdu, next_oid, next_oid_len); + + if(response) + snmp_free_pdu(response); + + response = mte_get_response(item, pdu); + if (!response) + break; /* XXX: proper failure */ + + if (item->mteTriggerValueIDWildcard == TV_TRUE && + ((response->variables->type >= SNMP_NOSUCHOBJECT && + response->variables->type <= SNMP_ENDOFMIBVIEW) || + snmp_oid_compare(item->mteTriggerValueID, + item->mteTriggerValueIDLen, + response->variables->name, + item->mteTriggerValueIDLen) != 0)) { + DEBUGMSGTL(("mteTriggerTable", + "DONE, last varbind processed\n")); + break; + } + + /* + * shorter pointers + */ + next_oid = response->variables->name; + next_oid_len = response->variables->name_length; + + /* + * Send a "bad type" notification if the type of the target object is + * non-INTEGER and the test type is either `boolean' or `threshold' + * (which want to do arithmetic). + */ + if (((item->mteTriggerTest[0] & MTETRIGGERTEST_BOOLEAN) || + (item->mteTriggerTest[0] & MTETRIGGERTEST_THRESHOLD)) && + response->errstat == SNMPERR_SUCCESS && + !mte_is_integer_type(response->variables->type)) { + long failure = MTE_FAILURE_BADTYPE; + send_mte_trap(item, mteTriggerFailure, + sizeof(mteTriggerFailure) / sizeof(oid), + next_oid, next_oid_len, &failure, + NULL, NULL, "failure: bad type"); + /* + * RFC2981, p.15: "If the value syntax of those objects + * [returned by a getNext-style match] is not usable, that + * results in a `badType' error THAT TERMINATES THE SCAN." + * (my emphasis). + */ + break; + } + + /* + * Clone the value. XXX: What happens if it's an unsigned type? Or a + * 64-bit type, or an OCTET STRING for the sake of argument. Do + * everything in 64-bit arithmetic perhaps? Generate "bad type" + * notifications for non-INTEGER cases (except for existence). + */ + if (response->errstat == SNMPERR_SUCCESS && + response->variables->val.integer) + memdup((unsigned char **) &value, + (unsigned char *) response->variables->val.integer, + sizeof(*response->variables->val.integer)); + else + value = NULL; + + snprint_variable(buf, sizeof(buf), + next_oid, next_oid_len, response->variables); + buf[sizeof(buf) - 1] = '\0'; + DEBUGMSGTL(("mteTriggerTable", "received %s (type %d)\n", buf, + response->variables->type)); + + /* + * see if we have old values for this + */ + laststate = header_complex_get_from_oid(item->hc_storage_old, + next_oid, next_oid_len); + if (laststate) { + old_value = laststate->value; + lastbool = laststate->lastbool; + lastthresh = laststate->lastthreshold; + } else { + old_value = NULL; + lastthresh = MTE_THRESHOLD_BEGIN; + } + + /* + * deal with existence tests + */ + if (item->mteTriggerTest[0] & MTETRIGGERTEST_EXISTENCE) { + if ((item->mteTriggerExistenceTest[0] & + MTETRIGGEREXISTENCETEST_PRESENT) + && value && !old_value && + (item->started || + (item->mteTriggerExistenceStartup[0] & + MTETRIGGEREXISTENCESTARTUP_PRESENT))) { + /* + * XXX: if mteTriggerExistenceTest is not "present", for + * example, and then turned on when has been previously + * off, do we respect the value of the last known + * existence status? + */ + send_mte_trap(item, mteTriggerFired, + sizeof(mteTriggerFired) / sizeof(oid), + next_oid, next_oid_len, + value, item->mteTriggerExistenceObjectsOwner, + item->mteTriggerExistenceObjects, + "existence: present"); + run_mte_events(item, next_oid, next_oid_len, + item->mteTriggerExistenceEventOwner, + item->mteTriggerExistenceEvent); + } + + if ((item->mteTriggerExistenceTest[0] & + MTETRIGGEREXISTENCETEST_CHANGED) + && value && old_value && *old_value != *value) { + /* + * XXX: if mteTriggerExistenceTest is not "present", for + * example, and then turned on when has been previously + * off, do we respect the value of the last known + * existence status? + */ + send_mte_trap(item, mteTriggerFired, + sizeof(mteTriggerFired) / sizeof(oid), + next_oid, next_oid_len, + value, item->mteTriggerExistenceObjectsOwner, + item->mteTriggerExistenceObjects, + "existence: changed"); + run_mte_events(item, next_oid, next_oid_len, + item->mteTriggerExistenceEventOwner, + item->mteTriggerExistenceEvent); + } + } + + /* + * Deal with boolean tests. + */ + if ((item->mteTriggerTest[0] & MTETRIGGERTEST_BOOLEAN) && + ((item->mteTriggerSampleType == + MTETRIGGERSAMPLETYPE_ABSOLUTEVALUE && value) + || (item->mteTriggerSampleType == + MTETRIGGERSAMPLETYPE_DELTAVALUE && value && old_value))) { + if (item->mteTriggerSampleType == + MTETRIGGERSAMPLETYPE_DELTAVALUE) { + /* + * XXX: Must check the discontinuity OID here. + */ + disco = mte_discontinuity_occurred(item); + if (disco == -1) { + /* + * An error notification has already been sent; just bail + * out now. + */ + /* + * XXX: should save values here? + */ + return; + } else if (disco == 1) { + /* + * A discontinuity has occurred; the right thing to do here + * depends on the exact type. FOR NOW, assume long. + */ + x = *((long *) value) + (INT_MAX - + *((long *) old_value)); + } else { + x = *((long *) value) - *((long *) old_value); + } + } else { + x = *((long *) value); + } + + switch (item->mteTriggerBooleanComparison) { + case MTETRIGGERBOOLEANCOMPARISON_UNEQUAL: + boolresult = (x != item->mteTriggerBooleanValue); + break; + + case MTETRIGGERBOOLEANCOMPARISON_EQUAL: + boolresult = (x == item->mteTriggerBooleanValue); + break; + + case MTETRIGGERBOOLEANCOMPARISON_LESS: + boolresult = (x < item->mteTriggerBooleanValue); + break; + + case MTETRIGGERBOOLEANCOMPARISON_LESSOREQUAL: + boolresult = (x <= item->mteTriggerBooleanValue); + break; + + case MTETRIGGERBOOLEANCOMPARISON_GREATER: + boolresult = (x > item->mteTriggerBooleanValue); + break; + + case MTETRIGGERBOOLEANCOMPARISON_GREATEROREQUAL: + boolresult = (x >= item->mteTriggerBooleanValue); + break; + + default: + snmp_log(LOG_WARNING, + "illegal value in mteTriggerBooleanComparison object: %ld", + item->mteTriggerBooleanComparison); + boolresult = item->lastboolresult; /* to fail next test */ + } + + if (boolresult && + ((item->mteTriggerBooleanStartup == + MTETRIGGERBOOLEANSTARTUP_TRUE + && lastbool == (char)-1) || lastbool != boolresult)) { + send_mte_trap(item, mteTriggerFired, + sizeof(mteTriggerFired) / sizeof(oid), + next_oid, next_oid_len, + &x, item->mteTriggerBooleanObjectsOwner, + item->mteTriggerBooleanObjects, + "boolean: true"); + run_mte_events(item, next_oid, next_oid_len, + item->mteTriggerBooleanEventOwner, + item->mteTriggerBooleanEvent); + } + + DEBUGMSGTL(("mteTriggerTable", + "value: %d %ld %lu x: %d %ld %lu\n", *value, + *value, *value, x, x, x)); + + DEBUGMSGTL(("mteTriggerTable", + "boolean result: x=%d %s configured=%d = %d\n", + x, + se_find_label_in_slist("mteBooleanOperators", + item-> + mteTriggerBooleanComparison), + item->mteTriggerBooleanValue, boolresult)); + } + + /* + * Deal with threshold tests. XXX: doesn't handle "delta-type" + * sampling. + */ + if ((item->mteTriggerTest[0] & MTETRIGGERTEST_THRESHOLD) && + ((item->mteTriggerSampleType == + MTETRIGGERSAMPLETYPE_ABSOLUTEVALUE && value) + || (item->mteTriggerSampleType == + MTETRIGGERSAMPLETYPE_DELTAVALUE && value && old_value))) { + /* + * XXX: correct intepretation of mteTriggerThresholdStartup? + */ + /* + * only fires when passed and just set to active? What + * about a newly discovered node that is past a + * threshold once we've been active for a turn at least? + */ + /* + * XXX: Check notions of > vs >= + */ + if (((item->started == MTE_STARTED && laststate && + lastthresh == MTE_THRESHOLD_LOW) || + (item->started != MTE_STARTED && + (item->mteTriggerThresholdStartup == + MTETRIGGERTHRESHOLDSTARTUP_RISING + || item->mteTriggerThresholdStartup == + MTETRIGGERTHRESHOLDSTARTUP_RISINGORFALLING))) + && (*value >= item->mteTriggerThresholdRising)) { + send_mte_trap(item, mteTriggerRising, + sizeof(mteTriggerRising) / sizeof(oid), + next_oid, next_oid_len, value, + item->mteTriggerThresholdObjectsOwner, + item->mteTriggerThresholdObjects, + "threshold: rising"); + run_mte_events(item, next_oid, next_oid_len, + item->mteTriggerThresholdRisingEventOwner, + item->mteTriggerThresholdRisingEvent); + } + if (((item->started == MTE_STARTED && laststate && + lastthresh == MTE_THRESHOLD_HIGH) || + (item->started != MTE_STARTED && + (item->mteTriggerThresholdStartup == + MTETRIGGERTHRESHOLDSTARTUP_FALLING + || item->mteTriggerThresholdStartup == + MTETRIGGERTHRESHOLDSTARTUP_RISINGORFALLING))) + && (*value <= item->mteTriggerThresholdFalling)) { + send_mte_trap(item, mteTriggerFalling, + sizeof(mteTriggerFalling) / sizeof(oid), + next_oid, next_oid_len, value, + item->mteTriggerThresholdObjectsOwner, + item->mteTriggerThresholdObjects, + "threshold: falling"); + run_mte_events(item, next_oid, next_oid_len, + item->mteTriggerThresholdFallingEventOwner, + item->mteTriggerThresholdFallingEvent); + } + + } + + if (value) { + struct last_state *new_last_state = + SNMP_MALLOC_STRUCT(last_state); + new_last_state->value = value; + new_last_state->lastbool = boolresult; + header_complex_add_data_by_oid(&item->hc_storage, next_oid, + next_oid_len, new_last_state); + + /* + * set our notion of the current known threshold state + */ + if (lastthresh == MTE_THRESHOLD_LOW && + *value >= item->mteTriggerThresholdRising && + *value > item->mteTriggerThresholdFalling) + new_last_state->lastthreshold = MTE_THRESHOLD_HIGH; + else if (lastthresh == MTE_THRESHOLD_HIGH && + *value < item->mteTriggerThresholdRising && + *value <= item->mteTriggerThresholdFalling) + new_last_state->lastthreshold = MTE_THRESHOLD_LOW; + else if (lastthresh == MTE_THRESHOLD_BEGIN) { + if (*value >= item->mteTriggerThresholdRising) + new_last_state->lastthreshold = MTE_THRESHOLD_HIGH; + else if (*value <= item->mteTriggerThresholdFalling) + new_last_state->lastthreshold = MTE_THRESHOLD_LOW; + /* + * XXX: else??? in between? undefined? + */ + } else { + new_last_state->lastthreshold = lastthresh; + } + } + + /* + * extract from old hc storage + */ + if (laststate) { + header_complex_extract_entry(&item->hc_storage_old, + header_complex_find_entry(item-> + hc_storage_old, + (void *) + laststate)); + last_state_clean(laststate); + } + + } while (item->mteTriggerValueIDWildcard == TV_TRUE); + + if(response) + snmp_free_pdu(response); + + /* + * loop through old values for DNE cases + */ + if (item->mteTriggerExistenceTest[0] & MTETRIGGEREXISTENCETEST_ABSENT) { + + struct header_complex_index *iter; + + /* + * XXX: broken + */ + if ((item->mteTriggerExistenceStartup[0] & + MTETRIGGEREXISTENCESTARTUP_ABSENT)) { + /* + * XXX: send trap that nothing was found? + */ + /* + * only if !wild? (see mib) + */ + } + for (iter = item->hc_storage_old; iter; iter = iter->next) { + laststate = (struct last_state *) iter->data; + send_mte_trap(item, mteTriggerFired, + sizeof(mteTriggerFired) / sizeof(oid), + iter->name, iter->namelen, laststate->value, + item->mteTriggerExistenceObjectsOwner, + item->mteTriggerExistenceObjects, + "existence: absent"); + } + header_complex_free_all(item->hc_storage_old, last_state_clean); + item->hc_storage_old = NULL; + } + + item->started = MTE_STARTED; +} /* mte_run_trigger */ + + + +/* + * handling routines + */ +void +mte_enable_trigger(struct mteTriggerTable_data *item) +{ + if (!item) + return; + + if (item->alarmreg) + snmp_alarm_unregister(item->alarmreg); + + if (item->mteTriggerFrequency > 0) { + DEBUGMSGTL(("mteTriggertable", "Enabling trigger for %s/%s @ %u\n", + item->mteOwner, item->mteTriggerName, + item->mteTriggerFrequency)); + item->alarmreg = + snmp_alarm_register(item->mteTriggerFrequency, SA_REPEAT, + mte_run_trigger, item); + } +} + +void +mte_disable_trigger(struct mteTriggerTable_data *item) +{ + if (!item) + return; + + if (item->alarmreg) { + DEBUGMSGTL(("mteTriggertable", "Disabling trigger for %s/%s\n", + item->mteOwner, item->mteTriggerName)); + snmp_alarm_unregister(item->alarmreg); + item->alarmreg = 0; + } + item->started = MTE_NOTSTARTED; +} |