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 */
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 */
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 */
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 */
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 */
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 */
// 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 */
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 */