Exemplo n.º 1
0
int
smux_trap (oid *name, size_t namelen,
	   oid *iname, size_t inamelen,
	   struct trap_object *trapobj, size_t trapobjlen,
	   unsigned int tick, u_char sptrap)
{
  unsigned int i;
  u_char buf[BUFSIZ];
  u_char *ptr;
  size_t len, length;
  struct in_addr addr;
  unsigned long val;
  u_char *h1, *h1e;

  ptr = buf;
  len = BUFSIZ;
  length = len;

  /* When SMUX connection is not established. */
  if (smux_sock < 0)
    return 0;

  /* SMUX header. */
  ptr = asn_build_header (ptr, &len, (u_char) SMUX_TRAP, 0);

  /* Sub agent enterprise oid. */
  ptr = asn_build_objid (ptr, &len,
			 (u_char) 
			 (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
			 smux_oid, smux_oid_len);

  /* IP address. */
  addr.s_addr = 0;
  ptr = asn_build_string (ptr, &len, 
			  (u_char)
			  (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_IPADDRESS),
			  (u_char *)&addr, sizeof (addr));

  /* Generic trap integer. */
  val = SNMP_TRAP_ENTERPRISESPECIFIC;
  ptr = asn_build_int (ptr, &len, 
		       (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		       &val, sizeof (val));

  /* Specific trap integer. */
  val = sptrap;
  ptr = asn_build_int (ptr, &len, 
		       (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		       &val, sizeof (val));

  /* Timeticks timestamp. */
  val = 0;
  ptr = asn_build_unsigned_int (ptr, &len, 
				(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_TIMETICKS),
				&val, sizeof (val));
  
  /* Variables. */
  h1 = ptr;
  ptr = asn_build_sequence (ptr, &len, 
			    (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
			    0);


  /* Iteration for each objects. */
  h1e = ptr;
  for (i = 0; i < trapobjlen; i++)
    {
      int ret;
      oid oid[MAX_OID_LEN];
      size_t oid_len;
      void *val;
      size_t val_len;
      u_char val_type;

      /* Make OID. */
      if (trapobj[i].namelen > 0) 
        {
          oid_copy (oid, name, namelen);
          oid_copy (oid + namelen, trapobj[i].name, trapobj[i].namelen);
          oid_copy (oid + namelen + trapobj[i].namelen, iname, inamelen);
          oid_len = namelen + trapobj[i].namelen + inamelen;
        }
      else 
        {
          oid_copy (oid, name, namelen);
          oid_copy (oid + namelen, trapobj[i].name, trapobj[i].namelen * (-1));
          oid_len = namelen + trapobj[i].namelen * (-1) ;
        }

      if (debug_smux) 
        {
          smux_oid_dump ("Trap", name, namelen);
          if (trapobj[i].namelen < 0)
            smux_oid_dump ("Trap", 
                           trapobj[i].name, (- 1) * (trapobj[i].namelen));
          else 
            {
              smux_oid_dump ("Trap", trapobj[i].name, (trapobj[i].namelen));
              smux_oid_dump ("Trap", iname, inamelen);
            }
          smux_oid_dump ("Trap", oid, oid_len);
          zlog_info ("BUFSIZ: %d // oid_len: %d", BUFSIZ, oid_len);
      }

      ret = smux_get (oid, &oid_len, 1, &val_type, &val, &val_len);

      if (debug_smux)
	zlog_debug ("smux_get result %d", ret);

      if (ret == 0)
	ptr = snmp_build_var_op (ptr, oid, &oid_len,
				 val_type, val_len, val, &len);
    }

  /* Now variable size is known, fill in size */
  asn_build_sequence(h1, &length,
		     (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
		     ptr - h1e);

  /* Fill in size of whole sequence */
  len = BUFSIZ;
  asn_build_header (buf, &len, (u_char) SMUX_TRAP, (ptr - buf) - 2);

  return send (smux_sock, buf, (ptr - buf), 0);
}
Exemplo n.º 2
0
void
smux_getresp_send (oid objid[], size_t objid_len, long reqid, long errstat,
		   long errindex, u_char val_type, void *arg, size_t arg_len)
{
  int ret;
  u_char buf[BUFSIZ];
  u_char *ptr, *h1, *h1e, *h2, *h2e;
  size_t len, length;

  ptr = buf;
  len = BUFSIZ;
  length = len;

  if (debug_smux)
    {
      zlog_debug ("SMUX GETRSP send");
      zlog_debug ("SMUX GETRSP reqid: %ld", reqid);
    }

  h1 = ptr;
  /* Place holder h1 for complete sequence */
  ptr = asn_build_sequence (ptr, &len, (u_char) SMUX_GETRSP, 0);
  h1e = ptr;
 
  ptr = asn_build_int (ptr, &len,
		       (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		       &reqid, sizeof (reqid));

  if (debug_smux)
    zlog_debug ("SMUX GETRSP errstat: %ld", errstat);

  ptr = asn_build_int (ptr, &len,
		       (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		       &errstat, sizeof (errstat));
  if (debug_smux)
    zlog_debug ("SMUX GETRSP errindex: %ld", errindex);

  ptr = asn_build_int (ptr, &len,
		       (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		       &errindex, sizeof (errindex));

  h2 = ptr;
  /* Place holder h2 for one variable */
  ptr = asn_build_sequence (ptr, &len, 
			   (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
			   0);
  h2e = ptr;

  ptr = snmp_build_var_op (ptr, objid, &objid_len, 
			   val_type, arg_len, arg, &len);

  /* Now variable size is known, fill in size */
  asn_build_sequence(h2,&length,(u_char)(ASN_SEQUENCE|ASN_CONSTRUCTOR),ptr-h2e);

  /* Fill in size of whole sequence */
  asn_build_sequence(h1,&length,(u_char)SMUX_GETRSP,ptr-h1e);

  if (debug_smux)
    zlog_debug ("SMUX getresp send: %ld", (ptr - buf));
  
  ret = send (smux_sock, buf, (ptr - buf), 0);
}
//*
//* 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;
}
Exemplo n.º 4
0
unsigned int
encode_vbind (char *oid_string, char oid_asntype, union t_val *value,
	      unsigned char *out_buffer, size_t out_size)
{
  oid var_name[MAX_OID_LEN];
  size_t name_len = MAX_OID_LEN;
  oid oid_value[MAX_OID_LEN];
  size_t oid_value_len = MAX_OID_LEN;
  unsigned char *data_ptr;
  unsigned char buf[SPRINT_MAX_LEN];
  unsigned int ltmp;
  struct tree *tp;
  struct range_list *rp;
  long len=0;
  int rv;
  long longval;
  unsigned long ulongval;

  memset (buf, 0, SPRINT_MAX_LEN);
  if (!get_node (oid_string, var_name, &name_len))
    {
      if (!read_objid (oid_string, var_name, &name_len))
	{
	  /* enable random access */
	  if (!netsnmp_ds_get_boolean
	      (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_RANDOM_ACCESS))
	    {
	      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
					 NETSNMP_DS_LIB_RANDOM_ACCESS);
	    }

	  if (!get_node (oid_string, var_name, &name_len))
	    {
	      /* Not found, try UCD style OID access */
	      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
					 NETSNMP_DS_LIB_READ_UCD_STYLE_OID);
	      if (!netsnmp_ds_get_boolean
		  (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_READ_UCD_STYLE_OID))
		{
		  netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
					     NETSNMP_DS_LIB_READ_UCD_STYLE_OID);
		}

	      if (!read_objid (oid_string, var_name, &name_len))
		{

		  /* Hmm, still not found, go back to net-snmp-style OID and try regex access */
		  netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
					     NETSNMP_DS_LIB_READ_UCD_STYLE_OID);

		  if (!netsnmp_ds_get_boolean
		      (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_REGEX_ACCESS))
		    {
		      netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID,
						 NETSNMP_DS_LIB_REGEX_ACCESS);
		    }

		  if (!get_wild_node (oid_string, var_name, &name_len))
		    {
		      /* Ran out of ideas. */
		      fprintf(stderr, "/* Error: Can't find oid %s at line %d */\n",
			      oid_string, line);
		      snmp_perror ("encode_vbind");
		      return 0;
		    }
		}
	    }
	}
    }

  switch (oid_asntype)
    {
    case 'i':
      longval = value->intval;
      data_ptr = _docsis_snmp_build_var_op (out_buffer,
				    var_name,
				    &name_len,
				    ASN_INTEGER,
				    sizeof (long),
				    (unsigned char *) &longval,
				    &out_size);
      return data_ptr - out_buffer;
      break;
      ;;
    case 'g':
      ulongval = value->intval;
      data_ptr = _docsis_snmp_build_var_op (out_buffer,
				    var_name,
				    &name_len,
				    ASN_GAUGE,
				    sizeof (unsigned long),
				    (unsigned char *) &ulongval,
				    &out_size);
      return data_ptr - out_buffer;
      break;
      ;;
    case 'c':
      ulongval = value->intval;
      data_ptr = _docsis_snmp_build_var_op (out_buffer,
				    var_name,
				    &name_len,
				    ASN_COUNTER,
				    sizeof (unsigned long),
				    (unsigned char *) &ulongval,
				    &out_size);
      return data_ptr - out_buffer;
      break;
      ;;
    case 'u':
      ulongval = value->intval;
      data_ptr = _docsis_snmp_build_var_op (out_buffer,
				    var_name,
				    &name_len,
				    ASN_GAUGE,
				    sizeof (unsigned long),
				    (unsigned char *) &ulongval,
				    &out_size);
      return data_ptr - out_buffer;
      break;
      ;;
    case 't':
      ulongval = value->intval;
      data_ptr = _docsis_snmp_build_var_op (out_buffer,
                                    var_name,
                                    &name_len,
                                    ASN_TIMETICKS,
                                    sizeof (unsigned long),
                                    (unsigned char *) &ulongval,
                                    &out_size);
      return data_ptr - out_buffer;
      break;
      ;;
    case 's':
    case 'x':
    case 'd':
      if (oid_asntype == 'd')
	{
	  /* ltmp = ascii_to_binary(value->strval, buf);
	     strncpy((char*)buf, value, SPRINT_MAX_BUF);
	     ltmp = strlen((char*)buf); */
	}
      else if (oid_asntype == 's')
	{
	  strncpy ((char *) buf, value->strval, SPRINT_MAX_LEN);
	  len = strlen ((char *) buf);
	}
      else if (oid_asntype == 'x')
	{
	  if ((rv = hexadecimal_to_binary (value->strval, buf)) == -1)
	    {
	      fprintf(stderr, "Invalid hexadecimal string at line %d\n", line);
	      return 0;
	    }
	  ltmp = (unsigned int) rv;
	  len = ltmp;
	}

      if (len < 0 || len > SPRINT_MAX_LEN - 1)
	{
	  fprintf(stderr, "String too long at line %d, max allowed %d\n", line,
		  SPRINT_MAX_LEN);
	  return 0;
	  break;
	}
      tp = get_tree (var_name, name_len, get_tree_head ());
      if (tp && tp->ranges
	  && !netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID,
				      NETSNMP_DS_LIB_DONT_CHECK_RANGE))
	{
	  rp = tp->ranges;
	  while (rp)
	    {
	      if (rp->low <= len && len <= rp->high)
		break;
	      rp = rp->next;
	    }
	  if (!rp)
	    {
	      fprintf(stderr, "Value too long at line %d\n", line);
	      return 0;
	      break;
	    }
	}
      /* If length is more than 127, won't fit into a 1-byte quantity */
      if (len+name_len+8 < 0x7f ) {
     		data_ptr = _docsis_snmp_build_var_op (out_buffer,
                                    var_name,
                                    &name_len,
                                    ASN_OCTET_STR,
                                    len, (unsigned char *) buf,
                                    &out_size);
      } else {
      		data_ptr = snmp_build_var_op (out_buffer,
				    var_name,
				    &name_len,
				    ASN_OCTET_STR,
				    len, (unsigned char *) buf,
				    &out_size);
      }
#ifdef DEBUG
      fprintf (stderr, "encoded len %ld var_len %d leftover %ud difference %d\n", len, name_len, out_size, (data_ptr - out_buffer) );
#endif
      return data_ptr - out_buffer;
      break;
      ;;
    case 'a':
      if (!inet_aton (value->strval, (struct in_addr *) &ltmp))
	{
	  fprintf(stderr, "Invalid IP address %s at line %d\n", value->strval, line);
	  return 0;
	}
      data_ptr = _docsis_snmp_build_var_op (out_buffer,
				    var_name,
				    &name_len,
				    ASN_IPADDRESS,
				    sizeof (struct in_addr),
				    (unsigned char *) &ltmp, &out_size);
      return data_ptr - out_buffer;
      break;
      ;;
    case 'o':

	strncpy ((char *) buf, value->strval, SPRINT_MAX_LEN);
	len = strlen ((char *) buf);

	if (!read_objid ((char *) buf, oid_value, &oid_value_len))
	  {
		fprintf(stderr, "Can't find oid %s at line %d\n", buf, line);
		return 0;
    	  }

	data_ptr = _docsis_snmp_build_var_op (out_buffer,
                                    var_name,
                                    &name_len,
                                    ASN_OBJECT_ID,
                                    oid_value_len*sizeof(oid),
                                    (unsigned char *) &oid_value, &out_size);
	return data_ptr - out_buffer;
	break;
	;;

    default:
      fprintf(stderr, "Variable type %s not supported yet\n", &oid_asntype);
      return 0;
      ;;
    }
/* NOTREACHED */
}
/*
 * Takes a session and a pdu and serializes the ASN PDU into the area
 * pointed to by packet.  out_length is the size of the data area available.
 * Returns the length of the completed packet in out_length.  If any errors
 * occur, -1 is returned.  If all goes well, 0 is returned.
 */
int snmp_build_trap(
        snmp_session *session,
        snmp_pdu *pdu,
        uint8  *packet,
        int         *out_length
)
{
        uint8  buf[SNMP_MAX_TRAP_LEN];
        uint8  *cp;
#ifdef WEBADMIN
        uint8  *newpacket;   // add -- by arius 5/18/2000
#endif WEBADMIN
        variable_list *vp;
        int         totallength;
        int         length;

        length = *out_length;
        cp = packet;
        for(vp = pdu->variables; vp; vp = vp->next){
                cp = snmp_build_var_op(cp, vp->name, &vp->name_len, vp->type, vp->val_len, (uint8 *)vp->val.string, &length);
                if (cp == NULL) return (FALSE);
        }
        totallength = cp - packet;

        length = SNMP_MAX_TRAP_LEN;
        cp = asn_build_header(buf, &length, (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
        if (cp == NULL) return (FALSE);
        bcopy((char *)packet, (char *)cp, totallength);
        totallength += cp - buf;

        length = *out_length;
        if (pdu->command != TRP_REQ_MSG){
                // request id
                cp = asn_build_int(packet, &length,
                       (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
                       (long *)&pdu->reqid, sizeof(pdu->reqid));
                if (cp == NULL) return (FALSE);
                // error status
                cp = asn_build_int(cp, &length,
                       (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
                       (long *)&pdu->errstatus, sizeof(pdu->errstatus));
                if(cp == NULL) return (FALSE);
                // error index
                cp = asn_build_int(cp, &length,
                       (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
               (long *)&pdu->errindex, sizeof(pdu->errindex));
                if(cp == NULL) return (FALSE);
        } else {        // this is a trap message
                // enterprise
                cp = asn_build_objid(packet, &length,
                       (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
                       (oid *)SnmpVersionID, SNMP_VER_LEN);
                if (cp == NULL) return (FALSE);
                // agent-addr
                cp = asn_build_string(cp, &length, (uint8)IPADDRESS,
                       (uint8 *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
                if(cp == NULL) return (FALSE);
                // generic trap
                cp = asn_build_int(cp, &length,
                       (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
                       (long *)&pdu->generic_trap, sizeof(pdu->generic_trap));
                if (cp == NULL) return (FALSE);
                // specific trap
                cp = asn_build_int(cp, &length,
                       (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
                       (long *)&pdu->specific_trap, sizeof(pdu->specific_trap));
                if (cp == NULL) return (FALSE);
                // timestamp
                cp = asn_build_int(cp, &length, (uint8)TIMETICKS,
                       (long *)&pdu->time_stamp, sizeof(pdu->time_stamp));
                if (cp == NULL) return (FALSE);
        }
        if (length < totallength)       return (FALSE);
        bcopy((char *)buf, (char *)cp, totallength);
        totallength += cp - packet;

        length = SNMP_MAX_TRAP_LEN;
        cp = asn_build_header(buf, &length, (uint8)pdu->command, totallength);
        if (cp == NULL) return (FALSE);
        if (length < totallength) return (FALSE);

        bcopy((char *)packet, (char *)cp, totallength);
        totallength += cp - buf;

        length = *out_length;
// modified -- by arius 5/18/2000
#ifdef WEBADMIN
newpacket = packet;
        cp = snmp_build_auth( newpacket, &length, session->community,
                session->community_len,(long) SNMP_VERSION_1, totallength);
cp  -= totallength;   // save new pointer
#else
        cp = snmp_build_auth( packet, &length, session->community,
                session->community_len,(long) SNMP_VERSION_1, totallength);
#endif WEBADMIN
// end of here
        if (cp == NULL) return (FALSE);

        if ((*out_length - (cp - packet)) < totallength) return (FALSE);

        bcopy((char *)buf, (char *)cp, totallength);
        totallength += cp - packet;
        *out_length = totallength;

//      if( session->qoS & USEC_QOS_AUTH )
//              md5Digest( packet, totallength, cp - (session->contextLen + 16),
//              cp - (session->contextLen + 16) );

        return (TRUE);
}