Пример #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;
}
void setVariable(uint8 *var_val,uint8 var_val_type,int var_val_len,uint8  *statP,int statLen)
{
	int 	buffersize = 1000;

	switch(var_val_type){
		case ASN_INTEGER:
		case COUNTER:
		case GAUGE:
		case TIMETICKS:
			asn_parse_int(var_val, &buffersize, &var_val_type, (long *)statP, statLen);
			break;
		case ASN_OCTET_STRING:
		case IPADDRESS:
		case OPAQUE:
			asn_parse_string(var_val, &buffersize, &var_val_type, statP, &statLen);
			break;
		case ASN_OBJECT_ID:
			asn_parse_objid(var_val, &buffersize, &var_val_type, (oid *)statP, &statLen);
			break;
	}
}
Пример #3
0
u_char *
snmp_parse_var_op(u_char *data,
                  oid *var_name,
                  size_t *var_name_len,
                  u_char *var_val_type,
                  size_t *var_val_len,
                  u_char **var_val,
                  size_t *listlength)
{
    u_char	    var_op_type;
    size_t		    var_op_len = *listlength;
    u_char	    *var_op_start = data;

    data = asn_parse_sequence(data, &var_op_len, &var_op_type,
                              (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op");
    if (data == NULL) {
        /* msg detail is set */
        return NULL;
    }
    data = asn_parse_objid(data, &var_op_len, &var_op_type, var_name, var_name_len);
    if (data == NULL) {
        ERROR_MSG("No OID for variable");
        return NULL;
    }
    if (var_op_type != (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
        return NULL;
    *var_val = data;	/* save pointer to this object */
    /* find out what type of object this is */
    data = asn_parse_header(data, &var_op_len, var_val_type);
    if (data == NULL) {
        ERROR_MSG("No header for value");
        return NULL;
    }
    /* XXX no check for type! */
    *var_val_len = var_op_len;
    data += var_op_len;
    *listlength -= (int)(data - var_op_start);
    return data;
}
Пример #4
0
static void
setVariable(u_char *var_val,
	    u_char var_val_type,
	    size_t var_val_len,
	    u_char *statP,
	    size_t statLen)
{
    size_t buffersize = 1000;

    switch(var_val_type){
	case ASN_INTEGER:
	    asn_parse_int(var_val, &buffersize, &var_val_type, (long *)statP, statLen);
	    break;
	case ASN_COUNTER:
	case ASN_GAUGE:
	case ASN_TIMETICKS:
	    asn_parse_unsigned_int(var_val, &buffersize, &var_val_type, (u_long *)statP, statLen);
	    break;
	case ASN_COUNTER64:
	    asn_parse_unsigned_int64(var_val, &buffersize, &var_val_type,
				     (struct counter64 *)statP, statLen);
	    break;
	case ASN_OCTET_STR:
	case ASN_IPADDRESS:
	case ASN_OPAQUE:
	case ASN_NSAP:
	    asn_parse_string(var_val, &buffersize, &var_val_type, statP, &statLen);
	    break;
	case ASN_OBJECT_ID:
	    asn_parse_objid(var_val, &buffersize, &var_val_type, (oid *)statP, &statLen);
	    break;
	case ASN_BIT_STR:
	    asn_parse_bitstring(var_val, &buffersize, &var_val_type, statP, &statLen);
	    break;
    }
}
Пример #5
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;
}
Пример #6
0
/* Parse all Vars from the buffer */
u_char *snmp_var_DecodeVarBind(u_char *Buffer, int *BufLen,
			       struct variable_list **VarP,
			       int Version)
{
  struct variable_list *Var, **VarLastP;
  u_char *bufp, *tmp;
  u_char  VarBindType;
  u_char *DataPtr;
  int     DataLen;
  oid TmpBuf[MAX_NAME_LEN];

  int AllVarLen = *BufLen;
  int ThisVarLen = 0;

  VarLastP = VarP;
#ifdef DEBUG_VARS_DECODE
  printf("VARS: Decoding buffer of length %d\n", *BufLen);
#endif

  /* Now parse the variables */
  bufp = asn_parse_header(Buffer, &AllVarLen, &VarBindType);
  if (bufp == NULL)
    ASN_PARSE_ERROR(NULL);

  if (VarBindType != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) {
      snmp_set_api_error(SNMPERR_PDU_PARSE);
      ASN_PARSE_ERROR(NULL);
  }

#ifdef DEBUG_VARS_DECODE
  printf("VARS: All Variable length %d\n", AllVarLen);
#endif

  /* We know how long the variable list is.  Parse it. */
  while ((int)AllVarLen > 0) {

    /* Create a new variable */
    Var = snmp_var_new(NULL, MAX_NAME_LEN);
    if (Var == NULL)
      return(NULL);
    
    /* Parse the header to find out the length of this variable. */
    ThisVarLen = AllVarLen;
    tmp = asn_parse_header(bufp, &ThisVarLen, &VarBindType);
    if (tmp == NULL)
      ASN_PARSE_ERROR(NULL);

    /* Now that we know the length , figure out how it relates to 
     * the entire variable list
     */
    AllVarLen = AllVarLen - (ThisVarLen + (tmp - bufp));
    bufp = tmp;

    /* Is it valid? */
    if (VarBindType != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) {
      snmp_set_api_error(SNMPERR_PDU_PARSE);
      ASN_PARSE_ERROR(NULL);
    }

#ifdef DEBUG_VARS_DECODE
    printf("VARS: Header type 0x%x (%d bytes left)\n", VarBindType, ThisVarLen);
#endif

    /* Parse the OBJID */
    bufp = asn_parse_objid(bufp, &ThisVarLen, &VarBindType, 
			   Var->name, &(Var->name_length));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

    if (VarBindType != (u_char)(ASN_UNIVERSAL | 
				ASN_PRIMITIVE | 
				ASN_OBJECT_ID)) {
      snmp_set_api_error(SNMPERR_PDU_PARSE);
      ASN_PARSE_ERROR(NULL);
    }

#ifdef DEBUG_VARS_DECODE
    printf("VARS: Decoded OBJID (%d bytes). (%d bytes left)\n", 
	   Var->name_length, ThisVarLen);
#endif

    /* Keep a pointer to this object */
    DataPtr = bufp;
    DataLen = ThisVarLen;

    /* find out type of object */
    bufp = asn_parse_header(bufp, &ThisVarLen, &(Var->type));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);
    ThisVarLen = DataLen;

#ifdef DEBUG_VARS_DECODE
    printf("VARS: Data type %d\n", Var->type);
#endif

    /* Parse the type */
    
    switch((short)Var->type){

    case ASN_INTEGER:
      Var->val.integer = (int *)malloc(sizeof(int));
      if (Var->val.integer == NULL) {
	snmp_set_api_error(SNMPERR_OS_ERR);
	return(NULL);
      }
      Var->val_len = sizeof(int);
      bufp = asn_parse_int(DataPtr, &ThisVarLen, 
			   &Var->type, (int *)Var->val.integer, 
			   Var->val_len);
#ifdef DEBUG_VARS_DECODE
      printf("VARS: Decoded integer '%d' (%d bytes left)\n",
	     *(Var->val.integer), ThisVarLen);
#endif
      break;

    case SMI_COUNTER32:
    case SMI_GAUGE32:
      /*  case SMI_UNSIGNED32: */
    case SMI_TIMETICKS:
      Var->val.integer = (int *)malloc(sizeof(u_int));
      if (Var->val.integer == NULL) {
	snmp_set_api_error(SNMPERR_OS_ERR);
	return(NULL);
      }
      Var->val_len = sizeof(u_int);
      bufp = asn_parse_unsigned_int(DataPtr, &ThisVarLen, 
				    &Var->type, (u_int *)Var->val.integer, 
				    Var->val_len);
#ifdef DEBUG_VARS_DECODE
      printf("VARS: Decoded timeticks '%d' (%d bytes left)\n",
	     *(Var->val.integer), ThisVarLen);
#endif
      break;

    case ASN_OCTET_STR:
    case SMI_IPADDRESS:
    case SMI_OPAQUE:
      Var->val_len = *&ThisVarLen; /* String is this at most */
      Var->val.string = (u_char *)malloc((unsigned)Var->val_len);
      if (Var->val.string == NULL) {
	snmp_set_api_error(SNMPERR_OS_ERR);
	return(NULL);
      }
      bufp = asn_parse_string(DataPtr, &ThisVarLen, 
			      &Var->type, Var->val.string, 
			      &Var->val_len);
#ifdef DEBUG_VARS_DECODE
      printf("VARS: Decoded string '%s' (length %d) (%d bytes left)\n",
	     (Var->val.string), Var->val_len, ThisVarLen);
#endif
      break;
         
    case ASN_OBJECT_ID:
      Var->val_len = MAX_NAME_LEN;
      bufp = asn_parse_objid(DataPtr, &ThisVarLen, 
			     &Var->type, TmpBuf, &Var->val_len);
      Var->val_len *= sizeof(oid);
      Var->val.objid = (oid *)malloc((unsigned)Var->val_len);
      if (Var->val.integer == NULL) {
	snmp_set_api_error(SNMPERR_OS_ERR);
	return(NULL);
      }
      /* Only copy if we successfully decoded something */
      if (bufp) {
	memcpy((char *)Var->val.objid, (char *)TmpBuf, Var->val_len);
      }
#ifdef DEBUG_VARS_DECODE
      printf("VARS: Decoded OBJID (length %d) (%d bytes left)\n",
	      Var->val_len, ThisVarLen);
#endif
      break;

    case ASN_NULL:
    case SMI_NOSUCHINSTANCE:
    case SMI_NOSUCHOBJECT:
    case SMI_ENDOFMIBVIEW:
      Var->val_len   = 0;
      Var->val.objid = NULL;
      bufp = asn_parse_null(DataPtr, &ThisVarLen, &Var->type);
#ifdef DEBUG_VARS_DECODE
      printf("VARS: Decoded ASN_NULL (length %d) (%d bytes left)\n",
	     Var->val_len, ThisVarLen);
#endif
      break;

    case SMI_COUNTER64:
#ifdef STDERR_OUTPUT
      fprintf(stderr, WIDE("Unable to parse type SMI_COUNTER64!\n"));
#endif
      snmp_set_api_error(SNMPERR_UNSUPPORTED_TYPE);
      return(NULL);
      break;

    default:
#ifdef STDERR_OUTPUT
      fprintf(stderr, WIDE("bad type returned (%x)\n"), Var->type);
#endif
      snmp_set_api_error(SNMPERR_PDU_PARSE);
      return(NULL);
      break;
    } /* End of var type switch */

    /* Why is this here? XXXXX */
    if (bufp == NULL)
      return(NULL);

#ifdef DEBUG_VARS_DECODE
    printf("VARS: Adding to list of decoded variables.  (%d bytes remain.)\n", AllVarLen);
#endif
    /* Add variable to the list */
    *VarLastP = Var;
    VarLastP = &(Var->next_variable);
  }

  return(bufp);
}
Пример #7
0
char *   
snmp_parse_trap(u_char * trapdata,  /* IN - actual trap data from packet */
   unsigned    datalen,             /* IN - length of trapdata */
   struct trap_info *   trapInfo)   /* IN/OUT - struct to fill in */
{
   u_char * more;    /* pointer to next unparsed PDU data */
   u_char * nextVar; /* pointer to next unparsed TRAP variable */
   unsigned   left;  /* length of more */
   long     version; /* SNMP version, always v1 */
   u_char   type;    /* data types for checking */
   u_char * varValPtr;
   int   vars_in_struct;
   struct trapVar *  vars; /* trap variables data structures */
   u_long   trapType;
   unsigned length;  /* scratch for passing to asn1 */

   /* do some basic setup of the passed data structures */
   vars_in_struct = trapInfo->trapVars;
   trapInfo->trapVars = 0;       /* bump later if vars are present */

   left = datalen;
   more = snmp_auth_parse(trapdata, &left, (u_char*)trapInfo->community, 
    (unsigned*)&trapInfo->commLen, &version);
   if (!more)
      return "community parse";

   more = asn_parse_header(more, &left, &type);
   if (!more || type != TRP_REQ_MSG)
      return "trap pdu header";

   more = asn_parse_objid(more, &left, &type, &trapInfo->objId[0],
    (unsigned*)&trapInfo->objLen);
   if (!more || type != ASN_OBJECT_ID)
      return "sys ObjId";

   length = 4;       /* number of bytes in IP address buffer */
   more = asn_parse_string(more, &left, &type, 
    (u_char*)(&trapInfo->agent_ip), &length);

   if (!more || type != IPADDRESS)
      return "agent's IP address";

   more = asn_parse_int(more, &left, &type, (long*)&trapType, sizeof(long));
   if (!more || type != ASN_INTEGER || trapType > 6)
      return "trap type";
   trapInfo->trapType = trapType;

   more = asn_parse_int(more, &left, &type, (long*)&trapType, sizeof(long));
   if (!more || type != ASN_INTEGER)
      return "specific type";
   trapInfo->trapSpecific = trapType;

   more = asn_parse_int(more, &left, &type, (long*)&trapInfo->time, sizeof(long));
   if (!more || type != TIMETICKS)
      return "timestamp";

   if (!left)     /* no variables in trap ? */
      return NULL;

   /* rest of packet is a sequence of variables */
   more = asn_parse_header(more, &left, &type);    /* strip off leading SEQ */
   if (!more || type != SEQUENCE)
      return "trap vars header";

   vars = trapInfo->vars;     /* set pointer array to receive variables data */

   while (left)   /* keep parsing & counting vars as long as there's data */
   {
      /* extract variable info for this var */
      length = left;    /* number of valid bytes left in packet buffer */
      varNameLen = MAX_OID_LEN ; /* define the max size of varName */
      nextVar = snmp_parse_var_op(more, varName, &varNameLen, &varType,
       &varLen, &varValPtr, &left);

      if (!nextVar)     /* quit if parse failed */
         return ("var_op header");

      /* extract the variable's value; pointed to by varValPtr: */
      length -= more - nextVar;     /* deduct size of header -> max. length of var */
      switch (varType)
      {
      case ASN_INTEGER:
      case GAUGE:
      case COUNTER:
      case TIMETICKS:
         varLen = sizeof(long);     /* size required by asn_parse_int() */
         nextVar = asn_parse_int(varValPtr, &length, &varType,
          (long *)(&varVal[0]), varLen);
         break;
      case ASN_OCTET_STR:
      case IPADDRESS:
      case OPAQUE:
         varLen = MAX_TRAP_VAR;
         nextVar = asn_parse_string(varValPtr, &length, &varType,
          varVal, &varLen);
         break;
      case ASN_OBJECT_ID:
         varLen = MAX_TRAP_VAR;
         nextVar = asn_parse_objid(varValPtr, &length, &varType,
          (oid *)(&varVal[0]), &varLen);
         break;
      case ASN_NULL:
         nextVar = asn_parse_null(varValPtr, &length, &varType);
         break;
         default:
         SNMPERROR("wrong type");
         return NULL;
      }

      if (!nextVar)
         return("variable");

      /* if another trap variable info slot is available, fill it in */
      if (trapInfo->trapVars <= vars_in_struct)
      {
         oidcpy(vars->varName, varName, varNameLen);
         if (vars->varBufLen <= varLen)   /* need to truncate? */
            vars->varValLen = vars->varBufLen-1;
         else     /* we have room for the full variable data field */
            vars->varValLen = varLen;
         MEMCPY(vars->varBuf, varVal, vars->varValLen);
         vars->varNameLen = varNameLen;
         vars->varType = varType;
         vars++;     /* point to next variable info structure */
      }
      trapInfo->trapVars++;      /* another var */
      more = nextVar;      /* bump pointer to pdu */
   }
   return NULL;
}
Пример #8
0
/* FUNCTION: snmp_print_value()
 * Print the value into a buffer and return the buffer. 
 * 
 * Buffer is static to this function.
 *
 * PARAM1: u_char * var_val          - ASN.1 encoded value
 * PARAM1: u_char  var_val_type      - ASN.1 type of value
 *
 * RETURNS: 
 */
char *
snmp_print_value(u_char *var_val, u_char var_val_type)
{
   /* set an abritrarily large buffer parm for asn1 parsing. 
    * We don't use the returned value for this anyway.
    */
   unsigned   asn_buf_size = 1000;     /*  */
   unsigned   set_var_size = _MAX_PATH;  /* bytes in field to set */
   long tmpvalue=0;

   static char datastr[_MAX_PATH];
   static char datatmp[_MAX_PATH];
   static oid  dataoid[_MAX_PATH];

   datastr[0]=0;  /* null terminate */

   if (!var_val)
      return datastr;

   switch (var_val_type)
   {
   case ASN_INTEGER:
   case COUNTER:
   case GAUGE: /* valid for GAUGE32 and UNSIGNED32 too */
   case TIMETICKS:
      if (!asn_parse_int(var_val, &asn_buf_size, &var_val_type, 
         &tmpvalue, sizeof(long)))
      {
         break;
      }
      sprintf(datastr,"%ld",tmpvalue) ;

      break;
   case ASN_BIT_STR:
      if (!asn_parse_bits(var_val, &asn_buf_size, &var_val_type, 
         (unsigned char *)datatmp, &set_var_size))
      {
         break;
      }
      strcpy(datastr,datatmp);
         break;
   case ASN_OCTET_STR:
   case IPADDRESS:
   case OPAQUE:
      if (!asn_parse_string(var_val, &asn_buf_size, &var_val_type, 
         (unsigned char *)datatmp, &set_var_size))
      {
         break;
      }
      *(datatmp + set_var_size) = '\0'; /* null terminate the strings */
      strcpy(datastr,datatmp);
      break;
   case ASN_OBJECT_ID:
      if (!asn_parse_objid(var_val, &asn_buf_size, &var_val_type, 
         dataoid, &set_var_size))
      {
         break;
      }
      strcpy(datastr, print_oid(dataoid, set_var_size));
      break;
   case ASN_NULL:
      strcpy (datastr, "<NULL>");
      break;
   }

   return datastr;
}
//*
//*---------------------------------------------------------------------------------
//* Function Name: snmp_parse_var
//* Description  : Get variables by parsing snmp message. The message is decoded in
//*        BER deconding rules.
//* Return Value : Pointer of decoding variables
//* Calling To   : asn_parse_header, asn_parse_objid, asn_parse_int,
//*        asn_parse_string
//* Called By    : snmp_parse
//*---------------------------------------------------------------------------------
//*
variable_list   *snmp_parse_var(uint8 *data,int length)
{
    uint8                       type;
    variable_list               vh, *vp;
    uint8                       *varBindP;
    int                         varBind_len;
    uint8                       objId[SNMP_MAX_NAME_LEN];
    uint8                       *varVal;
    int                         parse_ok;

    data = asn_parse_header(data, &length, &type);
    if ((data == NULL) || (type != (uint8) (ASN_SEQUENCE | ASN_CONSTRUCTOR)))
        return ( NULL );

    vh.next  = NULL;
    vp       = &vh;
    varBindP = data;
    parse_ok = TRUE;

    while (length > 0) {
        varBind_len = length;

        vp->next = (variable_list *) malloc(sizeof(variable_list));
        if (vp->next == NULL) {
            parse_ok = FALSE;
            break;      //---SNMP: Memory allocation error on 'snmp_parse_var'.
        }
        else {
            vp             = vp->next;
            vp->next       = NULL;
            vp->name       = NULL;
            vp->name_len   = SNMP_MAX_NAME_LEN;
            vp->val.string = NULL;
        }

        varBindP = asn_parse_header(varBindP, &varBind_len, &type);
        if ((varBindP == NULL) ||
            (type != (uint8) (ASN_SEQUENCE | ASN_CONSTRUCTOR))) {
            parse_ok = FALSE;
            break;
        }

        //*
        //*  Parse variable bind name.
        //*
        varBindP = asn_parse_objid(varBindP, &varBind_len, &type, objId, &vp->name_len);
        if ((varBindP == NULL) ||
            (type != (uint8) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))) {
            parse_ok = FALSE;
            break;
        }

        vp->name = (oid *) malloc((unsigned) vp->name_len * sizeof(oid));
        if (vp->name == NULL) {
            parse_ok = FALSE;
            break;      //-----SNMP: Memory alloc error on 'snmp_parse_var'.
        }
        else {
            bcopy((char *) objId, (char *) vp->name, vp->name_len * sizeof(oid));
        }

        //*
        //*  Parse variable bind value.
        //*
        varVal   = varBindP;
        varBindP = asn_parse_header(varBindP, &varBind_len, &vp->type);
        if (varBindP == NULL) {
            parse_ok = FALSE;
            break;
        }
        else {
            vp->val_len = varBind_len;
            varBindP    = varBindP + varBind_len;  // skip value body to next variable
            length      = length - (int)(varBindP - data);
            data        = varBindP;
            varBind_len = SNMP_MAX_LEN;
        }

        switch (vp->type) {
            case ASN_INTEGER:
            case COUNTER:
            case GAUGE:
            case TIMETICKS:
                 vp->val_len     = sizeof(long);   // support long intger only
                 vp->val.integer = (long *) malloc(vp->val_len);
                 if (vp->val.integer == NULL) {
                        parse_ok = FALSE;
                     break;  //---SNMP:Memory alloc error on 'snmp_parse_var'.
                 }
                 asn_parse_int(varVal, &varBind_len, &vp->type,
                           (long *) vp->val.integer, vp->val_len);
                 break;
            case ASN_OCTET_STRING:
            case IPADDRESS:
            case OPAQUE:
                 vp->val.string = (uint8 *) malloc(vp->val_len);
                 if (vp->val.string == NULL) {
                        parse_ok = FALSE;
                        break;  //----SNMP:Memory alloc error on 'snmp_parse_var'.
                 }
                 asn_parse_string(varVal, &varBind_len, &vp->type,
                           vp->val.string, &vp->val_len);
                 break;
            case ASN_OBJECT_ID:
                 vp->val_len = SNMP_MAX_NAME_LEN;
                 asn_parse_objid(varVal, &varBind_len, &vp->type, objId, &vp->val_len);
                 vp->val_len = vp->val_len * sizeof(oid);
                 vp->val.objid = (oid *) malloc((unsigned) vp->val_len);
                 if (vp->val.objid == NULL) {
                        parse_ok = FALSE;
                     break;   //---SNMP:Memory alloc error on 'snmp_parse_var'.
                 }
                 bcopy((char *) objId, (char *) vp->val.objid, vp->val_len);
                 break;
            case ASN_NULL:
                 break;
            default:
                 parse_ok = FALSE;  //-----Warning: Bad type received.
                 break;
        }

        if ( ! parse_ok ) break;
    }

    if ( parse_ok ) {
        return( vh.next );
    }
    else {
        while ( vh.next ) {
            vp      = vh.next;
            vh.next = vp->next;
            if (vp->name != NULL) free((char *) vp->name);
            if (vp->val.string != NULL) free((char *) vp->val.string);
            free((char *) vp);
        }
        return ( NULL );
    }
}
Пример #10
0
/* Decodes PDU from Packet into PDU.
 *
 * Returns a pointer to the next byte of the packet, which is where the
 * Variable Bindings start.
 */
u_char *snmp_pdu_decode(u_char *Packet,       /* data */
			int *Length,          /* &length */
			struct snmp_pdu *PDU) /* pdu */
{
  u_char *bufp;
  u_char PDUType;
  int four;
  u_char ASNType;
  oid objid[MAX_NAME_LEN];

  bufp = asn_parse_header(Packet, Length, &PDUType);
  if (bufp == NULL)
    ASN_PARSE_ERROR(NULL);

#ifdef DEBUG_PDU_DECODE
  printf("PDU Type: %d\n", PDUType);
#endif

  PDU->command = PDUType;
  switch (PDUType) {

  case TRP_REQ_MSG:

    /* SNMPv1 Trap Message */

    /* enterprise */
    PDU->enterprise_length = MAX_NAME_LEN;
    bufp = asn_parse_objid(bufp, Length,
			   &ASNType, objid, &PDU->enterprise_length);
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

    PDU->enterprise = (oid *)malloc(PDU->enterprise_length * sizeof(oid));
    if (PDU->enterprise == NULL) {
      snmp_set_api_error(SNMPERR_OS_ERR);
      return(NULL);
    }

    memcpy((char *)PDU->enterprise, (char *)objid, 
	   PDU->enterprise_length * sizeof(oid));
	
    /* Agent-addr */
    four = 4;
    bufp = asn_parse_string(bufp, Length, 
			    &ASNType, 
			    (u_char *)&PDU->agent_addr.sin_addr.s_addr, 
			    &four);
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

    /* Generic trap */
    bufp = asn_parse_int(bufp, Length, 
			 &ASNType, 
			 (int *)&PDU->trap_type, 
			 sizeof(PDU->trap_type));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

    /* Specific Trap */
    bufp = asn_parse_int(bufp, Length, 
			 &ASNType, 
			 (int *)&PDU->specific_type, 
			 sizeof(PDU->specific_type));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

    /* Timestamp */
    bufp = asn_parse_unsigned_int(bufp, Length, 
				  &ASNType, 
				  &PDU->time, sizeof(PDU->time));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);
    break;

    /**********************************************************************/

  case SNMP_PDU_GETBULK:

    /* SNMPv2 Bulk Request */

    /* request id */
    bufp = asn_parse_int(bufp, Length, 
			 &ASNType, 
			 &PDU->reqid, sizeof(PDU->reqid));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

    /* non-repeaters */
    bufp = asn_parse_int(bufp, Length, 
			 &ASNType, 
			 &PDU->non_repeaters, sizeof(PDU->non_repeaters));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

    /* max-repetitions */
    bufp = asn_parse_int(bufp, Length, 
			 &ASNType, 
			 &PDU->max_repetitions, sizeof(PDU->max_repetitions));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

    break;
    /**********************************************************************/

  default:

    /* Normal PDU Encoding */

    /* request id */
    bufp = asn_parse_int(bufp, Length, 
			 &ASNType, 
			 &PDU->reqid, sizeof(PDU->reqid));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

#ifdef DEBUG_PDU_DECODE
    printf("PDU Request ID: %d\n", PDU->reqid);
#endif

    /* error status */
    bufp = asn_parse_int(bufp, Length, 
			 &ASNType, 
			 &PDU->errstat, sizeof(PDU->errstat));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

#ifdef DEBUG_PDU_DECODE
    printf("PDU Error Status: %d\n", PDU->errstat);
#endif

    /* error index */
    bufp = asn_parse_int(bufp, Length, 
			 &ASNType, 
			 &PDU->errindex, sizeof(PDU->errindex));
    if (bufp == NULL)
      ASN_PARSE_ERROR(NULL);

#ifdef DEBUG_PDU_DECODE
    printf("PDU Error Index: %d\n", PDU->errindex);
#endif

    break;
  }

  return(bufp);
}