summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralex <alex@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2008-02-08 23:26:20 +0000
committeralex <alex@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2008-02-08 23:26:20 +0000
commitd3fe02b7bbe894a89726f107fd8a593decae5027 (patch)
tree206fa89d7fcf8edfd5e24e5af6fdb7622e8300e0
parent3aeadf322092f6e3bd0257c601114274760d3540 (diff)
downloadzabbix-d3fe02b7bbe894a89726f107fd8a593decae5027.tar.gz
zabbix-d3fe02b7bbe894a89726f107fd8a593decae5027.tar.xz
zabbix-d3fe02b7bbe894a89726f107fd8a593decae5027.zip
- [DEV-114] special processing of simple SNMP OIDs like ifDescr, ifInOctets, etc (Alexei)
- [DEV-114] monitoring of SNMP objects having flexible Index (Alexei) git-svn-id: svn://svn.zabbix.com/trunk@5337 97f52cf1-0a1b-0410-bd0e-c28be96e8082
-rw-r--r--ChangeLog2
-rw-r--r--include/common.h2
-rw-r--r--src/libs/zbxcommon/str.c98
-rw-r--r--src/zabbix_server/poller/checks_agent.c3
-rw-r--r--src/zabbix_server/poller/checks_snmp.c550
5 files changed, 648 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index bc251e29..9008a713 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
Changes for 1.5:
+ - [DEV-114] special processing of simple SNMP OIDs like ifDescr, ifInOctets, etc (Alexei)
+ - [DEV-114] monitoring of SNMP objects having flexible Index (Alexei)
- [DEV-104] added maintenance mode (Artem)
- [DEV-103] added support of disabling login rights for a users group (Artem)
- [DEV-102] added support of UTF8 for GUI (Artem)
diff --git a/include/common.h b/include/common.h
index a371208f..5dc51927 100644
--- a/include/common.h
+++ b/include/common.h
@@ -563,6 +563,8 @@ void rtrim_spaces(char *c);
void delete_reol(char *c);
int get_param(const char *param, int num, char *buf, int maxlen);
int num_param(const char *param);
+int get_key_param(char *param, int num, char *buf, int maxlen);
+int num_key_param(char *param);
int calculate_item_nextcheck(zbx_uint64_t itemid, int item_type, int delay, char *delay_flex, time_t now);
int check_time_period(const char *period, time_t now);
char zbx_num2hex(u_char c);
diff --git a/src/libs/zbxcommon/str.c b/src/libs/zbxcommon/str.c
index 55f4bb2f..e802c4e7 100644
--- a/src/libs/zbxcommon/str.c
+++ b/src/libs/zbxcommon/str.c
@@ -1466,3 +1466,101 @@ int str_in_list(char *list, const char *value, const char delimiter)
}
return ret;
}
+
+/******************************************************************************
+ * *
+ * Function: get_key_param *
+ * *
+ * Purpose: return parameter by index (num) from parameter list (param) *
+ * to be used for keys: key[param1,param2] *
+ * *
+ * Parameters: *
+ * param - parameter list *
+ * num - requested parameter index *
+ * buf - pointer of output buffer *
+ * maxlem - size of output buffer *
+ * *
+ * Return value: *
+ * 1 - requested parameter missed *
+ * 0 - requested parameter found (value - 'buf' can be empty string) *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: delimeter for parameters is ',' *
+ * *
+ ******************************************************************************/
+int get_key_param(char *param, int num, char *buf, int maxlen)
+{
+ int ret = 0;
+
+ char *pl, *pr;
+
+ pl = strchr(param, '[');
+ pr = strrchr(param, ']');
+
+ if(pl > pr)
+ return 1;
+
+ if(!pl || !pr || (pl && !pr) || (!pl && pr))
+ return 1;
+
+ if(pr != NULL)
+ pr[0] = 0;
+
+ ret = get_param(pl+1, num, buf, maxlen);
+
+ if(pr != NULL)
+ pr[0]=']';
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Function: num_key_param *
+ * *
+ * Purpose: calculate count of parameters from parameter list (param) *
+ * to be used for keys: key[param1,param2] *
+ * *
+ * Parameters: *
+ * param - parameter list *
+ * *
+ * Return value: count of parameters *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: delimeter vor parameters is ',' *
+ * *
+ ******************************************************************************/
+int num_key_param(char *param)
+{
+ int ret = 1;
+
+ char *pl, *pr;
+
+ if(param == NULL)
+ return 0;
+
+ pl = strchr(param, '[');
+ pr = strrchr(param, ']');
+
+ if(pl > pr)
+ return 0;
+
+ if(!pl || !pr || (pl && !pr) || (!pl && pr))
+ return 0;
+
+ if(pl != NULL)
+ pl[0] = 0;
+ if(pr != NULL)
+ pr[0] = 0;
+
+ ret = num_param(pl+1);
+
+ if(pl != NULL)
+ pl[0]='[';
+ if(pr != NULL)
+ pr[0]=']';
+
+ return ret;
+}
diff --git a/src/zabbix_server/poller/checks_agent.c b/src/zabbix_server/poller/checks_agent.c
index b8a2578d..99b5a7c6 100644
--- a/src/zabbix_server/poller/checks_agent.c
+++ b/src/zabbix_server/poller/checks_agent.c
@@ -60,7 +60,9 @@ int get_value_agent(DB_ITEM *item, AGENT_RESULT *result)
addr,
item->key);
+ zabbix_log(LOG_LEVEL_DEBUG, "Before zbx_tcp_connect");
if (SUCCEED == (ret = zbx_tcp_connect(&s, addr, item->port, 0))) {
+ zabbix_log(LOG_LEVEL_DEBUG, "After1 zbx_tcp_connect");
zbx_snprintf(packet, sizeof(packet), "%s\n",item->key);
zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", packet);
@@ -72,6 +74,7 @@ int get_value_agent(DB_ITEM *item, AGENT_RESULT *result)
ret = zbx_tcp_recv_ext(&s, &buf, ZBX_TCP_READ_UNTIL_CLOSE);
}
}
+ zabbix_log(LOG_LEVEL_DEBUG, "After2 zbx_tcp_connect");
if( SUCCEED == ret )
{
diff --git a/src/zabbix_server/poller/checks_snmp.c b/src/zabbix_server/poller/checks_snmp.c
index b289a1bc..c8ceadb9 100644
--- a/src/zabbix_server/poller/checks_snmp.c
+++ b/src/zabbix_server/poller/checks_snmp.c
@@ -20,7 +20,344 @@
#include "checks_snmp.h"
#ifdef HAVE_SNMP
-int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
+
+/* Function: snmp_get_index
+ * *
+ * Purpose: find index of OID with given value *
+ * *
+ * Parameters: DB_ITEM *item - configuration of zabbix item *
+ * char *OID - OID of table with values of interest *
+ * char *value - value to look for *
+ * int *idx - result to be placed here *
+ * *
+ * Return value: NOTSUPPORTED - OID does not exist, any other critical error *
+ * NETWORK_ERROR - recoverable network error *
+ * SUCCEED - success, variable 'idx' contains index having *
+ * value 'value' */
+static int snmp_get_index (DB_ITEM * item, char *OID, char *value, int *idx)
+{
+ const char *__function_name = "snmp_get_index";
+ struct snmp_session session, *ss;
+ struct snmp_pdu *pdu;
+ struct snmp_pdu *response;
+
+ oid anOID[MAX_OID_LEN];
+ oid rootOID[MAX_OID_LEN];
+ size_t anOID_len = MAX_OID_LEN;
+ size_t rootOID_len = MAX_OID_LEN;
+
+ char temp[MAX_STRING_LEN];
+ char strval[MAX_STRING_LEN];
+ char error[MAX_STRING_LEN];
+ struct variable_list *vars;
+
+ int len;
+ int status;
+ int running;
+
+ unsigned char *ip;
+ int ret = NOTSUPPORTED;
+
+ zabbix_log (LOG_LEVEL_DEBUG, "In %s(oid:%s)",
+ __function_name,
+ OID);
+
+ *idx = 0;
+
+ assert ((item->type == ITEM_TYPE_SNMPv1) ||
+ (item->type == ITEM_TYPE_SNMPv2c) ||
+ (item->type == ITEM_TYPE_SNMPv3));
+
+ snmp_sess_init (&session);
+
+ switch (item->type)
+ {
+ case ITEM_TYPE_SNMPv1:
+ session.version = SNMP_VERSION_1;
+ break;
+
+ case ITEM_TYPE_SNMPv2c:
+ session.version = SNMP_VERSION_2c;
+ break;
+
+ case ITEM_TYPE_SNMPv3:
+ session.version = SNMP_VERSION_3;
+ break;
+
+ default:
+ zbx_snprintf (error, sizeof (error),
+ "Error in %s. Wrong item type [%d]. Must be SNMP.",
+ __function_name,
+ item->type);
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ return NOTSUPPORTED;
+ }
+
+
+ if (item->useip == 1)
+ {
+ zbx_snprintf (temp, sizeof (temp), "%s:%d", item->host_ip,
+ item->snmp_port);
+ session.peername = temp;
+ session.remote_port = item->snmp_port;
+ }
+ else
+ {
+ zbx_snprintf (temp, sizeof (temp), "%s:%d",
+ item->host_dns, item->snmp_port);
+ session.peername = temp;
+ session.remote_port = item->snmp_port;
+ }
+
+ if ((session.version == SNMP_VERSION_1)
+ || (item->type == ITEM_TYPE_SNMPv2c))
+ {
+ session.community = (u_char *) item->snmp_community;
+ session.community_len = strlen ((void *) session.community);
+ zabbix_log (LOG_LEVEL_DEBUG, "SNMP [%s@%s:%d]",
+ session.community, session.peername, session.remote_port);
+ }
+ else if (session.version == SNMP_VERSION_3)
+ {
+ /* set the SNMPv3 user name */
+ session.securityName = item->snmpv3_securityname;
+ session.securityNameLen = strlen (session.securityName);
+
+ /* set the security level to authenticated, but not encrypted */
+
+ if (item->snmpv3_securitylevel ==
+ ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV)
+ {
+ session.securityLevel = SNMP_SEC_LEVEL_NOAUTH;
+ }
+ else if (item->snmpv3_securitylevel ==
+ ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV)
+ {
+ session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
+
+ /* set the authentication method to MD5 */
+ session.securityAuthProto = usmHMACMD5AuthProtocol;
+ session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
+ session.securityAuthKeyLen = USM_AUTH_KU_LEN;
+
+ if (generate_Ku (session.securityAuthProto,
+ session.securityAuthProtoLen,
+ (u_char *) item->snmpv3_authpassphrase,
+ strlen (item->snmpv3_authpassphrase),
+ session.securityAuthKey,
+ &session.securityAuthKeyLen) != SNMPERR_SUCCESS)
+ {
+ zbx_snprintf (error, sizeof (error),
+ "Error generating Ku from authentication pass phrase.");
+
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ return NOTSUPPORTED;
+ }
+ }
+ else if (item->snmpv3_securitylevel ==
+ ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV)
+ {
+ session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
+
+ /* set the authentication method to MD5 */
+ session.securityAuthProto = usmHMACMD5AuthProtocol;
+ session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
+ session.securityAuthKeyLen = USM_AUTH_KU_LEN;
+
+ if (generate_Ku (session.securityAuthProto,
+ session.securityAuthProtoLen,
+ (u_char *) item->snmpv3_authpassphrase,
+ strlen (item->snmpv3_authpassphrase),
+ session.securityAuthKey,
+ &session.securityAuthKeyLen) != SNMPERR_SUCCESS)
+ {
+ zbx_snprintf (error, sizeof (error),
+ "Error generating Ku from authentication pass phrase.");
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ return NOTSUPPORTED;
+ }
+
+ /* set the private method to DES */
+ session.securityPrivProto = usmDESPrivProtocol;
+ session.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
+ session.securityPrivKeyLen = USM_PRIV_KU_LEN;
+
+ if (generate_Ku (session.securityAuthProto,
+ session.securityAuthProtoLen,
+ (u_char *) item->snmpv3_privpassphrase,
+ strlen (item->snmpv3_privpassphrase),
+ session.securityPrivKey,
+ &session.securityPrivKeyLen) != SNMPERR_SUCCESS)
+ {
+ zbx_snprintf (error, sizeof (error),
+ "Error generating Ku from priv pass phrase.");
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ return NOTSUPPORTED;
+ }
+ }
+ zabbix_log (LOG_LEVEL_DEBUG, "SNMPv3 [%s@%s:%d]",
+ session.securityName,
+ session.peername, session.remote_port);
+ }
+ else
+ {
+ zbx_snprintf (error, sizeof (error),
+ "Error in %s. Unsupported session version [%d]",
+ __function_name, (int) session.version);
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ return NOTSUPPORTED;
+ }
+
+ zabbix_log (LOG_LEVEL_DEBUG, "OID [%s]", OID);
+
+ SOCK_STARTUP;
+ ss = snmp_open (&session);
+
+ if (ss == NULL)
+ {
+ SOCK_CLEANUP;
+
+ zbx_snprintf (error, sizeof (error), "Error doing snmp_open()");
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ return NOTSUPPORTED;
+ }
+
+ /* create OID from string */
+ snmp_parse_oid (OID, rootOID, &rootOID_len);
+ /* copy rootOID to anOID */
+ memcpy (anOID, rootOID, rootOID_len * sizeof (oid));
+ anOID_len = rootOID_len;
+
+ running = 1;
+ while (running)
+ {
+ zabbix_log (LOG_LEVEL_DEBUG, "%s: snmp_pdu_create()",
+ __function_name);
+ /* prepare PDU */
+ pdu = snmp_pdu_create (SNMP_MSG_GETNEXT); /* create empty PDU */
+ snmp_add_null_var (pdu, anOID, anOID_len); /* add OID as variable to PDU */
+ /* communicate with agent */
+ status = snmp_synch_response (ss, pdu, &response);
+
+ /* process response */
+ if (status == STAT_SUCCESS)
+ {
+ if (response->errstat == SNMP_ERR_NOERROR)
+ {
+ for (vars = response->variables; vars && running;
+ vars = vars->next_variable)
+ {
+ memcpy (strval, vars->val.string, vars->val_len);
+ strval[vars->val_len] = 0; /* terminate */
+
+ len =
+ snprint_objid (temp, sizeof (temp), vars->name,
+ vars->name_length);
+ zabbix_log (LOG_LEVEL_DEBUG,
+ "VAR: %s = %s (type=%d)(length = %d)", temp,
+ strval, vars->type, vars->val_len);
+
+ /* verify if we are in the same subtree */
+ if ((vars->name_length < rootOID_len) ||
+ (memcmp
+ (rootOID, vars->name,
+ rootOID_len * sizeof (oid)) != 0))
+ {
+ /* not part of this subtree */
+ running = 0;
+ zabbix_log (LOG_LEVEL_ERR, "NOT FOUND: %s[%s]", OID,
+ value);
+ ret = NOTSUPPORTED;
+ }
+ else
+ {
+ /* verify if OIDs are increasing */
+ if ((vars->type != SNMP_ENDOFMIBVIEW) &&
+ (vars->type != SNMP_NOSUCHOBJECT) &&
+ (vars->type != SNMP_NOSUCHINSTANCE))
+ {
+ /* not an exception value */
+ if (snmp_oid_compare
+ (anOID, anOID_len, vars->name,
+ vars->name_length) >= 0)
+ {
+ zabbix_log (LOG_LEVEL_ERR,
+ "Error: OID not increasing.");
+ ret = NOTSUPPORTED;
+ running = 0;
+ }
+
+ /*__compare with key value__ */
+ if (strcmp (value, strval) == 0)
+ {
+ *idx = vars->name[vars->name_length - 1];
+ zabbix_log (LOG_LEVEL_DEBUG,
+ "FOUND: Index is %d", *idx);
+ ret = SUCCEED;
+ running = 0;
+ }
+
+ /* go to next variable */
+ memmove ((char *) anOID, (char *) vars->name,
+ vars->name_length * sizeof (oid));
+ anOID_len = vars->name_length;
+ }
+ else
+ {
+ /* an exception value, so stop */
+ zabbix_log (LOG_LEVEL_DEBUG,
+ "%s: Exception value found",
+ __function_name);
+ running = 0;
+ ret = NOTSUPPORTED;
+ }
+ } /*same subtree */
+ } /*for */
+ }
+ else
+ {
+ zbx_snprintf (error, sizeof (error), "SNMP error [%s]",
+ snmp_errstring (response->errstat));
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ running = 0;
+ ret = NOTSUPPORTED;
+ }
+ }
+ else if (status == STAT_TIMEOUT)
+ {
+ zbx_snprintf (error, sizeof (error),
+ "Timeout while connecting to [%s]",
+ session.peername);
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ running = 0;
+ ret = NETWORK_ERROR;
+ }
+ else
+ {
+ zbx_snprintf (error, sizeof (error), "SNMP error [%d]", status);
+ zabbix_log (LOG_LEVEL_ERR, "%s", error);
+ running = 0;
+ ret = NOTSUPPORTED;
+ }
+
+ if (response)
+ {
+ zabbix_log (LOG_LEVEL_DEBUG, "%s: snmp_free_pdu()",
+ __function_name);
+ snmp_free_pdu (response);
+ }
+ } /* while(running) */
+
+ snmp_close (ss);
+
+ SOCK_CLEANUP;
+
+ zabbix_log (LOG_LEVEL_DEBUG, "%s: end", __function_name);
+ return ret;
+}
+
+
+int get_snmp(DB_ITEM *item, char *snmp_oid, AGENT_RESULT *value)
{
#define NEW_APPROACH
@@ -47,7 +384,8 @@ int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
int ret=SUCCEED;
- zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP()");
+ zabbix_log( LOG_LEVEL_DEBUG, "In get_snmp(oid:%s)",
+ snmp_oid);
init_result(value);
@@ -210,7 +548,7 @@ int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
}
zabbix_log( LOG_LEVEL_DEBUG, "OID [%s]",
- item->snmp_oid);
+ snmp_oid);
SOCK_STARTUP;
ss = snmp_open(&session);
@@ -231,7 +569,7 @@ int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
pdu = snmp_pdu_create(SNMP_MSG_GET);
/* Changed to snmp_parse_oid */
/* read_objid(item->snmp_oid, anOID, &anOID_len);*/
- snmp_parse_oid(item->snmp_oid, anOID, &anOID_len);
+ snmp_parse_oid(snmp_oid, anOID, &anOID_len);
#if OTHER_METHODS
get_node("sysDescr.0", anOID, &anOID_len);
@@ -284,11 +622,11 @@ int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
/* SET_UI64_RESULT(value, (zbx_uint64_t)*vars->val.integer);*/
SET_UI64_RESULT(value, (unsigned long)*vars->val.integer);
zabbix_log( LOG_LEVEL_DEBUG, "OID [%s] Type [%d] UI64[" ZBX_FS_UI64 "]",
- item->snmp_oid,
+ snmp_oid,
vars->type,
(zbx_uint64_t)*vars->val.integer);
zabbix_log( LOG_LEVEL_DEBUG, "OID [%s] Type [%d] ULONG[%lu]",
- item->snmp_oid,
+ snmp_oid,
vars->type,
(zbx_uint64_t)(unsigned long)*vars->val.integer);
}
@@ -415,7 +753,7 @@ int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
count++;
zbx_snprintf(error,sizeof(error),"OID [%s] value #%d has unknow type [%X]",
- item->snmp_oid,
+ snmp_oid,
count,
vars->type);
@@ -490,4 +828,202 @@ int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
SOCK_CLEANUP;
return ret;
}
+
+/******************************************************************************
+ * *
+ * Function: snmp_normalize *
+ * *
+ * Purpose: translate well known MIBs into numerics *
+ * *
+ * Parameters: *
+ * *
+ * Return value: *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+static void snmp_normalize(char *buf, char *oid, int maxlen)
+{
+#define ZBX_MIB_NORM struct zbx_mib_norm_t
+
+ZBX_MIB_NORM
+{
+ char *mib;
+ char *replace;
+};
+
+static ZBX_MIB_NORM mibs[]=
+{
+ {"ifIndex", "1.3.6.1.2.1.2.2.1.1"},
+ {"ifDescr", "1.3.6.1.2.1.2.2.1.2"},
+ {"ifType", "1.3.6.1.2.1.2.2.1.3"},
+ {"ifMtu", "1.3.6.1.2.1.2.2.1.4"},
+ {"ifSpeed", "1.3.6.1.2.1.2.2.1.5"},
+ {"ifPhysAddress", "1.3.6.1.2.1.2.2.1.6"},
+ {"ifAdminStatus", "1.3.6.1.2.1.2.2.1.7"},
+ {"ifOperStatus", "1.3.6.1.2.1.2.2.1.8"},
+ {"ifInOctets", "1.3.6.1.2.1.2.2.1.10"},
+ {"ifInUcastPkts", "1.3.6.1.2.1.2.2.1.11"},
+ {"ifInNUcastPkts", "1.3.6.1.2.1.2.2.1.12"},
+ {"ifInDiscards", "1.3.6.1.2.1.2.2.1.13"},
+ {"ifInErrors", "1.3.6.1.2.1.2.2.1.14"},
+ {"ifInUnknownProtos", "1.3.6.1.2.1.2.2.1.15"},
+ {"ifOutOctets", "1.3.6.1.2.1.2.2.1.17"},
+ {"ifOutNUcastPkts", "1.3.6.1.2.1.2.2.1.18"},
+ {"ifOutDiscards", "1.3.6.1.2.1.2.2.1.19"},
+ {"ifOutErrors", "1.3.6.1.2.1.2.2.1.20"},
+ {"ifOutQLen", "1.3.6.1.2.1.2.2.1.21"},
+ {NULL}
+};
+ int found = 0;
+ int i;
+
+ zabbix_log( LOG_LEVEL_DEBUG, "In snmp_normalize(oid:%s)",
+ oid);
+
+ for(i=0;mibs[i].mib!=NULL;i++)
+ {
+ if(strncmp(mibs[i].mib,oid,strlen(mibs[i].mib)) == 0)
+ {
+ found = 1;
+ if(strlen(mibs[i].mib) == strlen(oid))
+ {
+ zbx_strlcpy(buf, mibs[i].replace, maxlen);
+ }
+ else
+ {
+ zbx_snprintf(buf, maxlen, "%s%s",
+ mibs[i].replace,
+ oid+strlen(mibs[i].mib));
+ }
+ break;
+ }
+ }
+ if(0 == found)
+ {
+ zbx_strlcpy(buf, oid, maxlen);
+ }
+
+ zabbix_log( LOG_LEVEL_DEBUG, "End of snmp_normalize(result:%s)",
+ buf);
+}
+
+int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
+{
+ int ret = SUCCEED;
+ char error[MAX_STRING_LEN];
+ char method[MAX_STRING_LEN];
+ char oid_normalized[MAX_STRING_LEN];
+ char oid_index[MAX_STRING_LEN];
+ char oid_full[MAX_STRING_LEN];
+ char index_value[MAX_STRING_LEN];
+ int idx;
+ char *pl;
+ int num;
+
+ zabbix_log( LOG_LEVEL_DEBUG, "In get_value_snmp(key:%s, oid:%s)",
+ item->key,
+ item->snmp_oid);
+
+ num = num_key_param(item->snmp_oid);
+
+ switch (num)
+ {
+ case 0:
+ zabbix_log( LOG_LEVEL_DEBUG,"Standard processing");
+ snmp_normalize(oid_normalized, item->snmp_oid, sizeof(oid_normalized));
+ ret = get_snmp(item, oid_normalized, value);
+ break;
+ case 3:
+ do {
+ zabbix_log( LOG_LEVEL_DEBUG,"Special processing");
+ oid_index[0]='\0';
+ method[0]='\0';
+ index_value[0]='\0';
+ if(get_key_param(item->snmp_oid, 1, method, MAX_STRING_LEN) != 0
+ || get_key_param(item->snmp_oid, 2, oid_index, MAX_STRING_LEN) != 0
+ || get_key_param(item->snmp_oid, 3, index_value, MAX_STRING_LEN) != 0
+ )
+ {
+ zbx_snprintf(error,sizeof(error),"Cannot retrieve all three parameters from [%s]",
+ item->snmp_oid);
+
+ zabbix_log( LOG_LEVEL_ERR, "%s",
+ error);
+ SET_MSG_RESULT(value, strdup(error));
+
+ ret = NOTSUPPORTED;
+ break;
+ }
+ zabbix_log( LOG_LEVEL_DEBUG,"method:%s", method);
+ zabbix_log( LOG_LEVEL_DEBUG,"oid_index:%s", oid_index);
+ zabbix_log( LOG_LEVEL_DEBUG,"index_value:%s", index_value);
+ if(strcmp("index", method) != 0)
+ {
+ zbx_snprintf(error,sizeof(error),"Unsupported method [%s] in the OID [%s]",
+ method,
+ item->snmp_oid);
+
+ zabbix_log( LOG_LEVEL_ERR, "%s",
+ error);
+ SET_MSG_RESULT(value, strdup(error));
+
+ ret = NOTSUPPORTED;
+ break;
+ }
+ snmp_normalize(oid_normalized, oid_index, sizeof(oid_normalized));
+ if(snmp_get_index (item, oid_normalized, index_value, &idx) != SUCCEED)
+ {
+ zbx_snprintf(error,sizeof(error),"Cannot find index [%s] of the OID [%s]",
+ oid_index,
+ item->snmp_oid);
+
+ zabbix_log( LOG_LEVEL_ERR, "%s",
+ error);
+ SET_MSG_RESULT(value, strdup(error));
+
+ ret = NOTSUPPORTED;
+ break;
+ }
+
+ zabbix_log( LOG_LEVEL_DEBUG,"Found index:%d", idx);
+ pl=strchr(item->snmp_oid,'[');
+ if(NULL == pl)
+ {
+ zbx_snprintf(error,sizeof(error),"Cannot find left bracket in the OID [%s]",
+ item->snmp_oid);
+
+ zabbix_log( LOG_LEVEL_ERR, "%s",
+ error);
+ SET_MSG_RESULT(value, strdup(error));
+
+ ret = NOTSUPPORTED;
+ break;
+ }
+ pl[0]='\0';
+ snmp_normalize(oid_normalized, item->snmp_oid, sizeof(oid_normalized));
+ zbx_snprintf(oid_full, sizeof(oid_full), "%s.%d",
+ oid_normalized,
+ idx);
+ zabbix_log( LOG_LEVEL_DEBUG,"Full OID:%s", oid_full);
+ ret = get_snmp(item, oid_full, value);
+ pl[0]='[';
+ } while(0);
+ break;
+ default:
+ zbx_snprintf(error,sizeof(error),"OID [%s] contains unsupported parameters",
+ item->snmp_oid);
+
+ zabbix_log( LOG_LEVEL_ERR, "%s",
+ error);
+ SET_MSG_RESULT(value, strdup(error));
+
+ ret = NOTSUPPORTED;
+ }
+
+ return ret;
+}
+
#endif