コード例 #1
0
ファイル: snmp.c プロジェクト: fbn-dd/netplan
/*
 * simple printing of returned data
 */
int snmpStoreResult (tSession *session, struct snmp_pdu *pdu, char **result)
{
	char buf[RESULTSIZE];
	struct variable_list *vp;
	struct snmp_session *sp = session->sess;
	unsigned int o = session->current_oid;
	unsigned int i,j;

	*result = (char*)calloc(RESULTSIZE+1, sizeof(char));

	vp = pdu->variables;
	if (pdu->errstat == SNMP_ERR_NOERROR) {
		while (vp) {
			snprint_value(*result, RESULTSIZE, vp->name, vp->name_length, vp);

			// tolower & remove spaces and linebreaks
			for (i=0, j=0; i<strlen(*result); i++) {
				if ((*result)[i] > 0x22) {
					if ((*result)[i] >= 0x41 && (*result)[i] <= 0x5A) {
						(*result)[j] = (*result)[i] + 0x20;
					} else {
						(*result)[j] = (*result)[i];
					}
					j++;
				}
			}
			(*result)[j] = 0;

			// fix lancom snr
			if (session->oidList.oid[o].id_oidtype == 12 &&
				( session->oidList.oid[o].id_type == 2 ||
  				session->oidList.oid[o].id_type == 5 ||
  				session->oidList.oid[o].id_type == 9 ||
  				session->oidList.oid[o].id_type == 24 )) {
				snprintf(*result, RESULTSIZE, "%.0f", atoi(*result) * 0.64);
			}

			snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp);
			syslog(LOG_DEBUG, "snmpStoreResult: %s: %s", sp->peername, buf);
			vp = vp->next_variable;
		}
		return 1;
	} else {
		if (vp) {
			snprint_objid(buf, sizeof(buf), vp->name, vp->name_length);
		} else {
			strcpy(buf, "(empty buf)");
		}

		syslog(LOG_ERR, "snmpStoreResult: %s: %s: (%s)", sp->peername, buf, snmp_errstring(pdu->errstat));

		if (pdu->errstat == SNMP_ERR_NOSUCHNAME) {
			snprintf(*result, RESULTSIZE, "U");
			return 1;
		}

		return 0;
	}
}
コード例 #2
0
static char	*snmp_get_octet_string(struct variable_list *vars)
{
	const char	*__function_name = "snmp_get_octet_string";
	static char	buf[MAX_STRING_LEN];
	const char	*hint;
	char		*strval_dyn = NULL, is_hex = 0;
	size_t          offset = 0;
	struct tree     *subtree;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	/* find the subtree to get display hint */
	subtree = get_tree(vars->name, vars->name_length, get_tree_head());
	hint = subtree ? subtree->hint : NULL;

	/* we will decide if we want the value from vars->val or what snprint_value() returned later */
	if (-1 == snprint_value(buf, sizeof(buf), vars->name, vars->name_length, vars))
		goto end;

	zabbix_log(LOG_LEVEL_DEBUG, "%s() full value:'%s'", __function_name, buf);

	/* decide if it's Hex, offset will be possibly needed later */
	if (0 == strncmp(buf, "Hex-STRING: ", 12))
	{
		is_hex = 1;
		offset = 12;
	}

	/* in case of no hex and no display hint take the value from */
	/* vars->val, it contains unquoted and unescaped string */
	if (0 == is_hex && NULL == hint)
	{
		strval_dyn = zbx_malloc(strval_dyn, vars->val_len + 1);
		memcpy(strval_dyn, vars->val.string, vars->val_len);
		strval_dyn[vars->val_len] = '\0';
	}
	else
	{
		if (0 == is_hex && 0 == strncmp(buf, "STRING: ", 8))
			offset = 8;

		strval_dyn = zbx_strdup(strval_dyn, buf + offset);
	}

	zbx_rtrim(strval_dyn, ZBX_WHITESPACE);
	zbx_ltrim(strval_dyn, ZBX_WHITESPACE);
end:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():'%s'", __function_name, strval_dyn ? strval_dyn : "(null)");

	return strval_dyn;
}
コード例 #3
0
ファイル: action.c プロジェクト: AndreMantas/oflops
int 
handle_snmp_event(struct oflops_context * ctx, struct snmp_event * se) {
  netsnmp_variable_list *vars;
  int len = 1024;
  char msg[1024], log[1024];
  struct timeval now;
  int i;
  gettimeofday(&now, NULL);

  for(vars = se->pdu->variables; vars; vars = vars->next_variable)  {
    snprint_value(msg, len, vars->name, vars->name_length, vars);
    if((vars->name_length == ctx->cpuOID_len) &&
       (memcmp(vars->name, ctx->cpuOID,  ctx->cpuOID_len * sizeof(oid)) == 0) ) {
      snprintf(log, len, "cpu : %s %%", msg);
      oflops_log(now, SNMP_MSG, log);
    } else {
      for(i=0;i<ctx->n_channels;i++) {
	if((vars->name_length == ctx->channels[i].inOID_len) &&
	   (memcmp(vars->name, ctx->channels[i].inOID,  
		   ctx->channels[i].inOID_len * sizeof(oid)) == 0) ) {
	  snprintf(log, len, "port %d : rx %s pkts",  
		   (int)ctx->channels[i].outOID[ctx->channels[i].outOID_len-1], msg);
	  oflops_log(now, SNMP_MSG, log);
	  break;
	}
	
	if((vars->name_length == ctx->channels[i].outOID_len) &&
	   (memcmp(vars->name, ctx->channels[i].outOID,  
		   ctx->channels[i].outOID_len * sizeof(oid))==0) ) {
	  snprintf(log, len, "port %d : tx %s pkts",  
		   (int)ctx->channels[i].outOID[ctx->channels[i].outOID_len-1], msg);
	  oflops_log(now, SNMP_MSG, log);
	  break;
	}
      } //for
    }// if cpu
  }// variable iterator
  return 0;
}
コード例 #4
0
ファイル: checks_snmp.c プロジェクト: Shmuma/z
/*int	get_value_snmp(double *result,char *result_str,DB_ITEM *item,char *error, int max_error_len)*/
int	get_value_snmp(DB_ITEM *item, AGENT_RESULT *value)
{

	#define NEW_APPROACH

	struct snmp_session session, *ss;
	struct snmp_pdu *pdu;
	struct snmp_pdu *response;

#ifdef NEW_APPROACH
	char temp[MAX_STRING_LEN];
#endif

	oid anOID[MAX_OID_LEN];
	size_t anOID_len = MAX_OID_LEN;

	struct variable_list *vars;
	int status;

	char 	*p, *c;
	double dbl;

	unsigned char *ip;

	char error[MAX_STRING_LEN];

	int ret=SUCCEED;

	zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP()");

	init_result(value);

/*	assert((item->type == ITEM_TYPE_SNMPv1)||(item->type == ITEM_TYPE_SNMPv2c)); */
	assert((item->type == ITEM_TYPE_SNMPv1)||(item->type == ITEM_TYPE_SNMPv2c)||(item->type == ITEM_TYPE_SNMPv3));

	snmp_sess_init( &session );
/*	session.version = version;*/
	if(item->type == ITEM_TYPE_SNMPv1)
	{
		session.version = SNMP_VERSION_1;
	}
	else if(item->type == ITEM_TYPE_SNMPv2c)
	{
		session.version = SNMP_VERSION_2c;
	}
	else if(item->type == ITEM_TYPE_SNMPv3)
	{
		session.version = SNMP_VERSION_3;
	}
	else
	{
		zbx_snprintf(error,sizeof(error),"Error in get_value_SNMP. Wrong item type [%d]. Must be SNMP.",
			item->type);
		zabbix_log( LOG_LEVEL_ERR, "%s",
			error);
		SET_MSG_RESULT(value, strdup(error));

		return NOTSUPPORTED;
	}


	if(item->useip == 1)
	{
	#ifdef NEW_APPROACH
		zbx_snprintf(temp,sizeof(temp),"%s:%d",
			item->host_ip,
			item->snmp_port);
		session.peername = temp;
		session.remote_port = item->snmp_port;
	#else
		session.peername = item->host_ip;
		session.remote_port = item->snmp_port;
	#endif
	}
	else
	{
	#ifdef NEW_APPROACH
		zbx_snprintf(temp, sizeof(temp), "%s:%d",
			item->host_dns,
			item->snmp_port);
		session.peername = temp;
		session.remote_port = item->snmp_port;
	#else
		session.peername = item->host_dns;
		session.remote_port = item->snmp_port;
	#endif
	}

	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);
				SET_MSG_RESULT(value, strdup(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);
				SET_MSG_RESULT(value, strdup(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);
				SET_MSG_RESULT(value, strdup(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 get_value_SNMP. Unsupported session.version [%d]",
			(int)session.version);
		zabbix_log( LOG_LEVEL_ERR, "%s",
			error);
		SET_MSG_RESULT(value, strdup(error));
		
		return NOTSUPPORTED;
	}

	zabbix_log( LOG_LEVEL_DEBUG, "OID [%s]",
		item->snmp_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);
		SET_MSG_RESULT(value, strdup(error));

		return NOTSUPPORTED;
	}
	zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 0.2");

	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);

#if OTHER_METHODS
	get_node("sysDescr.0", anOID, &anOID_len);
	read_objid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len);
	read_objid("system.sysDescr.0", anOID, &anOID_len);
#endif

	snmp_add_null_var(pdu, anOID, anOID_len);
	zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 0.3");
  
	status = snmp_synch_response(ss, pdu, &response);
	zabbix_log( LOG_LEVEL_DEBUG, "Status send [%d]", status);
	zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 0.4");

	zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 1");

	if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)
	{

	zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 2");
/*		for(vars = response->variables; vars; vars = vars->next_variable)
		{
			print_variable(vars->name, vars->name_length, vars);
		}*/

		for(vars = response->variables; vars; vars = vars->next_variable)
		{
			int count=1;
			zabbix_log( LOG_LEVEL_DEBUG, "AV loop(%d)", vars->type);

/*			if(	(vars->type == ASN_INTEGER) ||*/
			if(	(vars->type == ASN_UINTEGER)||
				(vars->type == ASN_COUNTER) ||
#ifdef OPAQUE_SPECIAL_TYPES
				(vars->type == ASN_UNSIGNED64) ||
#endif
				(vars->type == ASN_TIMETICKS) ||
				(vars->type == ASN_GAUGE)
			)
			{
/*				*result=(long)*vars->val.integer;*/
				/*
				 * This solves situation when large numbers are stored as negative values
				 * http://sourceforge.net/tracker/index.php?func=detail&aid=700145&group_id=23494&atid=378683
				 */ 
				/*zbx_snprintf(result_str,sizeof(result_str),"%ld",(long)*vars->val.integer);*/
/*				zbx_snprintf(result_str,sizeof(result_str),"%lu",(long)*vars->val.integer);*/

				/* Not correct. Returns huge values. */
/*				SET_UI64_RESULT(value, (zbx_uint64_t)*vars->val.integer);*/
				if (vars->type == ASN_GAUGE && *vars->val.integer >= 4294967294) {
					SET_UI64_RESULT(value, (unsigned long)0);
				}
				else {
					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,
					    vars->type,
					    (zbx_uint64_t)*vars->val.integer);
				zabbix_log( LOG_LEVEL_DEBUG, "OID [%s] Type [%d] ULONG[%lu]",
					    item->snmp_oid,
					    vars->type,
					    (zbx_uint64_t)(unsigned long)*vars->val.integer);
			}
			else if(vars->type == ASN_COUNTER64)
			{
				/* Incorrect code for 32 bit platforms */
/*				SET_UI64_RESULT(value, ((vars->val.counter64->high)<<32)+(vars->val.counter64->low));*/
				SET_UI64_RESULT(value, (((zbx_uint64_t)vars->val.counter64->high)<<32)+((zbx_uint64_t)vars->val.counter64->low));
			}
			else if(vars->type == ASN_INTEGER
#define ASN_FLOAT           (ASN_APPLICATION | 8)
#define ASN_DOUBLE          (ASN_APPLICATION | 9)

#ifdef OPAQUE_SPECIAL_TYPES
				|| (vars->type == ASN_INTEGER64)
#endif
			)
			{
				/* Negative integer values are converted to double */
				if(*vars->val.integer<0)
				{
					SET_DBL_RESULT(value, (double)*vars->val.integer);
				}
				else
				{
					SET_UI64_RESULT(value, (zbx_uint64_t)*vars->val.integer);
				}
			}
#ifdef OPAQUE_SPECIAL_TYPES
			else if(vars->type == ASN_FLOAT)
			{
				SET_DBL_RESULT(value, *vars->val.floatVal);
			}
			else if(vars->type == ASN_DOUBLE)
			{
				SET_DBL_RESULT(value, *vars->val.doubleVal);
			}
#endif
			else if(vars->type == ASN_OCTET_STR)
			{
				if(item->value_type == ITEM_VALUE_TYPE_FLOAT)
				{
					p = malloc(vars->val_len+1);
					if(p)
					{
						memcpy(p, vars->val.string, vars->val_len);
						p[vars->val_len] = '\0';
						dbl = strtod(p, NULL);

						SET_DBL_RESULT(value, dbl);
					}
					else
					{
						zbx_snprintf(error,sizeof(error),"Cannot allocate required memory");
						zabbix_log( LOG_LEVEL_ERR, "%s", error);
						SET_MSG_RESULT(value, strdup(error));
					}
				}
				else if(item->value_type != ITEM_VALUE_TYPE_STR)
				{
					zbx_snprintf(error,sizeof(error),"Cannot store SNMP string value (ASN_OCTET_STR) in item having numeric type");
					zabbix_log( LOG_LEVEL_ERR, "%s",
						error);
					SET_MSG_RESULT(value, strdup(error));

					ret = NOTSUPPORTED;
				}
				else
				{
					zabbix_log( LOG_LEVEL_DEBUG, "ASN_OCTET_STR [%s]", vars->val.string);
					zabbix_log( LOG_LEVEL_DEBUG, "ASN_OCTET_STR [%d]", vars->val_len);
					
					p = malloc(1024);
					if(p)
					{
						memset(p,0,1024);
						snprint_value(p, 1023, vars->name, vars->name_length, vars);
						/* Skip STRING: and STRING_HEX: */
						c=strchr(p,':');
						if(c==NULL)
						{
							SET_STR_RESULT(value, strdup(p));
						}
						else
						{
							SET_STR_RESULT(value, strdup(c+1));
						}
						zabbix_log( LOG_LEVEL_DEBUG, "ASN_OCTET_STR [%s]", p);
						free(p);
					}
					else
					{
						zbx_snprintf(error,MAX_STRING_LEN-1,"Cannot allocate required memory");
						zabbix_log( LOG_LEVEL_ERR, "%s", error);
						SET_MSG_RESULT(value, strdup(error));
					}

/*					p = malloc(vars->val_len+1);
					if(p)
					{
						zabbix_log( LOG_LEVEL_WARNING, "Result [%s] len [%d]",vars->val.string,vars->val_len);
						memcpy(p, vars->val.string, vars->val_len);
						p[vars->val_len] = '\0';

						SET_STR_RESULT(value, p);
					}
					else
					{
						zbx_snprintf(error,sizeof(error),"Cannot allocate required memory");
						zabbix_log( LOG_LEVEL_ERR, "%s", error);
						SET_MSG_RESULT(value, strdup(error));
					}*/
				}
			}
			else if(vars->type == ASN_IPADDRESS)
			{
/*				ip = vars->val.string;
				zbx_snprintf(result_str,sizeof(result_str),"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);*/
/*				if(item->type == 0)
				{
					ret = NOTSUPPORTED;
				}*/
				if(item->value_type != ITEM_VALUE_TYPE_STR)
				{
					zbx_snprintf(error,sizeof(error),"Cannot store SNMP string value (ASN_IPADDRESS) in item having numeric type");
					zabbix_log( LOG_LEVEL_ERR, "%s",
						error);
					SET_MSG_RESULT(value, strdup(error));
					ret = NOTSUPPORTED;
				}
				else
				{
					p = malloc(MAX_STRING_LEN);
					if(p)
					{
						ip = vars->val.string;
						zbx_snprintf(p,MAX_STRING_LEN-1,"%d.%d.%d.%d",
							ip[0],
							ip[1],
							ip[2],
							ip[3]);
						SET_STR_RESULT(value, p);
                                        }
					else
					{
						zbx_snprintf(error,MAX_STRING_LEN-1,"Cannot allocate required memory");
						zabbix_log( LOG_LEVEL_ERR, "%s",
							error);
						SET_MSG_RESULT(value, strdup(error));
					}
				}
			}
			else
			{
/* count is not really used. Has to be removed */ 
				count++;

				zbx_snprintf(error,sizeof(error),"OID [%s] value #%d has unknow type [%X]",
					item->snmp_oid,
					count,
					vars->type);

				zabbix_log( LOG_LEVEL_ERR, "%s",
					error);
				SET_MSG_RESULT(value, strdup(error));

				ret  = NOTSUPPORTED;
			}
		}
	}
	else
	{
		if (status == STAT_SUCCESS)
		{
			zabbix_log( LOG_LEVEL_WARNING, "SNMP error in packet. Reason: %s\n",
				snmp_errstring(response->errstat));
			if(response->errstat == SNMP_ERR_NOSUCHNAME)
			{
				zbx_snprintf(error,sizeof(error),"SNMP error [%s]",
					snmp_errstring(response->errstat));

				zabbix_log( LOG_LEVEL_ERR, "%s",
					error);
				SET_MSG_RESULT(value, strdup(error));

				ret=NOTSUPPORTED;
			}
			else
			{
				zbx_snprintf(error,sizeof(error),"SNMP error [%s]",
					snmp_errstring(response->errstat));

				zabbix_log( LOG_LEVEL_ERR, "%s",
					error);
				SET_MSG_RESULT(value, strdup(error));

				ret=NOTSUPPORTED;
			}
		}
		else if(status == STAT_TIMEOUT)
		{
			zbx_snprintf(error,sizeof(error),"Timeout while connecting to [%s]",
				session.peername);

/*			snmp_sess_perror("snmpget", ss);*/
			zabbix_log( LOG_LEVEL_ERR, "%s",
				error);
			SET_MSG_RESULT(value, strdup(error));

			ret = NETWORK_ERROR;
		}
		else
		{
			zbx_snprintf(error,sizeof(error),"SNMP error [%d]",
				status);

			zabbix_log( LOG_LEVEL_ERR, "%s",
				error);
			SET_MSG_RESULT(value, strdup(error));

			ret=NOTSUPPORTED;
		}
	}

	if (response)
	{
		snmp_free_pdu(response);
	}
	snmp_close(ss);

	SOCK_CLEANUP;
	return ret;
}
コード例 #5
0
ファイル: rtgsnmp.c プロジェクト: hdimov/rtg.phoenix
void *poller(void *thread_args)
{
    worker_t *worker = (worker_t *) thread_args;
    crew_t *crew = worker->crew;
    target_t *entry = NULL;
    void *sessp = NULL;
    struct snmp_session session;
    struct snmp_pdu *pdu = NULL;
    struct snmp_pdu *response = NULL;
    oid anOID[MAX_OID_LEN];
    size_t anOID_len = MAX_OID_LEN;
    struct variable_list *vars = NULL;
    unsigned long long result = 0;
    unsigned long long last_value = 0;
    unsigned long long insert_val = 0;
    int status = 0, bits = 0, init = 0;
    char query[BUFSIZE];
    char storedoid[BUFSIZE];
    char result_string[BUFSIZE];

    if (set.verbose >= HIGH)
	printf("Thread [%d] starting.\n", worker->index);
    if (MYSQL_VERSION_ID > 40000)
       mysql_thread_init();
    else 
       my_thread_init();

    while (1) {
	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] locking (wait on work)\n", worker->index);

	PT_MUTEX_LOCK(&crew->mutex);

	while (current == NULL) {
		PT_COND_WAIT(&crew->go, &crew->mutex);
	}
	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] done waiting, received go (work cnt: %d)\n", worker->index, crew->work_count);

	if (current != NULL) {
	    if (set.verbose >= HIGH)
	      printf("Thread [%d] processing %s %s (%d work units remain in queue)\n", worker->index, current->host, current->objoid, crew->work_count);
	    snmp_sess_init(&session);
		if (set.snmp_ver == 2)
	      session.version = SNMP_VERSION_2c;
		else
	      session.version = SNMP_VERSION_1;
	    session.peername = current->host;
		session.remote_port = set.snmp_port;
	    session.community = current->community;
	    session.community_len = strlen(session.community);

	    sessp = snmp_sess_open(&session);
	    anOID_len = MAX_OID_LEN;
	    pdu = snmp_pdu_create(SNMP_MSG_GET);
	    read_objid(current->objoid, anOID, &anOID_len);
	    entry = current;
	    last_value = current->last_value;
	    init = current->init;
	    insert_val = 0;
	    bits = current->bits;
	    strncpy(storedoid, current->objoid, sizeof(storedoid));
		current = getNext();
	}
	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] unlocking (done grabbing current)\n", worker->index);
	PT_MUTEX_UNLOCK(&crew->mutex);
	snmp_add_null_var(pdu, anOID, anOID_len);
	if (sessp != NULL) 
	   status = snmp_sess_synch_response(sessp, pdu, &response);
	else
	   status = STAT_DESCRIP_ERROR;

	/* Collect response and process stats */
	PT_MUTEX_LOCK(&stats.mutex);
	if (status == STAT_DESCRIP_ERROR) {
	    stats.errors++;
            printf("*** SNMP Error: (%s) Bad descriptor.\n", session.peername);
	} else if (status == STAT_TIMEOUT) {
	    stats.no_resp++;
	    printf("*** SNMP No response: (%s@%s).\n", session.peername,
	       storedoid);
	} else if (status != STAT_SUCCESS) {
	    stats.errors++;
	    printf("*** SNMP Error: (%s@%s) Unsuccessuful (%d).\n", session.peername,
	       storedoid, status);
	} else if (status == STAT_SUCCESS && response->errstat != SNMP_ERR_NOERROR) {
	    stats.errors++;
	    printf("*** SNMP Error: (%s@%s) %s\n", session.peername,
	       storedoid, snmp_errstring(response->errstat));
	} else if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
	    stats.polls++;
	} 
	PT_MUTEX_UNLOCK(&stats.mutex);

	/* Liftoff, successful poll, process it */
	if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
	    vars = response->variables;
#ifdef OLD_UCD_SNMP
            sprint_value(result_string, anOID, anOID_len, vars);
#else
	    snprint_value(result_string, BUFSIZE, anOID, anOID_len, vars);
#endif
	    switch (vars->type) {
		/*
		 * Switch over vars->type and modify/assign result accordingly.
		 */
		case ASN_COUNTER64:
		    if (set.verbose >= DEBUG) printf("64-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = vars->val.counter64->high;
		    result = result << 32;
		    result = result + vars->val.counter64->low;
		    break;
		case ASN_COUNTER:
		    if (set.verbose >= DEBUG) printf("32-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_INTEGER:
		    if (set.verbose >= DEBUG) printf("Integer result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_GAUGE:
		    if (set.verbose >= DEBUG) printf("32-bit gauge: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_TIMETICKS:
		    if (set.verbose >= DEBUG) printf("Timeticks result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_OPAQUE:
		    if (set.verbose >= DEBUG) printf("Opaque result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		default:
		    if (set.verbose >= DEBUG) printf("Unknown result type: (%s@%s) %s\n", session.peername, storedoid, result_string);
	    }

		/* Gauge Type */
		if (bits == 0) {
			if (result != last_value) {
				insert_val = result;
				if (set.verbose >= HIGH)
					printf("Thread [%d]: Gauge change from %lld to %lld\n", worker->index, last_value, insert_val);
			} else {
				if (set.withzeros) 
					insert_val = result;
				if (set.verbose >= HIGH)
					printf("Thread [%d]: Gauge steady at %lld\n", worker->index, insert_val);
			}
	    /* Counter Wrap Condition */
	    } else if (result < last_value) {
			PT_MUTEX_LOCK(&stats.mutex);
              stats.wraps++;
			PT_MUTEX_UNLOCK(&stats.mutex);
	      if (bits == 32) insert_val = (THIRTYTWO - last_value) + result;
	      else if (bits == 64) insert_val = (SIXTYFOUR - last_value) + result;
	      if (set.verbose >= LOW) {
	         printf("*** Counter Wrap (%s@%s) [poll: %llu][last: %llu][insert: %llu]\n",
	         session.peername, storedoid, result, last_value, insert_val);
	      }
	    /* Not a counter wrap and this is not the first poll */
	    } else if ((last_value >= 0) && (init != NEW)) {
		insert_val = result - last_value;
	        /* Print out SNMP result if verbose */
	        if (set.verbose == DEBUG)
		  printf("Thread [%d]: (%lld-%lld) = %llu\n", worker->index, result, last_value, insert_val);
	        if (set.verbose == HIGH)
		  printf("Thread [%d]: %llu\n", worker->index, insert_val);
            /* last_value < 0, so this must be the first poll */
	    } else {
                if (set.verbose >= HIGH) printf("Thread [%d]: First Poll, Normalizing\n", worker->index);
	    }

		/* Check for bogus data, either negative or unrealistic */
	    if (insert_val > entry->maxspeed || result < 0) {
			if (set.verbose >= LOW) printf("*** Out of Range (%s@%s) [insert_val: %llu] [oor: %lld]\n",
				session.peername, storedoid, insert_val, entry->maxspeed);
			insert_val = 0;
			PT_MUTEX_LOCK(&stats.mutex);
			stats.out_of_range++;
			PT_MUTEX_UNLOCK(&stats.mutex);
	    }

		if (!(set.dboff)) {
			if ( (insert_val > 0) || (set.withzeros) ) {
				PT_MUTEX_LOCK(&crew->mutex);
				snprintf(query, sizeof(query), "INSERT INTO %s VALUES (%d, NOW(), %llu)",
					entry->table, entry->iid, insert_val);
				if (set.verbose >= DEBUG) printf("SQL: %s\n", query);
				status = mysql_query(&mysql, query);
				if (status) printf("*** MySQL Error: %s\n", mysql_error(&mysql));
				PT_MUTEX_UNLOCK(&crew->mutex);

				if (!status) {
					PT_MUTEX_LOCK(&stats.mutex);
					stats.db_inserts++;
					PT_MUTEX_UNLOCK(&stats.mutex);
				} 
			} /* insert_val > 0 or withzeros */	
		} /* !dboff */

	} /* STAT_SUCCESS */

        if (sessp != NULL) {
           snmp_sess_close(sessp);
           if (response != NULL) snmp_free_pdu(response);
        }

	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] locking (update work_count)\n", worker->index);
	PT_MUTEX_LOCK(&crew->mutex);
	crew->work_count--;
	/* Only if we received a positive result back do we update the
	   last_value object */
	if (status == STAT_SUCCESS) entry->last_value = result;
	if (init == NEW) entry->init = LIVE;
	if (crew->work_count <= 0) {
	    if (set.verbose >= HIGH) printf("Queue processed. Broadcasting thread done condition.\n");
		PT_COND_BROAD(&crew->done);
	}
	if (set.verbose >= DEVELOP)
	    printf("Thread [%d] unlocking (update work_count)\n", worker->index);

		PT_MUTEX_UNLOCK(&crew->mutex);
    }				/* while(1) */
}
コード例 #6
0
ファイル: docsis_snmp.c プロジェクト: tenpin784/docsis
int
decode_vbind (unsigned char *data, unsigned int vb_len)
{
  unsigned char *var_val;
  oid var_name[MAX_OID_LEN];	/* To test the objid */
  size_t name_len = MAX_OID_LEN;	/* To test the objid */
  int badtype=0;
  size_t len;
  struct variable_list *vp;
  oid objid[MAX_OID_LEN];
  char _docsis_snmp_label[50];	/* To hold the 'name' of the type, i.e. Integer etc */
  char *enum_string = NULL;
  static char outbuf[16384];
  struct tree *subtree;
  struct enum_list *enums;

  memset (outbuf, 0, 16384);

  vp = (struct variable_list *) malloc (sizeof (struct variable_list));
  if (vp == NULL)
    {
      fprintf (stderr, "Out of memory\n");
      return 0;
    }
  memset (vp, 0, sizeof (struct variable_list));

  vp->next_variable = NULL;
  vp->val.string = NULL;
  vp->name_length = MAX_OID_LEN;
  vp->name = 0;
  data = snmp_parse_var_op (data, objid, &vp->name_length, &vp->type, &vp->val_len,
		       &var_val, (size_t *) & vb_len);

  if (data == NULL)
    return -1;
  if (snmp_set_var_objid (vp, objid, vp->name_length))
    return -1;

  len = PACKET_LENGTH;

  if (netsnmp_ds_get_boolean
      (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX))
    {
      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
                                 NETSNMP_DS_LIB_EXTENDED_INDEX);
    } /* Disable extended index format ... makes it harder to parse tokens in lex */
  if (!netsnmp_ds_get_boolean
      (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM))
    {
      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
                                 NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM);
    } /* Enable printing numeric enums */
  if (netsnmp_ds_get_boolean
      (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES))
    {
      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
                                 NETSNMP_DS_LIB_ESCAPE_QUOTES);
    } /* Disable escape quotes in string index output  */

  netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID,
			      NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
			      NETSNMP_OID_OUTPUT_SUFFIX);

  if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_OID_OUTPUT_NUMERIC)) {
        netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
                                                  NETSNMP_OID_OUTPUT_NUMERIC);
  }

  snprint_objid (outbuf, 1023, vp->name, vp->name_length);

  if (!get_node (outbuf, var_name, &name_len))
    {
      if (!read_objid (outbuf, var_name, &name_len))
	{
	  fprintf (stderr,
		   "/* Hmm ... can't find oid %s at line %d ... perhaps the MIBs are not installed ? */\n",
		   outbuf, line);
	  /* temporarily set full output format */
	  netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID,
			      NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
			      NETSNMP_OID_OUTPUT_FULL);
	  memset (outbuf, 0, 1024);
	  snprint_objid (outbuf, 1023, vp->name, vp->name_length);
	  /* Go back to suffix-mode for better readability */
	  netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID,
			      NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
			      NETSNMP_OID_OUTPUT_SUFFIX);
	}
    }

  printf("%s", outbuf);

/* save the subtree - we need it later to show enums */
  subtree = get_tree (var_name, name_len, get_tree_head() );

/* This first switch is just for saving the type in the format we actually want
   to print. */

  switch ((short) vp->type)
    {
    case ASN_INTEGER:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "Integer");
      break;
    case ASN_COUNTER:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "Counter32");
      break;
    case ASN_GAUGE:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "Gauge32");
      break;
    case ASN_TIMETICKS:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "TimeTicks");
      break;
    case ASN_UINTEGER:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "Unsigned32");
      break;
#ifdef OPAQUE_SPECIAL_TYPES
    case ASN_OPAQUE_COUNTER64:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "OpaqueCounter64");
      break;
    case ASN_OPAQUE_U64:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "OpaqueU64");
      break;
#endif /* OPAQUE_SPECIAL_TYPES */
    case ASN_COUNTER64:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "Counter64");
      break;
#ifdef OPAQUE_SPECIAL_TYPES
    case ASN_OPAQUE_FLOAT:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "OpaqueFloat");
      break;
    case ASN_OPAQUE_DOUBLE:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "OpaqueDouble");
      break;
    case ASN_OPAQUE_I64:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "OpaqueI64");
      break;
#endif /* OPAQUE_SPECIAL_TYPES */
    case ASN_OCTET_STR:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "String");
      break;
    case ASN_IPADDRESS:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "IPAddress");
      break;
    case ASN_OPAQUE:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "Opaque");
      break;
    case ASN_NSAP:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "NSAP");
      break;
    case ASN_OBJECT_ID:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "ObjectID");
      break;
    case ASN_BIT_STR:
      memset (_docsis_snmp_label, 0, 50);
      sprintf (_docsis_snmp_label, "BitString");
      break;
    }

  switch ((short) vp->type)
    {
    case ASN_INTEGER:

      vp->val.integer = (long *) vp->buf;
      vp->val_len = sizeof (long);
      asn_parse_int (var_val, &len, &vp->type,
		     (long *) vp->val.integer, sizeof (vp->val.integer));

      break;
    case ASN_COUNTER:
    case ASN_GAUGE:
    case ASN_TIMETICKS:
    case ASN_UINTEGER:
      vp->val.integer = (long *) vp->buf;
      vp->val_len = sizeof (u_long);
      asn_parse_unsigned_int (var_val, &len, &vp->type,
			      (u_long *) vp->val.integer,
			      sizeof (vp->val.integer));

      break;

#ifdef OPAQUE_SPECIAL_TYPES
    case ASN_OPAQUE_COUNTER64:
    case ASN_OPAQUE_U64:
#endif /* OPAQUE_SPECIAL_TYPES */
    case ASN_COUNTER64:
      vp->val.counter64 = (struct counter64 *) vp->buf;
      vp->val_len = sizeof (struct counter64);
      asn_parse_unsigned_int64 (var_val, &len, &vp->type,
				(struct counter64 *) vp->val.counter64,
				sizeof (*vp->val.counter64));
      break;
#ifdef OPAQUE_SPECIAL_TYPES
    case ASN_OPAQUE_FLOAT:
      vp->val.floatVal = (float *) vp->buf;
      vp->val_len = sizeof (float);
      asn_parse_float (var_val, &len, &vp->type,
		       vp->val.floatVal, vp->val_len);
      break;
    case ASN_OPAQUE_DOUBLE:
      vp->val.doubleVal = (double *) vp->buf;
      vp->val_len = sizeof (double);
      asn_parse_double (var_val, &len, &vp->type,
			vp->val.doubleVal, vp->val_len);
      break;
    case ASN_OPAQUE_I64:
      vp->val.counter64 = (struct counter64 *) vp->buf;
      vp->val_len = sizeof (struct counter64);
      asn_parse_signed_int64 (var_val, &len, &vp->type,
			      (struct counter64 *) vp->val.counter64,
			      sizeof (*vp->val.counter64));

      break;
#endif /* OPAQUE_SPECIAL_TYPES */
    case ASN_OCTET_STR:
    case ASN_IPADDRESS:
    case ASN_OPAQUE:
    case ASN_NSAP:
      if (vp->val_len < sizeof (vp->buf))
	{
	  vp->val.string = (u_char *) vp->buf;
	}
      else
	{
	  vp->val.string = (u_char *) malloc ((unsigned) vp->val_len+1);
	  memset(vp->val.string, 0, vp->val_len+1);
	}
      asn_parse_string (var_val, &len, &vp->type, vp->val.string,
			&vp->val_len);
      break;
    case ASN_OBJECT_ID:
      vp->val_len = MAX_OID_LEN;
      asn_parse_objid (var_val, &len, &vp->type, objid, &vp->val_len);
      vp->val_len *= sizeof (oid);
      vp->val.objid = (oid *) malloc ((unsigned) vp->val_len);
      memmove (vp->val.objid, objid, vp->val_len);
      break;
    case SNMP_NOSUCHOBJECT:
    case SNMP_NOSUCHINSTANCE:
    case SNMP_ENDOFMIBVIEW:
    case ASN_NULL:
      break;
    case ASN_BIT_STR:
      vp->val.bitstring = (u_char *) malloc (vp->val_len);
      asn_parse_bitstring (var_val, &len, &vp->type,
			   vp->val.bitstring, &vp->val_len);
      break;
    default:
      fprintf(stderr, "Error: bad type returned (%x)\n", vp->type);
      badtype = 1;
      break;
    }

  if (!netsnmp_ds_get_boolean
      (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_FULL_OID))
    {
      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
				 NETSNMP_DS_LIB_PRINT_FULL_OID);
    }
  if (!netsnmp_ds_get_boolean
      (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS))
    {
      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
				 NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS);
    }
  if (!netsnmp_ds_get_boolean
      (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT))
    {
      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
				 NETSNMP_DS_LIB_QUICK_PRINT);
    }

  if (!strcmp (_docsis_snmp_label, "String"))	/* Strings need special treatment - see below  */
    {
      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
				 NETSNMP_DS_LIB_QUICK_PRINT);
      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
				 NETSNMP_DS_LIB_ESCAPE_QUOTES);
    }

  switch ((short) vp->type)
    {
    case ASN_OCTET_STR:
	if (str_isprint((char *) vp->val.string, vp->val_len))
		{
		 	snprintf(outbuf, vp->val_len+5, "\"%s\"", vp->val.string);
		} else {
			snprint_hexadecimal (outbuf, 16383, (char *) vp->val.string, vp->val_len);
      			memset (_docsis_snmp_label, 0, 50);
      			sprintf (_docsis_snmp_label, "HexString");
		}
	break;

    case ASN_BIT_STR:
		snprint_hexadecimal (outbuf, 1023, (char *) vp->val.bitstring, vp->val_len);
		break;
    case ASN_OBJECT_ID:
      		netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID,
			  	NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
			  	NETSNMP_OID_OUTPUT_NUMERIC);
		snprint_value (outbuf, 1023, vp->name, vp->name_length, vp);
      		netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID,
				NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
				NETSNMP_OID_OUTPUT_SUFFIX);
		break;

    default:
	snprint_value (outbuf, 1023, vp->name, vp->name_length, vp);

    }

    if ( subtree )
    {
   	enums = subtree->enums;
	   	for (; enums; enums = enums->next) {
			if (enums->value == *vp->val.integer) {
			enum_string = enums->label;
       			break;
			}
		}
    }
  if (enum_string)
	printf(" %s %s; /* %s */", _docsis_snmp_label, outbuf, enum_string);
  else
	printf(" %s %s;", _docsis_snmp_label, outbuf);


  snmp_free_var (vp);

  return badtype;
}
コード例 #7
0
ファイル: snmp.c プロジェクト: n8ohu/dmrshark
static int snmp_get_rssi_cb(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic) {
	char value[15] = {0,};
	char *endptr = NULL;
	int value_num = 0;
	struct variable_list *vars = NULL;
	repeater_t *repeater = NULL;
	in_addr_t ipaddr;
	flag_t dodbupdate = 0;

	if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
		if (pdu->errstat == SNMP_ERR_NOERROR) {
			ipaddr = inet_addr(sp->peername);
			repeater = repeaters_findbyip((struct in_addr *)&ipaddr);

			for (vars = pdu->variables; vars; vars = vars->next_variable) {
				if (netsnmp_oid_equals(vars->name, vars->name_length, oid_rssi_ts1, oid_rssi_ts1_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG LOGLEVEL_SNMP "snmp: invalid ts1 rssi value received: %s\n", sp->peername);
					else {
						if (value_num > -200) {
							if (repeater != NULL) {
								repeater->slot[0].rssi = value_num;
								if (repeater->slot[0].avg_rssi == 0)
									repeater->slot[0].avg_rssi = value_num;
								else
									repeater->slot[0].avg_rssi = (repeater->slot[0].avg_rssi+value_num)/2.0;
								dodbupdate = 1;
							}
							console_log(LOGLEVEL_SNMP "snmp [%s]: got ts1 rssi value %d\n", sp->peername, value_num);
						}
					}
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_rssi_ts2, oid_rssi_ts2_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG LOGLEVEL_SNMP "snmp: invalid ts2 rssi value received: %s\n", value);
					else {
						if (value_num > -200) {
							if (repeater != NULL) {
								repeater->slot[1].rssi = value_num;
								if (repeater->slot[1].avg_rssi == 0)
									repeater->slot[1].avg_rssi = value_num;
								else
									repeater->slot[1].avg_rssi = (repeater->slot[1].avg_rssi+value_num)/2.0;
								dodbupdate = 1;
							}
							console_log(LOGLEVEL_SNMP "snmp [%s]: got ts2 rssi value %d\n", sp->peername, value_num);
						}
					}
				}
			}

			if (dodbupdate)
				remotedb_update(repeater);

			snmp_rssi_received = 1;
		} else
			console_log(LOGLEVEL_DEBUG "snmp: rssi read error\n");
    } else
    	console_log(LOGLEVEL_DEBUG "snmp: rssi read timeout\n");

	return 1;
}
コード例 #8
0
ファイル: snmp.c プロジェクト: n8ohu/dmrshark
static int snmp_get_repeaterinfo_cb(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic) {
	char value[200] = {0,};
	char *endptr = NULL;
	int value_num = 0;
	struct variable_list *vars = NULL;
	repeater_t *repeater = NULL;
	in_addr_t ipaddr;
	char value_utf16[sizeof(value)/2] = {0,};
	char value_utf8[sizeof(value_utf16)/2] = {0,};
	int length = 0;
	flag_t dodbupdate = 0;

	if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
		if (pdu->errstat == SNMP_ERR_NOERROR) {
			ipaddr = inet_addr(sp->peername);
			repeater = repeaters_findbyip((struct in_addr *)&ipaddr);

			for (vars = pdu->variables; vars; vars = vars->next_variable) {
				if (netsnmp_oid_equals(vars->name, vars->name_length, oid_id, oid_id_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG "snmp [%s]: invalid id value received: %s\n", sp->peername, value);
					else {
						if (repeater != NULL) {
							repeater->id = value_num;
							dodbupdate = 1;
						}
						console_log("snmp [%s]: got id value %d\n", sp->peername, value_num);
					}
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_repeatertype, oid_repeatertype_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					length = snmp_hexstring_to_bytearray(value+12, value_utf16, sizeof(value_utf16)); // +12: cutting "Hex-STRING: " text returned by snprint_value().
					snmp_utf16_to_utf8(value_utf16, length, value_utf8, sizeof(value_utf8));
					if (repeater != NULL) {
						strncpy(repeater->type, value_utf8, sizeof(repeater->type));
						dodbupdate = 1;
					}
					console_log("snmp [%s]: got repeater type value %s\n", sp->peername, value_utf8);
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_fwversion, oid_fwversion_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					length = snmp_hexstring_to_bytearray(value+12, value_utf16, sizeof(value_utf16)); // +12: cutting "Hex-STRING: " text returned by snprint_value().
					snmp_utf16_to_utf8(value_utf16, length, value_utf8, sizeof(value_utf8));
					if (repeater != NULL) {
						strncpy(repeater->fwversion, value_utf8, sizeof(repeater->fwversion));
						dodbupdate = 1;
					}
					console_log("snmp [%s]: got repeater fw version value %s\n", sp->peername, value_utf8);
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_callsign, oid_callsign_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					length = snmp_hexstring_to_bytearray(value+12, value_utf16, sizeof(value_utf16)); // +12: cutting "Hex-STRING: " text returned by snprint_value().
					snmp_utf16_to_utf8(value_utf16, length, value_utf8, sizeof(value_utf8));
					if (repeater != NULL) {
						strncpy(repeater->callsign, value_utf8, sizeof(repeater->callsign));
						dodbupdate = 1;
					}
					console_log("snmp [%s]: got repeater callsign value %s\n", sp->peername, value_utf8);
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_dlfreq, oid_dlfreq_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG "snmp [%s]: invalid dl freq value received: %s\n", sp->peername, value);
					else {
						if (repeater != NULL) {
							repeater->dlfreq = value_num;
							dodbupdate = 1;
						}
						console_log("snmp [%s]: got dl freq value %d\n", sp->peername, value_num);
					}
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_ulfreq, oid_ulfreq_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG "snmp [%s]: invalid dl freq value received: %s\n", sp->peername, value);
					else {
						if (repeater != NULL) {
							repeater->ulfreq = value_num;
							dodbupdate = 1;
						}
						console_log("snmp [%s]: got ul freq value %d\n", sp->peername, value_num);
					}
				}
			}

			if (dodbupdate)
				remotedb_update_repeater(repeater);

			snmp_repeaterinfo_received = 1;
		} else
			console_log(LOGLEVEL_DEBUG "snmp [%s]: repeater info read error\n", sp->peername);
    } else
    	console_log(LOGLEVEL_DEBUG "snmp [%s]: repeater info read timeout\n", sp->peername);

	return 1;
}
コード例 #9
0
/*! \fn char *snmp_getnext(host_t *current_host, char *snmp_oid)
 *  \brief performs a single snmp_getnext for a specific snmp OID
 *
 *	This function will poll a specific snmp OID for a host.  The host snmp
 *  session must already be established.
 *
 *  \return returns the character representaton of the snmp OID, or "U" if
 *  unsuccessful.
 *
 */
char *snmp_getnext(host_t *current_host, char *snmp_oid) {
	struct snmp_pdu *pdu       = NULL;
	struct snmp_pdu *response  = NULL;
	struct variable_list *vars = NULL;
	size_t anOID_len           = MAX_OID_LEN;
	oid    anOID[MAX_OID_LEN];
	int    status;
	char   *result_string;

	if (!(result_string = (char *) malloc(RESULTS_BUFFER))) {
		die("ERROR: Fatal malloc error: snmp.c snmp_get!");
	}
	result_string[0] = '\0';

	status           = STAT_DESCRIP_ERROR;

	if (current_host->snmp_session != NULL) {
		anOID_len = MAX_OID_LEN;
		pdu       = snmp_pdu_create(SNMP_MSG_GETNEXT);

		if (!snmp_parse_oid(snmp_oid, anOID, &anOID_len)) {
			SPINE_LOG(("ERROR: Problems parsing SNMP OID\n"));
			SET_UNDEFINED(result_string);
			return result_string;
		}else{
			snmp_add_null_var(pdu, anOID, anOID_len);
		}

		/* poll host */
		status = snmp_sess_synch_response(current_host->snmp_session, pdu, &response);

		/* liftoff, successful poll, process it!! */
		if (status == STAT_SUCCESS) {
			if (response == NULL) {
				SPINE_LOG(("ERROR: An internal Net-Snmp error condition detected in Cacti snmp_get\n"));

				SET_UNDEFINED(result_string);
				status = STAT_ERROR;
			}else{
				if (response->errstat == SNMP_ERR_NOERROR) {
					vars = response->variables;

					#ifdef USE_NET_SNMP
					snprint_value(result_string, RESULTS_BUFFER, anOID, anOID_len, vars);
					#else
					sprint_value(result_string, anOID, anOID_len, vars);
					#endif
				}
			}
		}

		if (response) {
			snmp_free_pdu(response);
			response = NULL;
		}
	}else{
		status = STAT_DESCRIP_ERROR;
	}

	if (status != STAT_SUCCESS) {
		current_host->ignore_host = TRUE;

		SET_UNDEFINED(result_string);
	}

	return result_string;
}
コード例 #10
0
ファイル: snmp.c プロジェクト: philips/reconnoiter
/* Handling of results */
static void noit_snmp_log_results(noit_module_t *self, noit_check_t *check,
                                  struct snmp_pdu *pdu) {
  struct check_info *info = check->closure;
  struct variable_list *vars;
  struct timeval duration;
  char buff[128];
  stats_t current;
  int nresults = 0;

  noit_check_stats_clear(check, &current);

  if(pdu)
    for(vars = pdu->variables; vars; vars = vars->next_variable)
      nresults++;

  gettimeofday(&current.whence, NULL);
  sub_timeval(current.whence, check->last_fire_time, &duration);
  current.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
  current.available = pdu ? NP_AVAILABLE : NP_UNAVAILABLE;
  current.state = (nresults == info->noids) ? NP_GOOD : NP_BAD;
  snprintf(buff, sizeof(buff), "%d/%d gets", nresults, info->noids);
  current.status = buff;

  /* We have no results over which to iterate. */
  if(!pdu) {
    noit_check_set_stats(check, &current);
    return;
  }

  /* manipulate the information ourselves */
  nresults = 0;
  for(vars = pdu->variables; vars; vars = vars->next_variable) {
    char *sp;
    int oid_idx;
    double float_conv;
    u_int64_t u64;
    int64_t i64;
    char *endptr;
    char varbuff[256];

    /* find the oid to which this is the response */
    oid_idx = nresults; /* our current idx is the most likely */
    if(info->oids[oid_idx].oidlen != vars->name_length ||
       memcmp(info->oids[oid_idx].oid, vars->name,
              vars->name_length * sizeof(oid))) {
      /* Not the most obvious guess */
      for(oid_idx = info->noids - 1; oid_idx >= 0; oid_idx--) {
        if(info->oids[oid_idx].oidlen == vars->name_length &&
           memcmp(info->oids[oid_idx].oid, vars->name,
                  vars->name_length * sizeof(oid))) break;
      }
    }
    if(oid_idx < 0) {
      snprint_variable(varbuff, sizeof(varbuff),
                       vars->name, vars->name_length, vars);
      noitL(nlerr, "Unexpected oid results to %s`%s`%s: %s\n",
            check->target, check->module, check->name, varbuff);
      nresults++;
      continue;
    }

#define SETM(a,b) noit_stats_set_metric(check, &current, \
                                        info->oids[oid_idx].confname, a, b)
    if(info->oids[oid_idx].type_should_override) {
      snprint_value(varbuff, sizeof(varbuff), vars->name, vars->name_length, vars);
      sp = strchr(varbuff, ' ');
      if(sp) sp++;
      noit_stats_set_metric_coerce(check, &current, info->oids[oid_idx].confname,
                                   info->oids[oid_idx].type_override,
                                   sp);
    }
    else {
      switch(vars->type) {
        case ASN_OCTET_STR:
          sp = malloc(1 + vars->val_len);
          memcpy(sp, vars->val.string, vars->val_len);
          sp[vars->val_len] = '\0';
          SETM(METRIC_STRING, sp);
          free(sp);
          break;
        case ASN_INTEGER:
        case ASN_GAUGE:
          SETM(METRIC_INT32, vars->val.integer);
          break;
        case ASN_TIMETICKS:
        case ASN_COUNTER:
          SETM(METRIC_UINT32, vars->val.integer);
          break;
        case ASN_INTEGER64:
          printI64(varbuff, vars->val.counter64);
          i64 = strtoll(varbuff, &endptr, 10);
          SETM(METRIC_INT64, (varbuff == endptr) ? NULL : &i64);
          break;
        case ASN_COUNTER64:
          printU64(varbuff, vars->val.counter64);
          u64 = strtoull(varbuff, &endptr, 10);
          SETM(METRIC_UINT64, (varbuff == endptr) ? NULL : &u64);
          break;
        case ASN_FLOAT:
          if(vars->val.floatVal) float_conv = *(vars->val.floatVal);
          SETM(METRIC_DOUBLE, vars->val.floatVal ? &float_conv : NULL);
          break;
        case ASN_DOUBLE:
          SETM(METRIC_DOUBLE, vars->val.doubleVal);
          break;
        case SNMP_NOSUCHOBJECT:
        case SNMP_NOSUCHINSTANCE:
          SETM(METRIC_STRING, NULL);
          break;
        default:
          snprint_variable(varbuff, sizeof(varbuff), vars->name, vars->name_length, vars);
          /* Advance passed the first space and use that unless there
           * is no space or we have no more string left.
           */
          sp = strchr(varbuff, ' ');
          if(sp) sp++;
          SETM(METRIC_STRING, (sp && *sp) ? sp : NULL);
      }
    }
    nresults++;
  }
  noit_check_set_stats(check, &current);
}
コード例 #11
0
ファイル: host_info.cpp プロジェクト: cviecco/snapp-collector
///////////////////////////////////////////////////////////////
/// Given a host loads all the oid mappings for that host
/// Uses snmp bulk get to minimize the time required for each
/// mapping.
int Host_Info::load_oid_table(){
    unsigned int thread_id;
    struct snmp_session session;
    
    map<string,OID_Value_Table>::iterator iter;
    int fvalue=0;
////

    //netsnmp_session session, *ss;
    int             numprinted = 0;
    int             reps = 15, non_reps = 0;

    netsnmp_pdu    *pdu, *response=NULL;
    netsnmp_variable_list *vars;
    int             arg;
    oid             name[MAX_OID_LEN];
    size_t          name_length;
    oid             root[MAX_OID_LEN];
    size_t          rootlen;
    int             count;
    int             running;
    int             status;
    int             check;
    int             exitval = 0;

    struct snmp_pdu *req, *resp;
    void *sp;


    char snmp_err_str[SNMP_ERR_STR_SIZE];
    char buf[512];
    char *placeholder;
    char buf2[512];
///
    string temp_string1,temp_string2;
    int i;
////////////    


    thread_id=(unsigned int)((uint64_t) pthread_self());
    simple_snmp_sess_init(&session);

    session.retries=4;
    session.version   = SNMP_VERSION_2c;
    //ARE THE NEXT TWO LINES  VALID???!
    session.peername  = (char *)   ip_address.c_str();
    session.community = (u_char *) community.c_str();
    session.community_len = strlen(community.c_str());
   
    
    for (iter = oid_table.begin(); iter != oid_table.end(); iter++){
        /// 
        assert(0==iter->first.compare(iter->second.oid));
        print_log(LOG_INFO,"Doing host=%s for oid %s\n",ip_address.c_str(),iter->first.c_str());  
 

       rootlen = MAX_OID_LEN;
       //rootlen = strlen(iter->first.c_str());
       if (!read_objid(iter->first.c_str(), root, &rootlen)) {
       //if (!Read_objid_ts(iter->first.c_str(), root, &rootlen)) {

            //snmp_perror(argv[arg]);
            //exit(1);
          print_log(LOG_ERR,"Cannot parse the oid='%s' rootlen=%d host=%s\n",iter->first.c_str(),rootlen,ip_address.c_str());
          snmp_perror("read_objid");
          return -1;
       }
       if(!(sp = snmp_sess_open(&session))){
          snmp_perror("snmp_open");
          print_log(LOG_WARNING,"[Thread %u] SNMP table builder, failed to open session to %s\n",thread_id,ip_address.c_str());

          return -1;
       }
       running=1;
   
       //why memmove and not memcpy? ask the netsmpbulk writers
       memmove(name, root, rootlen * sizeof(oid));
       name_length = rootlen;
       //should be a while
       while(running==1){
            /*
            * create PDU for GETBULK request and add object name to request 
             */
            pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
            pdu->non_repeaters = non_reps;
            pdu->max_repetitions = reps;    /* fill the packet */
            snmp_add_null_var(pdu, name, name_length);

            /*
            * do the request 
            */
            //status = snmp_synch_response(sp, pdu, &response);
            status = snmp_sess_synch_response(sp,pdu,&response);
            switch (status){
                case STAT_SUCCESS:
                      if (response->errstat == SNMP_ERR_NOERROR) {
                          //Yay success!
                          
//////////////
                for (vars = response->variables; vars;
                     vars = vars->next_variable) {
                    if ((vars->name_length < rootlen)
                        || (memcmp(root, vars->name, rootlen * sizeof(oid))
                            != 0)) {
                        /*
                         * not part of this subtree 
                         */
                        running = 0;
                        continue;
                    }
                    numprinted++;
                    //print_log(LOG_DEBUG,"num_printed=%d\n",numprinted);
                    //print_variable(vars->name, vars->name_length, vars);
                    if ((vars->type != SNMP_ENDOFMIBVIEW) &&
                        (vars->type != SNMP_NOSUCHOBJECT) &&
                        (vars->type != SNMP_NOSUCHINSTANCE)) {
                        /*
                         * not an exception value 
                         */
/*
                        if (check
                            && snmp_oid_compare(name, name_length,
                                                vars->name,
                                                vars->name_length) >= 0) {
                            fprintf(stderr, "Error: OID not increasing: ");
                            fprint_objid(stderr, name, name_length);
                            fprintf(stderr, " >= ");
                            fprint_objid(stderr, vars->name,
                                         vars->name_length);
                            fprintf(stderr, "\n");
                            running = 0;
                            exitval = 1;
                        }
*/
                        snmp_err_str[0]=0;
                        snprint_objid(snmp_err_str,SNMP_ERR_STR_SIZE-1,vars->name,vars->name_length);
                        snprint_value(buf, sizeof(buf)-5, vars->name, vars->name_length, vars);
                        
                        //print_log(LOG_DEBUG,"[Thread %u] '%s'='%s'\n",thread_id,snmp_err_str,buf);
                       
                        temp_string1=snmp_err_str;
                        size_t found;
                        found=temp_string1.find_last_of("."); 
                        temp_string2=temp_string1.substr(found+1);
                  
                        string search_string;
                        found=iter->first.find_last_not_of(".0123456789");
                        if(found==iter->first.npos){
                          //not found the search string is the whole thing!
                          search_string=iter->first;  
                        } 
                        else{
                          search_string=iter->first.substr(found);
                        }
                        search_string=iter->first.substr((iter->first.length()*2)/3);
                        string suffix_str;
                        //iterate over the data.
                        found=temp_string1.find(iter->first);
                        found=temp_string1.find(search_string);
                        print_log(LOG_DEBUG,"[Thread %u] [host %s] found=%u first=%s temp_string1=%s search_str=%s\n" , 
                              thread_id,ip_address.c_str(), found,iter->first.c_str(),temp_string1.c_str(),search_string.c_str());
                        if(temp_string1.npos!=found){
                           //print_log(LOG_INFO,"[Thread %u] [host %s] found!\n",thread_id,ip_address.c_str());
                           //suffix_str=temp_string1.substr(found+iter->first.length()+1); 
                           suffix_str=temp_string1.substr(found+search_string.length()+1);    
                           //print_log(LOG_INFO,"[Thread %u] found=%u first=%s temp_string1=%s\n" , thread_id,found,iter->first.c_str(),temp_string1.c_str());             
                           print_log(LOG_DEBUG,"[Thread %u] [host %s] found =%s!\n",thread_id,ip_address.c_str(),suffix_str.c_str());
                        }
                        else{
                           print_log(LOG_DEBUG,"[Thread %u] [host %s] NOT found!\n",thread_id,ip_address.c_str());
                           found=temp_string1.find_last_of(".");
                           suffix_str=temp_string1.substr(found+1);
                        }

                        
                        //print_log(LOG_DEBUG,"[Thread %u] index='%s'\n",thread_id,temp_string2.c_str());
                        uint64_t local_index;
                        local_index=atoll(temp_string2.c_str());

                        //printf("Raw Value = %s\n",buf);

                        temp_string2=extract_value_from_raw(buf);
                        //print_log(LOG_DEBUG,"[Thread %u] index=%lu value='%s' \n",thread_id,local_index,buf2);
                        //iter->second.indexof[temp_string2]=local_index;
                        //iter->second.valueof[local_index]=temp_string2; 
                        iter->second.suffix_of[temp_string2]=suffix_str;
                        iter->second.value_of[suffix_str]=temp_string2; 
                        print_log(LOG_DEBUG,"[Thread %u] [host %s] suffix_of[%s]='%s' \n",thread_id,ip_address.c_str(),temp_string2.c_str(),suffix_str.c_str());
                        

                        /*
                         * Check if last variable, and if so, save for next request.  
                         */
                        if (vars->next_variable == NULL) {
                            memmove(name, vars->name,
                                    vars->name_length * sizeof(oid));
                            name_length = vars->name_length;
                        }
                    } else {
                        /*
                         * an exception value, so stop 
                         */
                        running = 0;
                    }
                }
 

////////////////
                      }
                      else{
                        ///Error in response, report and exit loop
                        running=0;
                        snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"[Thread %u] Hostname: %-15s snmp_sync_response",thread_id, ip_address.c_str());
                        snmp_perror(snmp_err_str);

                      }
                      break;
                case STAT_TIMEOUT:
                        print_log(LOG_NOTICE,"[Thread %u] SNMP timeout(building table), host=%15s \n",thread_id, ip_address.c_str() );
                        running=0;
                      break;
                default:
                      //other error!
                         print_log(LOG_ERR,"SNMP MISC error\n");
                        running=0;
                      break;
            }
            if (response){
               snmp_free_pdu(response);
               response=NULL;
            }
            
            if(0==iter->second.suffix_of.size()){
              print_log(LOG_WARNING,"[Thread %u][host %s] no data inserted for %s\n",thread_id,ip_address.c_str(),iter->first.c_str());
              //fvalue=-1;
            }            

            //print_log(LOG_DEBUG,"[Thread %u] inserted %d values\n" ,thread_id,iter->second.indexof.size());
         
       }//end while

       if (response){
            snmp_free_pdu(response);
            response=NULL;
       }



       //is this the best place to clse it?
       snmp_sess_close(sp);
 
    }//end for
    return fvalue;
}
コード例 #12
0
ファイル: host_info.cpp プロジェクト: cviecco/snapp-collector
int Host_Info::load_oid_table_get(){
    unsigned int thread_id;
    struct snmp_session session;

    map<string,OID_Value_Table>::iterator iter;
    int fvalue=0;

    struct snmp_pdu *req, *resp;



    void *sp;
//    struct snmp_session *sptr;
    oid             name[MAX_OID_LEN];
    size_t          name_length=MAX_OID_LEN;
    oid             root[MAX_OID_LEN];
    size_t          rootlen=MAX_OID_LEN;
    struct variable_list *vars;


    char snmp_err_str[SNMP_ERR_STR_SIZE];
    char buf[512];
    char *placeholder;
    char buf2[512];
///
    string temp_string1,temp_string2;
    int running;
    int             status;
    int i;

    thread_id=(unsigned int) ((uint64_t)pthread_self());
    snmp_sess_init(&session);

    session.version   = SNMP_VERSION_2c;
    session.peername  = (char *)   ip_address.c_str();
    session.community = (u_char *) community.c_str();
    session.community_len = strlen(community.c_str());


    for (iter = oid_table.begin(); iter != oid_table.end(); iter++){

        assert(0==iter->first.compare(iter->second.oid));
        print_log(LOG_DEBUG,"Doing host=%s for oid %s\n",ip_address.c_str(),iter->first.c_str());


       rootlen = MAX_OID_LEN;
       //rootlen = strlen(iter->first.c_str());
       if (!read_objid(iter->first.c_str(), root, &rootlen)) {
       //if (!Read_objid_ts(iter->first.c_str(), root, &rootlen)) {

            //snmp_perror(argv[arg]);
            //exit(1);
          print_log(LOG_ERR,"Cannot parse the oid='%s' rootlen=%d  oid table get?\n",iter->first.c_str(),rootlen);
          snmp_perror("read_objid");
          return -1;
       }
       if(!(sp = snmp_sess_open(&session))){
          snmp_perror("snmp_open");
          print_log(LOG_WARNING,"[Thread %u] SNMP table builder, failed to open session to %s\n",thread_id,ip_address.c_str());

          return -1;
       }
////////////

  req = snmp_pdu_create(SNMP_MSG_GETNEXT);
  snmp_add_null_var(req, root, rootlen);

  status = snmp_sess_synch_response(sp,req,&resp);

  if(status == STAT_SUCCESS && resp->errstat == SNMP_ERR_NOERROR){
    char buf1[512];
    char *placeholder;
    int j;
    oid tmp[MAX_OID_LEN];
    char temp[MAX_OID_LEN];
    char ifIndexstr[MAX_OID_LEN];
    string value;
    uint64_t local_index;
 

    vars = resp->variables;

    //first = malloc(sizeof(struct Value_index_mapping));
    //assert(first!=NULL);

    //memset(buf1,'\0',sizeof(buf1));
    //memset(first->value,'\0',sizeof(first->value));
    //int toosmall = 
    snprint_value(buf1, sizeof(buf1), vars->name, vars->name_length, vars);
    placeholder = strstr(buf1,":");
    if(placeholder != NULL)
      placeholder = placeholder +2;
    if(strstr(placeholder,"\"")){
      placeholder = placeholder +1;
      //strncpy(first->value,placeholder,strlen(placeholder)-1);
      value=placeholder;
      value.resize(value.size()-1);
    }else{
      //strcpy(first->value,placeholder);
      value=placeholder;
    }



    memcpy(tmp,vars->name,vars->name_length * sizeof(oid));
    for(j=0;j<vars->name_length-rootlen;j++){
      if(j>0){
        i = sprintf(temp, ".%d", (int) tmp[rootlen+j]);
        strcat(ifIndexstr,temp);
      }else{
        i = sprintf(ifIndexstr, "%d", (int) tmp[rootlen+j]);
      }
    }
    //strcpy(first->index,ifIndexstr);
    temp_string2=ifIndexstr;

    local_index=atoll(temp_string2.c_str());
    assert(0==1); //this should never get here! under rev 3.1.0 initial
    //iter->second.indexof[value]=local_index;
    //iter->second.valueof[local_index]=value;
 
    //first->next = NULL;
    //current = first;
  }else{
    snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"Failure buidling snmp_table Hostname: %s snmp_sync_response",ip_address.c_str());
    snmp_perror(snmp_err_str);
    if(resp)
      snmp_free_pdu(resp);
    snmp_sess_close(sp);

    return -1;
  }



////////////////

       running=1;

       while(running==1) {
/////////
    oid tmp[MAX_OID_LEN];

    req = snmp_pdu_create(SNMP_MSG_GETNEXT);
    snmp_add_null_var(req,vars->name,vars->name_length);
    if(resp)
      snmp_free_pdu(resp);
    status = snmp_sess_synch_response(sp,req,&resp);

    if(status == STAT_SUCCESS && resp->errstat == SNMP_ERR_NOERROR){



      struct Value_index_mapping *tempIndex = NULL;
      char buf[512];
      char *placeholder;
      char ifIndexstr[MAX_OID_LEN];
      int j;
      char temp[MAX_OID_LEN];
      oid tmp[MAX_OID_LEN];
      string value_string;
      string index_string;
      int64_t local_index;
 
      vars = resp->variables;
      //tempIndex = malloc(sizeof(struct Value_index_mapping));  //why allocate a != struct?  
      //assert(tempIndex!=NULL);

      //memset(buf,'\0',sizeof(buf));
      //memset(tempIndex->value,'\0',sizeof(tempIndex->value));
      //will add a few extra bytes later, ensure we are covered
      snprint_value(buf, sizeof(buf)-5, vars->name, vars->name_length, vars);

      //printf("Raw Value = %s\n",buf);
      placeholder = strstr(buf,":");
      if(placeholder != NULL)
        placeholder = placeholder +2;
      if(strstr(placeholder,"\"")){
        placeholder = placeholder +1;
        //you assert on the size of the dest, not the origin
        assert(strlen(placeholder)+1<STD_STRING_SIZE);
        //strncpy(tempIndex->value,placeholder,strlen(placeholder));
        value_string=placeholder;
      }else{
        //strncpy(tempIndex->value,placeholder,STD_STRING_SIZE-1);
        value_string=placeholder;
        value_string.resize(value_string.size()-1);
      }

      memcpy(tmp,vars->name,vars->name_length * sizeof(oid));
      for(j=0;j<vars->name_length-rootlen;j++){
        if(j>0){
          i = sprintf(temp, ".%d",(int) tmp[rootlen+j]);
          strcat(ifIndexstr,temp);
        }else{
          i = sprintf(ifIndexstr, "%d",(int) tmp[rootlen+j]);
        }
      }
      //strcpy(tempIndex->index,ifIndexstr);
      index_string=ifIndexstr;

      local_index=atoll(index_string.c_str());
      assert(1==0); //this should never reach this under 3.1.0
      //iter->second.indexof[value_string]=local_index;
      //iter->second.valueof[local_index]=value_string;


      //print_log(LOG_DEBUG,"[Thread %u] Index = %u , Value = %s\n",thread_id,local_index,value_string.c_str());
      //current->next = tempIndex;
      //current = tempIndex;
      //current->next = NULL;
    }else{
      //snmp_perror("snmp_synch_response");
      //snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"[Thread %u] Hostname: %-15s snmp_sync_response",thread_id, hostInfo.name);
      snmp_perror(snmp_err_str);

      if(resp)
        snmp_free_pdu(resp);
      snmp_sess_close(sp);
      return -1;
    }

    //oid tmp[MAX_OID_LEN];
    memcpy(tmp,vars->name,vars->name_length * sizeof(oid));

    if(tmp[rootlen-1] != root[rootlen-1]){
      if(resp)
        snmp_free_pdu(resp);
      snmp_sess_close(sp);
      running=0;
      //done?
    }



//////////
       }      //end while


    }//end for each host

}
コード例 #13
0
ファイル: rtgsnmp.c プロジェクト: Prophidys/RTG2
void *poller(void *thread_args)
{
    worker_t *worker = (worker_t *) thread_args;
    crew_t *crew = worker->crew;
    target_t *entry = NULL;
    void *sessp = NULL;
    struct snmp_session session;
    struct snmp_pdu *pdu = NULL;
    struct snmp_pdu *response = NULL;
    oid anOID[MAX_OID_LEN];
    size_t anOID_len = MAX_OID_LEN;
    struct variable_list *vars = NULL;
    unsigned long long result = 0;
    unsigned long long last_value = 0;
    unsigned long long insert_val = 0;
    int poll_status = 0, db_status = 0, bits = 0, init = 0;
    char query[BUFSIZE];
    char storedoid[BUFSIZE];
    char result_string[BUFSIZE];
    int cur_work = 0;
    int prev_work = 99999999;
    int loop_count = 0;


#ifdef FEATURES
	/* Per thread SQL connection testing */
  #if HAVE_MYSQL
	MYSQL mysql;
  #elif HAVE_PGSQL
	PGconn *pgsql;
  #endif
	double rate = 0;
	struct timezone tzp;
	struct timeval current_time;
	struct timeval last_time;

	/* for thread settings */
	int oldstate, oldtype;
#endif

	debug(HIGH, "Thread [%d] starting.\n", worker->index);

    pthread_cleanup_push(cleanup_db, NULL);



    /* Attempt to connect to the MySQL Database */
#ifdef FEATURES
	/* Per thread MySQL connection testing */
    if (!(set->dboff)) {
	/* load the database driver */
	if (!(db_init(set))) {
		fatal("** Database error - check configuration.\n");
	}
	/* connect to the database */
	if (!(db_connect(set))) {
		fatal("server not responding.\n");
	}
		/* set up cancel function for exit */
		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
		pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
    }
#endif /* FEATURES */

    while (1) {

/*        if(loop_count >= POLLS_PER_TRANSACTION) {
            debug(HIGH, "Thread [%d] doing commit on %d\n", worker->index, POLLS_PER_TRANSACTION);
            db_status = db_commit(); 
            loop_count = 0;
        }
*/

#ifdef FEATURES
	/* see if we've been cancelled before we start another loop */
	pthread_testcancel();
#endif
	debug(DEVELOP, "Thread [%d] locking (wait on work)\n", worker->index);

	PT_MUTEX_LOCK(&crew->mutex);
#ifdef FEATURES
	/* add an unlock to the cancel stack */
	pthread_cleanup_push(cancel_lock, &crew->mutex);	
#endif

	while (current == NULL) {
		PT_COND_WAIT(&crew->go, &crew->mutex);
	}
	debug(DEVELOP, "Thread [%d] done waiting, received go (work cnt: %d)\n",
		worker->index, crew->work_count);
        cur_work = crew->work_count;
/*         if(cur_work > prev_work) {
            debug(HIGH, "Thread [%d] doing commit at %d\n", worker->index,time(NULL));
            db_status = db_commit(); 
            loop_count = 0;
        }
*/
        prev_work = cur_work;

	if (current != NULL) {
		debug(DEVELOP, "Thread [%d] processing %s %s (%d work units remain in queue)\n",
			worker->index, current->host->host, current->objoid, crew->work_count);
	    snmp_enable_stderrlog(); 
            snmp_sess_init(&session);
		if (current->host->snmp_ver == 2)
			session.version = SNMP_VERSION_2c;
		else
			session.version = SNMP_VERSION_1;
	    session.peername = current->host->host;
	    session.community = current->host->community;
		session.remote_port = set->snmp_port;
	    session.community_len = strlen(session.community);

	    sessp = snmp_sess_open(&session);
	    anOID_len = MAX_OID_LEN;
	    pdu = snmp_pdu_create(SNMP_MSG_GET);
	    read_objid(current->objoid, anOID, &anOID_len);
	    entry = current;
	    last_value = current->last_value;
#ifdef FEATURES
		/* save the time so we can calculate rate */
		last_time = current->last_time;
#endif
	    init = current->init;
	    insert_val = 0;
	    bits = current->bits;
	    strncpy(storedoid, current->objoid, sizeof(storedoid));
		current = getNext();
	}
	debug(DEVELOP, "Thread [%d] unlocking (done grabbing current)\n", worker->index);
	PT_MUTEX_UNLOCK(&crew->mutex);
#ifdef FEATURES
	/* take the unlock off the cancel stack */
	pthread_cleanup_pop(FALSE);
#endif

	snmp_add_null_var(pdu, anOID, anOID_len);
	if (sessp != NULL) 
	   poll_status = snmp_sess_synch_response(sessp, pdu, &response);
	else
	   poll_status = STAT_DESCRIP_ERROR;

	/* Collect response and process stats */
	PT_MUTEX_LOCK(&stats.mutex);
	if (poll_status == STAT_DESCRIP_ERROR) {
	    stats.errors++;
            printf("*** SNMP Error: (%s) Bad descriptor.\n", session.peername);
	} else if (poll_status == STAT_TIMEOUT) {
	    stats.no_resp++;
	    printf("*** SNMP No response: (%s@%s).\n", session.peername,
	       storedoid);
	} else if (poll_status != STAT_SUCCESS) {
	    stats.errors++;
	    printf("*** SNMP Error: (%s@%s) Unsuccessuful (%d).\n", session.peername,
	       storedoid, poll_status);
	} else if (poll_status == STAT_SUCCESS && response->errstat != SNMP_ERR_NOERROR) {
	    stats.errors++;
	    printf("*** SNMP Error: (%s@%s) %s\n", session.peername,
	       storedoid, snmp_errstring(response->errstat));
	} else if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR && response->variables->type == SNMP_NOSUCHINSTANCE) {
	    stats.errors++;
	    printf("*** SNMP Error: No Such Instance Exists (%s@%s)\n", session.peername, storedoid);
	} else if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
	    stats.polls++;
	} 
	PT_MUTEX_UNLOCK(&stats.mutex);

	/* Liftoff, successful poll, process it */
#ifdef FEATURES
	/* Get the current time */
	gettimeofday(&current_time, &tzp);
#endif

	if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR && response->variables->type != SNMP_NOSUCHINSTANCE) {
	    vars = response->variables;
#ifdef OLD_UCD_SNMP
            sprint_value(result_string, anOID, anOID_len, vars);
#else
	    snprint_value(result_string, BUFSIZE, anOID, anOID_len, vars);
#endif
	    switch (vars->type) {
		/*
		 * Switch over vars->type and modify/assign result accordingly.
		 */
		case ASN_COUNTER64:
		    debug(DEBUG, "64-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = vars->val.counter64->high;
		    result = result << 32;
		    result = result + vars->val.counter64->low;
		    break;
		case ASN_COUNTER:
		    debug(DEBUG, "32-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_INTEGER:
		    debug(DEBUG, "Integer result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_GAUGE:
		    debug(DEBUG, "32-bit gauge: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_TIMETICKS:
		    debug(DEBUG, "Timeticks result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_OPAQUE:
		    debug(DEBUG, "Opaque result: (%s@%s) %s\n", session.peername, storedoid, result_string);
		    result = (unsigned long) *(vars->val.integer);
		    break;
		case ASN_OCTET_STR:
		    debug(DEBUG, "String Result: (%s@%s) %s\n", session.peername, storedoid, result_string);
#ifdef HAVE_STRTOLL
		    result = strtoll(vars->val.string, NULL, 0);
#else
		    result = strtol(vars->val.string, NULL, 0);
#endif
		    break;
		default:
		    debug(LOW, "Unknown result type: (%s@%s) %s\n", session.peername, storedoid, result_string);
	    }

		/* Gauge Type */
		if (bits == 0) {
			if (result != last_value) {
				insert_val = result;
				debug(DEVELOP, "Thread [%d]: Gauge change from %lld to %lld\n", worker->index, last_value, insert_val);
			} else {
				if (set->withzeros) 
					insert_val = result;
				debug(DEVELOP, "Thread [%d]: Gauge steady at %lld\n", worker->index, insert_val);
			}
	    /* Counter Wrap Condition */
	    } else if (result < last_value) {
			PT_MUTEX_LOCK(&stats.mutex);
              stats.wraps++;
			PT_MUTEX_UNLOCK(&stats.mutex);
	      if (bits == 32) insert_val = (THIRTYTWO - last_value) + result;
	      else if (bits == 64) insert_val = (SIXTYFOUR - last_value) + result;

#ifdef FEATURES
			rate = insert_val / timediff(current_time, last_time);
#endif

	      debug(LOW, "*** Counter Wrap (%s@%s) [poll: %llu][last: %llu][insert: %llu]\n",
	         session.peername, storedoid, result, last_value, insert_val);
	    /* Not a counter wrap and this is not the first poll */
	    } else if ((last_value >= 0) && (init != NEW)) {
		insert_val = result - last_value;

#ifdef FEATURES
			rate = insert_val / timediff(current_time, last_time);
#endif
		
	        /* Print out SNMP result if verbose */
	        if (set->verbose == DEBUG)
		  printf("Thread [%d]: (%lld-%lld -- %llu) = %llu\n", worker->index, result, last_value, insert_val,rate);
	        if (set->verbose == HIGH)
		  printf("Thread [%d]: %llu\n", worker->index, insert_val);
            /* last_value < 0, so this must be the first poll */
	    } else {
#ifdef FEATURES
			/* set up this result for the next poll */
			entry->last_value = result;
#endif
			debug(HIGH, "Thread [%d]: First Poll, Normalizing\n", worker->index);
	    }

		/* Check for bogus data, either negative or unrealistic */
	    if (insert_val > entry->maxspeed || result < 0) {
			debug(LOW, "*** Out of Range (%s@%s) [insert_val: %llu] [oor: %lld]\n",
				session.peername, storedoid, insert_val, entry->maxspeed);
			insert_val = 0;
#ifdef FEATURES
			rate = 0;
#endif
			PT_MUTEX_LOCK(&stats.mutex);
			stats.out_of_range++;
			PT_MUTEX_UNLOCK(&stats.mutex);
	    }

		if (!(set->dboff)) {
			if ( (insert_val > 0) || (set->withzeros) ) {
#ifndef FEATURES
				/* MP - since we have our own database connection we don't need to lock it anymore */
				PT_MUTEX_LOCK(&crew->mutex);
#endif

                                debug(DEVELOP, "db_insert sent: %s %d %d %e\n",entry->table,entry->iid,insert_val,rate);
				/* insert into the database */
				db_status = db_insert(entry->table, entry->iid, insert_val, rate);

#ifndef FEATURES
				/* MP - since we have our own database connection we don't need to lock it anymore */
				PT_MUTEX_UNLOCK(&crew->mutex);
#endif

				if (db_status) {
					PT_MUTEX_LOCK(&stats.mutex);
					stats.db_inserts++;
					PT_MUTEX_UNLOCK(&stats.mutex);
				} else {
					fatal("Fatal database error.\n");
				}
			} /* insert_val > 0 or withzeros */	
		} /* !dboff */

	} /* STAT_SUCCESS */

/*	debug(HIGH, "Thread [%d] doing commit\n", worker->index);
        db_status = db_commit(); */

        if (sessp != NULL) {
           snmp_sess_close(sessp);
           if (response != NULL) snmp_free_pdu(response);
        }

	debug(DEVELOP, "Thread [%d] locking (update work_count)\n", worker->index);
	PT_MUTEX_LOCK(&crew->mutex);
	crew->work_count--;
	/* Only if we received a positive result back do we update the
	   last_value object */
	if (poll_status == STAT_SUCCESS) {
		entry->last_value = result;
		if (init == NEW) entry->init = LIVE;
	}

#ifdef FEATURES
	/* always update the time */
	entry->last_time = current_time;	
#endif

	if (crew->work_count <= 0) {
	    debug(HIGH, "Queue processed. Broadcasting thread done condition.\n");
		PT_COND_BROAD(&crew->done);
	}
	debug(DEVELOP, "Thread [%d] unlocking (update work_count)\n", worker->index);

		PT_MUTEX_UNLOCK(&crew->mutex);

        loop_count++;
    }				/* while(1) */
    pthread_cleanup_pop(FALSE);

/* Not reached */
}