Esempio n. 1
0
/*******************************************************************-o-******
 * snmp_comstr_build
 *
 * Parameters:
 *	*data
 *	*length
 *	*psid
 *	*slen
 *	*version
 *	 messagelen
 *      
 * Returns:
 *	Pointer into 'data' after built section.
 *
 *
 * Build the header of a community string-based message such as that found
 * in SNMPv1 and SNMPv2c.
 *
 * NOTE:	The length of the message will have to be inserted later,
 *		if not known.
 *
 * NOTE:	Version is an 'int'.  (CMU had it as a long, but was passing
 *		in a *int.  Grrr.)  Assign version to verfix and pass in
 *		that to asn_build_int instead which expects a long.  -- WH
 */
u_char         *
snmp_comstr_build(u_char * data,
                  size_t * length,
                  u_char * psid,
                  size_t * slen, long *version, size_t messagelen)
{
    long            verfix = *version;
    u_char         *h1 = data;
    u_char         *h1e;
    size_t          hlength = *length;


    /*
     * Build the the message wrapper (note length will be inserted later).
     */
    data =
        asn_build_sequence(data, length,
                           (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 0);
    if (data == NULL) {
        return NULL;
    }
    h1e = data;


    /*
     * Store the version field.
     */
    data = asn_build_int(data, length,
                         (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
                                   ASN_INTEGER), &verfix, sizeof(verfix));
    if (data == NULL) {
        return NULL;
    }


    /*
     * Store the community string.
     */
    data = asn_build_string(data, length,
                            (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
                                      ASN_OCTET_STR), psid,
                            *(u_char *) slen);
    if (data == NULL) {
        return NULL;
    }


    /*
     * Insert length.
     */
    asn_build_sequence(h1, &hlength,
                       (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
                       data - h1e + messagelen);


    return data;

}                               /* end snmp_comstr_build() */
Esempio n. 2
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);
}
Esempio n. 3
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);
}
Esempio n. 4
0
u_char         *
_docsis_snmp_build_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)
{
    size_t          dummyLen, headerLen;
    u_char         *dataPtr;

    dummyLen = *listlength;
    dataPtr = data;
#if 0
    data = asn_build_sequence(data, &dummyLen,
                              (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
                              0);
    if (data == NULL) {
        return NULL;
    }
#endif
    if (dummyLen < 2)
        return NULL;
    data += 2;
    dummyLen -= 2;

    headerLen = data - dataPtr;
    *listlength -= headerLen;
    DEBUGDUMPHEADER("send", "Name");
    data = asn_build_objid(data, listlength,
                           (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
                                     ASN_OBJECT_ID), var_name,
                           *var_name_len);
    DEBUGINDENTLESS();
    if (data == NULL) {
        ERROR_MSG("Can't build OID for variable");
        return NULL;
    }
    DEBUGDUMPHEADER("send", "Value");
    switch (var_val_type) {
    case ASN_INTEGER:
        data = asn_build_int(data, listlength, var_val_type,
                             (long *) var_val, var_val_len);
        break;
    case ASN_GAUGE:
    case ASN_COUNTER:
    case ASN_TIMETICKS:
    case ASN_UINTEGER:
        data = asn_build_unsigned_int(data, listlength, var_val_type,
                                      (u_long *) var_val, var_val_len);
        break;
#ifdef OPAQUE_SPECIAL_TYPES
    case ASN_OPAQUE_COUNTER64:
    case ASN_OPAQUE_U64:
#endif
    case ASN_COUNTER64:
        data = asn_build_unsigned_int64(data, listlength, var_val_type,
                                        (struct counter64 *) var_val,
                                        var_val_len);
        break;
    case ASN_OCTET_STR:
    case ASN_IPADDRESS:
    case ASN_OPAQUE:
    case ASN_NSAP:
        data = asn_build_string(data, listlength, var_val_type,
                                var_val, var_val_len);
        break;
    case ASN_OBJECT_ID:
        data = asn_build_objid(data, listlength, var_val_type,
                               (oid *) var_val, var_val_len / sizeof(oid));
        break;
    case ASN_NULL:
        data = asn_build_null(data, listlength, var_val_type);
        break;
    case ASN_BIT_STR:
        data = asn_build_bitstring(data, listlength, var_val_type,
                                   var_val, var_val_len);
        break;
    case SNMP_NOSUCHOBJECT:
    case SNMP_NOSUCHINSTANCE:
    case SNMP_ENDOFMIBVIEW:
        data = asn_build_null(data, listlength, var_val_type);
        break;
#ifdef OPAQUE_SPECIAL_TYPES
    case ASN_OPAQUE_FLOAT:
        data = asn_build_float(data, listlength, var_val_type,
                               (float *) var_val, var_val_len);
        break;
    case ASN_OPAQUE_DOUBLE:
        data = asn_build_double(data, listlength, var_val_type,
                                (double *) var_val, var_val_len);
        break;
    case ASN_OPAQUE_I64:
        data = asn_build_signed_int64(data, listlength, var_val_type,
                                      (struct counter64 *) var_val,
                                      var_val_len);
        break;
#endif                          /* OPAQUE_SPECIAL_TYPES */
    default:
        ERROR_MSG("wrong type");
        return NULL;
    }
    DEBUGINDENTLESS();
    if (data == NULL) {
        ERROR_MSG("Can't build value");
        return NULL;
    }
    dummyLen = (data - dataPtr) - headerLen;

    _docsis_asn_build_sequence(dataPtr, &dummyLen,
                       (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
                       dummyLen);
    return data;
}
//*
//* 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;
}
int
snmp_agent_parse(
        snmp_session *session,
        uint8 *indata,
        int inlength,
        uint8 *outdata,
        int *outlength
)
{
        uint8    msgtype, type;
        long      zero = 0;
        long      reqid, errstat, errindex, dummyindex;
        uint8    *out_auth, *out_header, *out_reqid;
        uint8    *startData = indata;
        int       startLength = inlength;
        long      version;
        uint8    *origdata = indata;
        int           origlen = inlength;
//      usecEntry *ue;
        int       packet_len, ret = 0;
#ifdef WEBADMIN
        int       newoutdata;   // add -- by arius 5/17/2000
        int       len;          // add -- by arius 5/17/2000
#endif WEBADMIN

        session->community_len = COMMUNITY_MAX_LEN;
        //get community name
        indata = snmp_parse_auth(indata, &inlength, community, &session->community_len, &version);

        if (indata == NULL){
//              increment_stat( SNMP_STAT_ENCODING_ERRORS );
                ERROR("bad auth encoding");
                return 0;
        }

#if 1 //ONLY SUPPORT VERSION 1
        if(version != SNMP_VERSION_1) {
                ERROR("wrong version");
                snmp_inbadversions++;
                return 0;
        }

#else ////////////////////////////////////////////
        if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) {
//              increment_stat( SNMP_STAT_ENCODING_ERRORS );
                ERROR("wrong version");
                snmp_inbadversions++;
                return 0;
        }

        if( version == SNMP_VERSION_2C || version == SNMP_VERSION_2 ) {
                if( version == SNMP_VERSION_2 ) {
                        ret = check_auth( session, origdata, origlen, indata - session->community_len, session->community_len, &ue );
                        *outlength = (SNMP_MAX_LEN < session->MMS) ? SNMP_MAX_LEN : session->MMS;
                        session->MMS = SNMP_MAX_LEN;
                } else if( version == SNMP_VERSION_2C ) {
                        ret = community_auth( session );
                        session->version = SNMP_VERSION_2C;
                }

                if( ret < 0 ) {
//                      increment_stat( -ret );
                        if( (indata=asn_parse_header(indata, &inlength, &msgtype))
                        &&  asn_parse_int(indata, &inlength, &type, &reqid, sizeof(reqid)) )
                        {
                                if( msgtype == REPORT_MSG ) return 0;
                                if( !(session->qoS & USEC_QOS_GENREPORT) ) return 0;
                                session->agentBoots = _agentBoots;
                                session->agentClock = _agentStartTime;
                                memcpy( session->agentID, _agentID, 12 );
                                session->MMS = SNMP_MAX_LEN;
                                create_report( session, outdata, outlength, -ret, reqid );
                                return 1;
                        } else {
                                return 0;
                        }
                } else if( ret > 0 ) {
//                      increment_stat( ret );
                        return 0;
                }

        } else  {
#endif  /////////////////////////////////////////////////////

        //VERSION 1
        if(community_auth( session )==0) return 0;
//      session->version = SNMP_VERSION_1;

#if 0 ////////
        }
#endif ///////

        indata = asn_parse_header(indata, &inlength, &msgtype);
        if (indata == NULL){
//              increment_stat( SNMP_STAT_ENCODING_ERRORS );
                ERROR("bad header");
                return 0;
        }

    // XXX: increment by total number of vars at correct place:
    snmp_intotalreqvars++;

        if(msgtype == GET_REQ_MSG)      snmp_ingetrequests++;
        else if (msgtype == GETNEXT_REQ_MSG) snmp_ingetnexts++;
        else if (msgtype ==     SET_REQ_MSG) snmp_insetrequests++;
        else return 0;

//   if (msgtype == GETBULK_REQ_MSG: //version 2

        // Request ID
        indata = asn_parse_int(indata, &inlength, &type, &reqid, sizeof(reqid));
        if (indata == NULL){
//              increment_stat( SNMP_STAT_ENCODING_ERRORS );
                ERROR("bad parse of reqid");
                return 0;
        }

        //Error Status
        indata = asn_parse_int(indata, &inlength, &type, &errstat, sizeof(errstat));
        if (indata == NULL){
//              increment_stat( SNMP_STAT_ENCODING_ERRORS );
                ERROR("bad parse of errstat");
                snmp_inasnparseerrors++;
                return 0;
        }

        //Error Index
    indata = asn_parse_int(indata, &inlength, &type, &errindex, sizeof(errindex));
    if (indata == NULL){
//              increment_stat( SNMP_STAT_ENCODING_ERRORS );
                ERROR("bad parse of errindex");
                return 0;
        }

     //
     // Now start cobbling together what is known about the output packet.
     // The final lengths are not known now, so they will have to be recomputed
     // later.
     //

    // setup for response
//Simon    time( (time_t *) &session->agentTime );
//Simon    session->agentClock = _agentStartTime;
//Simon    session->agentBoots = _agentBoots;
//Simon   memcpy( session->agentID, _agentID, 12 );

        out_auth = outdata;

        //Set Resp Community
        out_header = snmp_build_auth(out_auth, outlength,
                                     community,session->community_len,
                                     (long)SNMP_VERSION_1,0);
        if (out_header == NULL){
                ERROR("snmp_build_auth failed");
                snmp_inasnparseerrors++;
                return 0;
        }

        out_reqid = asn_build_sequence(out_header, outlength, (uint8)GET_RSP_MSG, 0);
        if (out_reqid == NULL){
                ERROR("out_reqid == NULL");
                return 0;
        }

        //Set Resp ID
        type = (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER);
        // return identical request id
        outdata = asn_build_int(out_reqid, outlength, type, &reqid, sizeof(reqid));
        if (outdata == NULL){
                ERROR("build reqid failed");
                return 0;
        }

    // assume that error status will be zero
        outdata = asn_build_int(outdata, outlength, type, &zero, sizeof(zero));
        if (outdata == NULL){
                ERROR("build errstat failed");
                return 0;
        }

    // assume that error index will be zero
        outdata = asn_build_int(outdata, outlength, type, &zero, sizeof(zero));
        if (outdata == NULL){
                ERROR("build errindex failed");
                return 0;
        }

#if 0 ///////////////////////////////////////////
        if (msgtype == GETBULK_REQ_MSG)
        errstat = bulk_var_op_list(indata, inlength, outdata, *outlength,
                                    errstat, errindex, &errindex );
    else
#endif 0 ////////////////////////////////////////

        errstat = parse_var_op_list(session, indata, inlength, outdata, *outlength,
                                    &errindex, msgtype, RESERVE1);

        if (msgtype== SET_REQ_MSG){
                if (errstat == SNMP_ERR_NOERROR)
                        errstat = parse_var_op_list(session, indata, inlength, outdata, *outlength,
                                        &errindex, msgtype, RESERVE2);
                if (errstat == SNMP_ERR_NOERROR){
                //
                //* SETS require 3-4 passes through the var_op_list.  The first two
                //* passes verify that all types, lengths, and values are valid
                //* and may reserve resources and the third does the set and a
                //* fourth executes any actions.  Then the identical GET RESPONSE
                //* packet is returned.
                //* If either of the first two passes returns an error, another
                //* pass is made so that any reserved resources can be freed.
                //*
              parse_var_op_list(session, indata, inlength, outdata, *outlength,
                                &dummyindex, msgtype, COMMIT);
              parse_var_op_list(session, indata, inlength, outdata, *outlength,
                                &dummyindex, msgtype, ACTION);
              if (create_identical(session, startData, out_auth, startLength, 0L, 0L )){
                  *outlength = packet_end - out_auth;
                  return 1;
              }
              return 0;
        } else {
              parse_var_op_list(session, indata, inlength, outdata, *outlength,
                                &dummyindex, msgtype, COMM_FREE);
        }
    }
    switch((short)errstat){
        case SNMP_ERR_NOERROR:
            // re-encode the headers with the real lengths
            *outlength = packet_end - out_header;
            packet_len = *outlength;
            outdata = asn_build_sequence(out_header, outlength, GET_RSP_MSG,
                                        packet_end - out_reqid);
// add --- By arius 5/17/2000
#ifdef WEBADMIN
newoutdata = packet_end - outdata;  // how many shifts
len = packet_end - out_reqid;
packet_end = outdata;               // save new pointer end of packet
outdata -= len;
out_reqid = out_reqid - newoutdata;
#endif WEBADMIN
// end of here
            if (outdata != out_reqid){
                ERROR("internal error: header");
                return 0;
            }

            *outlength = packet_end - out_auth;
            outdata = snmp_build_auth(out_auth, outlength,
                                          community, session->community_len,
                                          (long)SNMP_VERSION_1,
                                          packet_end - out_header );
// add --- By arius 5/17/2000
#ifdef WEBADMIN
out_header -= (packet_end - outdata);
packet_end = outdata;            // save new pointer end of packet
#endif WEBADMIN
// end of here
            *outlength = packet_end - out_auth;
#if 0
            // packet_end is correct for old SNMP.  This dichotomy needs to be fixed.
            if (session->version == SNMP_VERSION_2)
                packet_end = out_auth + packet_len;
#endif
            break;
        case SNMP_ERR_TOOBIG:
            snmp_intoobigs++;
#if notdone
            if (session->version == SNMP_VERSION_2){
                create_toobig(out_auth, *outlength, reqid, pi);
                break;
            } // else FALLTHRU
#endif
        case SNMP_ERR_NOACCESS:
        case SNMP_ERR_WRONGTYPE:
        case SNMP_ERR_WRONGLENGTH:
        case SNMP_ERR_WRONGENCODING:
        case SNMP_ERR_WRONGVALUE:
        case SNMP_ERR_NOCREATION:
        case SNMP_ERR_INCONSISTENTVALUE:
        case SNMP_ERR_RESOURCEUNAVAILABLE:
        case SNMP_ERR_COMMITFAILED:
        case SNMP_ERR_UNDOFAILED:
        case SNMP_ERR_AUTHORIZATIONERROR:
        case SNMP_ERR_NOTWRITABLE:
    case SNMP_ERR_INCONSISTENTNAME:
        case SNMP_ERR_NOSUCHNAME:
        case SNMP_ERR_BADVALUE:
        case SNMP_ERR_READONLY:
        case SNMP_ERR_GENERR:
            if (create_identical(session, startData, out_auth, startLength, errstat,
                                 errindex)){
                *outlength = packet_end - out_auth;
                return 1;
            }
            return 0;
        default:
            return 0;
    }

#if 0
    if( session->qoS & USEC_QOS_AUTH ) {
        md5Digest( out_auth, *outlength, outdata - (session->contextLen + 16),
            outdata - (session->contextLen + 16) );
    }
#endif

        return 1;
}
//*
//*---------------------------------------------------------------------------------
//* Function Name: snmp_build_auth
//* Description  : Encodes the community name and version number in BER encoding
//*        rules.
//* Return Value : pointer of message with community name and version number encoded
//*        in it.
//*---------------------------------------------------------------------------------
//*
uint8 *snmp_build_auth(
uint8 *outdata,
int   *outlength,
uint8 *community,
int       community_len,
long  version,
int       messagelen
)
{
        // build the the message wrapper (30 82 Length)
    // 5 bytes = version header + version value + community header

// add -- By arius 5/17/2000
#ifdef WEBADMIN
   uint8   *oldoutdata;
   int     newoutlength;

   oldoutdata = outdata;
   outdata = asn_build_sequence(outdata, outlength, (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
          0);
#else
        outdata = asn_build_sequence(outdata, outlength, (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
                      messagelen + community_len + 5);
#endif WEBADMIN
// end of here

        if (outdata == NULL){
                ERROR("buildheader");
                return NULL;
        }

        // store the version field (02 length version)
        outdata = asn_build_int(outdata, outlength,
                (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
                &version, sizeof(version));
        if(outdata == NULL){
                ERROR("buildint");
                return NULL;
        }

        outdata = asn_build_string(outdata, outlength,
            (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STRING),
            community, community_len);
        if(outdata == NULL){
                ERROR("buildstring");
                return NULL;
        }

// add -- By arius 5/17/2000
#ifdef WEBADMIN
   if (messagelen)
   {
     newoutlength = *outlength + (community_len + 5 + 4);  // (default 4) include 30 82 Length
     outdata = asn_build_sequence(oldoutdata, &newoutlength , (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
             messagelen + community_len + 5);
   }
#endif WEBADMIN
// end of here

        return outdata;
}