Beispiel #1
0
//==============[ operator<(Oid &x,Oid &y) ]=============================
// less than < overloaded
int operator<(const Oid &lhs, const Oid &rhs)
{
  int result;
  // call nCompare with the current
  // Oidx, Oidy and len of Oidx
  if((result = lhs.nCompare(rhs.len(), rhs))<0)  return 1;
  if (result > 0)    return 0;

  // if here, equivalent substrings, call the shorter one <
  return (lhs.len() < rhs.len());
}
//------------[ convert SNMP++ VB to WinSNMP smiVALUE ]----------------
int convertVbToSmival( const Vb &tempvb, SmiVALUE *smival )
{
  smival->syntax = tempvb.get_syntax();
  switch ( smival->syntax ) {

    // case sNMP_SYNTAX_NULL
  case sNMP_SYNTAX_NULL:
  case sNMP_SYNTAX_NOSUCHOBJECT:
  case sNMP_SYNTAX_NOSUCHINSTANCE:
  case sNMP_SYNTAX_ENDOFMIBVIEW:
    break;

    // case sNMP_SYNTAX_INT32:
  case sNMP_SYNTAX_INT:
    tempvb.get_value(smival->value.sNumber);
    break;

    //    case sNMP_SYNTAX_UINT32:
  case sNMP_SYNTAX_GAUGE32:
  case sNMP_SYNTAX_CNTR32:
  case sNMP_SYNTAX_TIMETICKS:
    //  case sNMP_SYNTAX_UINT32:
    tempvb.get_value(smival->value.uNumber);
    break;

    // case Counter64
  case sNMP_SYNTAX_CNTR64:
    {
      Counter64 c64;
      tempvb.get_value(c64);
      smival->value.hNumber.hipart = c64.high();
      smival->value.hNumber.lopart = c64.low();
    }
    break;

  case sNMP_SYNTAX_BITS:
  case sNMP_SYNTAX_OCTETS:
  case sNMP_SYNTAX_OPAQUE:
  case sNMP_SYNTAX_IPADDR:
    {
      OctetStr os;
      tempvb.get_value(os);
      smival->value.string.ptr = NULL;
      smival->value.string.len = os.len();
      if ( smival->value.string.len > 0 )
      {
        smival->value.string.ptr
          = (SmiLPBYTE) new  unsigned char [smival->value.string.len];
        if ( smival->value.string.ptr )
        {
          for (int i=0; i<(int) smival->value.string.len ; i++)
            smival->value.string.ptr[i] = os[i];
        }
        else
        {
          smival->syntax = sNMP_SYNTAX_NULL;  // invalidate the smival
          return SNMP_CLASS_RESOURCE_UNAVAIL;
        }
      }
    }
    break;

  case sNMP_SYNTAX_OID:
    {
      Oid oid;
      tempvb.get_value(oid);
      smival->value.oid.ptr = NULL;
      smival->value.oid.len = oid.len();
      if ( smival->value.oid.len > 0 )
      {
        smival->value.oid.ptr
          = (SmiLPUINT32) new unsigned long [ smival->value.oid.len];
        if ( smival->value.oid.ptr )
        {
          for (int i=0; i<(int)smival->value.oid.len ; i++)
            smival->value.oid.ptr[i] = oid[i];
        }
        else
        {
          smival->syntax = sNMP_SYNTAX_NULL;  // invalidate the smival
          return SNMP_CLASS_RESOURCE_UNAVAIL;
        }
      }
    }
    break;

  default:
    return SNMP_CLASS_INTERNAL_ERROR;
  }
  return SNMP_CLASS_SUCCESS;
}
Beispiel #3
0
//=============[ int operator == oid,oid ]=================================
// equivlence operator overloaded
int operator==(const Oid &lhs, const Oid &rhs)
{
  // ensure same len, then use nCompare
  if (rhs.len() != lhs.len()) return 0;
  return (lhs.nCompare(rhs.len(), rhs) == 0);
}
int SnmpMessage::load(const Pdu &cpdu,
                      const OctetStr &community,
                      const snmp_version version,
                      const OctetStr* engine_id,
                      const OctetStr* security_name,
                      const int security_model)
{
  int status;
  const Pdu *pdu = &cpdu;
  Pdu temppdu;

  // make sure pdu is valid
  if ( !pdu->valid())
    return SNMP_CLASS_INVALID_PDU;

  // create a raw pdu
  snmp_pdu *raw_pdu;
  raw_pdu = snmp_pdu_create( (int) pdu->get_type());

  Oid enterprise;

  // load it up
  raw_pdu->reqid = pdu->get_request_id();
#ifdef _SNMPv3
  raw_pdu->msgid = pdu->get_message_id();
#endif
  raw_pdu->errstat= (unsigned long) pdu->get_error_status();
  raw_pdu->errindex= (unsigned long) pdu->get_error_index();

  // if its a V1 trap then load up other values
  // for v2, use normal pdu format
  if (raw_pdu->command == sNMP_PDU_V1TRAP)
  {
    // DON'T forget about the v1 trap agent address (changed by Frank Fock)
    GenAddress gen_addr;
    IpAddress ip_addr;
    int addr_set = FALSE;

    if (pdu->get_v1_trap_address(gen_addr))
    {
      /* User did set the v1 trap address */
      if ((gen_addr.get_type() != Address::type_ip) &&
          (gen_addr.get_type() != Address::type_udp) )
      {
	LOG_BEGIN(ERROR_LOG | 4);
	LOG("SNMPMessage: Bad v1 trap address type in pdu");
	LOG(gen_addr.get_type());
	LOG_END;

        snmp_free_pdu( raw_pdu);
        return SNMP_CLASS_INVALID_PDU;
      }

      ip_addr = gen_addr;
      if (!ip_addr.valid())
      {
	LOG_BEGIN(ERROR_LOG | 1);
	LOG("SNMPMessage: Copied v1 trap address not valid");
	LOG_END;

        snmp_free_pdu( raw_pdu);
        return SNMP_CLASS_RESOURCE_UNAVAIL;
      }
      addr_set = TRUE;
    }
    else
    {
      /* User did not set the v1 trap address */
      char addrString[256];
      if (gethostname(addrString, 255) == 0)
      {
          ip_addr = addrString;
          addr_set = TRUE;
      }
    }
    struct sockaddr_in agent_addr;  // agent address socket struct
    // prepare the agent address
    memset(&agent_addr, 0, sizeof(agent_addr));
    agent_addr.sin_family = AF_INET;
    if (addr_set)
    {
      agent_addr.sin_addr.s_addr
        = inet_addr(((IpAddress &)ip_addr).IpAddress::get_printable());
      LOG_BEGIN(INFO_LOG | 7);
      LOG("SNMPMessage: Setting v1 trap address");
      LOG(((IpAddress &)ip_addr).IpAddress::get_printable());
      LOG_END;
    }
    raw_pdu->agent_addr = agent_addr;

    //-----[ compute generic trap value ]-------------------------------
    // determine the generic value
    // 0 - cold start
    // 1 - warm start
    // 2 - link down
    // 3 - link up
    // 4 - authentication failure
    // 5 - egpneighborloss
    // 6 - enterprise specific
    Oid trapid;
    pdu->get_notify_id( trapid);
    if ( !trapid.valid() || trapid.len() < 2 )
      {
        snmp_free_pdu( raw_pdu);
        return SNMP_CLASS_INVALID_NOTIFYID;
      }
    raw_pdu->specific_type=0;
    if ( trapid == coldStart)
      raw_pdu->trap_type = 0;  // cold start
    else if ( trapid == warmStart)
      raw_pdu->trap_type = 1;  // warm start
    else if( trapid == linkDown)
      raw_pdu->trap_type = 2;  // link down
    else if ( trapid == linkUp)
      raw_pdu->trap_type = 3;  // link up
    else if ( trapid == authenticationFailure )
      raw_pdu->trap_type = 4;  // authentication failure
    else if ( trapid == egpNeighborLoss)
      raw_pdu->trap_type = 5;  // egp neighbor loss
    else {
      raw_pdu->trap_type = 6;     // enterprise specific
      // last oid subid is the specific value
      // if 2nd to last subid is "0", remove it
      // enterprise is always the notify oid prefix
      raw_pdu->specific_type = (int) trapid[(int) (trapid.len()-1)];

      trapid.trim(1);
      if ( trapid[(int)(trapid.len()-1)] == 0 )
        trapid.trim(1);
      enterprise = trapid;
    }

    if ( raw_pdu->trap_type !=6)
      pdu->get_notify_enterprise( enterprise);
    if ( enterprise.len() >0) {
      // note!!
      // these are hooks into an SNMP++ oid
      // and therefor the raw_pdu enterprise
      // should not free them. null them out!!
      SmiLPOID rawOid;
      rawOid = enterprise.oidval();
      raw_pdu->enterprise = rawOid->ptr;
      raw_pdu->enterprise_length = (int) rawOid->len;
    }

    // timestamp
    TimeTicks timestamp;
    pdu->get_notify_timestamp( timestamp);
    raw_pdu->time = ( unsigned long) timestamp;

  }

  // if its a v2 trap then we need to make a few adjustments
  // vb #1 is the timestamp
  // vb #2 is the id, represented as an Oid
  if (( raw_pdu->command == sNMP_PDU_TRAP) ||
      ( raw_pdu->command == sNMP_PDU_INFORM))
  {
    Vb tempvb;

    temppdu = *pdu;
    temppdu.trim(temppdu.get_vb_count());

    // vb #1 is the timestamp
    TimeTicks timestamp;
    tempvb.set_oid(SNMP_MSG_OID_SYSUPTIME);   // sysuptime
    pdu->get_notify_timestamp( timestamp);
    tempvb.set_value ( timestamp);
    temppdu += tempvb;

    // vb #2 is the id
    Oid trapid;
    tempvb.set_oid(SNMP_MSG_OID_TRAPID);
    pdu->get_notify_id( trapid);
    tempvb.set_value( trapid);
    temppdu += tempvb;

    // append the remaining vbs
    for (int z=0; z<pdu->get_vb_count(); z++) {
      pdu->get_vb( tempvb,z);
      temppdu += tempvb;
    }

    pdu = &temppdu;          // reassign the pdu to the temp one
  }
  // load up the payload
  // for all Vbs in list, add them to the pdu
  int vb_count;
  Vb tempvb;
  Oid tempoid;
  SmiLPOID smioid;
  SmiVALUE smival;

  vb_count = pdu->get_vb_count();
  for (int z=0;z<vb_count;z++) {
    pdu->get_vb( tempvb,z);
    tempvb.get_oid( tempoid);
    smioid = tempoid.oidval();
    // clear the value portion, in case its
    // not already been done so by the app writer
    // only do it in the case its a get,next or bulk
    if ((raw_pdu->command == sNMP_PDU_GET) ||
        (raw_pdu->command == sNMP_PDU_GETNEXT) ||
        (raw_pdu->command == sNMP_PDU_GETBULK))
      tempvb.set_null();
    status = convertVbToSmival( tempvb, &smival );
    if ( status != SNMP_CLASS_SUCCESS) {
      snmp_free_pdu( raw_pdu);
      return status;
    }
    // add the vb to the raw pdu
    snmp_add_var( raw_pdu, smioid->ptr, (int) smioid->len, &smival);

    freeSmivalDescriptor( &smival);
  }

  // ASN1 encode the pdu
#ifdef _SNMPv3
  if (version == version3)
  {
    if ((!engine_id) || (!security_name))
    {
      LOG_BEGIN(ERROR_LOG | 4);
      LOG("SNMPMessage: Need security name and engine id for v3 message");
      LOG_END;

      // prevention of SNMP++ Enterprise Oid death
      if ( enterprise.len() >0) {
	raw_pdu->enterprise = 0;
	raw_pdu->enterprise_length=0;
      }
      snmp_free_pdu( raw_pdu);
      return SNMP_CLASS_INVALID_TARGET;
    }

    status = v3MP::I->snmp_build(raw_pdu, databuff, (int *)&bufflen,
				 *engine_id, *security_name, security_model,
				 pdu->get_security_level(),
				 pdu->get_context_engine_id(),
				 pdu->get_context_name());
    if (status == SNMPv3_MP_OK) {
      if ((pdu->get_type() == sNMP_PDU_RESPONSE) &&
          ((int)pdu->get_maxsize_scopedpdu() < pdu->get_asn1_length())) {

	LOG_BEGIN(ERROR_LOG | 1);
	LOG("SNMPMessage: *BUG*: Serialized response pdu is too big (len) (max)");
	LOG(pdu->get_asn1_length());
	LOG(pdu->get_maxsize_scopedpdu());
	LOG_END;

        // prevention of SNMP++ Enterprise Oid death
        if ( enterprise.len() >0) {
          raw_pdu->enterprise = 0;
          raw_pdu->enterprise_length=0;
        }
        snmp_free_pdu( raw_pdu);
        return SNMP_ERROR_TOO_BIG;
      }
    }
  }
  else
#endif
    status = snmp_build( raw_pdu, databuff, (int *) &bufflen, version,
                         community.data(), (int) community.len());

  LOG_BEGIN(DEBUG_LOG | 4);
  LOG("SNMPMessage: return value for build message");
  LOG(status);
  LOG_END;

  if ((status != 0)
#ifdef _SNMPv3
      && ((version != version3) || (status != SNMPv3_MP_OK))
#endif
      ) {
    valid_flag = false;
    // prevention of SNMP++ Enterprise Oid death
    if ( enterprise.len() >0) {
      raw_pdu->enterprise = 0;
      raw_pdu->enterprise_length=0;
    }
    snmp_free_pdu( raw_pdu);
#ifdef _SNMPv3
    if (version == version3)
      return status;
    else
#endif
      // NOTE: This is an assumption - in most cases during normal
      // operation the reason is a tooBig - another could be a
      // damaged variable binding.
      return SNMP_ERROR_TOO_BIG;
  }
  valid_flag = true;

  // prevention of SNMP++ Enterprise Oid death
  if ( enterprise.len() >0) {
    raw_pdu->enterprise = 0;
    raw_pdu->enterprise_length=0;
  }

  snmp_free_pdu( raw_pdu);

  return SNMP_CLASS_SUCCESS;
}