agent_trap.c

/**
 * This function allows you to make a distinction between generic 
 * traps from different classes of equipment. For example, you may want 
 * to handle a SNMP_TRAP_LINKDOWN trap for a particular device in a 
 * different manner to a generic system SNMP_TRAP_LINKDOWN trap.
 *   
 *
 * @param trap is the generic trap type.  The trap types are:
 * - SNMP_TRAP_COLDSTART:
 * cold start
 * - SNMP_TRAP_WARMSTART:
 * warm start
 * - SNMP_TRAP_LINKDOWN:
 * link down
 * - SNMP_TRAP_LINKUP:
 * link up
 * - SNMP_TRAP_AUTHFAIL:
 * authentication failure
 * - SNMP_TRAP_EGPNEIGHBORLOSS:
 * egp neighbor loss
 * - SNMP_TRAP_ENTERPRISESPECIFIC:
 * enterprise specific
 *
 * @param specific is the specific trap value.
 *
 * @param enterprise is an enterprise oid in which you want to send specific 
 * traps from. 
 *
 * @param enterprise_length is the length of the enterprise oid, use macro,
 * OID_LENGTH, to compute length.
 *
 * @param vars is used to supply list of variable bindings to form an SNMPv2 
 * trap.
 *
 * @param context currently unused 
 *
 * @param flags currently unused 
 *
 * @return void
 *
 * @see send_easy_trap
 * @see send_v2trap
 */
int
netsnmp_send_traps(int trap, int specific,
                          const oid * enterprise, int enterprise_length,
                          netsnmp_variable_list * vars,
                          const char * context, int flags)
{
    netsnmp_pdu           *template_v1pdu;
    netsnmp_pdu           *template_v2pdu;
    netsnmp_variable_list *vblist = NULL;
    netsnmp_variable_list *trap_vb;
    netsnmp_variable_list *var;
    in_addr_t             *pdu_in_addr_t;
    u_long                 uptime;
    struct trap_sink *sink;
    const char            *v1trapaddress;
    int                    res = 0;


    DEBUGMSGTL(( "trap", "send_trap %d %d ", trap, specific));
    DEBUGMSGOID(("trap", enterprise, enterprise_length));
    DEBUGMSG(( "trap", "\n"));


    if (vars) {
        vblist = snmp_clone_varbind( vars );
        if (!vblist) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to clone varbind list\n");
            return -1;
        }
    }


    if ( trap == -1 ) {
        /*
         * Construct the SNMPv2-style notification PDU
         */
        if (!vblist) {
            snmp_log(LOG_WARNING,
                     "send_trap: called with NULL v2 information\n");
            return -1;

        }


        template_v2pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
        if (!template_v2pdu) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to construct v2 template PDU\n");
            snmp_free_varbind(vblist);
            return -1;
        }


        /*
         * Check the varbind list we've been given.
         * If it starts with a 'sysUptime.0' varbind, then use that.
         * Otherwise, prepend a suitable 'sysUptime.0' varbind.
         */
        if (!snmp_oid_compare( vblist->name,    vblist->name_length,
                               sysuptime_oid, sysuptime_oid_len )) {
            template_v2pdu->variables = vblist;
            trap_vb  = vblist->next_variable;
        } else {
            uptime   = netsnmp_get_agent_uptime();
            var = NULL;
            snmp_varlist_add_variable( &var,
                           sysuptime_oid, sysuptime_oid_len,
                           ASN_TIMETICKS, (u_char*)&uptime, sizeof(uptime));
            if (!var) {
                snmp_log(LOG_WARNING,
                     "send_trap: failed to insert sysUptime varbind\n");
                snmp_free_pdu(template_v2pdu);
                snmp_free_varbind(vblist);
                return -1;
            }
            template_v2pdu->variables = var;
            var->next_variable        = vblist;
            trap_vb  = vblist;
        }


        /*
         * 'trap_vb' should point to the snmpTrapOID.0 varbind,
         *   identifying the requested trap.  If not then bomb out.
         * If it's a 'standard' trap, then we need to append an
         *   snmpEnterprise varbind (if there isn't already one).
         */
        if (!trap_vb ||
            snmp_oid_compare(trap_vb->name, trap_vb->name_length,
                             snmptrap_oid,  snmptrap_oid_len)) {
            snmp_log(LOG_WARNING,
                     "send_trap: no v2 trapOID varbind provided\n");
            snmp_free_pdu(template_v2pdu);
            return -1;
        }
        if (!snmp_oid_compare(vblist->val.objid, OID_LENGTH(trap_prefix),
                              trap_prefix,       OID_LENGTH(trap_prefix))) {
            var = find_varbind_in_list( template_v2pdu->variables,
                                        snmptrapenterprise_oid,
                                        snmptrapenterprise_oid_len);
            if (!var &&
                !snmp_varlist_add_variable( &(template_v2pdu->variables),
                     snmptrapenterprise_oid, snmptrapenterprise_oid_len,
                     ASN_OBJECT_ID,
                     enterprise, enterprise_length*sizeof(oid))) {
                snmp_log(LOG_WARNING,
                     "send_trap: failed to add snmpEnterprise to v2 trap\n");
                snmp_free_pdu(template_v2pdu);
                return -1;
            }
        }
            


        /*
         * If everything's OK, convert the v2 template into an SNMPv1 trap PDU.
         */
        template_v1pdu = convert_v2pdu_to_v1( template_v2pdu );
        if (!template_v1pdu) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to convert v2->v1 template PDU\n");
        }


    } else {
        /*
         * Construct the SNMPv1 trap PDU....
         */
        template_v1pdu = snmp_pdu_create(SNMP_MSG_TRAP);
        if (!template_v1pdu) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to construct v1 template PDU\n");
            snmp_free_varbind(vblist);
            return -1;
        }
        template_v1pdu->trap_type     = trap;
        template_v1pdu->specific_type = specific;
        template_v1pdu->time          = netsnmp_get_agent_uptime();


        if (snmp_clone_mem((void **) &template_v1pdu->enterprise,
                       enterprise, enterprise_length * sizeof(oid))) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to set v1 enterprise OID\n");
            snmp_free_varbind(vblist);
            snmp_free_pdu(template_v1pdu);
            return -1;
        }
        template_v1pdu->enterprise_length = enterprise_length;


        template_v1pdu->flags    |= UCD_MSG_FLAG_FORCE_PDU_COPY;
        template_v1pdu->variables = vblist;


        /*
         * ... and convert it into an SNMPv2-style notification PDU.
         */


        template_v2pdu = convert_v1pdu_to_v2( template_v1pdu );
        if (!template_v2pdu) {
            snmp_log(LOG_WARNING,
                     "send_trap: failed to convert v1->v2 template PDU\n");
        }
    }


    /*
     * Check whether we're ignoring authFail traps
     */
    if (template_v1pdu) {
      if (template_v1pdu->trap_type == SNMP_TRAP_AUTHFAIL &&
        snmp_enableauthentraps == SNMP_AUTHENTICATED_TRAPS_DISABLED) {
        snmp_free_pdu(template_v1pdu);
        snmp_free_pdu(template_v2pdu);
        return 0;
      }


    /*
     * Ensure that the v1 trap PDU includes the local IP address
     */
       pdu_in_addr_t = (in_addr_t *) template_v1pdu->agent_addr;
       v1trapaddress = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
                                             NETSNMP_DS_AGENT_TRAP_ADDR);
       if (v1trapaddress != NULL) {
           /* "v1trapaddress" was specified in config, try to resolve it */
           res = netsnmp_gethostbyname_v4(v1trapaddress, pdu_in_addr_t);
       }
       if (v1trapaddress == NULL || res < 0) {
           /* "v1trapaddress" was not specified in config or the resolution failed,
            * try any local address */
           *pdu_in_addr_t = get_myaddr();
       }


    }


    if (template_v2pdu) {
/* A context name was provided, so copy it and its length to the v2 pdu
* template. */
if (context != NULL)
{
template_v2pdu->contextName    = strdup(context);
template_v2pdu->contextNameLen = strlen(context);
}
    }


    /*
     *  Now loop through the list of trap sinks
     *   and call the trap callback routines,
     *   providing an appropriately formatted PDU in each case
     */
    for (sink = sinks; sink; sink = sink->next) {
#ifndef NETSNMP_DISABLE_SNMPV1
        if (sink->version == SNMP_VERSION_1) {
          if (template_v1pdu) {
            send_trap_to_sess(sink->sesp, template_v1pdu);
          }
        } else {
#endif
          if (template_v2pdu) {
            template_v2pdu->command = sink->pdutype;
            send_trap_to_sess(sink->sesp, template_v2pdu);
          }
#ifndef NETSNMP_DISABLE_SNMPV1
        }
#endif
    }
    if (template_v1pdu)
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                        SNMPD_CALLBACK_SEND_TRAP1, template_v1pdu);
    if (template_v2pdu)
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                        SNMPD_CALLBACK_SEND_TRAP2, template_v2pdu);
    snmp_free_pdu(template_v1pdu);
    snmp_free_pdu(template_v2pdu);
    return 0;
}


void
send_enterprise_trap_vars(int trap,
                          int specific,
                          const oid * enterprise, int enterprise_length,
                          netsnmp_variable_list * vars)
{
    netsnmp_send_traps(trap, specific,
                       enterprise, enterprise_length,
                       vars, NULL, 0);
    return;
}



void

send_trap_vars(int trap, int specific, netsnmp_variable_list * vars)
{
    if (trap == SNMP_TRAP_ENTERPRISESPECIFIC)
        send_enterprise_trap_vars(trap, specific, objid_enterprisetrap,
                                  OID_LENGTH(objid_enterprisetrap), vars);
    else
        send_enterprise_trap_vars(trap, specific, trap_version_id,
                                  OID_LENGTH(trap_version_id), vars);
}

/**

 * Uses the supplied list of variable bindings to form an SNMPv2 trap
 * which is sent to SNMPv2-capable sinks  on  the  configured  list.  
 * An equivalent INFORM is sent to the configured list of inform sinks.  
 * Sinks that can only handle SNMPv1 traps are skipped.
 *
 * This function eventually calls send_enterprise_trap_vars.  If the
 * trap type is not set to SNMP_TRAP_ENTERPRISESPECIFIC the enterprise 
 * and enterprise_length paramater is set to the pre defined NETSNMP_SYSTEM_MIB 
 * oid and length respectively.  If the trap type is set to 
 * SNMP_TRAP_ENTERPRISESPECIFIC the enterprise and enterprise_length 
 * parameters are set to the pre-defined NETSNMP_NOTIFICATION_MIB oid and length 
 * respectively.
 *
 * @param vars is used to supply list of variable bindings to form an SNMPv2 
 * trap.
 *
 * @return void
 *
 * @see send_easy_trap
 * @see send_enterprise_trap_vars
 */


void
send_v2trap(netsnmp_variable_list * vars)
{
    send_trap_vars( -1, -1, vars);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值