Exemple #1
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);
}
Exemple #2
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;
}