diff options
Diffstat (limited to 'agent/mibgroup/notification')
-rw-r--r-- | agent/mibgroup/notification/snmpNotifyFilterProfileTable.c | 847 | ||||
-rw-r--r-- | agent/mibgroup/notification/snmpNotifyFilterProfileTable.h | 69 | ||||
-rw-r--r-- | agent/mibgroup/notification/snmpNotifyTable.c | 1222 | ||||
-rw-r--r-- | agent/mibgroup/notification/snmpNotifyTable.h | 76 |
4 files changed, 2214 insertions, 0 deletions
diff --git a/agent/mibgroup/notification/snmpNotifyFilterProfileTable.c b/agent/mibgroup/notification/snmpNotifyFilterProfileTable.c new file mode 100644 index 0000000..b12cdc8 --- /dev/null +++ b/agent/mibgroup/notification/snmpNotifyFilterProfileTable.c @@ -0,0 +1,847 @@ +/* + * 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 <sys/types.h> +#if HAVE_STDLIB_H +#include <stdlib.h> +#endif +#if HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif + + +/* + * minimal include directives + */ +#include <net-snmp/net-snmp-features.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +#include "header_complex.h" +#include "snmpNotifyFilterProfileTable.h" + +#ifndef NETSNMP_NO_WRITE_SUPPORT +netsnmp_feature_require(header_complex_find_entry) +#endif /* NETSNMP_NO_WRITE_SUPPORT */ + +/* + * snmpNotifyFilterProfileTable_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. + */ + + +oid snmpNotifyFilterProfileTable_variables_oid[] = + { 1, 3, 6, 1, 6, 3, 13, 1, 2 }; + + +/* + * variable2 snmpNotifyFilterProfileTable_variables: + * this variable defines function callbacks and type return information + * for the snmpNotifyFilterProfileTable mib section + */ + + +struct variable2 snmpNotifyFilterProfileTable_variables[] = { + /* + * magic number , variable type , ro/rw , callback fn , L, oidsuffix + */ +#define SNMPNOTIFYFILTERPROFILENAME 3 + {SNMPNOTIFYFILTERPROFILENAME, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_snmpNotifyFilterProfileTable, 2, {1, 1}}, +#define SNMPNOTIFYFILTERPROFILESTORTYPE 4 + {SNMPNOTIFYFILTERPROFILESTORTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_snmpNotifyFilterProfileTable, 2, {1, 2}}, +#define SNMPNOTIFYFILTERPROFILEROWSTATUS 5 + {SNMPNOTIFYFILTERPROFILEROWSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_snmpNotifyFilterProfileTable, 2, {1, 3}}, + +}; +/* + * (L = length of the oidsuffix) + */ + + +/* + * global storage of our data, saved in and configured by header_complex() + */ +static struct header_complex_index *snmpNotifyFilterProfileTableStorage = + NULL; + + + + +/* + * init_snmpNotifyFilterProfileTable(): + * Initialization routine. This is called when the agent starts up. + * At a minimum, registration of your variables should take place here. + */ +void +init_snmpNotifyFilterProfileTable(void) +{ + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "initializing... ")); + + + /* + * register ourselves with the agent to handle our mib tree + */ + REGISTER_MIB("snmpNotifyFilterProfileTable", + snmpNotifyFilterProfileTable_variables, variable2, + snmpNotifyFilterProfileTable_variables_oid); + + + /* + * register our config handler(s) to deal with registrations + */ + snmpd_register_config_handler("snmpNotifyFilterProfileTable", + parse_snmpNotifyFilterProfileTable, NULL, + NULL); + + + + + /* + * we need to be called back later to store our data + */ + snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, + store_snmpNotifyFilterProfileTable, NULL); + + + /* + * place any other initialization junk you need here + */ + + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "done.\n")); +} + + +/* + * snmpNotifyFilterProfileTable_add(): adds a structure node to our data set + */ +int +snmpNotifyFilterProfileTable_add(struct snmpNotifyFilterProfileTable_data + *thedata) +{ + netsnmp_variable_list *vars = NULL; + int retVal; + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "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_PRIV_IMPLIED_OCTET_STR, + (u_char *) thedata->snmpTargetParamsName, + thedata->snmpTargetParamsNameLen); + + if (header_complex_maybe_add_data(&snmpNotifyFilterProfileTableStorage, vars, + thedata, 1) != NULL){ + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "registered an entry\n")); + retVal = SNMPERR_SUCCESS; + }else{ + retVal = SNMPERR_GENERR; + } + + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "done.\n")); + return retVal; +} + + +/* + * parse_snmpNotifyFilterProfileTable(): + * parses .conf file entries needed to configure the mib. + */ +void +parse_snmpNotifyFilterProfileTable(const char *token, char *line) +{ + size_t tmpint; + struct snmpNotifyFilterProfileTable_data *StorageTmp = + SNMP_MALLOC_STRUCT(snmpNotifyFilterProfileTable_data); + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "parsing config... ")); + + if (StorageTmp == NULL) { + config_perror("malloc failure"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->snmpTargetParamsName, + &StorageTmp->snmpTargetParamsNameLen); + if (StorageTmp->snmpTargetParamsName == NULL) { + config_perror("invalid specification for snmpTargetParamsName"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->snmpNotifyFilterProfileName, + &StorageTmp->snmpNotifyFilterProfileNameLen); + if (StorageTmp->snmpNotifyFilterProfileName == NULL) { + config_perror("invalid specification for snmpNotifyFilterProfileName"); + SNMP_FREE(StorageTmp); + return; + } + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->snmpNotifyFilterProfileStorType, + &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp-> + snmpNotifyFilterProfileRowStatus, &tmpint); + + if (snmpNotifyFilterProfileTable_add(StorageTmp) != SNMPERR_SUCCESS){ + SNMP_FREE(StorageTmp->snmpTargetParamsName); + SNMP_FREE(StorageTmp->snmpNotifyFilterProfileName); + SNMP_FREE(StorageTmp); + } + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "done.\n")); +} + + + + +/* + * store_snmpNotifyFilterProfileTable(): + * stores .conf file entries needed to configure the mib. + */ +int +store_snmpNotifyFilterProfileTable(int majorID, int minorID, + void *serverarg, void *clientarg) +{ + char line[SNMP_MAXBUF]; + char *cptr; + struct snmpNotifyFilterProfileTable_data *StorageTmp; + struct header_complex_index *hcindex; + + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "storing data... ")); + + for (hcindex = snmpNotifyFilterProfileTableStorage; hcindex != NULL; + hcindex = hcindex->next) { + StorageTmp = + (struct snmpNotifyFilterProfileTable_data *) hcindex->data; + + if ((StorageTmp->snmpNotifyFilterProfileStorType == ST_NONVOLATILE) || + (StorageTmp->snmpNotifyFilterProfileStorType == ST_PERMANENT)) { + + memset(line, 0, sizeof(line)); + strcat(line, "snmpNotifyFilterProfileTable "); + cptr = line + strlen(line); + + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->snmpTargetParamsName, + &StorageTmp-> + snmpTargetParamsNameLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp-> + snmpNotifyFilterProfileName, + &StorageTmp-> + snmpNotifyFilterProfileNameLen); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + snmpNotifyFilterProfileStorType, + NULL); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp-> + snmpNotifyFilterProfileRowStatus, + NULL); + + snmpd_store_config(line); + } + } + DEBUGMSGTL(("snmpNotifyFilterProfileTable", "done.\n")); + return 0; +} + + + + +/* + * var_snmpNotifyFilterProfileTable(): + * Handle this table separately from the scalar value case. + * The workings of this are basically the same as for var_snmpNotifyFilterProfileTable above. + */ +unsigned char * +var_snmpNotifyFilterProfileTable(struct variable *vp, + oid * name, + size_t * length, + int exact, + size_t * var_len, + WriteMethod ** write_method) +{ + + + struct snmpNotifyFilterProfileTable_data *StorageTmp = NULL; + int found = 1; + + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", + "var_snmpNotifyFilterProfileTable: Entering... \n")); + /* + * this assumes you have registered all your data properly + */ + if ((StorageTmp = (struct snmpNotifyFilterProfileTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyFilterProfileTableStorage, vp, name, + length, exact, var_len, write_method)) == NULL) { + found = 0; + } + + switch (vp->magic) { +#ifndef NETSNMP_NO_WRITE_SUPPORT + case SNMPNOTIFYFILTERPROFILENAME: + *write_method = write_snmpNotifyFilterProfileName; + break; + + case SNMPNOTIFYFILTERPROFILESTORTYPE: + *write_method = write_snmpNotifyFilterProfileStorType; + break; + + case SNMPNOTIFYFILTERPROFILEROWSTATUS: + *write_method = write_snmpNotifyFilterProfileRowStatus; + break; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + default: + *write_method = NULL; + } + + if (!found) { + return NULL; + } + + /* + * this is where we do the value assignments for the mib results. + */ + switch (vp->magic) { + + case SNMPNOTIFYFILTERPROFILENAME: + *var_len = StorageTmp->snmpNotifyFilterProfileNameLen; + return (u_char *) StorageTmp->snmpNotifyFilterProfileName; + + case SNMPNOTIFYFILTERPROFILESTORTYPE: + *var_len = sizeof(StorageTmp->snmpNotifyFilterProfileStorType); + return (u_char *) & StorageTmp->snmpNotifyFilterProfileStorType; + + case SNMPNOTIFYFILTERPROFILEROWSTATUS: + *var_len = sizeof(StorageTmp->snmpNotifyFilterProfileRowStatus); + return (u_char *) & StorageTmp->snmpNotifyFilterProfileRowStatus; + + + default: + ERROR_MSG(""); + } + + return NULL; +} + + + +static struct snmpNotifyFilterProfileTable_data *StorageNew; + +#ifndef NETSNMP_NO_WRITE_SUPPORT + +int +write_snmpNotifyFilterProfileName(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 snmpNotifyFilterProfileTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - + (sizeof(snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", + "write_snmpNotifyFilterProfileName entering action=%d... \n", + action)); + if (action != RESERVE1 && + (StorageTmp = (struct snmpNotifyFilterProfileTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyFilterProfileTableStorage, NULL, + &name[sizeof + (snmpNotifyFilterProfileTable_variables_oid) + / sizeof(oid) + 3 - 1], &newlen, 1, NULL, + NULL)) == NULL) { + if ((StorageTmp = StorageNew) == NULL) + return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ + } + + + switch (action) { + case RESERVE1: + if (var_val_type != ASN_OCTET_STR) { + return SNMP_ERR_WRONGTYPE; + } + if (var_val_len < 1 || var_val_len > 32) { + return SNMP_ERR_WRONGLENGTH; + } + break; + + + case RESERVE2: + /* + * memory reseveration, final preparation... + */ + tmpvar = StorageTmp->snmpNotifyFilterProfileName; + tmplen = StorageTmp->snmpNotifyFilterProfileNameLen; + StorageTmp->snmpNotifyFilterProfileName = (char*)calloc(1, var_val_len + 1); + if (NULL == StorageTmp->snmpNotifyFilterProfileName) + return SNMP_ERR_RESOURCEUNAVAILABLE; + 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 + */ + memcpy(StorageTmp->snmpNotifyFilterProfileName, var_val, var_val_len); + StorageTmp->snmpNotifyFilterProfileNameLen = var_val_len; + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->snmpNotifyFilterProfileName); + StorageTmp->snmpNotifyFilterProfileName = tmpvar; + StorageTmp->snmpNotifyFilterProfileNameLen = 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; +} + + + +int +write_snmpNotifyFilterProfileStorType(int action, + u_char * var_val, + u_char var_val_type, + size_t var_val_len, + u_char * statP, + oid * name, size_t name_len) +{ + static int tmpvar; + long value = *((long *) var_val); + struct snmpNotifyFilterProfileTable_data *StorageTmp = NULL; + size_t newlen = + name_len - + (sizeof(snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", + "write_snmpNotifyFilterProfileStorType entering action=%d... \n", + action)); + if (action != RESERVE1 && + (StorageTmp = (struct snmpNotifyFilterProfileTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyFilterProfileTableStorage, NULL, + &name[sizeof + (snmpNotifyFilterProfileTable_variables_oid) + / sizeof(oid) + 3 - 1], &newlen, 1, NULL, + NULL)) == NULL) { + if ((StorageTmp = StorageNew) == NULL) + return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ + } + + switch (action) { + case RESERVE1: + if (var_val_type != ASN_INTEGER) { + return SNMP_ERR_WRONGTYPE; + } + if (var_val_len != sizeof(long)) { + return SNMP_ERR_WRONGLENGTH; + } + if (value != SNMP_STORAGE_OTHER && value != SNMP_STORAGE_VOLATILE + && value != SNMP_STORAGE_NONVOLATILE) { + return SNMP_ERR_WRONGVALUE; + } + break; + + + case RESERVE2: + /* + * memory reseveration, final preparation... + */ + break; + + + case FREE: + /* + * Release any resources that have been allocated + */ + break; + + + case ACTION: + /* + * The variable has been stored in long_ret for + * you to use, and you have just been asked to do something with + * it. Note that anything done here must be reversable in the UNDO case + */ + tmpvar = StorageTmp->snmpNotifyFilterProfileStorType; + StorageTmp->snmpNotifyFilterProfileStorType = *((long *) var_val); + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + StorageTmp->snmpNotifyFilterProfileStorType = tmpvar; + break; + + + case COMMIT: + /* + * Things are working well, so it's now safe to make the change + * permanently. Make sure that anything done here can't fail! + */ + snmp_store_needed(NULL); + break; + } + return SNMP_ERR_NOERROR; +} + + + + + + +int +write_snmpNotifyFilterProfileRowStatus(int action, + u_char * var_val, + u_char var_val_type, + size_t var_val_len, + u_char * statP, + oid * name, size_t name_len) +{ + struct snmpNotifyFilterProfileTable_data *StorageTmp = NULL; + static struct snmpNotifyFilterProfileTable_data *StorageDel; + size_t newlen = + name_len - + (sizeof(snmpNotifyFilterProfileTable_variables_oid) / sizeof(oid) + + 3 - 1); + static int old_value; + int set_value = *((long *) var_val); + netsnmp_variable_list *vars; + struct header_complex_index *hciptr; + + + DEBUGMSGTL(("snmpNotifyFilterProfileTable", + "write_snmpNotifyFilterProfileRowStatus entering action=%d... \n", + action)); + StorageTmp = (struct snmpNotifyFilterProfileTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyFilterProfileTableStorage, NULL, + &name[sizeof + (snmpNotifyFilterProfileTable_variables_oid) / + sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); + + switch (action) { + case RESERVE1: + if (var_val_type != ASN_INTEGER || var_val == NULL) { + return SNMP_ERR_WRONGTYPE; + } + if (var_val_len != sizeof(long)) { + return SNMP_ERR_WRONGLENGTH; + } + if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) { + return SNMP_ERR_WRONGVALUE; + } + /* + * stage one: test validity + */ + if (StorageTmp == NULL) { + /* + * create the row now? + */ + + + /* + * ditch illegal values now + */ + if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { + return SNMP_ERR_INCONSISTENTVALUE; + } + } else { + /* + * row exists. Check for a valid state change + */ + if (set_value == RS_CREATEANDGO + || set_value == RS_CREATEANDWAIT) { + /* + * can't create a row that exists + */ + return SNMP_ERR_INCONSISTENTVALUE; + } + if ((set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) && + StorageTmp->snmpNotifyFilterProfileNameLen == 0) { + /* + * can't activate row without a profile name + */ + return SNMP_ERR_INCONSISTENTVALUE; + } + /* + * XXX: interaction with row storage type needed + */ + } + + /* + * memory reseveration, final preparation... + */ + if (StorageTmp == NULL && + (set_value == RS_CREATEANDGO + || set_value == RS_CREATEANDWAIT)) { + /* + * creation + */ + vars = NULL; + + snmp_varlist_add_variable(&vars, NULL, 0, + ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0); + + if (header_complex_parse_oid + (& + (name + [sizeof(snmpNotifyFilterProfileTable_variables_oid) / + sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { + snmp_free_var(vars); + return SNMP_ERR_INCONSISTENTNAME; + } + + StorageNew = + SNMP_MALLOC_STRUCT(snmpNotifyFilterProfileTable_data); + if (StorageNew == NULL) + return SNMP_ERR_GENERR; + memdup((u_char **) & (StorageNew->snmpTargetParamsName), + vars->val.string, vars->val_len); + StorageNew->snmpTargetParamsNameLen = vars->val_len; + StorageNew->snmpNotifyFilterProfileStorType = ST_NONVOLATILE; + + StorageNew->snmpNotifyFilterProfileRowStatus = RS_NOTREADY; + snmp_free_var(vars); + } + + + break; + + case RESERVE2: + break; + + case FREE: + /* + * XXX: free, zero vars + */ + /* + * Release any resources that have been allocated + */ + if (StorageNew != NULL) { + SNMP_FREE(StorageNew->snmpTargetParamsName); + SNMP_FREE(StorageNew->snmpNotifyFilterProfileName); + free(StorageNew); + StorageNew = NULL; + } + break; + + + + + case ACTION: + /* + * The variable has been stored in set_value for you to + * use, and you have just been asked to do something with + * it. Note that anything done here must be reversable in + * the UNDO case + */ + + if (StorageTmp == NULL && + (set_value == RS_CREATEANDGO || + set_value == RS_CREATEANDWAIT)) { + /* + * row creation, so add it + */ + if (StorageNew != NULL) + snmpNotifyFilterProfileTable_add(StorageNew); + /* + * XXX: ack, and if it is NULL? + */ + } else if (set_value != RS_DESTROY) { + /* + * set the flag? + */ + if (StorageTmp == NULL) + return SNMP_ERR_GENERR; /* should never ever get here */ + + old_value = StorageTmp->snmpNotifyFilterProfileRowStatus; + StorageTmp->snmpNotifyFilterProfileRowStatus = + *((long *) var_val); + } else { + /* + * destroy... extract it for now + */ + if (StorageTmp) { + hciptr = + header_complex_find_entry + (snmpNotifyFilterProfileTableStorage, StorageTmp); + StorageDel = (struct snmpNotifyFilterProfileTable_data *) + header_complex_extract_entry((struct + header_complex_index **) + &snmpNotifyFilterProfileTableStorage, + hciptr); + } + + } + break; + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + if (StorageTmp == NULL && + (set_value == RS_CREATEANDGO || + set_value == RS_CREATEANDWAIT)) { + /* + * row creation, so remove it again + */ + hciptr = + header_complex_find_entry + (snmpNotifyFilterProfileTableStorage, StorageNew); + StorageDel = (struct snmpNotifyFilterProfileTable_data *) + header_complex_extract_entry((struct header_complex_index + **) + &snmpNotifyFilterProfileTableStorage, + hciptr); + /* + * XXX: free it + */ + } else if (StorageDel != NULL) { + /* + * row deletion, so add it again + */ + snmpNotifyFilterProfileTable_add(StorageDel); + StorageDel = NULL; + } else if (set_value != RS_DESTROY) { + if (StorageTmp) + StorageTmp->snmpNotifyFilterProfileRowStatus = old_value; + } + break; + + + + + case COMMIT: + /* + * Things are working well, so it's now safe to make the change + * permanently. Make sure that anything done here can't fail! + */ + if (StorageDel != NULL) { + SNMP_FREE(StorageDel->snmpTargetParamsName); + SNMP_FREE(StorageDel->snmpNotifyFilterProfileName); + free(StorageDel); + StorageDel = NULL; + } + if (StorageTmp && set_value == RS_CREATEANDGO) { + if (StorageTmp->snmpNotifyFilterProfileNameLen) + StorageTmp->snmpNotifyFilterProfileRowStatus = RS_ACTIVE; + StorageNew = NULL; + } else if (StorageTmp && set_value == RS_CREATEANDWAIT) { + if (StorageTmp->snmpNotifyFilterProfileNameLen) + StorageTmp->snmpNotifyFilterProfileRowStatus = RS_NOTINSERVICE; + StorageNew = NULL; + } + snmp_store_needed(NULL); + break; + } + return SNMP_ERR_NOERROR; +} + + +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + + +char * +get_FilterProfileName(const char *paramName, size_t paramName_len, + size_t * profileName_len) +{ + netsnmp_variable_list *vars = NULL; + struct snmpNotifyFilterProfileTable_data *data; + + /* + * put requested info into var structure + */ + snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, + (const u_char *) paramName, paramName_len); + + /* + * get the data from the header_complex storage + */ + data = (struct snmpNotifyFilterProfileTable_data *) + header_complex_get(snmpNotifyFilterProfileTableStorage, vars); + + /* + * free search index + */ + snmp_free_var(vars); + + /* + * return the requested information (if this row is active) + */ + if (data && data->snmpNotifyFilterProfileRowStatus == RS_ACTIVE) { + *profileName_len = data->snmpNotifyFilterProfileNameLen; + return data->snmpNotifyFilterProfileName; + } + + *profileName_len = 0; + return NULL; +} diff --git a/agent/mibgroup/notification/snmpNotifyFilterProfileTable.h b/agent/mibgroup/notification/snmpNotifyFilterProfileTable.h new file mode 100644 index 0000000..616bcdc --- /dev/null +++ b/agent/mibgroup/notification/snmpNotifyFilterProfileTable.h @@ -0,0 +1,69 @@ +/* + * This file was generated by mib2c and is intended for use as a mib module + * for the ucd-snmp snmpd agent. + */ + + +#ifndef _MIBGROUP_SNMPNOTIFYFILTERPROFILETABLE_H +#define _MIBGROUP_SNMPNOTIFYFILTERPROFILETABLE_H + + +/* + * we may use header_complex from the header_complex module + */ + + +config_require(header_complex) + + + /* + * our storage structure(s) + */ + struct snmpNotifyFilterProfileTable_data { + + char *snmpTargetParamsName; + size_t snmpTargetParamsNameLen; + char *snmpNotifyFilterProfileName; + size_t snmpNotifyFilterProfileNameLen; + long snmpNotifyFilterProfileStorType; + long snmpNotifyFilterProfileRowStatus; + + }; + + + + +/* + * enum definitions from the covered mib sections + */ + + + + + + + + +/* + * function prototypes + */ + + + void init_snmpNotifyFilterProfileTable(void); + FindVarMethod var_snmpNotifyFilterProfileTable; + void parse_snmpNotifyFilterProfileTable(const char *, + char *); + SNMPCallback store_snmpNotifyFilterProfileTable; + +#ifndef NETSNMP_NO_WRITE_SUPPORT + WriteMethod write_snmpNotifyFilterProfileName; + WriteMethod write_snmpNotifyFilterProfileStorType; + WriteMethod write_snmpNotifyFilterProfileRowStatus; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + + char *get_FilterProfileName(const char *paramName, + size_t paramName_len, + size_t * profileName_len); + + +#endif /* _MIBGROUP_SNMPNOTIFYFILTERPROFILETABLE_H */ diff --git a/agent/mibgroup/notification/snmpNotifyTable.c b/agent/mibgroup/notification/snmpNotifyTable.c new file mode 100644 index 0000000..8d09c59 --- /dev/null +++ b/agent/mibgroup/notification/snmpNotifyTable.c @@ -0,0 +1,1222 @@ +/* + * 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> + +#include <sys/types.h> +#if HAVE_STDLIB_H +#include <stdlib.h> +#endif +#if HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif + +/* + * minimal include directives + */ +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +#include "header_complex.h" +#include "snmpNotifyTable.h" +#include "snmpNotifyFilterProfileTable.h" +#include "target/snmpTargetParamsEntry.h" +#include "target/snmpTargetAddrEntry.h" +#include "target/target.h" +#include "snmp-notification-mib/snmpNotifyFilterTable/snmpNotifyFilterTable.h" +#include <net-snmp/agent/agent_callbacks.h> +#include <net-snmp/agent/agent_trap.h> +#include <net-snmp/agent/mib_module_config.h> +#include "net-snmp/agent/sysORTable.h" + +#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE +# include "notification-log-mib/notification_log.h" +#endif + +#ifndef NETSNMP_NO_WRITE_SUPPORT +netsnmp_feature_require(header_complex_find_entry) +#endif /* NETSNMP_NO_WRITE_SUPPORT */ + +SNMPCallback store_snmpNotifyTable; + +/* + * snmpNotifyTable_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. + */ + + +oid snmpNotifyTable_variables_oid[] = + { 1, 3, 6, 1, 6, 3, 13, 1, 1 }; + +static oid snmpNotifyFullCompliance[] = + { SNMP_OID_SNMPMODULES, 13, 3, 1, 3 }; /* SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance */ + + +/* + * variable2 snmpNotifyTable_variables: + * this variable defines function callbacks and type return information + * for the snmpNotifyTable mib section + */ + + +struct variable2 snmpNotifyTable_variables[] = { + /* + * magic number , variable type , ro/rw , callback fn , L, oidsuffix + */ +#define SNMPNOTIFYTAG 4 + {SNMPNOTIFYTAG, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, + var_snmpNotifyTable, 2, {1, 2}}, +#define SNMPNOTIFYTYPE 5 + {SNMPNOTIFYTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_snmpNotifyTable, 2, {1, 3}}, +#define SNMPNOTIFYSTORAGETYPE 6 + {SNMPNOTIFYSTORAGETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_snmpNotifyTable, 2, {1, 4}}, +#define SNMPNOTIFYROWSTATUS 7 + {SNMPNOTIFYROWSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_snmpNotifyTable, 2, {1, 5}}, + +}; +/* + * (L = length of the oidsuffix) + */ + + +/* + * global storage of our data, saved in and configured by header_complex() + */ +static struct header_complex_index *snmpNotifyTableStorage = NULL; + +static int +_checkFilter(const char* paramName, netsnmp_pdu *pdu) +{ + /* + * find appropriate filterProfileEntry + */ + netsnmp_variable_list *var, *trap_var; + char *profileName; + size_t profileNameLen; + struct vacm_viewEntry *vp, *head; + int vb_oid_excluded = 0; + extern const oid snmptrap_oid[]; + extern const size_t snmptrap_oid_len; + + netsnmp_assert(NULL != paramName); + netsnmp_assert(NULL != pdu); + + DEBUGMSGTL(("send_notifications", "checking filters...\n")); + + /* + A notification originator uses the snmpNotifyFilterTable to filter + notifications. A notification filter profile may be associated with + a particular entry in the snmpTargetParamsTable. The associated + filter profile is identified by an entry in the + snmpNotifyFilterProfileTable whose index is equal to the index of the + entry in the snmpTargetParamsTable. If no such entry exists in the + snmpNotifyFilterProfileTable, no filtering is performed for that + management target. + */ + profileName = get_FilterProfileName(paramName, strlen(paramName), + &profileNameLen); + if (NULL == profileName) { + DEBUGMSGTL(("send_notifications", " no matching profile\n")); + return 0; + } + + /* + If such an entry does exist, the value of snmpNotifyFilterProfileName + of the entry is compared with the corresponding portion of the index + of all active entries in the snmpNotifyFilterTable. All such entries + for which this comparison results in an exact match are used for + filtering a notification generated using the associated + snmpTargetParamsEntry. If no such entries exist, no filtering is + performed, and a notification may be sent to the management target. + */ + head = snmpNotifyFilterTable_vacm_view_subtree(profileName); + if (NULL == head) { + DEBUGMSGTL(("send_notifications", " no matching filters\n")); + return 0; + } + + /* + Otherwise, if matching entries do exist, a notification may be sent + if the NOTIFICATION-TYPE OBJECT IDENTIFIER of the notification (this + is the value of the element of the variable bindings whose name is + snmpTrapOID.0, i.e., the second variable binding) is specifically + included, and none of the object instances to be included in the + variable-bindings of the notification are specifically excluded by + the matching entries. + */ + trap_var = find_varbind_in_list( pdu->variables, + snmptrap_oid, + snmptrap_oid_len); + if (NULL != trap_var) { + /* + For a notification name, if none match, + then the notification name is considered excluded, and the + notification should not be sent to this management target. + */ + vp = netsnmp_view_get(head, profileName, trap_var->val.objid, + trap_var->val_len / sizeof(oid), VACM_MODE_FIND); + if ((NULL == vp) || (SNMP_VIEW_INCLUDED != vp->viewType)) { + DEBUGMSGTL(("send_notifications", " filtered (snmpTrapOID.0 ")); + DEBUGMSGOID(("send_notifications",trap_var->val.objid, + trap_var->val_len / sizeof(oid))); + DEBUGMSG(("send_notifications", " not included)\n")); + free(head); + return 1; + } + } + + /* + * check varbinds + */ + for(var = pdu->variables; var; var = var->next_variable) { + /* + For an + object instance, if none match, the object instance is considered + included, and the notification may be sent to this management target. + */ + + if (var == trap_var) { + continue; + } + + vp = netsnmp_view_get(head, profileName, var->name, + var->name_length, VACM_MODE_FIND); + if ((NULL != vp) && (SNMP_VIEW_EXCLUDED == vp->viewType)) { + DEBUGMSGTL(("send_notifications"," filtered (varbind ")); + DEBUGMSGOID(("send_notifications",var->name, var->name_length)); + DEBUGMSG(("send_notifications", " excluded)\n")); + vb_oid_excluded = 1; + break; + } + } + + free(head); + + return vb_oid_excluded; +} + +int +send_notifications(int major, int minor, void *serverarg, void *clientarg) +{ + struct header_complex_index *hptr; + struct snmpNotifyTable_data *nptr; + netsnmp_session *sess, *sptr; + netsnmp_pdu *template_pdu = (netsnmp_pdu *) serverarg; + int count = 0, send = 0; + + DEBUGMSGTL(("send_notifications", "starting: pdu=%p, vars=%p\n", + template_pdu, template_pdu->variables)); + + for (hptr = snmpNotifyTableStorage; hptr; hptr = hptr->next) { + nptr = (struct snmpNotifyTable_data *) hptr->data; + if (nptr->snmpNotifyRowStatus != RS_ACTIVE) + continue; + if (!nptr->snmpNotifyTag) + continue; + + sess = get_target_sessions(nptr->snmpNotifyTag, NULL, NULL); + + /* + * filter appropriately, per section 6 of RFC 3413 + */ + + for (sptr = sess; sptr; sptr = sptr->next) { + send = 0; +#ifndef NETSNMP_DISABLE_SNMPV1 + if (sptr->version == SNMP_VERSION_1 && + minor == SNMPD_CALLBACK_SEND_TRAP1) { + send = 1; + } else +#endif + if ((sptr->version == SNMP_VERSION_3 +#ifndef NETSNMP_DISABLE_SNMPV2C + || sptr->version == SNMP_VERSION_2c +#endif + ) && minor == SNMPD_CALLBACK_SEND_TRAP2) { + if (nptr->snmpNotifyType == SNMPNOTIFYTYPE_INFORM) { + template_pdu->command = SNMP_MSG_INFORM; + } else { + template_pdu->command = SNMP_MSG_TRAP2; + } + send = 1; + } + if (send && sess->paramName) { + int filter = _checkFilter(sess->paramName, template_pdu); + if (filter) + send = 0; + } + if (send) { + send_trap_to_sess(sptr, template_pdu); + ++count; + } /* session to send to */ + } /* for(sptr) */ + } /* for(hptr) */ + + DEBUGMSGTL(("send_notifications", "sent %d notifications\n", count)); + +#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE + if (count) + log_notification(template_pdu, NULL); +#endif + + return 0; +} + +#define MAX_ENTRIES 1024 + +int +notifyTable_register_notifications(int major, int minor, + void *serverarg, void *clientarg) +{ + struct targetAddrTable_struct *ptr; + struct targetParamTable_struct *pptr; + struct snmpNotifyTable_data *nptr; + int confirm, i; + char buf[SNMP_MAXBUF_SMALL]; + netsnmp_transport *t = NULL; + struct agent_add_trap_args *args = + (struct agent_add_trap_args *) serverarg; + netsnmp_session *ss; + + if (!args || !(args->ss)) { + return (0); + } + confirm = args->confirm; + ss = args->ss; + + /* + * XXX: START move target creation to target code + */ + for (i = 0; i < MAX_ENTRIES; i++) { + sprintf(buf, "internal%d", i); + if (get_addrForName(buf) == NULL && get_paramEntry(buf) == NULL) + break; + } + if (i == MAX_ENTRIES) { + snmp_log(LOG_ERR, + "Can't register new trap destination: max limit reached: %d", + MAX_ENTRIES); + snmp_sess_close(ss); + return (0); + } + + /* + * address + */ + t = snmp_sess_transport(snmp_sess_pointer(ss)); + if (!t) { + snmp_log(LOG_ERR, + "Cannot add new trap destination, transport is closed."); + snmp_sess_close(ss); + return 0; + } + ptr = snmpTargetAddrTable_create(); + ptr->name = strdup(buf); + memcpy(ptr->tDomain, t->domain, t->domain_length * sizeof(oid)); + ptr->tDomainLen = t->domain_length; + ptr->tAddressLen = t->remote_length; + ptr->tAddress = t->remote; + + ptr->timeout = ss->timeout / 1000; + ptr->retryCount = ss->retries; + SNMP_FREE(ptr->tagList); + ptr->tagList = strdup(ptr->name); + ptr->params = strdup(ptr->name); + ptr->storageType = ST_READONLY; + ptr->rowStatus = RS_ACTIVE; + ptr->sess = ss; + DEBUGMSGTL(("trapsess", "adding to trap table\n")); + snmpTargetAddrTable_add(ptr); + + /* + * param + */ + pptr = snmpTargetParamTable_create(); + pptr->paramName = strdup(buf); + pptr->mpModel = ss->version; + if (ss->version == SNMP_VERSION_3) { + pptr->secModel = ss->securityModel; + pptr->secLevel = ss->securityLevel; + pptr->secName = (char *) malloc(ss->securityNameLen + 1); + if (pptr->secName == NULL) { + snmpTargetParamTable_dispose(pptr); + return 0; + } + memcpy((void *) pptr->secName, (void *) ss->securityName, + ss->securityNameLen); + pptr->secName[ss->securityNameLen] = 0; + } +#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) + else { + pptr->secModel = +#ifndef NETSNMP_DISABLE_SNMPV1 + ss->version == SNMP_VERSION_1 ? SNMP_SEC_MODEL_SNMPv1 : +#endif + SNMP_SEC_MODEL_SNMPv2c; + pptr->secLevel = SNMP_SEC_LEVEL_NOAUTH; + pptr->secName = NULL; + if (ss->community && (ss->community_len > 0)) { + pptr->secName = (char *) malloc(ss->community_len + 1); + if (pptr->secName == NULL) { + snmpTargetParamTable_dispose(pptr); + return 0; + } + memcpy((void *) pptr->secName, (void *) ss->community, + ss->community_len); + pptr->secName[ss->community_len] = 0; + } + } +#endif + pptr->storageType = ST_READONLY; + pptr->rowStatus = RS_ACTIVE; + snmpTargetParamTable_add(pptr); + /* + * XXX: END move target creation to target code + */ + + /* + * notify table + */ + nptr = SNMP_MALLOC_STRUCT(snmpNotifyTable_data); + if (nptr == NULL) + return 0; + nptr->snmpNotifyName = strdup(buf); + nptr->snmpNotifyNameLen = strlen(buf); + nptr->snmpNotifyTag = strdup(buf); + nptr->snmpNotifyTagLen = strlen(buf); + nptr->snmpNotifyType = confirm ? + SNMPNOTIFYTYPE_INFORM : SNMPNOTIFYTYPE_TRAP; + nptr->snmpNotifyStorageType = ST_READONLY; + nptr->snmpNotifyRowStatus = RS_ACTIVE; + + snmpNotifyTable_add(nptr); + return 0; +} + + +/* + * XXX: this really needs to be done for the target mib entries too. + * But we can only trust that we've added stuff here and we don't want + * to destroy other valid entries in the target tables, so... Don't + * do too many kill -HUPs to your agent as re reading the config file + * will be a slow memory leak in the target mib. + */ +int +notifyTable_unregister_notifications(int major, int minor, + void *serverarg, void *clientarg) +{ + struct header_complex_index *hptr, *nhptr; + + for (hptr = snmpNotifyTableStorage; hptr; hptr = nhptr) { + struct snmpNotifyTable_data *nptr = hptr->data; + nhptr = hptr->next; + if (nptr->snmpNotifyStorageType == ST_READONLY) { + header_complex_extract_entry(&snmpNotifyTableStorage, hptr); + free(nptr->snmpNotifyName); + free(nptr->snmpNotifyTag); + free(nptr); + } + } + snmpNotifyTableStorage = NULL; + return (0); +} + +/* + * init_snmpNotifyTable(): + * Initialization routine. This is called when the agent starts up. + * At a minimum, registration of your variables should take place here. + */ +void +init_snmpNotifyTable(void) +{ + DEBUGMSGTL(("snmpNotifyTable", "initializing... ")); + + + /* + * register ourselves with the agent to handle our mib tree + */ + REGISTER_MIB("snmpNotifyTable", snmpNotifyTable_variables, variable2, + snmpNotifyTable_variables_oid); + + + /* + * register our config handler(s) to deal with registrations + */ + snmpd_register_config_handler("snmpNotifyTable", parse_snmpNotifyTable, + NULL, NULL); + + + /* + * we need to be called back later to store our data + */ + snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, + store_snmpNotifyTable, NULL); + +#ifndef DISABLE_SNMPV1 + snmp_register_callback(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_SEND_TRAP1, send_notifications, + NULL); +#endif + snmp_register_callback(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_SEND_TRAP2, send_notifications, + NULL); + snmp_register_callback(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_REGISTER_NOTIFICATIONS, + notifyTable_register_notifications, NULL); + snmp_register_callback(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_PRE_UPDATE_CONFIG, + notifyTable_unregister_notifications, NULL); + + /* + * place any other initialization junk you need here + */ + + REGISTER_SYSOR_ENTRY(snmpNotifyFullCompliance, + "The MIB modules for managing SNMP Notification, plus filtering."); + + DEBUGMSGTL(("snmpNotifyTable", "done.\n")); +} + +void +shutdown_snmpNotifyTable(void) +{ + DEBUGMSGTL(("snmpNotifyTable", "shutting down ... ")); + + notifyTable_unregister_notifications(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_PRE_UPDATE_CONFIG, + NULL, + NULL); + + snmp_unregister_callback(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_PRE_UPDATE_CONFIG, + notifyTable_unregister_notifications, NULL, FALSE); + snmp_unregister_callback(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_REGISTER_NOTIFICATIONS, + notifyTable_register_notifications, NULL, FALSE); + snmp_unregister_callback(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_SEND_TRAP2, send_notifications, + NULL, FALSE); +#ifndef DISABLE_SNMPV1 + snmp_unregister_callback(SNMP_CALLBACK_APPLICATION, + SNMPD_CALLBACK_SEND_TRAP1, send_notifications, + NULL, FALSE); +#endif + snmp_unregister_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, + store_snmpNotifyTable, NULL, FALSE); + + UNREGISTER_SYSOR_ENTRY(snmpNotifyFullCompliance); + + DEBUGMSGTL(("snmpNotifyTable", "done.\n")); +} + +/* + * snmpNotifyTable_add(): adds a structure node to our data set + */ +int +snmpNotifyTable_add(struct snmpNotifyTable_data *thedata) +{ + netsnmp_variable_list *vars = NULL; + int retVal; + + DEBUGMSGTL(("snmpNotifyTable", "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_PRIV_IMPLIED_OCTET_STR, (u_char *) thedata->snmpNotifyName, thedata->snmpNotifyNameLen); /* snmpNotifyName */ + + + + if (header_complex_maybe_add_data(&snmpNotifyTableStorage, vars, thedata, 1) + != NULL){ + DEBUGMSGTL(("snmpNotifyTable", "registered an entry\n")); + retVal = SNMPERR_SUCCESS; + }else{ + retVal = SNMPERR_GENERR; + } + + + DEBUGMSGTL(("snmpNotifyTable", "done.\n")); + return retVal; +} + + +/* + * parse_snmpNotifyTable(): + * parses .conf file entries needed to configure the mib. + */ +void +parse_snmpNotifyTable(const char *token, char *line) +{ + size_t tmpint; + struct snmpNotifyTable_data *StorageTmp = + SNMP_MALLOC_STRUCT(snmpNotifyTable_data); + + + DEBUGMSGTL(("snmpNotifyTable", "parsing config... ")); + + + if (StorageTmp == NULL) { + config_perror("malloc failure"); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->snmpNotifyName, + &StorageTmp->snmpNotifyNameLen); + if (StorageTmp->snmpNotifyName == NULL) { + config_perror("invalid specification for snmpNotifyName"); + SNMP_FREE(StorageTmp); + return; + } + + line = + read_config_read_data(ASN_OCTET_STR, line, + &StorageTmp->snmpNotifyTag, + &StorageTmp->snmpNotifyTagLen); + if (StorageTmp->snmpNotifyTag == NULL) { + config_perror("invalid specification for snmpNotifyTag"); + SNMP_FREE(StorageTmp); + return; + } + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->snmpNotifyType, &tmpint); + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->snmpNotifyStorageType, &tmpint); + if (!StorageTmp->snmpNotifyStorageType) + StorageTmp->snmpNotifyStorageType = ST_READONLY; + + line = + read_config_read_data(ASN_INTEGER, line, + &StorageTmp->snmpNotifyRowStatus, &tmpint); + if (!StorageTmp->snmpNotifyRowStatus) + StorageTmp->snmpNotifyRowStatus = RS_ACTIVE; + + + if (snmpNotifyTable_add(StorageTmp) != SNMPERR_SUCCESS){ + SNMP_FREE(StorageTmp->snmpNotifyName); + SNMP_FREE(StorageTmp->snmpNotifyTag); + SNMP_FREE(StorageTmp); + } + + + DEBUGMSGTL(("snmpNotifyTable", "done.\n")); +} + + + + +/* + * store_snmpNotifyTable(): + * stores .conf file entries needed to configure the mib. + */ +int +store_snmpNotifyTable(int majorID, int minorID, void *serverarg, + void *clientarg) +{ + char line[SNMP_MAXBUF]; + char *cptr; + size_t tmpint; + struct snmpNotifyTable_data *StorageTmp; + struct header_complex_index *hcindex; + + + DEBUGMSGTL(("snmpNotifyTable", "storing data... ")); + + + for (hcindex = snmpNotifyTableStorage; hcindex != NULL; + hcindex = hcindex->next) { + StorageTmp = (struct snmpNotifyTable_data *) hcindex->data; + + /* + * store permanent and nonvolatile rows. + * XXX should there be a qualification on RowStatus?? + */ + if ((StorageTmp->snmpNotifyStorageType == ST_NONVOLATILE) || + (StorageTmp->snmpNotifyStorageType == ST_PERMANENT) ){ + + memset(line, 0, sizeof(line)); + strcat(line, "snmpNotifyTable "); + cptr = line + strlen(line); + + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->snmpNotifyName, + &StorageTmp->snmpNotifyNameLen); + cptr = + read_config_store_data(ASN_OCTET_STR, cptr, + &StorageTmp->snmpNotifyTag, + &StorageTmp->snmpNotifyTagLen); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->snmpNotifyType, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->snmpNotifyStorageType, + &tmpint); + cptr = + read_config_store_data(ASN_INTEGER, cptr, + &StorageTmp->snmpNotifyRowStatus, + &tmpint); + + snmpd_store_config(line); + } + } + DEBUGMSGTL(("snmpNotifyTable", "done.\n")); + return 0; +} + + + + +/* + * var_snmpNotifyTable(): + * Handle this table separately from the scalar value case. + * The workings of this are basically the same as for var_snmpNotifyTable above. + */ +unsigned char * +var_snmpNotifyTable(struct variable *vp, + oid * name, + size_t * length, + int exact, + size_t * var_len, WriteMethod ** write_method) +{ + struct snmpNotifyTable_data *StorageTmp = NULL; + int found = 1; + + DEBUGMSGTL(("snmpNotifyTable", + "var_snmpNotifyTable: Entering... \n")); + /* + * this assumes you have registered all your data properly + */ + if ((StorageTmp = (struct snmpNotifyTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyTableStorage, vp, name, length, exact, + var_len, write_method)) == NULL) { + found = 0; + } + + switch (vp->magic) { +#ifndef NETSNMP_NO_WRITE_SUPPORT + case SNMPNOTIFYTAG: + *write_method = write_snmpNotifyTag; + break; + case SNMPNOTIFYTYPE: + *write_method = write_snmpNotifyType; + break; + case SNMPNOTIFYSTORAGETYPE: + *write_method = write_snmpNotifyStorageType; + break; + case SNMPNOTIFYROWSTATUS: + *write_method = write_snmpNotifyRowStatus; + break; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + default: + *write_method = NULL; + } + + if (!found) { + return NULL; + } + +#ifndef NETSNMP_NO_READ_SUPPORT + switch (vp->magic) { + case SNMPNOTIFYTAG: + *var_len = StorageTmp->snmpNotifyTagLen; + return (u_char *) StorageTmp->snmpNotifyTag; + + case SNMPNOTIFYTYPE: + *var_len = sizeof(StorageTmp->snmpNotifyType); + return (u_char *) & StorageTmp->snmpNotifyType; + + case SNMPNOTIFYSTORAGETYPE: + *var_len = sizeof(StorageTmp->snmpNotifyStorageType); + return (u_char *) & StorageTmp->snmpNotifyStorageType; + + case SNMPNOTIFYROWSTATUS: + *var_len = sizeof(StorageTmp->snmpNotifyRowStatus); + return (u_char *) & StorageTmp->snmpNotifyRowStatus; + + default: + ERROR_MSG(""); + } +#endif /* !NETSNMP_NO_READ_SUPPORT */ + return NULL; +} + +static int +is_delim(const char c) +{ + return (c == 0x020 || c == 0x09 || c == 0x0d || c == 0x0b); +} + +int +snmpTagValid(const char *tag, const size_t tagLen) +{ + size_t i = 0; + + + for (i = 0; i < tagLen; i++) { + if (is_delim(tag[i])) { + /* + * Delimeters aren't allowed. + */ + return 0; + } + } + return 1; +} + +static struct snmpNotifyTable_data *StorageNew; + +#ifndef NETSNMP_NO_WRITE_SUPPORT + +int +write_snmpNotifyTag(int action, + u_char * var_val, + u_char var_val_type, + size_t var_val_len, + u_char * statP, oid * name, size_t name_len) +{ + static char *tmpvar; + struct snmpNotifyTable_data *StorageTmp = NULL; + static size_t tmplen; + size_t newlen = + name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("snmpNotifyTable", + "write_snmpNotifyTag entering action=%d... \n", action)); + if (action != RESERVE1 && + (StorageTmp = (struct snmpNotifyTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyTableStorage, NULL, + &name[sizeof(snmpNotifyTable_variables_oid) / + sizeof(oid) + 3 - 1], &newlen, 1, NULL, + NULL)) == NULL) { + if ((StorageTmp = StorageNew) == NULL) + return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ + } + + + switch (action) { + case RESERVE1: + if (var_val_type != ASN_OCTET_STR) { + return SNMP_ERR_WRONGTYPE; + } + if (var_val_len > 255) { + return SNMP_ERR_WRONGLENGTH; + } + if (!snmpTagValid((char *) var_val, var_val_len)) { + return SNMP_ERR_WRONGVALUE; + } + break; + + + case RESERVE2: + /* + * memory reseveration, final preparation... + */ + tmpvar = StorageTmp->snmpNotifyTag; + tmplen = StorageTmp->snmpNotifyTagLen; + StorageTmp->snmpNotifyTag = (char*)calloc(1, var_val_len + 1); + if (NULL == StorageTmp->snmpNotifyTag) + return SNMP_ERR_RESOURCEUNAVAILABLE; + break; + + + case FREE: + /* + * Release any resources that have been allocated + */ + break; + + + case ACTION: + memcpy(StorageTmp->snmpNotifyTag, var_val, var_val_len); + StorageTmp->snmpNotifyTagLen = var_val_len; + break; + + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + SNMP_FREE(StorageTmp->snmpNotifyTag); + StorageTmp->snmpNotifyTag = tmpvar; + StorageTmp->snmpNotifyTagLen = tmplen; + tmpvar = NULL; + break; + + + case COMMIT: + /* + * Things are working well, so it's now safe to make the change + * permanently. Make sure that anything done here can't fail! + */ + SNMP_FREE(tmpvar); + snmp_store_needed(NULL); + break; + } + + return SNMP_ERR_NOERROR; +} + + + +int +write_snmpNotifyType(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 snmpNotifyTable_data *StorageTmp = NULL; + long value = *((long *) var_val); + size_t newlen = + name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("snmpNotifyTable", + "write_snmpNotifyType entering action=%d... \n", action)); + if (action != RESERVE1 && + (StorageTmp = (struct snmpNotifyTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyTableStorage, NULL, + &name[sizeof(snmpNotifyTable_variables_oid) / + sizeof(oid) + 3 - 1], &newlen, 1, NULL, + NULL)) == NULL) { + if ((StorageTmp = StorageNew) == NULL) + return SNMP_ERR_NOSUCHNAME; + } + + switch (action) { + case RESERVE1: + if (var_val_type != ASN_INTEGER) { + return SNMP_ERR_WRONGTYPE; + } + if (var_val_len != sizeof(long)) { + return SNMP_ERR_WRONGLENGTH; + } + if (value < 1 || value > 2) { + return SNMP_ERR_WRONGVALUE; + } + break; + + case ACTION: + tmpvar = StorageTmp->snmpNotifyType; + StorageTmp->snmpNotifyType = value; + break; + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + StorageTmp->snmpNotifyType = tmpvar; + break; + } + + return SNMP_ERR_NOERROR; +} + + + +int +write_snmpNotifyStorageType(int action, + u_char * var_val, + u_char var_val_type, + size_t var_val_len, + u_char * statP, oid * name, size_t name_len) +{ + static int tmpvar; + long value = *((long *) var_val); + struct snmpNotifyTable_data *StorageTmp = NULL; + size_t newlen = + name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + + 3 - 1); + + + DEBUGMSGTL(("snmpNotifyTable", + "write_snmpNotifyStorageType entering action=%d... \n", + action)); + if (action != RESERVE1 && + (StorageTmp = (struct snmpNotifyTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyTableStorage, NULL, + &name[sizeof(snmpNotifyTable_variables_oid) / + sizeof(oid) + 3 - 1], &newlen, 1, NULL, + NULL)) == NULL) { + if ((StorageTmp = StorageNew) == NULL) + return SNMP_ERR_NOSUCHNAME; + } + + + switch (action) { + case RESERVE1: + if (var_val_type != ASN_INTEGER) { + return SNMP_ERR_WRONGTYPE; + } + if (var_val_len != sizeof(long)) { + return SNMP_ERR_WRONGLENGTH; + } + if (value != SNMP_STORAGE_OTHER && value != SNMP_STORAGE_VOLATILE + && value != SNMP_STORAGE_NONVOLATILE) { + return SNMP_ERR_WRONGVALUE; + } + break; + + case ACTION: + tmpvar = StorageTmp->snmpNotifyStorageType; + StorageTmp->snmpNotifyStorageType = value; + break; + + case UNDO: + StorageTmp->snmpNotifyStorageType = tmpvar; + break; + } + return SNMP_ERR_NOERROR; +} + + + +int +write_snmpNotifyRowStatus(int action, + u_char * var_val, + u_char var_val_type, + size_t var_val_len, + u_char * statP, oid * name, size_t name_len) +{ + struct snmpNotifyTable_data *StorageTmp = NULL; + static struct snmpNotifyTable_data *StorageDel; + size_t newlen = + name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + + 3 - 1); + static int old_value; + int set_value = *((long *) var_val); + static netsnmp_variable_list *vars, *vp; + struct header_complex_index *hciptr; + + + DEBUGMSGTL(("snmpNotifyTable", + "write_snmpNotifyRowStatus entering action=%d... \n", + action)); + StorageTmp = (struct snmpNotifyTable_data *) + header_complex((struct header_complex_index *) + snmpNotifyTableStorage, NULL, + &name[sizeof(snmpNotifyTable_variables_oid) / + sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); + + switch (action) { + case RESERVE1: + if (var_val_type != ASN_INTEGER || var_val == NULL) { + return SNMP_ERR_WRONGTYPE; + } + if (var_val_len != sizeof(long)) { + return SNMP_ERR_WRONGLENGTH; + } + if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) { + return SNMP_ERR_WRONGVALUE; + } + if (StorageTmp == NULL) { + /* + * create the row now? + */ + /* + * ditch illegal values now + */ + if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { + return SNMP_ERR_INCONSISTENTVALUE; + } + } else { + /* + * row exists. Check for a valid state change + */ + if (set_value == RS_CREATEANDGO + || set_value == RS_CREATEANDWAIT) { + /* + * can't create a row that exists + */ + return SNMP_ERR_INCONSISTENTVALUE; + } + /* + * XXX: interaction with row storage type needed + */ + } + + /* + * memory reseveration, final preparation... + */ + if (StorageTmp == NULL && + (set_value == RS_CREATEANDGO + || set_value == RS_CREATEANDWAIT)) { + /* + * creation + */ + vars = NULL; + + snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0); /* snmpNotifyName */ + + if (header_complex_parse_oid + (& + (name + [sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) + + 2]), newlen, vars) != SNMPERR_SUCCESS) { + /* + * XXX: free, zero vars + */ + snmp_free_var(vars); + return SNMP_ERR_INCONSISTENTNAME; + } + vp = vars; + + + StorageNew = SNMP_MALLOC_STRUCT(snmpNotifyTable_data); + if (StorageNew == NULL) { + return SNMP_ERR_RESOURCEUNAVAILABLE; + } + StorageNew->snmpNotifyName = (char*)calloc( 1, vp->val_len + 1 ); + if (StorageNew->snmpNotifyName == NULL) { + return SNMP_ERR_RESOURCEUNAVAILABLE; + } + memcpy(StorageNew->snmpNotifyName, vp->val.string, vp->val_len); + StorageNew->snmpNotifyNameLen = vp->val_len; + vp = vp->next_variable; + + /* + * default values + */ + StorageNew->snmpNotifyStorageType = ST_NONVOLATILE; + StorageNew->snmpNotifyType = SNMPNOTIFYTYPE_TRAP; + StorageNew->snmpNotifyTagLen = 0; + StorageNew->snmpNotifyTag = (char *) calloc(sizeof(char), 1); + if (StorageNew->snmpNotifyTag == NULL) { + return SNMP_ERR_RESOURCEUNAVAILABLE; + } + + StorageNew->snmpNotifyRowStatus = set_value; + snmp_free_var(vars); + } + break; + + case RESERVE2: + break; + + case FREE: + if (StorageNew != NULL) { + SNMP_FREE(StorageNew->snmpNotifyTag); + SNMP_FREE(StorageNew->snmpNotifyName); + free(StorageNew); + StorageNew = NULL; + } + break; + + case ACTION: + if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || + set_value == RS_CREATEANDWAIT)) { + /* + * row creation, so add it + */ + if (StorageNew != NULL) { + snmpNotifyTable_add(StorageNew); + } + } else if (set_value != RS_DESTROY) { + /* + * set the flag? + */ + if (StorageTmp == NULL) + return SNMP_ERR_GENERR; /* should never ever get here */ + + old_value = StorageTmp->snmpNotifyRowStatus; + StorageTmp->snmpNotifyRowStatus = *((long *) var_val); + } else { + /* + * destroy... extract it for now + */ + if (StorageTmp) { + hciptr = header_complex_find_entry(snmpNotifyTableStorage, + StorageTmp); + StorageDel = (struct snmpNotifyTable_data *) + header_complex_extract_entry((struct + header_complex_index **) + &snmpNotifyTableStorage, + hciptr); + } + } + break; + + case UNDO: + /* + * Back out any changes made in the ACTION case + */ + if (StorageTmp == NULL && (set_value == RS_CREATEANDGO || + set_value == RS_CREATEANDWAIT)) { + /* + * row creation, so remove it again + */ + hciptr = header_complex_find_entry(snmpNotifyTableStorage, + StorageNew); + StorageDel = (struct snmpNotifyTable_data *) + header_complex_extract_entry((struct header_complex_index + **) &snmpNotifyTableStorage, + hciptr); + /* + * XXX: free it + */ + } else if (StorageDel != NULL) { + /* + * row deletion, so add it again + */ + snmpNotifyTable_add(StorageDel); + } else if (set_value != RS_DESTROY) { + if (StorageTmp) + StorageTmp->snmpNotifyRowStatus = old_value; + } + break; + + case COMMIT: + if (StorageDel != NULL) { + SNMP_FREE(StorageDel->snmpNotifyTag); + SNMP_FREE(StorageDel->snmpNotifyName); + free(StorageDel); + StorageDel = NULL; + } + if (StorageTmp + && StorageTmp->snmpNotifyRowStatus == RS_CREATEANDGO) { + StorageTmp->snmpNotifyRowStatus = RS_ACTIVE; + StorageNew = NULL; + } else if (StorageTmp && + StorageTmp->snmpNotifyRowStatus == RS_CREATEANDWAIT) { + StorageTmp->snmpNotifyRowStatus = RS_NOTINSERVICE; + StorageNew = NULL; + } + snmp_store_needed(NULL); + break; + } + return SNMP_ERR_NOERROR; +} +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ diff --git a/agent/mibgroup/notification/snmpNotifyTable.h b/agent/mibgroup/notification/snmpNotifyTable.h new file mode 100644 index 0000000..18bf1bd --- /dev/null +++ b/agent/mibgroup/notification/snmpNotifyTable.h @@ -0,0 +1,76 @@ +/* + * This file was generated by mib2c and is intended for use as a mib module + * for the ucd-snmp snmpd agent. + */ + + +#ifndef _MIBGROUP_SNMPNOTIFYTABLE_H +#define _MIBGROUP_SNMPNOTIFYTABLE_H + + +/* + * we may use header_complex from the header_complex module + */ + + +config_require(header_complex) +config_require(target) +config_add_mib(SNMP-NOTIFICATION-MIB) + + + /* + * our storage structure(s) + */ + struct snmpNotifyTable_data { + + char *snmpNotifyName; + size_t snmpNotifyNameLen; + char *snmpNotifyTag; + size_t snmpNotifyTagLen; + long snmpNotifyType; + long snmpNotifyStorageType; + long snmpNotifyRowStatus; + + }; + + + + +/* + * enum definitions from the covered mib sections + */ + + + + + + +#define SNMPNOTIFYTYPE_TRAP 1 +#define SNMPNOTIFYTYPE_INFORM 2 + + + + +/* + * function prototypes + */ + + + void init_snmpNotifyTable(void); + void shutdown_snmpNotifyTable(void); + FindVarMethod var_snmpNotifyTable; + void parse_snmpNotifyTable(const char *, char *); + + int snmpNotifyTable_add(struct snmpNotifyTable_data + *thedata); + +#ifndef NETSNMP_NO_WRITE_SUPPORT + WriteMethod write_snmpNotifyTag; + WriteMethod write_snmpNotifyType; + WriteMethod write_snmpNotifyStorageType; + WriteMethod write_snmpNotifyRowStatus; +#endif /* !NETSNMP_NO_WRITE_SUPPORT */ + + + +#endif /* _MIBGROUP_SNMPNOTIFYTABLE_H */ |