Beispiel #1
0
unsigned int
decode_snmp_oid (unsigned char *data, size_t data_len)
{
  oid this_oid[MAX_OID_LEN];
  size_t oid_len = MAX_OID_LEN;
  unsigned char type;
  void *retval;			/* generic pointer, will only use to check return value */
  size_t len;
  static char outbuf[1024];

  memset (outbuf, 0, 1024);

  len = data_len;		/* The last char is the enable/disable switch */

  if ((retval =
       asn_parse_objid (data, &len, &type, this_oid, &oid_len)) == NULL)
    {
      fprintf(stderr, "OID.parse.error");
      return 0;
    }
  else
    {
      netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID,
			  NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
			  NETSNMP_OID_OUTPUT_NUMERIC);
      snprint_objid (outbuf, 1023, this_oid, oid_len);
    }
/*  fprintf(stderr, "%s %d", outbuf, (int) data[data_len - 1]); */
  printf("%s", outbuf);
  return 1;
}
Beispiel #2
0
/*
 * 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;
	}
}
int return_data(int status, struct snmp_session *sp, struct snmp_pdu *pdu)
{
  char buf[1024];
  struct variable_list *vp;
  int ix;
  char *getdata = NULL;
 
  switch (status) {
  case STAT_SUCCESS:
    vp = pdu->variables;
    if (pdu->errstat == SNMP_ERR_NOERROR) {
      while (vp) {
	snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp);
	/*mjpark------------------------------------------*/
	getdata = (char *)malloc(1 + vp->val_len);
	memcpy(getdata, vp->val.string, vp->val_len);
	getdata[vp->val_len] = '\0';
#if 0
	//Data over flow...
	int nVal;
	memcpy((void *)&nVal, getdata, 4);
#else
	unsigned long int nVal;
	memcpy((void *)&nVal, getdata, sizeof(unsigned long int));
#endif
	gpSnmp->val = nVal;

	//debug print
	/* printf("data length(%d), unsigned long int size(%d), int(%d)\n",vp->val_len, sizeof(unsigned long int), sizeof(int)); */
	printf("snmpVal(%d), psnmp(%p)\n", nVal, gpSnmp);
	/*------------------------------------------------*/
	vp = vp->next_variable;
      }
      free(getdata);
    }
    else {
      for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++);
      if (vp)
	snprint_objid(buf, sizeof(buf), vp->name, vp->name_length);
      else
	strcpy(buf, "(none)");
      fprintf(stdout, "%s: %s: %s\n", sp->peername, buf, snmp_errstring(pdu->errstat));
    }
    return 1;
  case STAT_TIMEOUT:
    fprintf(stdout, "%s: Timeout\n", sp->peername);
    return 0;
  
  case STAT_ERROR:
    snmp_perror(sp->peername);
    return 0;
  }
  return 0;
}
Beispiel #4
0
static int snmp_input(int op, netsnmp_session *session, int reqid, netsnmp_pdu *pdu, void *magic) {
  netsnmp_variable_list *var;
  char str_buf[STR_BUF_SIZE];
  for(var=pdu->variables; var; var=var->next_variable) {
    if (var->type == ASN_OBJECT_ID) {
      snprint_objid(str_buf, sizeof(str_buf), var->val.objid, var->val_len/sizeof(oid));
      printf("%s: snmp_input: oid=%s\n", program_name, str_buf);
    }
  }
  return 0;
}
Beispiel #5
0
static char    *
create_explanaition(CRTL_ENTRY_T * evptr, u_char is_rising,
                    u_long alarm_index, u_long event_index,
                    oid * alarmed_var,
                    size_t alarmed_var_length,
                    u_long value, u_long the_threshold,
                    u_long sample_type, char *alarm_descr)
{
#define UNEQ_LENGTH	(1 + 11 + 4 + 11 + 1 + 20)
    char            expl[UNEQ_LENGTH];
    static char     c_oid[SPRINT_MAX_LEN];
    size_t          sz;
    char           *descr;
    register char  *pch;
    register char  *tmp;


    snprint_objid(c_oid, sizeof(c_oid)-1, alarmed_var, alarmed_var_length);
    c_oid[sizeof(c_oid)-1] = '\0';
    for (pch = c_oid;;) {
        tmp = strchr(pch, '.');
        if (!tmp)
            break;
        if (isdigit(tmp[1]) || '"' == tmp[1])
            break;
        pch = tmp + 1;
    }

    snprintf(expl, UNEQ_LENGTH, "=%ld %s= %ld :%ld, %ld",
             (unsigned long) value,
             is_rising ? ">" : "<",
             (unsigned long) the_threshold,
             (long) alarm_index, (long) event_index);
    sz = 3 + strlen(expl) + strlen(pch);
    if (alarm_descr)
        sz += strlen(alarm_descr);

    descr = AGMALLOC(sz);
    if (!descr) {
        ag_trace("Can't allocate event description");
        return NULL;
    }

    if (alarm_descr) {
        strcpy(descr, alarm_descr);
        strcat(descr, ":");
    } else
        *descr = '\0';

    strcat(descr, pch);
    strcat(descr, expl);
    return descr;
}
Beispiel #6
0
// Show agent's nieghbor and Ips
// mib object used : ipNetToMediaIfIndex , ipNetToMediaNetAddress
void showNeighbor() {
  char ifIndex_oid[50] = "ipNetToMediaIfIndex";
  char ip_oid[50] = "ipNetToMediaNetAddress";
  printf("-----------------------Neighbor----------------------\n");
  printf("Interface  -->  Neighbor\n");
     while ( true ) {

    snmpgetnext(ifIndex_oid);
    int index ;
    char *ip ;
    vars  = response->variables;

    if ( vars->type == ASN_INTEGER) {
      char tmp[50] ;
     snprint_objid(tmp,50,vars->name,vars->name_length); // this returns response oid
      strcpy(ifIndex_oid,tmp); // update the oid for next getnext
      index = (int) *(vars->val.integer);
    } else {
      break;
    }
    cleanup();
    snmpgetnext(ip_oid);
    vars = response->variables;
    if ( vars->type == ASN_IPADDRESS) {
      char tmp[50];
      char oidTemp[50];
      snprint_objid(oidTemp,50,vars->name,vars->name_length);//this returns response oid
      strcpy(ip_oid,oidTemp); // update the oid for next getnext
      ip = parseIP(tmp);
    } else {
      break;
    }
    printf("%i  -->  %s\n" , index , ip);
    cleanup();
  }
  printf("----------------------------------------------------\n\n\n");
}
Beispiel #7
0
void
process_stdin(void)
{
    char        buf[MAX_LINE_TEMP];
    oid         name[MAX_OID_LEN];
    size_t      name_length;

    while ( NULL != fgets( buf, sizeof( buf ), stdin ) ) {
        char delim = ' ';
        char *nl = strchr(buf, '\n');
        char *rest = strchr(buf, delim);

        if (nl != NULL) {
            *nl = '\0';
        } /* else too-long line: output will look weird.  Too bad. */
        if (rest == NULL) {
            delim = '\t';
            rest = strchr(buf, delim);
        }
        if (rest != NULL) {
            *rest++ = '\0';
        }
        name_length = MAX_OID_LEN;
        /*
         * If it's not the whole line, only try to process buffer
         * longer than 5 characters.
         * The idea is to avoid false positives including, e.g.,
         * a hex dump.
         */
        if ( !(rest && strlen( buf ) <= 5) &&
              read_objid( buf, name, &name_length )) {
            char objbuf[MAX_LINE_TEMP];
            snprint_objid( objbuf, MAX_LINE_TEMP, name, name_length );
            fputs( objbuf, stdout );
        } else {
            fputs( buf, stdout );
        }
        /*
         * For future improvement: if delim == ' ' && rest && *rest == '='
         * see if rest looks like snmpget/snmpwalk output
         * and handle it in the context of the given node
         */
        if (rest) {
            fputc( delim, stdout );
            fputs( rest, stdout );
        }
        fputc( '\n', stdout );
    }
}
Beispiel #8
0
int print_result(int status, struct snmp_session *sp, struct snmp_pdu *pdu)
{
	char buf[1024];
	struct variable_list *vp;
	int ix;

	struct timeval now;
	struct timezone tz;
	struct tm *tm;

	gettimeofday(&now, &tz);
	tm = localtime(&now.tv_sec);
	fprintf(stdout, "%.2d:%.2d:%.2d.%.6d, status: %d, ", tm->tm_hour, tm->tm_min, tm->tm_sec,
	        now.tv_usec, status);
	switch (status) {
		case STAT_SUCCESS:
			vp = pdu->variables;
			if (pdu->errstat == SNMP_ERR_NOERROR) {
				while (vp) {
					snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp);
					fprintf(stdout, ":%s: %s\n", sp->peername, buf);
					vp = vp->next_variable;
				}
			}
			else {
				for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++)
					;
				if (vp) snprint_objid(buf, sizeof(buf), vp->name, vp->name_length);
				else strcpy(buf, "(none)");
				fprintf(stdout, ":%s: %s: %s\n",
				        sp->peername, buf, snmp_errstring(pdu->errstat));
			}
			return 1;
		case STAT_TIMEOUT:
			fprintf(stdout, ":%s: Timeout\n", sp -> peername);
			return 0;
		case STAT_ERROR:
			snmp_perror(sp->peername);
			return 0;
	}
	return 0;
}
int mp_snmp_subtree_query(netsnmp_session *ss,
                           const oid *subtree_oid,
                           const size_t subtree_len,
                           mp_snmp_subtree *subtree) {

    oid last_oid[MAX_OID_LEN];
    size_t last_len;
    netsnmp_pdu *request  = NULL;
    netsnmp_pdu *response = NULL;
    netsnmp_variable_list *var;
    size_t alloc_size = 0;
    int rc;

    /* prepare result */
    memset(subtree, '\0', sizeof(*subtree));
    subtree->vars = NULL;

    memcpy(last_oid, subtree_oid, subtree_len * sizeof(oid));
    last_len = subtree_len;

    for (;;) {
        /*
         * setup request
         */
        if (ss->version == SNMP_VERSION_1) {
            request = snmp_pdu_create(SNMP_MSG_GETNEXT);
        } else {
            request = snmp_pdu_create(SNMP_MSG_GETBULK);
            request->non_repeaters   = 0;
            request->max_repetitions = 16;
        }
        snmp_add_null_var(request, last_oid, last_len);

        /*
         * commence request
         */
        if (response) {
            snmp_free_pdu(response);
            response = NULL;
        }

        if (mp_verbose > 2) {
            char buf[128];

            snprint_objid((char *) &buf, sizeof(buf), last_oid, last_len);
            printf("Fetching next from OID %s\n", buf);
        }

        rc = snmp_synch_response(ss, request, &response);

        if (mp_verbose > 3)
            printf("snmp_synch_response(): rc=%d, errstat=%ld\n",
                   rc, response->errstat);

        if ((rc == STAT_SUCCESS) && response) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * loop over results (may only be one result in case of SNMP v1)
                 */
                for (var = response->variables; var; var = var->next_variable) {

                    /*
                     * check, if OIDs are incresing to prevent infinite
                     * loop with broken SNMP agents
                     */
                    if (snmp_oidtree_compare(var->name, var->name_length,
                                             last_oid, last_len) < 0) {
                        if (response)
                            snmp_free_pdu(response);

                        mp_snmp_deinit();

                        critical("SNMP error: OIDs are not incresing");
                    }

                    /*
                     * terminate, if oid does not belong to subtree anymore
                     */
                    if ((var->type == SNMP_ENDOFMIBVIEW) ||
                        (snmp_oidtree_compare(subtree_oid,
                                              subtree_len,
                                              var->name,
                                              var->name_length) != 0)) {
                        snmp_free_pdu(response);
                        return rc;
                    }

                    if (mp_verbose > 2)
                        print_variable(var->name, var->name_length, var);

                    if (var->type != SNMP_NOSUCHOBJECT ||
                        var->type != SNMP_NOSUCHINSTANCE) {
                        if (alloc_size <= subtree->size) {
                            alloc_size += 16;
                            subtree->vars =
                                mp_realloc(subtree->vars,
                                           alloc_size *
                                           sizeof(netsnmp_variable_list*));
                        }

                        subtree->vars[subtree->size] =
                            mp_malloc(sizeof(netsnmp_variable_list));
                        snmp_clone_var(var, subtree->vars[subtree->size]);
                        subtree->size++;
                    }

                    /*
                     * save last fetched oid
                     */
                    memcpy(last_oid, var->name,
                           var->name_length * sizeof(oid));
                    last_len = var->name_length;
                } /* for */
            } else if ((ss->version == SNMP_VERSION_1) &&
                       (response->errstat == SNMP_ERR_NOSUCHNAME)) {
                if (mp_verbose > 3)
                    printf("SNMP-V1: end of tree\n");
            } else {
                /*
                 * some other error occured
                 */
                if (mp_verbose > 0)
                    printf("SNMP error: respose->errstat = %ld",
                           response->errstat);

                rc = STAT_ERROR;
                //goto done;
                break;
            }
        } else {
            /* no response, assume an error */
            rc = STAT_ERROR;
            break;
        }
    }

    if (response)
        snmp_free_pdu(response);

    return rc;
}
Beispiel #10
0
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;
}
Beispiel #11
0
/** implements the table data helper.  This is the routine that takes
 *  care of all SNMP requests coming into the table. */
int
netsnmp_table_data_set_helper_handler(netsnmp_mib_handler *handler,
                                      netsnmp_handler_registration
                                      *reginfo,
                                      netsnmp_agent_request_info *reqinfo,
                                      netsnmp_request_info *requests)
{

    netsnmp_table_data_set_storage *data = NULL;
    newrow_stash   *newrowstash = NULL;
    netsnmp_table_row *row, *newrow = NULL;
    netsnmp_table_request_info *table_info;
    netsnmp_request_info *request;
    oid            *suffix;
    size_t          suffix_len;
    netsnmp_oid_stash_node **stashp = NULL;

    if (!handler)
        return SNMPERR_GENERR;
        
    DEBUGMSGTL(("netsnmp_table_data_set", "handler starting\n"));
    for (request = requests; request; request = request->next) {
        netsnmp_table_data_set *datatable =
            (netsnmp_table_data_set *) handler->myvoid;
        if (request->processed)
            continue;

        /*
         * extract our stored data and table info 
         */
        row = netsnmp_extract_table_row(request);
        table_info = netsnmp_extract_table_info(request);
        suffix = requests->requestvb->name + reginfo->rootoid_len + 2;
        suffix_len = requests->requestvb->name_length -
            (reginfo->rootoid_len + 2);

        if (MODE_IS_SET(reqinfo->mode)) {

            char buf[256]; /* is this reasonable size?? */
            int  rc;
            size_t len;

            /*
             * use a cached copy of the row for modification 
             */

            /*
             * cache location: may have been created already by other
             * SET requests in the same master request. 
             */
            rc = snprintf(buf, sizeof(buf), "dataset_row_stash:%s:",
                          datatable->table->name);
            if ((-1 == rc) || (rc >= sizeof(buf))) {
                snmp_log(LOG_ERR,"%s handler name too long\n",
                         datatable->table->name);
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_GENERR);
                continue;
            }
            len = sizeof(buf) - rc;
            rc = snprint_objid(&buf[rc], len, table_info->index_oid,
                               table_info->index_oid_len);
            if (-1 == rc) {
                snmp_log(LOG_ERR,"%s oid or name too long\n",
                         datatable->table->name);
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_GENERR);
                continue;
            }
            stashp = (netsnmp_oid_stash_node **)
                netsnmp_table_get_or_create_row_stash(reqinfo, buf);

            newrowstash
                = netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len);

            if (!newrowstash) {
                if (!row) {
                    if (datatable->allow_creation) {
                        /*
                         * entirely new row.  Create the row from the template 
                         */
                        newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                        newrow = newrowstash->newrow;
                    } else if (datatable->rowstatus_column == 0) {
                        /*
                         * A RowStatus object may be used to control the
                         *  creation of a new row.  But if this object
                         *  isn't declared (and the table isn't marked as
                         *  'auto-create'), then we can't create a new row.
                         */
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_NOCREATION);
                        continue;
                    }
                } else {
                    /*
                     * existing row that needs to be modified 
                     */
                    newrowstash = SNMP_MALLOC_TYPEDEF(newrow_stash);
                    newrow = netsnmp_table_data_set_clone_row(row);
                    newrowstash->newrow = newrow;
                }
                netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                           newrowstash);
            } else {
                newrow = newrowstash->newrow;
            }
            /*
             * all future SET data modification operations use this
             * temp pointer 
             */
            if (reqinfo->mode == MODE_SET_RESERVE1 ||
                reqinfo->mode == MODE_SET_RESERVE2)
                row = newrow;
        }

        if (row)
            data = (netsnmp_table_data_set_storage *) row->data;

        if (!row || !table_info || !data) {
            if (!MODE_IS_SET(reqinfo->mode)) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
        }

        data =
            netsnmp_table_data_set_find_column(data, table_info->colnum);

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
        case MODE_GETBULK:     /* XXXWWW */
            if (data && data->data.voidp)
                netsnmp_table_data_build_result(reginfo, reqinfo, request,
                                                row,
                                                table_info->colnum,
                                                data->type,
                                                data->data.voidp,
                                                data->data_len);
            break;

        case MODE_SET_RESERVE1:
            if (data) {
                /*
                 * Can we modify the existing row?
                 */
                if (!data->writable) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOTWRITABLE);
                } else if (request->requestvb->type != data->type) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                }
            } else if (datatable->rowstatus_column == table_info->colnum) {
                /*
                 * Otherwise, this is where we create a new row using
                 * the RowStatus object (essentially duplicating the
                 * steps followed earlier in the 'allow_creation' case)
                 */
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                    newrow = newrowstash->newrow;
                    row    = newrow;
                    netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                               newrowstash);
                }
            }
            break;

        case MODE_SET_RESERVE2:
            /*
             * If the agent receives a SET request for an object in a non-existant
             *  row, then the RESERVE1 pass will create the row automatically.
             *
             * But since the row doesn't exist at that point, the test for whether
             *  the object is writable or not will be skipped.  So we need to check
             *  for this possibility again here.
             *
             * Similarly, if row creation is under the control of the RowStatus
             *  object (i.e. allow_creation == 0), but this particular request
             *  doesn't include such an object, then the row won't have been created,
             *  and the writable check will also have been skipped.  Again - check here.
             */
            if (data && data->writable == 0) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                continue;
            }
            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_ACTIVE:
                case RS_NOTINSERVICE:
                    /*
                     * Can only operate on pre-existing rows.
                     */
                    if (!newrowstash || newrowstash->created) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    /*
                     * Can only operate on newly created rows.
                     */
                    if (!(newrowstash && newrowstash->created)) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_DESTROY:
                    /*
                     * Can operate on new or pre-existing rows.
                     */
                    break;

                case RS_NOTREADY:
                default:
                    /*
                     * Not a valid value to Set 
                     */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    continue;
                }
            }
            if (!data ) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOCREATION);
                continue;
            }

            /*
             * modify row and set new value 
             */
            SNMP_FREE(data->data.string);
            data->data.string =
                netsnmp_strdup_and_null(request->requestvb->val.string,
                                        request->requestvb->val_len);
            if (!data->data.string) {
                netsnmp_set_request_error(reqinfo, requests,
                                          SNMP_ERR_RESOURCEUNAVAILABLE);
            }
            data->data_len = request->requestvb->val_len;

            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_ACTIVE;
                    break;

                case RS_CREATEANDWAIT:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_NOTINSERVICE;
                    break;

                case RS_DESTROY:
                    newrowstash->deleted = 1;
                    break;
                }
            }
            break;

        case MODE_SET_ACTION:

            /*
             * Install the new row into the stored table.
	     * Do this only *once* per row ....
             */
            if (newrowstash->state != STATE_ACTION) {
                newrowstash->state = STATE_ACTION;
		if (newrowstash->created) {
                    netsnmp_table_dataset_add_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      row, newrow);
                }
            }
            /*
             * ... but every (relevant) varbind in the request will
	     * need to know about this new row, so update the
	     * per-request row information regardless
             */
            if (newrowstash->created) {
		netsnmp_request_add_list_data(request,
			netsnmp_create_data_list(TABLE_DATA_NAME,
						 newrow, NULL));
            }
            break;

        case MODE_SET_UNDO:
            /*
             * extract the new row, replace with the old or delete 
             */
            if (newrowstash->state != STATE_UNDO) {
                newrowstash->state = STATE_UNDO;
                if (newrowstash->created) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      newrow, row);
                    netsnmp_table_dataset_delete_row(newrow);
                }
            }
            break;

        case MODE_SET_COMMIT:
            if (newrowstash->state != STATE_COMMIT) {
                newrowstash->state = STATE_COMMIT;
                if (!newrowstash->created) {
                    netsnmp_table_dataset_delete_row(row);
                }
                if (newrowstash->deleted) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                }
            }
            break;

        case MODE_SET_FREE:
            if (newrowstash && newrowstash->state != STATE_FREE) {
                newrowstash->state = STATE_FREE;
                netsnmp_table_dataset_delete_row(newrow);
            }
            break;
        }
    }

    /* next handler called automatically - 'AUTO_NEXT' */
    return SNMP_ERR_NOERROR;
}
int return_data(int status, struct snmp_session *sp, struct snmp_pdu *pdu)               /* simple printing of returned data */
{
  char buf[1024];
  struct variable_list *vp;
  int ix;
  char *getdata = NULL;
  unsigned long int nVal;
  /* unsigned char sVal; */
  /* int ipVal; */

  switch (status) {
  case STAT_SUCCESS:
    vp = pdu->variables;
    if (pdu->errstat == SNMP_ERR_NOERROR) {
      while (vp) {
	snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp);
	/*mjpark------------------------------------------*/
	getdata = (char *)malloc(1 + vp->val_len);
	memcpy(getdata, vp->val.string, vp->val_len);
	getdata[vp->val_len] = '\0';

	switch(vp->type)
	  {
	  case ASN_OCTET_STR:
	    /* { */
	    /* memcpy((void *)&sVal, getdata, sizeof(unsigned char)); */
	    /* gpSnmpstr->val = sVal; */
	    /* break; */
	    /* } */
	  case ASN_GAUGE:
	  case ASN_COUNTER:
	  case ASN_TIMETICKS:
	  case ASN_INTEGER:
	    {
	      memcpy((void *)&nVal, getdata, sizeof(unsigned long int));
	      gpSnmp->val = nVal;
	      break;
	    }
	  case ASN_IPADDRESS:
	    {
	      /* struct in_addr st_addr; */
    	      /* memcpy((void *)&ipVal, getdata, 4); */
	      /* st_addr.s_addr = ipVal; */
	      /* gpSnmpstr->val = inet_ntoa(st_addr); */
	      break;
	    }
	  }
	//debug print
	//printf("data length(%d), unsigned long int size(%d), int(%d)\n",vp->val_len, sizeof(unsigned long int), sizeof(int));
	/* printf("snmpVal(%d), psnmp(%p)\n", nVal, gpSnmp); */
	/*------------------------------------------------*/
	vp = vp->next_variable;
      }
      free(getdata);
    }
    else {
      for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++);
      if (vp)
	snprint_objid(buf, sizeof(buf), vp->name, vp->name_length);
      else
	strcpy(buf, "(none)");
      fprintf(stdout, "%s: %s: %s\n", sp->peername, buf, snmp_errstring(pdu->errstat));
    }
    return 1;
  case STAT_TIMEOUT:
    fprintf(stdout, "%s: Timeout\n", sp->peername);
    return 0;
  
  case STAT_ERROR:
    snmp_perror(sp->peername);
    return 0;
  }
  return 0;
}
Beispiel #13
0
/* TODO: Check if negative values wrap around. Problem: negative temperatures. */
static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
    double scale, double shift,
    const char *host_name, const char *data_name)
{
  value_t ret;
  uint64_t tmp_unsigned = 0;
  int64_t tmp_signed = 0;
  _Bool defined = 1;
  /* Set to true when the original SNMP type appears to have been signed. */
  _Bool prefer_signed = 0;

  if ((vl->type == ASN_INTEGER)
      || (vl->type == ASN_UINTEGER)
      || (vl->type == ASN_COUNTER)
#ifdef ASN_TIMETICKS
      || (vl->type == ASN_TIMETICKS)
#endif
      || (vl->type == ASN_GAUGE))
  {
    tmp_unsigned = (uint32_t) *vl->val.integer;
    tmp_signed = (int32_t) *vl->val.integer;

    if (vl->type == ASN_INTEGER)
      prefer_signed = 1;

    DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned);
  }
  else if (vl->type == ASN_COUNTER64)
  {
    tmp_unsigned = (uint32_t) vl->val.counter64->high;
    tmp_unsigned = tmp_unsigned << 32;
    tmp_unsigned += (uint32_t) vl->val.counter64->low;
    tmp_signed = (int64_t) tmp_unsigned;
    DEBUG ("snmp plugin: Parsed int64 value is %"PRIu64".", tmp_unsigned);
  }
  else if (vl->type == ASN_OCTET_STR)
  {
    /* We'll handle this later.. */
  }
  else
  {
    char oid_buffer[1024];

    memset (oid_buffer, 0, sizeof (oid_buffer));
    snprint_objid (oid_buffer, sizeof (oid_buffer) - 1,
        vl->name, vl->name_length);

#ifdef ASN_NULL
    if (vl->type == ASN_NULL)
      INFO ("snmp plugin: OID \"%s\" is undefined (type ASN_NULL)",
          oid_buffer);
    else
#endif
      WARNING ("snmp plugin: I don't know the ASN type #%i "
               "(OID: \"%s\", data block \"%s\", host block \"%s\")",
          (int) vl->type, oid_buffer,
          (data_name != NULL) ? data_name : "UNKNOWN",
          (host_name != NULL) ? host_name : "UNKNOWN");

    defined = 0;
  }

  if (vl->type == ASN_OCTET_STR)
  {
    int status = -1;

    if (vl->val.string != NULL)
    {
      char string[64];
      size_t string_length;

      string_length = sizeof (string) - 1;
      if (vl->val_len < string_length)
        string_length = vl->val_len;

      /* The strings we get from the Net-SNMP library may not be null
       * terminated. That is why we're using `memcpy' here and not `strcpy'.
       * `string_length' is set to `vl->val_len' which holds the length of the
       * string.  -octo */
      memcpy (string, vl->val.string, string_length);
      string[string_length] = 0;

      status = parse_value (string, &ret, type);
      if (status != 0)
      {
        ERROR ("snmp plugin: host %s: csnmp_value_list_to_value: Parsing string as %s failed: %s",
            (host_name != NULL) ? host_name : "UNKNOWN",
            DS_TYPE_TO_STRING (type), string);
      }
    }

    if (status != 0)
    {
      switch (type)
      {
        case DS_TYPE_COUNTER:
        case DS_TYPE_DERIVE:
        case DS_TYPE_ABSOLUTE:
          memset (&ret, 0, sizeof (ret));
          break;

        case DS_TYPE_GAUGE:
          ret.gauge = NAN;
          break;

        default:
          ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown "
              "data source type: %i.", type);
          ret.gauge = NAN;
      }
    }
  } /* if (vl->type == ASN_OCTET_STR) */
  else if (type == DS_TYPE_COUNTER)
  {
    ret.counter = tmp_unsigned;
  }
  else if (type == DS_TYPE_GAUGE)
  {
    if (!defined)
      ret.gauge = NAN;
    else if (prefer_signed)
      ret.gauge = (scale * tmp_signed) + shift;
    else
      ret.gauge = (scale * tmp_unsigned) + shift;
  }
  else if (type == DS_TYPE_DERIVE)
  {
    if (prefer_signed)
      ret.derive = (derive_t) tmp_signed;
    else
      ret.derive = (derive_t) tmp_unsigned;
  }
  else if (type == DS_TYPE_ABSOLUTE)
  {
    ret.absolute = (absolute_t) tmp_unsigned;
  }
  else
  {
    ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown data source "
        "type: %i.", type);
    ret.gauge = NAN;
  }

  return (ret);
} /* value_t csnmp_value_list_to_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'                                     *
 *                                                                            *
 * Author:                                                                    *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	snmp_get_index(struct snmp_session *ss, DC_ITEM *item, const char *OID, const char *value,
		int *idx, char *err, int bulk)
{
	const char		*__function_name = "snmp_get_index";
	oid			anOID[MAX_OID_LEN], rootOID[MAX_OID_LEN];
	size_t			anOID_len = MAX_OID_LEN, rootOID_len = MAX_OID_LEN;
	char			strval[MAX_STRING_LEN], *strval_dyn, snmp_oid[MAX_STRING_LEN], *error;
	int			status, running, ret = NOTSUPPORTED;
	struct snmp_pdu		*pdu, *response;
	struct variable_list	*vars;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() oid:'%s' value:'%s' bulk:%d", __function_name, OID, value, bulk);

	*idx = 0;
	*err = '\0';

	/* 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 (1 == running)
	{
		pdu = snmp_pdu_create(bulk ? SNMP_MSG_GETNEXT : SNMP_MSG_GET);	/* 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);
		zabbix_log(LOG_LEVEL_DEBUG, "%s() snmp_synch_response():%d", __function_name, status);

		/* process response */
		if (STAT_SUCCESS == status && SNMP_ERR_NOERROR == response->errstat)
		{
			for (vars = response->variables; vars && running; vars = vars->next_variable)
			{
				/* verify if we are in the same subtree */
				if (vars->name_length < rootOID_len ||
						0 != memcmp(rootOID, vars->name, rootOID_len * sizeof(oid)))
				{
					/* not part of this subtree */
					zbx_snprintf(err, MAX_STRING_LEN, "NOT FOUND: %s[%s]", OID, value);
					ret = NOTSUPPORTED;
					running = 0;
				}
				else
				{
					/* verify if OIDs are increasing */
					if (SNMP_ENDOFMIBVIEW != vars->type && SNMP_NOSUCHOBJECT != vars->type &&
							SNMP_NOSUCHINSTANCE != vars->type)
					{
						/* not an exception value */
						if (0 <= snmp_oid_compare(anOID, anOID_len, vars->name, vars->name_length))
						{
							zbx_snprintf(err, MAX_STRING_LEN, "OID not increasing.");
							ret = NOTSUPPORTED;
							running = 0;
						}

						if (ASN_OCTET_STR == vars->type)
						{
							if (NULL == (strval_dyn = snmp_get_octet_string(vars)))
							{
								zbx_strlcpy(err, "out of memory", MAX_STRING_LEN);
								ret = NOTSUPPORTED;
								running = 0;
							}
							else
							{
								strscpy(strval, strval_dyn);
								zbx_free(strval_dyn);
							}
						}
#ifdef OPAQUE_SPECIAL_TYPES
						else if (ASN_UINTEGER == vars->type || ASN_COUNTER == vars->type ||
								ASN_TIMETICKS == vars->type ||
								ASN_GAUGE == vars->type ||
								ASN_UNSIGNED64 == vars->type)
#else
						else if (ASN_UINTEGER == vars->type || ASN_COUNTER == vars->type ||
								ASN_TIMETICKS == vars->type || ASN_GAUGE == vars->type)
#endif
						{
							zbx_snprintf(strval, sizeof(strval), "%u", *vars->val.integer);
						}
						else if (ASN_COUNTER64 == vars->type)
						{
							zbx_snprintf(strval, sizeof(strval), ZBX_FS_UI64,
									(((zbx_uint64_t)vars->val.counter64->high) << 32) +
									(zbx_uint64_t)vars->val.counter64->low);
						}
#ifdef OPAQUE_SPECIAL_TYPES
						else if (ASN_INTEGER == vars->type || ASN_INTEGER64 == vars->type)
#else
						else if (ASN_INTEGER == vars->type)
#endif
						{
							zbx_snprintf(strval, sizeof(strval), "%d", *vars->val.integer);
						}
						else if (ASN_IPADDRESS == vars->type)
						{
							zbx_snprintf(strval, sizeof(strval), "%d.%d.%d.%d",
									vars->val.string[0],
									vars->val.string[1],
									vars->val.string[2],
									vars->val.string[3]);
						}
						else
						{
							error = zbx_get_snmp_type_error(vars->type);
							memset(snmp_oid, '\0', sizeof(snmp_oid));
							snprint_objid(snmp_oid, sizeof(snmp_oid) - 1,
									vars->name, vars->name_length);
							zabbix_log(LOG_LEVEL_DEBUG, "OID \"%s\": %s", snmp_oid, error);
							zbx_free(error);
						}

						if (0 == strcmp(value, strval))
						{
							*idx = vars->name[vars->name_length - 1];
							zabbix_log(LOG_LEVEL_DEBUG, "index found: %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, "exception value found");
						ret = NOTSUPPORTED;
						running = 0;
					}
				}
			}
		}
		else
		{
Beispiel #15
0
///////////////////////////////////////////////////////////////
/// 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;
}
Beispiel #16
0
/*
 * response handler
 */
int snmpAsyncResponse(int operation, struct snmp_session *sp, int reqid,
		    struct snmp_pdu *pdu, void *magic)
{
	char buf[RESULTSIZE];
	tSession *host = (tSession *)magic;
	struct snmp_pdu *req;
	tOid *oid;

	oid = &host->oidList.oid[host->current_oid];

	if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
		if (oid->doWalk) {
			if (pdu->variables->name_length >= oid->OidLen &&
				memcmp(pdu->variables->name, oid->Oid, oid->OidLen * sizeof(oid))==0 &&
				pdu->variables->type != SNMP_ENDOFMIBVIEW &&
				pdu->variables->type != SNMP_NOSUCHOBJECT &&
				pdu->variables->type != SNMP_NOSUCHINSTANCE) {

				snprint_objid(buf, RESULTSIZE, pdu->variables->name, pdu->variables->name_length);
				if (strcmp(buf, oid->currentName) == 0) {
					syslog(LOG_ERR, "snmpAsyncResponse: %s: oid %s not increasing", sp->peername, buf);
					snmpActiveHosts--;
					return 1;
				}
				strcpy(oid->currentName, buf);

				oid->resultWalkCount++;
				oid->resultWalk = (char**) realloc(oid->resultWalk, oid->resultWalkCount * sizeof(char*));
				if (snmpStoreResult(host, pdu, &oid->resultWalk[oid->resultWalkCount-1])) {
					req = snmp_pdu_create(SNMP_MSG_GETNEXT);
					snprint_objid(buf, RESULTSIZE, pdu->variables->name, pdu->variables->name_length);
					snmp_add_null_var(req, pdu->variables->name, pdu->variables->name_length);
					if (snmp_send(host->sess, req))
						return 1;
					else {
						syslog(LOG_ERR, "snmpAsyncResponse: snmp_send failed for: %s", sp->peername);
						snmp_free_pdu(req);
					}
				} else {
					oid->resultWalkCount--;
					oid->resultWalk = (char**) realloc(oid->resultWalk, oid->resultWalkCount * sizeof(char*));
					storeEmptyResult(host);
				}
			}
		} else {
			if (!snmpStoreResult(host, pdu, &oid->result)) {
				storeEmptyResult(host);
			}
		}
		if (host->current_oid < host->oidList.count-1) {
			host->current_oid++;
			req = snmp_pdu_create(host->oidList.oid[host->current_oid].doWalk ? SNMP_MSG_GETNEXT : SNMP_MSG_GET);
			snmp_add_null_var(req, host->oidList.oid[host->current_oid].Oid, host->oidList.oid[host->current_oid].OidLen);
			if (snmp_send(host->sess, req))
				return 1;
			else {
				syslog(LOG_ERR, "snmpAsyncResponse: snmp_send failed for: %s", sp->peername);
				snmp_free_pdu(req);
			}
		}
	} else {
		syslog(LOG_DEBUG, "snmpAsyncResponse: %s: Timeout", sp->peername);
		storeEmptyResult(host);
	}

	/* something went wrong (or end of variables) 
 	* this host not active any more
 	*/
	snmpActiveHosts--;
	return 1;
}