/* * Translate OID from binary coding to character */ static char *translateOid(unsigned char **cursorP,unsigned char *bufend,char **cmdP,char *cmdend){ unsigned char *cursor=*cursorP; char *cmdcur=*cmdP; int objlen,n=0; objlen=getObjectLength(&cursor,bufend); if(objlen<0) return("variable binding OID value length error"); // first byte of OID has two numbers sprintf(cmdcur,"%u.%u.",*cursor/40,*cursor%40); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 968-0.8.13-3 FP but replaced strchr(cmdcur,0) objlen--; cursor++; // then we get 7 bits per byte // high order bit of 1 means we have another byte for(;objlen>0;objlen--){ n=*cursor&0x7f; while(*cursor&0x80){ cursor++; n=(n<<7)|(*cursor&0x7f); objlen--; } cursor++; sprintf(cmdcur,"%u.",n); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 962-0.8.13-3 FP but replaced strchr(cmdcur,0) } if(*(cmdcur-1)=='.') cmdcur--; *cursorP=cursor; *cmdP=cmdcur; return(NULL); }
/* * Produce a debugging string describing an NValue. */ std::string NValue::debug() const { const ValueType type = getValueType(); if (isNull()) { return "<NULL>"; } std::ostringstream buffer; std::string out_val; const char* ptr; int64_t addr; buffer << getTypeName(type) << "::"; switch (type) { case VALUE_TYPE_TINYINT: buffer << static_cast<int32_t>(getTinyInt()); break; case VALUE_TYPE_SMALLINT: buffer << getSmallInt(); break; case VALUE_TYPE_INTEGER: buffer << getInteger(); break; case VALUE_TYPE_BIGINT: case VALUE_TYPE_TIMESTAMP: buffer << getBigInt(); break; case VALUE_TYPE_DOUBLE: buffer << getDouble(); break; case VALUE_TYPE_VARCHAR: ptr = reinterpret_cast<const char*>(getObjectValue()); addr = reinterpret_cast<int64_t>(ptr); out_val = std::string(ptr, getObjectLength()); buffer << "[" << getObjectLength() << "]"; buffer << "\"" << out_val << "\"[@" << addr << "]"; break; case VALUE_TYPE_VARBINARY: ptr = reinterpret_cast<const char*>(getObjectValue()); addr = reinterpret_cast<int64_t>(ptr); out_val = std::string(ptr, getObjectLength()); buffer << "[" << getObjectLength() << "]"; buffer << "-bin[@" << addr << "]"; break; case VALUE_TYPE_DECIMAL: buffer << createStringFromDecimal(); break; default: buffer << getTypeName(type); } std::string ret(buffer.str()); return (ret); }
/* * Translate an SNMP V1 or V2 Trap to a NodeBrain ALERT command * * alert '<oid>'=<value>,...; * * Here's an example of a full alert with a single <variable-binding>. * * *** include example here *** */ static char *translate(NB_MOD_Snmptrap *snmptrap,unsigned char *buf,int len,char *cmd,int cmdlen,char **handlerNameP){ char *cmdcur=cmd; char *cmdend=cmdcur+cmdlen; unsigned char *cursor=buf; unsigned char *bufend=buf+len; unsigned char *enterpriseOid; int objlen,generic; char *msg,version,senderAddr[40]; char trapOID[64],*trapOIDCur; // value of '1.3.6.1.6.3.1.1.4.1.0' (SNMP_TRAP_OID) //char *handler; nbCELL cell; char *oid,*value,*syntax,*attribute; fprintf(stderr,"translate: called\n"); fflush(stderr); *trapOID=0; if(*cursor!=0x30) return("packet not recognized"); cursor++; objlen=getObjectLength(&cursor,bufend); if(objlen<0) return("trap length error"); if(*cursor!=0x02 || *(cursor+1)!=0x01) return("expecting 02.01 to start trap"); cursor+=2; version=*cursor; cursor++; sprintf(cmdcur,"alert '1.3.6.1.6.3.18.1.4'="); // snmpTrapCommunity OID cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 976-0.8.13-3 FP but replaced strchr(cmdcur,0) if(*cursor!=0x04) return("expecting type 04 (string) for community string"); if(NULL!=(msg=translateValue(&cursor,bufend,&cmdcur,cmdend,""))) return(msg); fprintf(stderr,"translate: checking version specific stuff\n"); fflush(stderr); switch(version){ case 0: /* snmpV1 trap */ if(*cursor!=0xA4) return("expecting 0xA4 for V1 trap"); cursor++; objlen=getObjectLength(&cursor,bufend); if(objlen<0) return("buffer length confusion"); if(*cursor!=0x06) return("expecting 0x06 for enterprise OID"); strcpy(cmdcur,",'1.3.6.1.6.3.1.1.4.3'="); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4157-0.8.13-3 FP but replaced strchr(cmdcur,0) enterpriseOid=cursor; if(NULL!=(msg=translateValue(&cursor,bufend,&cmdcur,cmdend,""))) return(msg); if(*cursor!=0x40) return("expecting 0x40 for address"); strcpy(cmdcur,",'1.3.6.1.6.3.18.1.3'="); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4165-0.8.13-3 FP but replaced strchr(cmdcur,0) if(NULL!=(msg=translateValue(&cursor,bufend,&cmdcur,cmdend,""))) return(msg); if(*cursor!=0x02) return("expecting integer for trap generic type"); cursor++; if(*cursor>1) return("generic trap type length error - expecting 1"); cursor++; generic=*cursor; cursor++; if(*cursor!=0x02) return("expecting integer for trap specific type"); strcpy(cmdcur,",'1.3.6.1.6.3.1.1.4.1.0'="); // snmpTrapOID.0 cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4162-0.8.13-3 FP but replaced strchr(cmdcur,0) if(generic!=6){ sprintf(cmdcur,"\"1.3.6.1.6.3.1.1.5.%d\"",(*cursor)+1); // see RFC 3584 cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4156-0.8.13-3 FP but replaced strchr(cmdcur,0) cursor++; objlen=getObjectLength(&cursor,bufend); // step over trap specific type if(objlen<0) return("buffer length confusion"); } else{ trapOIDCur=cmdcur+1; //save location of trapOId if(NULL!=(msg=translateValue(&enterpriseOid,bufend,&cmdcur,cmdend,""))) return(msg); cmdcur--; // back up over ending quote to extend this enterprise oid strcpy(cmdcur,".0."); cmdcur+=3; if(NULL!=(msg=translateValue(&cursor,bufend,&cmdcur,cmdend,""))) return(msg); *trapOID='\''; objlen=cmdcur-trapOIDCur; strncpy(trapOID+1,trapOIDCur,objlen); *(trapOID+objlen+1)='\''; *(trapOID+objlen+2)=0; *cmdcur='"'; cmdcur++; } if(*cursor!=0x43) return("expecting 0x43 for uptime"); strcpy(cmdcur,",'1.3.6.1.2.1.1.3.0'="); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 966-0.8.13-3 FP but replaced strchr(cmdcur,0) if(NULL!=(msg=translateValue(&cursor,bufend,&cmdcur,cmdend,""))) return(msg); break; case 1: /* snmpV2 trap */ if(*cursor!=0xA7) return("expecting 0xA7 for trap"); cursor++; objlen=getObjectLength(&cursor,bufend); if(objlen<0) return("buffer length confusion"); if(*cursor!=0x02) return("expecting 0x02 for variable 1"); cursor++; objlen=getObjectLength(&cursor,bufend); if(objlen<0) return("variable 1 length error"); cursor+=objlen; if(*cursor!=0x02 || *(cursor+1)!=0x01 || *(cursor+2)!=0x00 || *(cursor+3)!=0x02 || *(cursor+4)!=0x01 || *(cursor+5)!=0x00) return("V2:expecting 02 01 00 02 01 00 to start trap"); cursor+=6; // Insert the sender's address - don't worry, this will be overridden if sender supplies in variable bindings sprintf(cmdcur,",'1.3.6.1.6.3.18.1.3'=\"%s\"",nbIpGetAddrString(senderAddr,snmptrap->sourceAddr)); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 980-0.8.13-3 FP but replaced strchr(cmdcur,0) break; default: return("unrecognized trap version"); } fprintf(stderr,"translate: checking for handler\n"); fflush(stderr); fprintf(stderr,"translate: processing variable bindings\n"); fflush(stderr); // Variable bindings same for V1 and V2 if(*cursor!=0x30) return("expecting 0x30 for variable binding list"); cursor++; objlen=getObjectLength(&cursor,bufend); if(objlen<0) return("variable binding list length error"); while(cursor<bufend){ if(*cursor!=0x30) return("expecting 0x30 for variable binding"); cursor++; objlen=getObjectLength(&cursor,bufend); if(objlen<0) return("variable binding length error"); if(*cursor!=0x06) return("expecting OID on left side of variable binding"); cursor++; *cmdcur=','; cmdcur++; oid=cmdcur; // save location of OID *cmdcur='\''; cmdcur++; if((msg=translateOid(&cursor,bufend,&cmdcur,cmdend))!=NULL) return(msg); *cmdcur='\''; cmdcur++; *cmdcur=0; // look up syntax for value representation if(snmptrap->syntaxContext && (cell=nbTermLocateHere(snmptrap->syntaxContext,oid))!=NULL && (cell=nbTermGetDefinition(snmptrap->syntaxContext,cell))!=NULL && nbCellGetType(snmptrap->syntaxContext,cell)==NB_TYPE_STRING){ syntax=nbCellGetString(snmptrap->syntaxContext,cell); } else syntax=""; // look up attribute name and replace if found if(snmptrap->attributeContext && (cell=nbTermLocateHere(snmptrap->attributeContext,oid))!=NULL && (cell=nbTermGetDefinition(snmptrap->attributeContext,cell))!=NULL && nbCellGetType(snmptrap->attributeContext,cell)==NB_TYPE_STRING){ attribute=nbCellGetString(snmptrap->attributeContext,cell); strcpy(oid,attribute); cmdcur=strchr(oid,0); } *cmdcur='='; cmdcur++; value=cmdcur; if((msg=translateValue(&cursor,bufend,&cmdcur,cmdend,syntax))!=NULL) return(msg); if(strncmp(oid,"'1.3.6.1.6.3.1.1.4.1.0'",23)==0 && *value=='"'){ oid=trapOID; *oid='\''; oid++; value++; while(value<cmdcur && *value!='"') *oid=*value,oid++,value++; *oid='\''; oid++; *oid=0; } } *cmdcur=0; // Check for handler if(snmptrap->handlerContext && (cell=nbTermLocateHere(snmptrap->handlerContext,trapOID))!=NULL && (cell=nbTermGetDefinition(snmptrap->handlerContext,cell))!=NULL && nbCellGetType(snmptrap->handlerContext,cell)==NB_TYPE_STRING){ *handlerNameP=nbCellGetString(snmptrap->handlerContext,cell); //handler=nbCellGetString(snmptrap->handlerContext,cell); //strcpy(cmd,handler); //cmdcur=strchr(cmd,0); //*cmdcur=':'; //cmdcur++; //strcpy(cmdcur,trapOID); //cmdcur=strchr(cmdcur,0); } fprintf(stderr,"translate: returning\n"); fflush(stderr); return(NULL); }
static char *translateValue(unsigned char **cursorP,unsigned char *bufend,char **cmdP,char *cmdend,char *syntax){ unsigned char *cursor=*cursorP,*lookahead; char *cmdcur=*cmdP,*msg; int objlen,n=0,type; char *hexchar="0123456789ABCDEF"; double d=0; time_t utime; struct tm tm; type=*cursor; /* get date type */ cursor++; objlen=getObjectLength(&cursor,bufend); if(objlen*2>cmdend-cmdcur-1){ /* all types except string need twice as much space after converted */ if(type!=4 || objlen>cmdend-cmdcur-1) return("object is too long for command buffer"); } switch(type){ case 0x02: /* integer */ if(objlen<1 || objlen>4) return("variable binding integer value length error"); for(;objlen>0;objlen--){ n=(n<<8)|*cursor; cursor++; } sprintf(cmdcur,"%d",n); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4164-0.8.13-3 FP but replaced strchr(cmdcur,0) break; case 0x04: /* string */ if(objlen<0) return("variable binding string value length error"); if(objlen>cmdend-cmdcur-1) return("value is too large for buffer"); if(strcmp(syntax,"DateAndTime")==0){ if(objlen!=8 && objlen!=11) return("variable binding DateAndTime value length error"); tm.tm_year=*cursor<<8; cursor++; tm.tm_year|=*cursor; tm.tm_year-=1900; cursor++; tm.tm_mon=*cursor-1; cursor++; tm.tm_mday=*cursor; cursor++; tm.tm_hour=*cursor; cursor++; tm.tm_min=*cursor; cursor++; tm.tm_sec=*cursor; cursor++; cursor++; // ignore deci-seconds objlen-=8; if(objlen){ if(*cursor=='+'){ cursor++; tm.tm_hour-=*cursor; cursor++; tm.tm_min-=*cursor; } else if(*cursor=='-'){ cursor++; tm.tm_hour+=*cursor; cursor++; tm.tm_min+=*cursor; } else return("variable binding DateAndtime value has unrecognized direction from UTC"); cursor++; } tm.tm_isdst=0; utime=nbClockTimeGm(&tm); sprintf(cmdcur,"%d",(int)utime); cmdcur=strchr(cmdcur,0); } else{ *cmdcur='"'; cmdcur++; for(lookahead=cursor+objlen-1;lookahead>=cursor && isprint(*lookahead);lookahead--); if(lookahead<cursor){ strncpy(cmdcur,(char *)cursor,objlen); translateUnquoteString(cmdcur,objlen); cmdcur+=objlen; } else{ for(lookahead=cursor;lookahead<cursor+objlen;lookahead++){ *cmdcur=*(hexchar+(*lookahead>>4)); cmdcur++; *cmdcur=*(hexchar+(*lookahead&0x0f)); cmdcur++; } } *cmdcur='"'; cmdcur++; cursor+=objlen; } break; case 0x05: /* NULLOBJ */ if(objlen!=0) return("variable binding NULLOBJ length error - expecting zero"); strcpy(cmdcur,"?"); /* we'll use NodeBrain's Unknown value for NULLOBJ */ cmdcur++; // 2014-06-24 eat - changed from 2 to 1 byte step because "?" replaced "??" break; case 0x06: /* OID */ *cmdcur='"'; cmdcur++; cursor=*cursorP+1; /* go back to the length */ if((msg=translateOid(&cursor,bufend,&cmdcur,cmdend))!=NULL) return(msg); *cmdcur='"'; cmdcur++; break; case 0x40: /* address */ if(objlen!=4) return("expecting 4 byte address"); *cmdcur='"'; cmdcur++; sprintf(cmdcur,"%3.3u.%3.3u.%3.3u.%3.3u",*cursor,*(cursor+1),*(cursor+2),*(cursor+3)); cmdcur+=15; *cmdcur='"'; cmdcur++; cursor+=4; break; case 0x41: /* counter32 */ if(objlen<1 || objlen>4) return("variable binding integer value length error"); for(;objlen>0;objlen--){ n=(n<<8)|*cursor; cursor++; } sprintf(cmdcur,"%d",n); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4154-0.8.13-3 FP but replaced strchr(cmdcur,0) break; case 0x42: /* unsigned */ if(objlen<1 || objlen>4) return("variable binding integer value length error"); for(;objlen>0;objlen--){ n=(n<<8)|*cursor; cursor++; } sprintf(cmdcur,"%d",n); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4158-0.8.13-3 FP but replaced strchr(cmdcur,0) break; case 0x43: /* timeticks */ if(objlen<0) return("variable binding OID value length error"); for(;objlen>0;objlen--){ n=(n<<8)|*cursor; cursor++; } sprintf(cmdcur,"%d",n); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4153-0.8.13-3 FP but replaced strchr(cmdcur,0) break; case 0x46: // 64 bit number if(objlen<1 || objlen>8) return("variable binding Counter64 value length error"); for(;objlen>0;objlen--){ d=d*256+*cursor; cursor++; } sprintf(cmdcur,"%.10g",d); cmdcur+=strlen(cmdcur); // 2013-01-14 eat - VID 4159-0.8.13-3 FP but replaced strchr(cmdcur,0) break; default: sprintf(mymsg,"unrecognized value type %x len=%d",type,objlen); return(mymsg); } *cursorP=cursor; *cmdP=cmdcur; return(NULL); }