Exemple #1
0
int snmp_preview(u_char *data, unsigned length, struct SnmpObjects *vbinds)
{
   int i = 0;       /* number of varbinds parsed */
   unsigned tmp;
   struct SnmpObject *obj; 
   vbinds->num=0;  /* number of varbinds present in vbinds */
   while (length)
   {
      /* parse the name, value pair */
      obj = &(vbinds->objs[i]);
      obj->namelen = MAX_NAME_LEN;
      data = snmp_parse_var_op(data, obj->name, &obj->namelen, 
         &obj->valuetype, &obj->valuelen, &obj->value, &length);
      if (data == NULL)
         return -1;
      /* obj->value points to ASN encoded value
       * - skip past "type" and "len" fields, so that "value"
       * points to received value.
       */
      tmp = data - obj->value;
      obj->value = asn_parse_header(obj->value, &tmp, &obj->valuetype);
      if (obj->value == NULL)
         return -1;
      i++;
      /* test which verifies that SET command contains valid VB ammount */
      if((i >= SNMP_MAX_OIDS) && (length > 0))  
         return -1 ;
   }
   vbinds->num=i;  /* number of varbinds present in vbinds */
   return 0;
}
Exemple #2
0
char *
smux_var (char *ptr, size_t len, oid objid[], size_t *objid_len,
          size_t *var_val_len,
          u_char *var_val_type,
          void **var_value)
{
  u_char type;
  u_char val_type;
  size_t val_len;
  u_char *val;

  if (debug_smux)
    zlog_debug ("SMUX var parse: len %ld", len);

  /* Parse header. */
  ptr = asn_parse_header (ptr, &len, &type);
  
  if (debug_smux)
    {
      zlog_debug ("SMUX var parse: type %d len %ld", type, len);
      zlog_debug ("SMUX var parse: type must be %d", 
		 (ASN_SEQUENCE | ASN_CONSTRUCTOR));
    }

  /* Parse var option. */
  *objid_len = MAX_OID_LEN;
  ptr = snmp_parse_var_op(ptr, objid, objid_len, &val_type, 
			  &val_len, &val, &len);

  if (var_val_len)
    *var_val_len = val_len;

  if (var_value)
    *var_value = (void*) val;

  if (var_val_type)
    *var_val_type = val_type;

  /* Requested object id length is objid_len. */
  if (debug_smux)
    smux_oid_dump ("Request OID", objid, *objid_len);

  if (debug_smux)
    zlog_debug ("SMUX val_type: %d", val_type);

  /* Check request value type. */
  if (debug_smux)
  switch (val_type)
    {
    case ASN_NULL:
      /* In case of SMUX_GET or SMUX_GET_NEXT val_type is set to
         ASN_NULL. */
      zlog_debug ("ASN_NULL");
      break;

    case ASN_INTEGER:
      zlog_debug ("ASN_INTEGER");
      break;
    case ASN_COUNTER:
    case ASN_GAUGE:
    case ASN_TIMETICKS:
    case ASN_UINTEGER:
      zlog_debug ("ASN_COUNTER");
      break;
    case ASN_COUNTER64:
      zlog_debug ("ASN_COUNTER64");
      break;
    case ASN_IPADDRESS:
      zlog_debug ("ASN_IPADDRESS");
      break;
    case ASN_OCTET_STR:
      zlog_debug ("ASN_OCTET_STR");
      break;
    case ASN_OPAQUE:
    case ASN_NSAP:
    case ASN_OBJECT_ID:
      zlog_debug ("ASN_OPAQUE");
      break;
    case SNMP_NOSUCHOBJECT:
      zlog_debug ("SNMP_NOSUCHOBJECT");
      break;
    case SNMP_NOSUCHINSTANCE:
      zlog_debug ("SNMP_NOSUCHINSTANCE");
      break;
    case SNMP_ENDOFMIBVIEW:
      zlog_debug ("SNMP_ENDOFMIBVIEW");
      break;
    case ASN_BIT_STR:
      zlog_debug ("ASN_BIT_STR");
      break;
    default:
      zlog_debug ("Unknown type");
      break;
    }
  return ptr;
}
Exemple #3
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;
}
//*
//* Parse_var_op_list goes through the list of variables and retrieves each one,
//* placing it's value in the output packet.  In the case of a set request,
//* if action is RESERVE, the value is just checked for correct type and
//* value, and resources may need to be reserved.  If the action is COMMIT,
//* the variable is set.  If the action is FREE, an error was discovered
//* somewhere in the previous RESERVE pass, so any reserved resources
//* should be FREE'd.
//* If any error occurs, an error code is returned.
//*
int
parse_var_op_list(
        snmp_session *session,
        uint8 *data,      //point to variable-binding of in-packet data
        int    length,     //in packet data length
        uint8 *out_data,  //point to variable-binding of out-packet data
        int    out_length, //out packet buffer length
        long   *index,     //error-index (output)
        int    msgtype,    //message type
        int    action      //???
)
{
        uint8  type;
        oid         var_name[SNMP_MAX_NAME_LEN];
        int         var_name_len, var_val_len;
        uint8  var_val_type, *var_val, statType;
        uint8 *statP;
        int         statLen;
        uint16  acl;
        int         (*write_method)();
        uint8  *headerP, *var_list_start;
        int         dummyLen;
#ifdef WEBADMIN
        int         dummyLen1;      // add -- By arius 5/17/2000
        uint8       *newpacket_end; // add -- By arius 5/17/2000
#endif WEBADMIN
        int         noSuchObject;
        int     (*WriteMethod)(int,uint8 *,uint8,int,uint8 *,oid *,int);
        int         err, exact;

//      if (msgtype== SET_REQ_MSG)      rw = SNMP_WRITE;
//  else rw = SNMP_READ;

        if (msgtype == GETNEXT_REQ_MSG) exact = FALSE;
        else exact = TRUE;

        //Parse variable-binging header
        data = asn_parse_header(data, &length, &type);

        if (data == NULL){
                ERROR("not enough space for varlist");
                return PARSE_ERROR;
        }
        if (type != (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR)){
                ERROR("wrong type");
                return PARSE_ERROR;
    }

        headerP = out_data;
        //Set Resp variable-binging header
    out_data = asn_build_sequence(out_data, &out_length,
                                (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), 0);

        if (out_data == NULL){
                ERROR("not enough space in output packet");
                return BUILD_ERROR;
        }

    var_list_start = out_data;

        *index = 1;
        while((int)length > 0){
                // parse the name, value pair
                var_name_len = SNMP_MAX_NAME_LEN;

                data = snmp_parse_var_op(data, var_name, &var_name_len, &var_val_type,
                                         &var_val_len, &var_val, (int *)&length);

                if (data == NULL)  return PARSE_ERROR;

                // now attempt to retrieve the variable on the local entity
                statP = getStatPtr(var_name, &var_name_len, &statType,
                           &statLen, &acl, exact,
                           &write_method, SNMP_VERSION_1, &noSuchObject,
                           (msgtype==SET_REQ_MSG?
                             (session->access & SNMP_ACCESS_WRITE):
                             (session->access & SNMP_ACCESS_READ)    )
                        );

                if (/* session->version == SNMP_VERSION_1 &&*/
                                    statP == NULL &&
                                    (msgtype != SET_REQ_MSG || !write_method))
                {
                        //** XXX: happens when running
                        //   XXX: snmpwalk localhost public .1
                        //   XXX: fix me some day.
                        //**
                        //** ERROR("warning: internal v1_error"); **
                        return SNMP_ERR_NOSUCHNAME;
                }

                // check if this variable is read-write (in the MIB sense).
                if( msgtype == SET_REQ_MSG && acl != RWRITE )
                        return SNMP_ERR_READONLY;
//          return session->version == SNMP_VERSION_1 ? SNMP_ERR_NOSUCHNAME : SNMP_ERR_NOTWRITABLE;

                //* Its bogus to check here on getnexts - the whole packet shouldn't
                //   be dumped - this should should be the loop in getStatPtr
                //   luckily no objects are set unreadable.  This can still be
                //  useful for sets to determine which are intrinsically writable

                if (msgtype== SET_REQ_MSG){
                        if (write_method == NULL){
                                if (statP != NULL){
                                        // see if the type and value is consistent with this entity's variable
                                        if (!goodValue(var_val_type, var_val_len, statType,statLen))
                                        {
//                                              if (session->version != SNMP_VERSION_1)
//                                                      return SNMP_ERR_WRONGTYPE; // poor approximation
//                                              else
                                                {
                                                        snmp_inbadvalues++;
                                                        return SNMP_ERR_BADVALUE;
                                                }
                                    }
                                    // actually do the set if necessary
                                        if (action == COMMIT)
                                                setVariable(var_val, var_val_type, var_val_len,statP, statLen);
                                } else {
//                                  if (session->version != SNMP_VERSION_1)
//                                              return SNMP_ERR_NOCREATION;
//                                  else
                                                return SNMP_ERR_NOSUCHNAME;
                                }
                        } else {
                                WriteMethod = (int (*)(int,uint8 *,uint8,int,uint8 *,oid *,int)) write_method;

                                err = (*WriteMethod)(action, var_val, var_val_type,
                                          var_val_len, statP, var_name,
                                          var_name_len);

                                //*
                                //* Map the SNMPv2 error codes to SNMPv1 error codes (RFC 2089).
                                //*

//                              if (session->version == SNMP_VERSION_1) {
                                    switch (err) {
                                        case SNMP_ERR_NOERROR:
                                                        // keep the no-error error:
                                                        break;
                                            case SNMP_ERR_WRONGVALUE:
                                            case SNMP_ERR_WRONGENCODING:
                                            case SNMP_ERR_WRONGTYPE:
                                            case SNMP_ERR_WRONGLENGTH:
                                            case SNMP_ERR_INCONSISTENTVALUE:
                                                        err = SNMP_ERR_BADVALUE;
                                                        break;
                                            case SNMP_ERR_NOACCESS:
                                            case SNMP_ERR_NOTWRITABLE:
                                            case SNMP_ERR_NOCREATION:
                                            case SNMP_ERR_INCONSISTENTNAME:
                                            case SNMP_ERR_AUTHORIZATIONERROR:
                                                        err = SNMP_ERR_NOSUCHNAME;
                                                        break;
                                            default:
                                                        err = SNMP_ERR_GENERR;
                                                        break;
//                                      }
                                }//if(session->version == SNMP_VERSION_1) ....

                                if (err != SNMP_ERR_NOERROR){
//                                      if (session->version == SNMP_VERSION_1) {
                                                snmp_inbadvalues++;
//                                      }
                                        return err;
                                }
                        }
                } else {
                        //* retrieve the value of the variable and place it into the
                        //* outgoing packet
                        if (statP == NULL){
                                statLen = 0;
                                if (exact){
                                        if (noSuchObject == TRUE){
                                                statType = SNMP_NOSUCHOBJECT;
                                        } else {
                                                statType = SNMP_NOSUCHINSTANCE;
                                        }
                                } else {
                                        statType = SNMP_ENDOFMIBVIEW;
                                }
                        } //if (statP == NULL) ...

                        out_data = snmp_build_var_op(out_data, var_name, &var_name_len,
                                                     statType, statLen, statP,
                                                     &out_length);
                        if (out_data == NULL){
                                return SNMP_ERR_TOOBIG;
                        }
                } //if (msgtype== SET_REQ_MSG) ...

                (*index)++;
        } //while((int)length > 0) ....
        if(msgtype!= SET_REQ_MSG){
                // save a pointer to the end of the packet
                packet_end = out_data;

                // Now rebuild header with the actual lengths
                dummyLen = packet_end - var_list_start;

// modified by ---- Arius 5/17/2000
#ifdef WEBADMIN
  dummyLen1 = packet_end - headerP;
  newpacket_end = asn_build_sequence(headerP, &dummyLen1,
                    (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), dummyLen);
  var_list_start -= (packet_end - newpacket_end);
  out_length += (packet_end - newpacket_end);
  // save new pointer to the end of the packet when the sapces will be adjust
  packet_end = newpacket_end;
  if (headerP == NULL)
#else
                if (asn_build_sequence(headerP, &dummyLen,
                                       (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
                                       dummyLen) == NULL)
#endif WEBADMIN
// end of here
                {
                        return SNMP_ERR_TOOBIG; // bogus error ????
                }
        }
        *index = 0;
        return SNMP_ERR_NOERROR;
}
Exemple #5
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;
}