/*
*  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);
  }
Exemple #2
0
/*
 * 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);
  }