diff options
Diffstat (limited to 'snmplib/default_store.c')
-rw-r--r-- | snmplib/default_store.c | 572 |
1 files changed, 572 insertions, 0 deletions
diff --git a/snmplib/default_store.c b/snmplib/default_store.c new file mode 100644 index 0000000..8dbc9bc --- /dev/null +++ b/snmplib/default_store.c @@ -0,0 +1,572 @@ +/* + * default_store.c: storage space for defaults + */ +/* Portions of this file are subject to the following copyright(s). See + * the Net-SNMP's COPYING file for more details and other copyrights + * that may apply: + */ +/* + * Portions of this file are copyrighted by: + * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms specified in the COPYING file + * distributed with the Net-SNMP package. + */ +/** @defgroup default_store storage space for defaults + * @ingroup library + * + The purpose of the default storage is three-fold: + + 1) To create a global storage space without creating a + whole bunch of globally accessible variables or a + whole bunch of access functions to work with more + privately restricted variables. + + 2) To provide a single location where the thread lock- + ing needs to be implemented. At the time of this + writing, however, thread locking is not yet in + place. + + 3) To reduce the number of cross dependencies between + code pieces that may or may not be linked together + in the long run. This provides for a single loca- + tion in which configuration data, for example, can + be stored for a separate section of code that may + not be linked in to the application in question. + + The functions defined here implement these goals. + + Currently, three data types are supported: booleans, inte- + gers, and strings. Each of these data types have separate + storage spaces. In addition, the storage space for each + data type is divided further by the application level. + Currently, there are two storage spaces. The first is + reserved for the SNMP library itself. The second is + intended for use in applications and is not modified or + checked by the library, and, therefore, this is the space + usable by you. + + These definitions correspond with the "storid" argument to the API + - \#define NETSNMP_DS_LIBRARY_ID 0 + - \#define NETSNMP_DS_APPLICATION_ID 1 + - \#define NETSNMP_DS_TOKEN_ID 2 + + These definitions correspond with the "which" argument to the API, + when the storeid argument is NETSNMP_DS_LIBRARY_ID + + library booleans + + - \#define NETSNMP_DS_LIB_MIB_ERRORS 0 + - \#define NETSNMP_DS_LIB_SAVE_MIB_DESCRS 1 + - \#define NETSNMP_DS_LIB_MIB_COMMENT_TERM 2 + - \#define NETSNMP_DS_LIB_MIB_PARSE_LABEL 3 + - \#define NETSNMP_DS_LIB_DUMP_PACKET 4 + - \#define NETSNMP_DS_LIB_LOG_TIMESTAMP 5 + - \#define NETSNMP_DS_LIB_DONT_READ_CONFIGS 6 + - \#define NETSNMP_DS_LIB_MIB_REPLACE 7 replace objects from latest module + - \#define NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM 8 print only numeric enum values + - \#define NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS 9 print only numeric enum values + - \#define NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS 10 dont print oid indexes specially + - \#define NETSNMP_DS_LIB_ALARM_DONT_USE_SIG 11 don't use the alarm() signal + - \#define NETSNMP_DS_LIB_PRINT_FULL_OID 12 print fully qualified oids + - \#define NETSNMP_DS_LIB_QUICK_PRINT 13 print very brief output for parsing + - \#define NETSNMP_DS_LIB_RANDOM_ACCESS 14 random access to oid labels + - \#define NETSNMP_DS_LIB_REGEX_ACCESS 15 regex matching to oid labels + - \#define NETSNMP_DS_LIB_DONT_CHECK_RANGE 16 don't check values for ranges on send + - \#define NETSNMP_DS_LIB_NO_TOKEN_WARNINGS 17 no warn about unknown config tokens + - \#define NETSNMP_DS_LIB_NUMERIC_TIMETICKS 18 print timeticks as a number + - \#define NETSNMP_DS_LIB_ESCAPE_QUOTES 19 shell escape quote marks in oids + - \#define NETSNMP_DS_LIB_REVERSE_ENCODE 20 encode packets from back to front + - \#define NETSNMP_DS_LIB_PRINT_BARE_VALUE 21 just print value (not OID = value) + - \#define NETSNMP_DS_LIB_EXTENDED_INDEX 22 print extended index format [x1][x2] + - \#define NETSNMP_DS_LIB_PRINT_HEX_TEXT 23 print ASCII text along with hex strings + - \#define NETSNMP_DS_LIB_PRINT_UCD_STYLE_OID 24 print OID's using the UCD-style prefix suppression + - \#define NETSNMP_DS_LIB_READ_UCD_STYLE_OID 25 require top-level OIDs to be prefixed with a dot + - \#define NETSNMP_DS_LIB_HAVE_READ_PREMIB_CONFIG 26 have the pre-mib parsing config tokens been processed + - \#define NETSNMP_DS_LIB_HAVE_READ_CONFIG 27 have the config tokens been processed + - \#define NETSNMP_DS_LIB_QUICKE_PRINT 28 + - \#define NETSNMP_DS_LIB_DONT_PRINT_UNITS 29 don't print UNITS suffix + - \#define NETSNMP_DS_LIB_NO_DISPLAY_HINT 30 don't apply DISPLAY-HINTs + - \#define NETSNMP_DS_LIB_16BIT_IDS 31 restrict requestIDs, etc to 16-bit values + - \#define NETSNMP_DS_LIB_DONT_PERSIST_STATE 32 don't save/load any persistant state + - \#define NETSNMP_DS_LIB_2DIGIT_HEX_OUTPUT 33 print a leading 0 on hex values <= 'f' + + + library integers + + - \#define NETSNMP_DS_LIB_MIB_WARNINGS 0 + - \#define NETSNMP_DS_LIB_SECLEVEL 1 + - \#define NETSNMP_DS_LIB_SNMPVERSION 2 + - \#define NETSNMP_DS_LIB_DEFAULT_PORT 3 + - \#define NETSNMP_DS_LIB_OID_OUTPUT_FORMAT 4 + - \#define NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT 5 + + library strings + + - \#define NETSNMP_DS_LIB_SECNAME 0 + - \#define NETSNMP_DS_LIB_CONTEXT 1 + - \#define NETSNMP_DS_LIB_PASSPHRASE 2 + - \#define NETSNMP_DS_LIB_AUTHPASSPHRASE 3 + - \#define NETSNMP_DS_LIB_PRIVPASSPHRASE 4 + - \#define NETSNMP_DS_LIB_OPTIONALCONFIG 5 + - \#define NETSNMP_DS_LIB_APPTYPE 6 + - \#define NETSNMP_DS_LIB_COMMUNITY 7 + - \#define NETSNMP_DS_LIB_PERSISTENT_DIR 8 + - \#define NETSNMP_DS_LIB_CONFIGURATION_DIR 9 + - \#define NETSNMP_DS_LIB_SECMODEL 10 + - \#define NETSNMP_DS_LIB_MIBDIRS 11 + - \#define NETSNMP_DS_LIB_OIDSUFFIX 12 + - \#define NETSNMP_DS_LIB_OIDPREFIX 13 + - \#define NETSNMP_DS_LIB_CLIENT_ADDR 14 + - \#define NETSNMP_DS_LIB_TEMP_FILE_PATTERN 15 + - \#define NETSNMP_DS_LIB_AUTHMASTERKEY 16 + - \#define NETSNMP_DS_LIB_PRIVMASTERKEY 17 + - \#define NETSNMP_DS_LIB_AUTHLOCALIZEDKEY 18 + - \#define NETSNMP_DS_LIB_PRIVLOCALIZEDKEY 19 + + * @{ + */ +#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_NETINET_IN_H +#include <netinet/in.h> +#endif +#if HAVE_STDLIB_H +#include <stdlib.h> +#endif +#if HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif + +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#if HAVE_DMALLOC_H +#include <dmalloc.h> +#endif + +#include <net-snmp/types.h> +#include <net-snmp/output_api.h> +#include <net-snmp/config_api.h> +#include <net-snmp/library/default_store.h> /* for "internal" definitions */ +#include <net-snmp/utilities.h> + +#include <net-snmp/library/snmp_api.h> + +netsnmp_feature_child_of(default_store_all, libnetsnmp) + +netsnmp_feature_child_of(default_store_void, default_store_all) + +#ifndef NETSNMP_FEATURE_REMOVE_DEFAULT_STORE_VOID +#endif /* NETSNMP_FEATURE_REMOVE_DEFAULT_STORE_VOID */ + + +static const char * stores [NETSNMP_DS_MAX_IDS] = { "LIB", "APP", "TOK" }; + +typedef struct netsnmp_ds_read_config_s { + u_char type; + char *token; + char *ftype; + int storeid; + int which; + struct netsnmp_ds_read_config_s *next; +} netsnmp_ds_read_config; + +static netsnmp_ds_read_config *netsnmp_ds_configs = NULL; + +static int netsnmp_ds_integers[NETSNMP_DS_MAX_IDS][NETSNMP_DS_MAX_SUBIDS]; +static char netsnmp_ds_booleans[NETSNMP_DS_MAX_IDS][NETSNMP_DS_MAX_SUBIDS/8]; +static char *netsnmp_ds_strings[NETSNMP_DS_MAX_IDS][NETSNMP_DS_MAX_SUBIDS]; +#ifndef NETSNMP_FEATURE_REMOVE_DEFAULT_STORE_VOID +static void *netsnmp_ds_voids[NETSNMP_DS_MAX_IDS][NETSNMP_DS_MAX_SUBIDS]; +#endif /* NETSNMP_FEATURE_REMOVE_DEFAULT_STORE_VOID */ + +/* + * Prototype definitions + */ +void netsnmp_ds_handle_config(const char *token, char *line); + +/** + * Stores "true" or "false" given an int value for value into + * netsnmp_ds_booleans[store][which] slot. + * + * @param storeid an index to the boolean storage container's first index(store) + * + * @param which an index to the boolean storage container's second index(which) + * + * @param value if > 0, "true" is set into the slot otherwise "false" + * + * @return Returns SNMPPERR_GENERR if the storeid and which parameters do not + * correspond to a valid slot, or SNMPERR_SUCCESS otherwise. + */ +int +netsnmp_ds_set_boolean(int storeid, int which, int value) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return SNMPERR_GENERR; + } + + DEBUGMSGTL(("netsnmp_ds_set_boolean", "Setting %s:%d = %d/%s\n", + stores[storeid], which, value, ((value) ? "True" : "False"))); + + if (value > 0) { + netsnmp_ds_booleans[storeid][which/8] |= (1 << (which % 8)); + } else { + netsnmp_ds_booleans[storeid][which/8] &= (0xff7f >> (7 - (which % 8))); + } + + return SNMPERR_SUCCESS; +} + +int +netsnmp_ds_toggle_boolean(int storeid, int which) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return SNMPERR_GENERR; + } + + if ((netsnmp_ds_booleans[storeid][which/8] & (1 << (which % 8))) == 0) { + netsnmp_ds_booleans[storeid][which/8] |= (1 << (which % 8)); + } else { + netsnmp_ds_booleans[storeid][which/8] &= (0xff7f >> (7 - (which % 8))); + } + + DEBUGMSGTL(("netsnmp_ds_toggle_boolean", "Setting %s:%d = %d/%s\n", + stores[storeid], which, netsnmp_ds_booleans[storeid][which/8], + ((netsnmp_ds_booleans[storeid][which/8]) ? "True" : "False"))); + + return SNMPERR_SUCCESS; +} + +int +netsnmp_ds_get_boolean(int storeid, int which) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return SNMPERR_GENERR; + } + + return (netsnmp_ds_booleans[storeid][which/8] & (1 << (which % 8))) ? 1:0; +} + +int +netsnmp_ds_set_int(int storeid, int which, int value) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return SNMPERR_GENERR; + } + + DEBUGMSGTL(("netsnmp_ds_set_int", "Setting %s:%d = %d\n", + stores[storeid], which, value)); + + netsnmp_ds_integers[storeid][which] = value; + return SNMPERR_SUCCESS; +} + +int +netsnmp_ds_get_int(int storeid, int which) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return SNMPERR_GENERR; + } + + return netsnmp_ds_integers[storeid][which]; +} + +int +netsnmp_ds_set_string(int storeid, int which, const char *value) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return SNMPERR_GENERR; + } + + DEBUGMSGTL(("netsnmp_ds_set_string", "Setting %s:%d = \"%s\"\n", + stores[storeid], which, (value ? value : "(null)"))); + + /* + * is some silly person is calling us with our own pointer? + */ + if (netsnmp_ds_strings[storeid][which] == value) + return SNMPERR_SUCCESS; + + if (netsnmp_ds_strings[storeid][which] != NULL) { + free(netsnmp_ds_strings[storeid][which]); + netsnmp_ds_strings[storeid][which] = NULL; + } + + if (value) { + netsnmp_ds_strings[storeid][which] = strdup(value); + } else { + netsnmp_ds_strings[storeid][which] = NULL; + } + + return SNMPERR_SUCCESS; +} + +char * +netsnmp_ds_get_string(int storeid, int which) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return NULL; + } + + return netsnmp_ds_strings[storeid][which]; +} + +#ifndef NETSNMP_FEATURE_REMOVE_DEFAULT_STORE_VOID +int +netsnmp_ds_set_void(int storeid, int which, void *value) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return SNMPERR_GENERR; + } + + DEBUGMSGTL(("netsnmp_ds_set_void", "Setting %s:%d = %p\n", + stores[storeid], which, value)); + + netsnmp_ds_voids[storeid][which] = value; + + return SNMPERR_SUCCESS; +} + +void * +netsnmp_ds_get_void(int storeid, int which) +{ + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS) { + return NULL; + } + + return netsnmp_ds_voids[storeid][which]; +} +#endif /* NETSNMP_FEATURE_REMOVE_DEFAULT_STORE_VOID */ + +int +netsnmp_ds_parse_boolean(char *line) +{ + char *value, *endptr; + int itmp; + char *st; + + value = strtok_r(line, " \t\n", &st); + if (strcasecmp(value, "yes") == 0 || + strcasecmp(value, "true") == 0) { + return 1; + } else if (strcasecmp(value, "no") == 0 || + strcasecmp(value, "false") == 0) { + return 0; + } else { + itmp = strtol(value, &endptr, 10); + if (*endptr != 0 || itmp < 0 || itmp > 1) { + config_perror("Should be yes|no|true|false|0|1"); + return -1; + } + return itmp; + } +} + +void +netsnmp_ds_handle_config(const char *token, char *line) +{ + netsnmp_ds_read_config *drsp; + char buf[SNMP_MAXBUF]; + char *value, *endptr; + int itmp; + char *st; + + DEBUGMSGTL(("netsnmp_ds_handle_config", "handling %s\n", token)); + + for (drsp = netsnmp_ds_configs; + drsp != NULL && strcasecmp(token, drsp->token) != 0; + drsp = drsp->next); + + if (drsp != NULL) { + DEBUGMSGTL(("netsnmp_ds_handle_config", + "setting: token=%s, type=%d, id=%s, which=%d\n", + drsp->token, drsp->type, stores[drsp->storeid], + drsp->which)); + + switch (drsp->type) { + case ASN_BOOLEAN: + itmp = netsnmp_ds_parse_boolean(line); + if ( itmp != -1 ) + netsnmp_ds_set_boolean(drsp->storeid, drsp->which, itmp); + DEBUGMSGTL(("netsnmp_ds_handle_config", "bool: %d\n", itmp)); + break; + + case ASN_INTEGER: + value = strtok_r(line, " \t\n", &st); + itmp = strtol(value, &endptr, 10); + if (*endptr != 0) { + config_perror("Bad integer value"); + } else { + netsnmp_ds_set_int(drsp->storeid, drsp->which, itmp); + } + DEBUGMSGTL(("netsnmp_ds_handle_config", "int: %d\n", itmp)); + break; + + case ASN_OCTET_STR: + if (*line == '"') { + copy_nword(line, buf, sizeof(buf)); + netsnmp_ds_set_string(drsp->storeid, drsp->which, buf); + } else { + netsnmp_ds_set_string(drsp->storeid, drsp->which, line); + } + DEBUGMSGTL(("netsnmp_ds_handle_config", "string: %s\n", line)); + break; + + default: + snmp_log(LOG_ERR, "netsnmp_ds_handle_config: type %d (0x%02x)\n", + drsp->type, drsp->type); + break; + } + } else { + snmp_log(LOG_ERR, "netsnmp_ds_handle_config: no registration for %s\n", + token); + } +} + + +int +netsnmp_ds_register_config(u_char type, const char *ftype, const char *token, + int storeid, int which) +{ + netsnmp_ds_read_config *drsp; + + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS || token == NULL) { + return SNMPERR_GENERR; + } + + if (netsnmp_ds_configs == NULL) { + netsnmp_ds_configs = SNMP_MALLOC_TYPEDEF(netsnmp_ds_read_config); + if (netsnmp_ds_configs == NULL) + return SNMPERR_GENERR; + drsp = netsnmp_ds_configs; + } else { + for (drsp = netsnmp_ds_configs; drsp->next != NULL; drsp = drsp->next); + drsp->next = SNMP_MALLOC_TYPEDEF(netsnmp_ds_read_config); + if (drsp->next == NULL) + return SNMPERR_GENERR; + drsp = drsp->next; + } + + drsp->type = type; + drsp->ftype = strdup(ftype); + drsp->token = strdup(token); + drsp->storeid = storeid; + drsp->which = which; + + switch (type) { + case ASN_BOOLEAN: + register_config_handler(ftype, token, netsnmp_ds_handle_config, NULL, + "(1|yes|true|0|no|false)"); + break; + + case ASN_INTEGER: + register_config_handler(ftype, token, netsnmp_ds_handle_config, NULL, + "integerValue"); + break; + + case ASN_OCTET_STR: + register_config_handler(ftype, token, netsnmp_ds_handle_config, NULL, + "string"); + break; + + } + return SNMPERR_SUCCESS; +} + +int +netsnmp_ds_register_premib(u_char type, const char *ftype, const char *token, + int storeid, int which) +{ + netsnmp_ds_read_config *drsp; + + if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || + which < 0 || which >= NETSNMP_DS_MAX_SUBIDS || token == NULL) { + return SNMPERR_GENERR; + } + + if (netsnmp_ds_configs == NULL) { + netsnmp_ds_configs = SNMP_MALLOC_TYPEDEF(netsnmp_ds_read_config); + if (netsnmp_ds_configs == NULL) + return SNMPERR_GENERR; + drsp = netsnmp_ds_configs; + } else { + for (drsp = netsnmp_ds_configs; drsp->next != NULL; drsp = drsp->next); + drsp->next = SNMP_MALLOC_TYPEDEF(netsnmp_ds_read_config); + if (drsp->next == NULL) + return SNMPERR_GENERR; + drsp = drsp->next; + } + + drsp->type = type; + drsp->ftype = strdup(ftype); + drsp->token = strdup(token); + drsp->storeid = storeid; + drsp->which = which; + + switch (type) { + case ASN_BOOLEAN: + register_prenetsnmp_mib_handler(ftype, token, netsnmp_ds_handle_config, + NULL, "(1|yes|true|0|no|false)"); + break; + + case ASN_INTEGER: + register_prenetsnmp_mib_handler(ftype, token, netsnmp_ds_handle_config, + NULL, "integerValue"); + break; + + case ASN_OCTET_STR: + register_prenetsnmp_mib_handler(ftype, token, netsnmp_ds_handle_config, + NULL, "string"); + break; + + } + return SNMPERR_SUCCESS; +} + +void +netsnmp_ds_shutdown(void) +{ + netsnmp_ds_read_config *drsp; + int i, j; + + for (drsp = netsnmp_ds_configs; drsp; drsp = netsnmp_ds_configs) { + netsnmp_ds_configs = drsp->next; + + if (drsp->ftype && drsp->token) { + unregister_config_handler(drsp->ftype, drsp->token); + } + if (drsp->ftype != NULL) { + free(drsp->ftype); + } + if (drsp->token != NULL) { + free(drsp->token); + } + free(drsp); + } + + for (i = 0; i < NETSNMP_DS_MAX_IDS; i++) { + for (j = 0; j < NETSNMP_DS_MAX_SUBIDS; j++) { + if (netsnmp_ds_strings[i][j] != NULL) { + free(netsnmp_ds_strings[i][j]); + netsnmp_ds_strings[i][j] = NULL; + } + } + } +} +/** @} */ |