Esempio n. 1
0
static boolean SNMP_parse_pduv1
   (
      SNMP_PARSE_PTR snmp
   )
{ /* Body */
   uint_32     typelen;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   if (typelen == 0) return FALSE;
   snmp->errstatp = snmp->inbuf + (typelen - 1);
   ASN1_READZERO_IGNORE(snmp, typelen);

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   if (typelen == 0) return FALSE;
   snmp->errindexp = snmp->inbuf + (typelen - 1);
   ASN1_READZERO_IGNORE(snmp, typelen);

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, typelen);
   snmp->inlen = typelen;

   /*
   ** We want nonrep to be (at least) the number of VarBinds in
   ** the VarBindList.  We pick typelen, because each VarBind is
   ** guaranteed to be at least one byte (in fact, they're guaranteed
   ** to be at least five bytes), so typelen is a guaranteed upper
   ** bound.  We pick reps = 1, because if ever nonrep weren't big
   ** enough (which will never happen), the remaining VarBinds will
   ** still be treated as non-repeaters.
   */
   snmp->nonrep = typelen;
   snmp->reps = 1;

   return TRUE;

} /* Endbody */
Esempio n. 2
0
static boolean SNMP_parse
   (
      SNMP_PARSE_PTR snmp,
      uint_32_ptr    writelen
   )
{ /* Body */
   uint_32     typelen, maxheadlen;
   uint_32     ctylen, idlen;
   uchar_ptr   ctyp,   idp,  pdup;
   volatile uint_8 tmp;

   maxheadlen = 0;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, typelen);
   maxheadlen += 4;
   snmp->inlen = typelen;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   ASN1_READ_INT(snmp, typelen, snmp->version);
   maxheadlen += 3;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_OCTET, ctylen);
   ctyp = snmp->inbuf;
   
   /* test for community string match */
   for (tmp=0; tmp < SNMPCFG_NUM_COMMUNITY; tmp++) {
      if (ctylen == snmp->communitylen[tmp]) {
         if( !memcmp(ctyp, snmp->community[tmp], ctylen) ) {
            break;
        }
      }
   } /* Endfor */
   
   /* if community string is bad, return */
   if(tmp == SNMPCFG_NUM_COMMUNITY) {
      IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_BAD_COMMUNITY++);
      /* Check before decrement, because SNMP_task will increment it */
      IF_SNMP_STATS_ENABLED(if(snmp->STATS.ST_RX_BAD_PARSE > 0) snmp->STATS.ST_RX_BAD_PARSE--);
      return FALSE;
   } /* Endif */
Esempio n. 3
0
static boolean SNMP_parse_awesome_pdubulk
   (
      SNMP_PARSE_PTR snmp
   )
{ /* Body */
   uint_32     typelen;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   if (typelen == 0) return FALSE;
   snmp->errstatp = snmp->inbuf + (typelen - 1);
   ASN1_READZERO_INT(snmp, typelen, snmp->nonrep);

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   if (typelen == 0) return FALSE;
   snmp->errindexp = snmp->inbuf + (typelen - 1);
   ASN1_READZERO_INT(snmp, typelen, snmp->reps);

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, typelen);
   snmp->inlen = typelen;

   return TRUE;

} /* Endbody */
Esempio n. 4
0
static boolean RTCSMIB_check
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   RTCSMIB_NODE_PTR     node = RTCSMIB_root;
   uchar_ptr            oidptr, valptr;
   uint_32              oidlen, vallen, valtype;
   boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_) = NULL;
   uint_32              varlen;
   uint_32              id;
   pointer              instance;
   boolean              found;

   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
   mib->inlen = varlen;
   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_OBJECT, oidlen);
   oidptr = mib->inbuf;

   /* Read the variable's type and length */
   mib->inbuf += oidlen;
   mib->inlen -= oidlen;
   ASN1_READ_TYPELEN(mib, valtype, vallen);
   valptr = mib->inbuf;

   mib->inbuf = oidptr;
   mib->inlen = oidlen;

   ASN1_READ_ID(mib,id);

   for (;;) {

      /*
      ** First, search the MIB for the requested leaf node.
      */

      if ((node->ID < id) && node->NEXT) {

         node = node->NEXT;
         continue;

      } else if (node->ID == id) {

         if (node->CHILD) {
            if (mib->inlen == 0) {
               mib->errstat = SNMP_ERROR_notWritable;
               return FALSE;
            } /* Endif */
            ASN1_READ_ID(mib,id);
            if (node->FIND) find = node->FIND;
            node = node->CHILD;
            continue;
         } /* Endif */

      } else {
         mib->errstat = SNMP_ERROR_notWritable;
         return FALSE;

      } /* Endif */

      /*
      ** We've found our leaf node.  Parse the instance identifier.
      */

      if (!(node->ACCESS & RTCSMIB_ACCESS_WRITE) || !node->PARSE) {
         mib->errstat = SNMP_ERROR_notWritable;
         return FALSE;
      } /* Endif */

      if (node->ASN1_TYPE != valtype) {
         mib->errstat = SNMP_ERROR_wrongType;
         return FALSE;
      } /* Endif */

      if (!node->PARSE(mib, RTCSMIB_OP_SET, find, &found, &instance)) return FALSE;

      if (!found) {
         mib->errstat = SNMP_ERROR_noCreation;
         return FALSE;
      } /* Endif */

      /*
      ** The instance exists -- the value can be set.
      */
      mib->totlen = 0;
      /* Start CR# 1866 */
      //return (mib->errstat == SNMP_ERROR_noError);
      mib->outbuf += mib->oidlen + 4;
      mib->outlen -= mib->oidlen + 4;
      mib->oidp = mib->outbuf;
      return FALSE;
   } /* Endfor */

} /* Endbody */
Esempio n. 5
0
static boolean RTCSMIB_powerful_getnext
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   RTCSMIB_NODE_PTR     node = RTCSMIB_root;
   boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_) = NULL;
   uint_32              varlen;
   uint_32              op, id;
   pointer              instance;
   boolean              found;

   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
   mib->inlen = varlen;
   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_OBJECT, varlen);
   mib->inlen = varlen;

   mib->oidlen = (node->ID > 0x3FFF) ? 3 : (node->ID > 0x7F) ? 2 : 1;
   ASN1_READ_ID(mib,id);

   op = RTCSMIB_OP_GETNEXT;

   for (;;) {

      /*
      ** First, search the MIB for the requested leaf node.
      */

      switch (op) {
      case RTCSMIB_OP_GETNEXT:

         if (node->ID < id) {

            if (node->NEXT) {
               if ((node->ID <= 0x7F) && (node->NEXT->ID > 0x7F)&&(node->NEXT->ID <= 0x3FFF)) //current is 1 byte and next is 2 bytes
                  mib->oidlen++;
               else
               if((node->ID <= 0x7F) && (node->NEXT->ID > 0x3FFF))//current is 1 byte and next is 3 bytes
                  mib->oidlen = mib->oidlen + 2;       
               else
               if ((node->ID <= 0x3FFF)&&(node->ID > 0x7F) && (node->NEXT->ID > 0x3FFF))//current is 2 bytes and next is 3 bytes 
                  mib->oidlen++;
               node = node->NEXT;
            } else {
               op = RTCSMIB_OP_FINDNEXT;
            } /* Endif */

            continue;

         } else if (node->ID == id) {

            if (node->CHILD) {
               if (mib->inlen == 0) {
                  op = RTCSMIB_OP_GETFIRST;
                  continue;
               } /* Endif */
               ASN1_READ_ID(mib,id);
               if (node->FIND) 
                  find = node->FIND;
               node = node->CHILD;
               mib->oidlen += (node->ID > 0x3FFF) ? 3 : (node->ID > 0x7F) ? 2 : 1;
               continue;
            } /* Endif */

            /* We might have found our leaf node -- break out of the switch */
            break;

         } else {
            op = RTCSMIB_OP_GETFIRST;
            continue;

         } /* Endif */

      case RTCSMIB_OP_GETFIRST:

         if (node->CHILD) {
            if (node->FIND) 
               find = node->FIND;
            node = node->CHILD;
            mib->oidlen += (node->ID > 0x3FFF) ? 3 : (node->ID > 0x7F) ? 2 : 1;
            continue;
         } /* Endif */

         /* We might have found our leaf node -- break out of the switch */
         break;

      case RTCSMIB_OP_FINDNEXT:

         if (node->NEXT) {
            if ((node->ID <= 0x7F) && (node->NEXT->ID > 0x7F)&&(node->NEXT->ID <= 0x3FFF)) //current is 1 byte and next is 2 bytes
                  mib->oidlen++;
               else
               if((node->ID <= 0x7F) && (node->NEXT->ID > 0x3FFF))//current is 1 byte and next is 3 bytes
                  mib->oidlen = mib->oidlen + 2;       
               else
               if ((node->ID <= 0x3FFF)&&(node->ID > 0x7F) && (node->NEXT->ID > 0x3FFF))//current is 2 bytes and next is 3 bytes michelle
               mib->oidlen++;
            node = node->NEXT;
            op = RTCSMIB_OP_GETFIRST;
            continue;
         } /* Endif */

         mib->oidlen -= (node->ID > 0x3FFF) ? 3 : (node->ID > 0x7F) ? 2 : 1;//reduce the corresponding bytes.
         node = node->PARENT;

         if (!node) {
            mib->errstat = SNMP_ERROR_endOfMibView;
            return FALSE;
         } /* Endif */

         continue;

      } /* Endswitch */

      /*
      ** We may have found our leaf node.  Parse the instance identifier.
      */

      if (!(node->ACCESS & RTCSMIB_ACCESS_READ) || !node->PARSE) {
         op = RTCSMIB_OP_FINDNEXT;
         continue;
      } /* Endif */

      if (mib->oidlen + 4 > mib->outlen) {
         mib->errstat = SNMP_ERROR_tooBig;
         return FALSE;
      } /* Endif */
      mib->outbuf += mib->oidlen + 4;
      mib->outlen -= mib->oidlen + 4;
      mib->oidp = mib->outbuf;

      if (!node->PARSE(mib, op, find, &found, &instance)) 
         return FALSE;

      if (!found) {
         mib->outbuf -= mib->oidlen + 4;
         mib->outlen += mib->oidlen + 4;
         op = RTCSMIB_OP_FINDNEXT;
         continue;
      } /* Endif */

      /*
      ** The instance exists -- output the value.
      */

      return RTCSMIB_output(mib, node, instance);

   } /* Endfor */

} /* Endbody */
Esempio n. 6
0
static boolean RTCSMIB_get
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   RTCSMIB_NODE_PTR     node = RTCSMIB_root;
   boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_) = NULL;
   uint_32              varlen;
   uint_32              id;
   pointer              instance;
   boolean              found;

   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
   mib->inlen = varlen;
   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_OBJECT, varlen);
   mib->inlen = varlen;

   mib->oidlen = 0;
   ASN1_READ_ID(mib,id);

   for (;;) {

      /*
      ** First, search the MIB for the requested leaf node.
      */

      if ((node->ID < id) && node->NEXT) {

         node = node->NEXT;
         continue;

      } else if (node->ID == id) {

         mib->oidlen += (id > 0x3FFF) ? 3 : (id > 0x7F) ? 2 : 1;
         
         if (node->CHILD) {
            if (mib->inlen == 0) {
               mib->errstat = SNMP_ERROR_noSuchObject;
               return FALSE;
            } /* Endif */
            ASN1_READ_ID(mib,id);
            if (node->FIND) find = node->FIND;
            node = node->CHILD;
            continue;
         } /* Endif */

      } else {
         mib->errstat = SNMP_ERROR_noSuchObject;
         return FALSE;

      } /* Endif */

      /*
      ** We've found our leaf node.  Parse the instance identifier.
      */

      if (!(node->ACCESS & RTCSMIB_ACCESS_READ) || !node->PARSE) {
         mib->errstat = SNMP_ERROR_noSuchObject;
         return FALSE;
      } /* Endif */

      if (mib->oidlen + 4 > mib->outlen) {
         mib->errstat = SNMP_ERROR_tooBig;
         return FALSE;
      } /* Endif */
      mib->outbuf += mib->oidlen + 4;
      mib->outlen -= mib->oidlen + 4;
      mib->oidp = mib->outbuf;

      if (!node->PARSE(mib, RTCSMIB_OP_GET, find, &found, &instance)) 
         return FALSE;

      if (!found) {
         mib->errstat = SNMP_ERROR_noSuchInstance;
         return FALSE;
      } /* Endif */

      /*
      ** The instance exists -- output the value.
      */

      return RTCSMIB_output(mib, node, instance);

   } /* Endfor */

} /* Endbody */
Esempio n. 7
0
// Start CR 2316
static boolean RTCSMIB_request_internal
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   uchar_ptr inbuffer, nextvar,checkbuffer;
   uint_32 inbuf_length, nextlength,check_length;
   uint_32 varlen;
   boolean  ok = FALSE;
   uint_32  index =0;
   uint_32  errstat =0;
   uint_32 error_index;

   mib->errstat = SNMP_ERROR_noError;

   switch (mib->pdutype) {
   case ASN1_TYPE_PDU_GET:
      ok = RTCSMIB_get(mib);
      break;
   case ASN1_TYPE_PDU_GETNEXT:
      ok = RTCSMIB_powerful_getnext(mib);
      break;
   case ASN1_TYPE_PDU_SET:
        inbuffer = mib->inbuf;   
        inbuf_length = mib->inlen;
        
        checkbuffer = inbuffer;
        check_length = inbuf_length;
        
        error_index =0;
        
        //check first to ensure all variables in set request are valid
        if (check_length >= 5)  /* Minmum length for a set operation is 5 */
        {
            ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
            nextvar = (uchar_ptr) (mib->inbuf + varlen);
            nextlength = check_length - ((uint_32)(nextvar - checkbuffer));
            mib->inbuf = checkbuffer;
            mib->inlen = check_length; 
            mib->errstat = SNMP_ERROR_noError;
            ok = RTCSMIB_check(mib);
            index++;
            if(mib->errstat)
            {
              errstat = mib->errstat;
              error_index = index;
            }
            mib->inbuf = nextvar;
            checkbuffer = nextvar;
            mib->inlen = nextlength;
            check_length = nextlength;
        }
        
        if(error_index) //invalid variable in set request,stop set operation to all variables 
        {
           mib->errstat = errstat;
           break;
        }
        
        mib->inbuf = inbuffer;
        mib->inlen = inbuf_length;
        
        //all variables are valid, so set beginning
        if (inbuf_length >= 5)  /* Minmum length for a set operation is 5 */
        {
            ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
            nextvar = (uchar_ptr) (mib->inbuf + varlen);
            nextlength = inbuf_length - ((uint_32)(nextvar - inbuffer));
            mib->inbuf = inbuffer;
            mib->inlen = inbuf_length; 
            ok = RTCSMIB_set(mib);
            mib->inbuf = nextvar;
            inbuffer = nextvar;
            mib->inlen = nextlength;
            inbuf_length = nextlength;
        } /* Endwhile */
      break;
   } /* Endswitch */

   if (!ok && !mib->errstat) {
      mib->errstat = SNMP_ERROR_PARSE;
   } /* Endif */

/* Start CR 2162 */
#ifndef TRAVERSE_MIB_IN_SNMP_TASK
   RTCSCMD_complete(mib, RTCS_OK);
#endif
/* End CR 2162 */
return (ok);
} /* Endbody */
Esempio n. 8
0
static boolean SNMP_parse_varbindlist
   (
      SNMP_PARSE_PTR snmp,
      uint_32_ptr    writelen
   )
{ /* Body */
   uchar_ptr   outp, varp;
   uint_32     outlen, varlen, varcount, index;

   outp = snmp->outbuf;
   outlen = snmp->outlen;
   index = 0;
   *writelen = 0;

   /* 
   ** Set the value of non repeaters variable to zero 
   ** if it is less than zero
   */
   #if 0 // nonrep is unsigned  
   if(snmp->nonrep < 0) {      
      snmp->nonrep = 0;
   }
   #endif
   
   while (snmp->nonrep && snmp->inlen) {
      snmp->nonrep--;
      varp = snmp->inbuf;
      varlen = snmp->inlen;
      index++;
      if (!SNMP_request(snmp, varp, varlen, outp, outlen, &varlen)) {
         if (SNMP_ERROR_USEINDEX(snmp->errstat)) {
            snmp->errindex = index;
         } /* Endif */
         return FALSE;
      } /* Endif */
      outp += varlen;
      outlen -= varlen;
      *writelen += varlen;
      ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, varlen);
      ASN1_READ_IGNORE(snmp, varlen);
   } /* Endwhile */

   while (snmp->inlen) {
      varp = snmp->inbuf;
      varlen = snmp->inlen;
      index++;
      for (varcount = 0; varcount < snmp->reps; varcount++) {
         if (!SNMP_request(snmp, varp, varlen, outp, outlen, &varlen)) {
            if (SNMP_ERROR_USEINDEX(snmp->errstat)) {
               snmp->errindex = index;
            } /* Endif */
            return FALSE;
         } /* Endif */
         varp = outp;
         outp += varlen;
         outlen -= varlen;
         *writelen += varlen;
      } /* Endfor */
      ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, varlen);
      ASN1_READ_IGNORE(snmp, varlen);
   } /* Endwhile */

   return TRUE;

} /* Endbody */