Esempio n. 1
0
/*
 * check a session validity for connectivity to the master agent.  If
 * not functioning, close and start attempts to reopen the session 
 */
void
agentx_check_session(unsigned int clientreg, void *clientarg)
{
    netsnmp_session *ss = (netsnmp_session *) clientarg;
    if (!ss) {
        if (clientreg)
            snmp_alarm_unregister(clientreg);
        return;
    }
    DEBUGMSGTL(("agentx/subagent", "checking status of session %p\n", ss));

    if (!agentx_send_ping(ss)) {
        snmp_log(LOG_WARNING,
                 "AgentX master agent failed to respond to ping.  Attempting to re-register.\n");
        /*
         * master agent disappeared?  Try and re-register.
         * close first, just to be sure .
         */
        agentx_unregister_callbacks(ss);
        agentx_close_session(ss, AGENTX_CLOSE_TIMEOUT);
        snmp_alarm_unregister(clientreg);       /* delete ping alarm timer */
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                            SNMPD_CALLBACK_INDEX_STOP, (void *) ss);
        snmp_close(main_session);
        main_session = NULL;
        agentx_reopen_session(0, NULL);
    } else {
        DEBUGMSGTL(("agentx/subagent", "session %p responded to ping\n",
                    ss));
    }
}
Esempio n. 2
0
/*
 * check a session validity for connectivity to the master agent.  If
 * not functioning, close and start attempts to reopen the session
 */
void agentx_check_session (unsigned int clientreg, void *clientarg)
{
    netsnmp_session *ss = (netsnmp_session *) clientarg;

    if (!ss)
    {
        if (clientreg)
            snmp_alarm_unregister (clientreg);
        return;
    }
    DEBUGMSGTL (("agentx/subagent", "checking status of session %p\n", ss));

    if (!agentx_send_ping (ss))
    {
        snmp_log (LOG_WARNING, "AgentX master agent failed to respond to ping.  Attempting to re-register.\n");
        /*
         * master agent disappeared?  Try and re-register.
         * close first, just to be sure .
         */
        agentx_unregister_callbacks (ss);
        agentx_close_session (ss, AGENTX_CLOSE_TIMEOUT);
        snmp_alarm_unregister (clientreg);    /* delete ping alarm timer */
        snmp_call_callbacks (SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_INDEX_STOP, (void *) ss);
        register_mib_detach ();
        if (main_session != NULL)
        {
            remove_trap_session (ss);
            snmp_close (main_session);
            /*
             * We need to remove the callbacks attached to the callback
             * session because they have a magic callback data structure
             * which includes a pointer to the main session
             *    (which is no longer valid).
             *
             * Given that the main session is not responsive anyway.
             * it shoudn't matter if we lose some outstanding requests.
             */
            if (agentx_callback_sess != NULL)
            {
                snmp_close (agentx_callback_sess);
                agentx_callback_sess = NULL;

                subagent_init_callback_session ();
            }
            main_session = NULL;
            agentx_reopen_session (0, NULL);
        }
        else
        {
            snmp_close (main_session);
            main_session = NULL;
        }
    }
    else
    {
        DEBUGMSGTL (("agentx/subagent", "session %p responded to ping\n", ss));
    }
}
void
agentx_reopen_session(unsigned int clientreg, void *clientarg)
{
    DEBUGMSGTL(("agentx/subagent", "agentx_reopen_session(%d) called\n",
                clientreg));

    if (subagent_open_master_session() == 0) {
        /*
         * Successful.  Delete the alarm handle if one exists.  
         */
        if (clientreg != 0) {
            snmp_alarm_unregister(clientreg);
        }

        /*
         * Reregister all our nodes.  
         */
        register_mib_reattach();

        /*
         * Register a ping alarm (if need be).  
         */
        subagent_register_ping_alarm(0, 0, 0, main_session);
    } else {
        if (clientreg == 0) {
            /*
             * Register a reattach alarm for later 
             */
            subagent_register_ping_alarm(0, 0, 0, main_session);
        }
    }
}
Esempio n. 4
0
/*
 * sql cleanup function, called at exit
 */
static void
netsnmp_mysql_cleanup(void)
{
    DEBUGMSGTL(("sql:cleanup"," called\n"));

    /** unregister alarm */
    if (_sql.alarm_id)
        snmp_alarm_unregister(_sql.alarm_id);

    /** save any queued traps */
    if (CONTAINER_SIZE(_sql.queue))
        _sql_process_queue(0,NULL);

    CONTAINER_FREE(_sql.queue);
    _sql.queue = NULL;

    if (_sql.trap_stmt) {
        mysql_stmt_close(_sql.trap_stmt);
        _sql.trap_stmt = NULL;
    }
    if (_sql.vb_stmt) {
        mysql_stmt_close(_sql.vb_stmt);
        _sql.vb_stmt = NULL;
    }
    
    /** disconnect from server */
    netsnmp_sql_disconnected();

    if (_sql.conn) {
        mysql_close(_sql.conn);
        _sql.conn = NULL;
    }

    mysql_library_end();
}
Esempio n. 5
0
File: rows.c Progetto: 274914765/C
static void rowapi_delete (RMON_ENTRY_T * eold)
{
    register RMON_ENTRY_T *eptr;

    register RMON_ENTRY_T *prev = NULL;

    TABLE_DEFINTION_T *table_ptr;

    table_ptr = (TABLE_DEFINTION_T *) eold->table_ptr;

    /*
     * delete timout scheduling 
     */
    snmp_alarm_unregister (eold->timer_id);
    ag_trace ("Entry %ld in %s has been deleted", eold->ctrl_index, table_ptr->name);

    /*
     * It it was valid entry => deactivate it 
     */
    if (RMON1_ENTRY_VALID == eold->status)
    {
        if (table_ptr->ClbkDeactivate)
            table_ptr->ClbkDeactivate (eold);
    }

    /*
     * delete it in users's sence 
     */
    if (table_ptr->ClbkDelete)
        table_ptr->ClbkDelete ((RMON_ENTRY_T *) eold->body);

    if (eold->body)
    {
        AGFREE (eold->body);
    }

    if (eold->owner)
        AGFREE (eold->owner);

    /*
     * delete it from the list in table 
     */

    table_ptr->current_number_of_entries--;

    for (eptr = table_ptr->first; eptr; eptr = eptr->next)
    {
        if (eptr == eold)
            break;
        prev = eptr;
    }

    if (prev)
        prev->next = eold->next;
    else
        table_ptr->first = eold->next;

    AGFREE (eold);
}
Esempio n. 6
0
File: alarm.c Progetto: 274914765/C
int alarm_Deactivate (RMON_ENTRY_T * eptr)
{
    CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;

    snmp_alarm_unregister (body->timer_id);
#if 0                            /* KUKU */
    ag_trace ("kuku_sum=%ld kuku_cnt=%ld sp=%ld", (long) kuku_sum, (long) kuku_cnt, (long) (kuku_sum / kuku_cnt));
#endif
    return 0;
}
Esempio n. 7
0
void
shutdown_pass_persist(void)
{
    if (pipe_check_alarm_id) {
        snmp_alarm_unregister(pipe_check_alarm_id);
        pipe_check_alarm_id = 0;
    }

    /* Close any open pipes. */
    destruct_persist_pipes();
}
void
expExpression_disable( struct expExpression *entry )
{
    if (!entry)
        return;

    if (entry->alarm) {
        snmp_alarm_unregister( entry->alarm );
        entry->alarm = 0;
        /* Perhaps release any previous results ?? */
    }
}
Esempio n. 9
0
void
mteTrigger_disable( struct mteTrigger *entry )
{
    if (!entry)
        return;

    if (entry->alarm) {
        snmp_alarm_unregister( entry->alarm );
        entry->alarm = 0;
        /* XXX - perhaps release any previous results */
    }
}
Esempio n. 10
0
void vxge_trap_manage(struct vxge_trap_info *trap, long enable)
{
	void (*service)(struct vxge_trap_info *trap);

	if (enable && trap->alarm_id) {
		/* unattended alarm, destroy it */
		snmp_alarm_unregister(trap->alarm_id);
		vxge_log("Unattended alarm removed\n");
	}

	service = (enable) ? vxge_trap_start : vxge_trap_stop;

	service(trap);
}
Esempio n. 11
0
static void
rowapi_too_long_creation_callback(unsigned int clientreg, void *clientarg)
{
    RMON_ENTRY_T   *eptr;
    TABLE_DEFINTION_T *table_ptr;

    eptr = (RMON_ENTRY_T *) clientarg;
    table_ptr = (TABLE_DEFINTION_T *) eptr->table_ptr;
    if (RMON1_ENTRY_VALID != eptr->status) {
        ag_trace("row #%d in %s was under creation more then %ld sec.",
                 eptr->ctrl_index, table_ptr->name,
                 (long) MAX_CREATION_TIME);
        rowapi_delete(eptr);
    } else {
        snmp_alarm_unregister(eptr->timer_id);
    }
}
Esempio n. 12
0
/** stops the recurring cache_load callback */
void
netsnmp_cache_timer_stop(netsnmp_cache *cache)
{
    if(NULL == cache)
        return;

    if(0 == cache->timer_id) {
        snmp_log(LOG_WARNING, "cache has no timer id.\n");
        return;
    }

    DEBUGMSGT(("cache_timer:stop",
               "stopping timer %lu for cache %p\n", cache->timer_id, cache));

    snmp_alarm_unregister(cache->timer_id);
    cache->flags |= NETSNMP_CACHE_AUTO_RELOAD;
}
static int
subagent_register_ping_alarm(int majorID, int minorID,
                             void *serverarg, void *clientarg)
{

    netsnmp_session *ss = (netsnmp_session *) clientarg;
    int             ping_interval =
        netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL);

    if (!ping_interval)         /* don't do anything if not setup properly */
        return 0;

    /*
     * register a ping alarm, if desired 
     */
    if (ss) {
        if (ss->securityModel != SNMP_DEFAULT_SECMODEL) {
            DEBUGMSGTL(("agentx/subagent",
                        "unregister existing alarm %d\n",
                        ss->securityModel));
            snmp_alarm_unregister(ss->securityModel);
        }

        DEBUGMSGTL(("agentx/subagent",
                    "register ping alarm every %d seconds\n",
                    ping_interval));
        /*
         * we re-use the securityModel parameter for an alarm stash,
         * since agentx doesn't need it 
         */
        ss->securityModel = snmp_alarm_register(ping_interval, SA_REPEAT,
                                                agentx_check_session, ss);
    } else {
        /*
         * attempt to open it later instead 
         */
        DEBUGMSGTL(("agentx/subagent",
                    "subagent not properly attached, postponing registration till later....\n"));
        snmp_alarm_register(ping_interval, SA_REPEAT,
                            agentx_reopen_session, NULL);
    }
    return 0;
}
void
expExpression_enable( struct expExpression *entry )
{
    DEBUGMSG(("disman:expr:run", "Enabling %s\n", entry->expName));
    if (!entry)
        return;

    if (entry->alarm) {
        /* or explicitly call expExpression_disable ?? */
        snmp_alarm_unregister( entry->alarm );
        entry->alarm = 0;
    }

    if (entry->expDeltaInterval) {
        entry->alarm = snmp_alarm_register(
                           entry->expDeltaInterval, SA_REPEAT,
                           expExpression_getData, entry );
        expExpression_getData( entry->alarm, (void*)entry );
    }
}
Esempio n. 15
0
void
sa_update_entry(struct snmp_alarm *alrm) {
  if (alrm->seconds == 0) {
    DEBUGMSGTL(("snmp_alarm_update_entry","illegal 0 length alarm timer specified\n"));
    return; /* illegal */
  }
  if (alrm->lastcall == 0) {
    /* never been called yet, call seconds from now. */
    alrm->lastcall = time(NULL);
    alrm->nextcall = alrm->lastcall + alrm->seconds;
  } else if (alrm->nextcall == 0) {
    /* We've been called but not reset for the next? call */
    if ((alrm->flags & SA_REPEAT) == SA_REPEAT) {
      alrm->nextcall = alrm->lastcall + alrm->seconds;
    } else {
      /* single time call, remove it */
      snmp_alarm_unregister(alrm->clientreg);
    }
  }
}
Esempio n. 16
0
File: rows.c Progetto: 274914765/C
static int rowapi_activate (TABLE_DEFINTION_T * table_ptr, RMON_ENTRY_T * eptr)
{
    RMON1_ENTRY_STATUS_T prev_status = eptr->status;

    eptr->status = RMON1_ENTRY_VALID;

    if (table_ptr->ClbkActivate)
    {
        if (0 != table_ptr->ClbkActivate (eptr))
        {
            ag_trace ("Can't activate entry #%ld in %s", eptr->ctrl_index, table_ptr->name);
            eptr->status = prev_status;
            return SNMP_ERR_BADVALUE;
        }
    }

    snmp_alarm_unregister (eptr->timer_id);
    eptr->timer_id = 0;
    ag_trace ("Entry %ld in %s has been activated", eptr->ctrl_index, table_ptr->name);
    return SNMP_ERR_NOERROR;
}
Esempio n. 17
0
File: alarm.c Progetto: 274914765/C
int alarm_Copy (RMON_ENTRY_T * eptr)
{
    CRTL_ENTRY_T *body = (CRTL_ENTRY_T *) eptr->body;

    CRTL_ENTRY_T *clone = (CRTL_ENTRY_T *) eptr->tmp;

    if (RMON1_ENTRY_VALID == eptr->status && clone->rising_threshold <= clone->falling_threshold)
    {
        ag_trace ("alarm_Copy failed: invalid thresholds");
        return SNMP_ERR_BADVALUE;
    }

    if (clone->interval != body->interval)
    {
        if (RMON1_ENTRY_VALID == eptr->status)
        {
            snmp_alarm_unregister (body->timer_id);
            body->timer_id = snmp_alarm_register (clone->interval, SA_REPEAT, alarm_check_var, eptr);
        }
        body->interval = clone->interval;
    }

    if (snmp_oid_compare (clone->var_name.objid, clone->var_name.length, body->var_name.objid, body->var_name.length))
    {
        memcpy (&body->var_name, &clone->var_name, sizeof (VAR_OID_T));
    }

    body->sample_type = clone->sample_type;
    body->startup_type = clone->startup_type;
    body->sample_type = clone->sample_type;
    body->rising_threshold = clone->rising_threshold;
    body->falling_threshold = clone->falling_threshold;
    body->rising_event_index = clone->rising_event_index;
    body->falling_event_index = clone->falling_event_index;
    /*
     * ag_trace ("alarm_Copy: rising_threshold=%lu falling_threshold=%lu",
     * body->rising_threshold, body->falling_threshold); 
     */
    return 0;
}
Esempio n. 18
0
void mteTrigger_enable (struct mteTrigger *entry)
{
    if (!entry)
        return;

    if (entry->alarm)
    {
        /* XXX - or explicitly call mteTrigger_disable ?? */
        snmp_alarm_unregister (entry->alarm);
        entry->alarm = 0;
    }

    if (entry->mteTriggerFrequency)
    {
        /*
         * register once to run ASAP, and another to run
         * at the trigger frequency
         */
        snmp_alarm_register (0, 0, mteTrigger_run, entry);
        entry->alarm = snmp_alarm_register (entry->mteTriggerFrequency, SA_REPEAT, mteTrigger_run, entry);
    }
}
Esempio n. 19
0
File: alarm.c Progetto: 274914765/C
static void alarm_check_var (unsigned int clientreg, void *clientarg)
{
    RMON_ENTRY_T *hdr_ptr;

    CRTL_ENTRY_T *body;

    u_long new_value;

    int ierr;

    hdr_ptr = (RMON_ENTRY_T *) clientarg;
    if (!hdr_ptr)
    {
        ag_trace ("Err: history_get_backet: hdr_ptr=NULL ? (Inserted in shock)");
        return;
    }

    body = (CRTL_ENTRY_T *) hdr_ptr->body;
    if (!body)
    {
        ag_trace ("Err: history_get_backet: body=NULL ? (Inserted in shock)");
        return;
    }

    if (RMON1_ENTRY_VALID != hdr_ptr->status)
    {
        ag_trace ("Err: history_get_backet when entry %d is not valid ?!!", (int) hdr_ptr->ctrl_index);
        snmp_alarm_unregister (body->timer_id);
        return;
    }

    ierr = fetch_var_val (body->var_name.objid, body->var_name.length, &new_value);
    if (SNMP_ERR_NOERROR != ierr)
    {
        ag_trace ("Err: Can't fetch var_name");
        return;
    }

    body->value = (SAMPLE_TYPE_ABSOLUTE == body->sample_type) ? new_value : new_value - body->last_abs_value;
    body->last_abs_value = new_value;
    /*
     * ag_trace ("fetched value=%ld check %ld", (long) new_value, (long) body->value); 
     */
#if 0                            /* KUKU */
    kuku_sum += body->value;
    kuku_cnt++;
#endif

    if (ALARM_RISING != body->prev_alarm &&
        body->value >= body->rising_threshold &&
        SNMP_ERR_NOERROR == event_api_send_alarm (1, hdr_ptr->ctrl_index,
                                                  body->rising_event_index,
                                                  body->var_name.objid,
                                                  body->var_name.length,
                                                  ALARM_RISING, body->value, body->rising_threshold, "Rising"))
        body->prev_alarm = ALARM_RISING;
    else if (ALARM_FALLING != body->prev_alarm &&
             body->value <= body->falling_threshold &&
             SNMP_ERR_NOERROR == event_api_send_alarm (0,
                                                       hdr_ptr->ctrl_index,
                                                       body->falling_event_index,
                                                       body->var_name.objid,
                                                       body->var_name.length, ALARM_RISING,
                                                       body->value, body->falling_threshold, "Falling"))
        body->prev_alarm = ALARM_FALLING;
}
/*
 *  Gather the data necessary for evaluating an expression.
 *
 *  This will retrieve *all* the data relevant for all
 *    instances of this expression, rather than just the
 *    just the values needed for expanding a given instance.
 */
void
expExpression_getData( unsigned int reg, void *clientarg )
{
    struct expExpression  *entry = (struct expExpression *)clientarg;
    netsnmp_tdata_row     *row;
    netsnmp_variable_list *var;
    int ret;

    if ( !entry && reg ) {
        snmp_alarm_unregister( reg );
        return;
    }

    if (( entry->expExpression[0] == '\0' ) ||
        !(entry->flags & EXP_FLAG_ACTIVE)   ||
        !(entry->flags & EXP_FLAG_VALID))
        return;

    DEBUGMSGTL(("disman:expr:run", "Gathering expression data (%s, %s)\n",
                                    entry->expOwner, entry->expName));

    /*
     *  This routine can be called in two situations:
     *    - regularly by 'snmp_alarm'  (reg != 0)
     *         (as part of ongoing delta-value sampling)
     *    - on-demand                  (reg == 0)
     *         (for evaluating a particular entry)
     *
     *  If a regularly sampled expression (entry->alarm != 0)
     *    is invoked on-demand (reg == 0), then use the most
     *    recent sampled values, rather than retrieving them again.
     */
    if ( !reg && entry->alarm )
        return;

    /*
     * XXX - may want to implement caching for on-demand evaluation
     *       of non-regularly sampled expressions.
     */

    /*
     * For a wildcarded expression, expExpressionPrefix is used
     *   to determine which object instances to retrieve.
     * (For a non-wildcarded expression, we already know
     *   explicitly which object instances will be needed).
     *
     * If we walk this object here, then the results can be
     *   used to build the necessary GET requests for each
     *   individual parameter object (within expObject_getData)
     *
     * This will probably be simpler (and definitely more efficient)
     *   than walking the object instances separately and merging
     *   merging the results).
     *
     * NB: Releasing any old results is handled by expObject_getData.
     *     Assigning to 'entry->pvars' without first releasing the
     *     previous contents does *not* introduce a memory leak.
     */
    if ( entry->expPrefix_len ) {
        var = (netsnmp_variable_list *)
                   SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
        snmp_set_var_objid( var, entry->expPrefix, entry->expPrefix_len);
        ret = netsnmp_query_walk( var, entry->session );
        DEBUGMSGTL(("disman:expr:run", "Walk returned %d\n", ret ));
        entry->pvars = var;
    }

    /* XXX - retrieve sysUpTime.0 value, and check for discontinuity */
  /*
    entry->flags &= ~EXP_FLAG_SYSUT;
    var = (netsnmp_variable_list *)
               SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
    snmp_set_var_objid( var, sysUT_oid, sysUT_oid_len );
    netsnmp_query_get( var, entry->session );
    if ( *var->val.integer != entry->sysUpTime ) {
        entry->flags |=  EXP_FLAG_SYSUT;
        entry->sysUpTime = *var->val.integer;
    }
    snmp_free_varbind(var);
   */

    /*
     * Loop through the list of relevant objects,
     *   and retrieve the corresponding values.
     */
    for ( row = expObject_getFirst(  entry->expOwner, entry->expName );
          row;
          row = expObject_getNext( row )) {

        /* XXX - may need to check whether owner/name still match */
        expObject_getData( entry, (struct expObject *)row->data);
    }
}
Esempio n. 21
0
void im_stop_heartbeat_cloud(void)
{
	
	snmp_alarm_unregister(timer_hearbeat);
	cnt_time = 0;
}
int
handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
                     netsnmp_pdu *pdu, void *magic)
{
    struct agent_netsnmp_set_info *asi = NULL;
    snmp_callback   mycallback;
    netsnmp_pdu    *internal_pdu = NULL;
    void           *retmagic = NULL;
    ns_subagent_magic *smagic = NULL;

    if (operation == NETSNMP_CALLBACK_OP_DISCONNECT) {
        struct synch_state *state = (struct synch_state *) magic;
        int             period =
            netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL);
        DEBUGMSGTL(("agentx/subagent",
                    "transport disconnect indication\n"));

        /*
         * deal with existing session. This happend if agentx sends
         * a message to the master, but the master goes away before
         * a response is sent. agentx will spin in snmp_synch_response_cb,
         * waiting for a response. At the very least, the waiting
         * flag must be set to break that loop. The rest is copied
         * from disconnect handling in snmp_sync_input.
         */
        if(state) {
            state->waiting = 0;
            state->pdu = NULL;
            state->status = STAT_ERROR;
            session->s_snmp_errno = SNMPERR_ABORT;
            SET_SNMP_ERROR(SNMPERR_ABORT);
        }

        /*
         * Deregister the ping alarm, if any, and invalidate all other
         * references to this session.  
         */
        if (session->securityModel != SNMP_DEFAULT_SECMODEL) {
            snmp_alarm_unregister(session->securityModel);
        }
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                            SNMPD_CALLBACK_INDEX_STOP, (void *) session);
        agentx_unregister_callbacks(session);
        remove_trap_session(session);
        register_mib_detach();
        main_session = NULL;
        if (period != 0) {
            /*
             * Pings are enabled, so periodically attempt to re-establish contact 
             * with the master agent.  Don't worry about the handle,
             * agentx_reopen_session unregisters itself if it succeeds in talking 
             * to the master agent.  
             */
            snmp_alarm_register(period, SA_REPEAT, agentx_reopen_session,
                                NULL);
        }
        return 0;
    } else if (operation != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
        DEBUGMSGTL(("agentx/subagent", "unexpected callback op %d\n",
                    operation));
        return 1;
    }

    /*
     * ok, we have a pdu from the net. Modify as needed 
     */

    DEBUGMSGTL(("agentx/subagent", "handling agentx request (req=0x%x,trans="
                "0x%x,sess=0x%x)\n", pdu->reqid,pdu->transid, pdu->sessid));
    pdu->version = AGENTX_VERSION_1;
    pdu->flags |= UCD_MSG_FLAG_ALWAYS_IN_VIEW;

    if (pdu->command == AGENTX_MSG_GET
        || pdu->command == AGENTX_MSG_GETNEXT
        || pdu->command == AGENTX_MSG_GETBULK) {
        smagic =
            (ns_subagent_magic *) calloc(1, sizeof(ns_subagent_magic));
        if (smagic == NULL) {
            DEBUGMSGTL(("agentx/subagent", "couldn't malloc() smagic\n"));
            return 1;
        }
        smagic->original_command = pdu->command;
        smagic->session = session;
        smagic->ovars = NULL;
        retmagic = (void *) smagic;
    }

    switch (pdu->command) {
    case AGENTX_MSG_GET:
        DEBUGMSGTL(("agentx/subagent", "  -> get\n"));
        pdu->command = SNMP_MSG_GET;
        mycallback = handle_subagent_response;
        break;

    case AGENTX_MSG_GETNEXT:
        DEBUGMSGTL(("agentx/subagent", "  -> getnext\n"));
        pdu->command = SNMP_MSG_GETNEXT;

        /*
         * We have to save a copy of the original variable list here because
         * if the master agent has requested scoping for some of the varbinds
         * that information is stored there.  
         */

        smagic->ovars = snmp_clone_varbind(pdu->variables);
        DEBUGMSGTL(("agentx/subagent", "saved variables\n"));
        mycallback = handle_subagent_response;
        break;

    case AGENTX_MSG_GETBULK:
        /*
         * WWWXXX 
         */
        DEBUGMSGTL(("agentx/subagent", "  -> getbulk\n"));
        pdu->command = SNMP_MSG_GETBULK;

        /*
         * We have to save a copy of the original variable list here because
         * if the master agent has requested scoping for some of the varbinds
         * that information is stored there.  
         */

        smagic->ovars = snmp_clone_varbind(pdu->variables);
        DEBUGMSGTL(("agentx/subagent", "saved variables at %p\n",
                    smagic->ovars));
        mycallback = handle_subagent_response;
        break;

    case AGENTX_MSG_RESPONSE:
        SNMP_FREE(smagic);
        DEBUGMSGTL(("agentx/subagent", "  -> response\n"));
        return 1;

    case AGENTX_MSG_TESTSET:
        /*
         * XXXWWW we have to map this twice to both RESERVE1 and RESERVE2 
         */
        DEBUGMSGTL(("agentx/subagent", "  -> testset\n"));
        asi = save_set_vars(session, pdu);
        if (asi == NULL) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING, "save_set_vars() failed\n");
            return 1;
        }
        asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_RESERVE1;
        mycallback = handle_subagent_set_response;
        retmagic = asi;
        break;

    case AGENTX_MSG_COMMITSET:
        DEBUGMSGTL(("agentx/subagent", "  -> commitset\n"));
        asi = restore_set_vars(session, pdu);
        if (asi == NULL) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
            return 1;
        }
        if (asi->mode != SNMP_MSG_INTERNAL_SET_RESERVE2) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING,
                     "dropping bad AgentX request (wrong mode %d)\n",
                     asi->mode);
            return 1;
        }
        asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_ACTION;
        mycallback = handle_subagent_set_response;
        retmagic = asi;
        break;

    case AGENTX_MSG_CLEANUPSET:
        DEBUGMSGTL(("agentx/subagent", "  -> cleanupset\n"));
        asi = restore_set_vars(session, pdu);
        if (asi == NULL) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
            return 1;
        }
        if (asi->mode == SNMP_MSG_INTERNAL_SET_RESERVE1 ||
            asi->mode == SNMP_MSG_INTERNAL_SET_RESERVE2) {
            asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_FREE;
        } else if (asi->mode == SNMP_MSG_INTERNAL_SET_ACTION) {
            asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_COMMIT;
        } else {
            snmp_log(LOG_WARNING,
                     "dropping bad AgentX request (wrong mode %d)\n",
                     asi->mode);
            SNMP_FREE(retmagic);
            return 1;
        }
        mycallback = handle_subagent_set_response;
        retmagic = asi;
        break;

    case AGENTX_MSG_UNDOSET:
        DEBUGMSGTL(("agentx/subagent", "  -> undoset\n"));
        asi = restore_set_vars(session, pdu);
        if (asi == NULL) {
            SNMP_FREE(smagic);
            snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
            return 1;
        }
        asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_UNDO;
        mycallback = handle_subagent_set_response;
        retmagic = asi;
        break;

    default:
        SNMP_FREE(smagic);
        DEBUGMSGTL(("agentx/subagent", "  -> unknown command %d (%02x)\n",
                    pdu->command, pdu->command));
        return 0;
    }

    /*
     * submit the pdu to the internal handler 
     */

    /*
     * We have to clone the PDU here, because when we return from this
     * callback, sess_process_packet will free(pdu), but this call also
     * free()s its argument PDU.  
     */

    internal_pdu = snmp_clone_pdu(pdu);
    internal_pdu->contextName = internal_pdu->community;
    internal_pdu->contextNameLen = internal_pdu->community_len;
    internal_pdu->community = NULL;
    internal_pdu->community_len = 0;
    snmp_async_send(agentx_callback_sess, internal_pdu, mycallback,
                    retmagic);
    return 1;
}
Esempio n. 23
0
/** 
 * trap related functions 
 **/
void vxge_trap_stop(struct vxge_trap_info *trap)
{
	snmp_alarm_unregister(trap->alarm_id);
	memset(trap, 0, sizeof(*trap));
	vxge_log("trap handler stopped...\n");
}
Esempio n. 24
0
int
write_wapialarmflag(int      action,
            u_char   *var_val,
            u_char   var_val_type,
            size_t   var_val_len,
            u_char   *statP,
            oid      *name,
            size_t   name_len)
{
    long value;
    int size;
    char temp[256];

    switch ( action ) {
        case RESERVE1:
          if (var_val_type != ASN_INTEGER) {
              fprintf(stderr, "write to wapiPwlanAp not ASN_INTEGER\n");
              return SNMP_ERR_WRONGTYPE;
          }
          if (var_val_len > sizeof(long)) {
              fprintf(stderr,"write to wapiPwlanAp: bad length\n");
              return SNMP_ERR_WRONGLENGTH;
          }
	  			value = * (long *) var_val ;
	  			if ( value != 0 && value != 1 ) {
              fprintf(stderr,"write to wapiPwlanAp: flag error \n");
              return SNMP_ERR_WRONGVALUE;
          }

          break;
        case RESERVE2:
          break;
        case FREE:   
          break;
        case ACTION:
       
          value = * (long *) var_val;
	     /* write config file .*/
	      memset(temp,0,10);
	      sprintf(temp,"%d",value);
              save_global_conf(SEP_EQUAL,AG_SNMP_CONF,"","ALARM_FLAG",temp);

	      /* write alarm time value.*/
				if( alarmFlag != value ){
		
					if( alarmFlag != 0 && value == 0 ){
						snmp_alarm_unregister(alarmId);	   
		          		}
					else if( alarmFlag == 0 && value != 0 ){
						alarmId=snmp_alarm_register(alarmTimes,  //10  /* seconds */
		        	                SA_REPEAT,      /* repeat (every 30 seconds). */
		                	        register_callback,      /* our callback */
		                        	NULL );    /* no callback data needed */
			     		}
			     		
					alarmFlag=value;
				}
          
          break;

        case UNDO:
             
          break;

        case COMMIT:
            
          break;
    }
    return SNMP_ERR_NOERROR;
}
Esempio n. 25
0
void
mteTrigger_run( unsigned int reg, void *clientarg)
{
    struct mteTrigger *entry = (struct mteTrigger *)clientarg;
    netsnmp_variable_list *var, *vtmp;
    netsnmp_variable_list *vp1, *vp1_prev;
    netsnmp_variable_list *vp2, *vp2_prev;
    netsnmp_variable_list *dvar = NULL;
    netsnmp_variable_list *dv1  = NULL, *dv2 = NULL;
    netsnmp_variable_list sysUT_var;
    int  cmp = 0, n, n2;
    long value;
    const char *reason;

    if (!entry) {
        snmp_alarm_unregister( reg );
        return;
    }
    if (!(entry->flags & MTE_TRIGGER_FLAG_ENABLED ) ||
            !(entry->flags & MTE_TRIGGER_FLAG_ACTIVE  ) ||
            !(entry->flags & MTE_TRIGGER_FLAG_VALID  )) {
        return;
    }

    {
        extern netsnmp_agent_session *netsnmp_processing_set;
        if (netsnmp_processing_set) {
            /*
             * netsnmp_handle_request will not be responsive to our efforts to
             *	Retrieve the requested MIB value(s)...
             * so we will skip it.
             * https://sourceforge.net/tracker/
             *	index.php?func=detail&aid=1557406&group_id=12694&atid=112694
             */
            DEBUGMSGTL(("disman:event:trigger:monitor",
                        "Skipping trigger (%s) while netsnmp_processing_set\n",
                        entry->mteTName));
            return;
        }
    }

    /*
     * Retrieve the requested MIB value(s)...
     */
    DEBUGMSGTL(( "disman:event:trigger:monitor", "Running trigger (%s)\n", entry->mteTName));
    var = (netsnmp_variable_list *)SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
    if (!var) {
        _mteTrigger_failure("failed to create mteTrigger query varbind");
        return;
    }
    snmp_set_var_objid( var, entry->mteTriggerValueID,
                        entry->mteTriggerValueID_len );
    if ( entry->flags & MTE_TRIGGER_FLAG_VWILD ) {
        n = netsnmp_query_walk( var, entry->session );
    } else {
        n = netsnmp_query_get(  var, entry->session );
    }
    if ( n != SNMP_ERR_NOERROR ) {
        DEBUGMSGTL(( "disman:event:trigger:monitor", "Trigger query (%s) failed: %d\n",
                     (( entry->flags & MTE_TRIGGER_FLAG_VWILD ) ? "walk" : "get"), n));
        _mteTrigger_failure( "failed to run mteTrigger query" );
        snmp_free_varbind(var);
        return;
    }

    /*
     * ... canonicalise the results (to simplify later comparisons)...
     */

    vp1 = var;
    vp1_prev = NULL;
    vp2 = entry->old_results;
    vp2_prev = NULL;
    entry->count=0;
    while (vp1) {
        /*
         * Flatten various missing values/exceptions into a single form
         */
        switch (vp1->type) {
        case SNMP_NOSUCHINSTANCE:
        case SNMP_NOSUCHOBJECT:
        case ASN_PRIV_RETRY:   /* Internal only ? */
            vp1->type = ASN_NULL;
        }
        /*
         * Keep track of how many entries have been retrieved.
         */
        entry->count++;

        /*
         * Ensure previous and current result match
         *  (with corresponding entries in both lists)
         * and set the flags indicating which triggers are armed
         */
        if (vp2) {
            cmp = snmp_oid_compare(vp1->name, vp1->name_length,
                                   vp2->name, vp2->name_length);
            if ( cmp < 0 ) {
                /*
                 * If a new value has appeared, insert a matching
                 * dummy entry into the previous result list.
                 *
                 * XXX - check how this is best done.
                 */
                vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                if (!vtmp) {
                    _mteTrigger_failure(
                        "failed to create mteTrigger temp varbind");
                    snmp_free_varbind(var);
                    return;
                }
                vtmp->type = ASN_NULL;
                snmp_set_var_objid( vtmp, vp1->name, vp1->name_length );
                vtmp->next_variable = vp2;
                if (vp2_prev) {
                    vp2_prev->next_variable = vtmp;
                } else {
                    entry->old_results      = vtmp;
                }
                vp2_prev   = vtmp;
                vp1->index = MTE_ARMED_ALL;	/* XXX - plus a new flag */
                vp1_prev   = vp1;
                vp1        = vp1->next_variable;
            }
            else if ( cmp == 0 ) {
                /*
                 * If it's a continuing entry, just copy across the armed flags
                 */
                vp1->index = vp2->index;
                vp1_prev   = vp1;
                vp1        = vp1->next_variable;
                vp2_prev   = vp2;
                vp2        = vp2->next_variable;
            } else {
                /*
                 * If a value has just disappeared, insert a
                 * matching dummy entry into the current result list.
                 *
                 * XXX - check how this is best done.
                 *
                 */
                if ( vp2->type != ASN_NULL ) {
                    vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                    if (!vtmp) {
                        _mteTrigger_failure(
                            "failed to create mteTrigger temp varbind");
                        snmp_free_varbind(var);
                        return;
                    }
                    vtmp->type = ASN_NULL;
                    snmp_set_var_objid( vtmp, vp2->name, vp2->name_length );
                    vtmp->next_variable = vp1;
                    if (vp1_prev) {
                        vp1_prev->next_variable = vtmp;
                    } else {
                        var                     = vtmp;
                    }
                    vp1_prev = vtmp;
                    vp2_prev = vp2;
                    vp2      = vp2->next_variable;
                } else {
                    /*
                     * But only if this entry has *just* disappeared.  If the
                     * entry from the last run was a dummy too, then remove it.
                     *   (leaving vp2_prev unchanged)
                     */
                    vtmp = vp2;
                    if (vp2_prev) {
                        vp2_prev->next_variable = vp2->next_variable;
                    } else {
                        entry->old_results      = vp2->next_variable;
                    }
                    vp2  = vp2->next_variable;
                    vtmp->next_variable = NULL;
                    snmp_free_varbind( vtmp );
                }
            }
        } else {
            /*
             * No more old results to compare.
             * Either all remaining values have only just been created ...
             *   (and we need to create dummy 'old' entries for them)
             */
            if ( vp2_prev ) {
                vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                if (!vtmp) {
                    _mteTrigger_failure(
                        "failed to create mteTrigger temp varbind");
                    snmp_free_varbind(var);
                    return;
                }
                vtmp->type = ASN_NULL;
                snmp_set_var_objid( vtmp, vp1->name, vp1->name_length );
                vtmp->next_variable     = vp2_prev->next_variable;
                vp2_prev->next_variable = vtmp;
                vp2_prev                = vtmp;
            }
            /*
             * ... or this is the first run through
             *   (and there were no old results at all)
             *
             * In either case, mark the current entry as armed and new.
             * Note that we no longer need to maintain 'vp1_prev'
             */
            vp1->index = MTE_ARMED_ALL;	/* XXX - plus a new flag */
            vp1        = vp1->next_variable;
        }
    }

    /*
     * ... and then work through these result(s), deciding
     *     whether or not to trigger the corresponding event.
     *
     *  Note that there's no point in evaluating Existence or
     *    Boolean tests if there's no corresponding event.
     *   (Even if the trigger matched, nothing would be done anyway).
     */
    if ((entry->mteTriggerTest & MTE_TRIGGER_EXISTENCE) &&
            (entry->mteTExEvent[0] != '\0' )) {
        /*
         * If we don't have a record of previous results,
         * this must be the first time through, so consider
         * the mteTriggerExistenceStartup tests.
         */
        if ( !entry->old_results ) {
            /*
             * With the 'present(0)' test, the trigger should fire
             *   for each value in the varbind list returned
             *   (whether the monitored value is wildcarded or not).
             */
            if (entry->mteTExTest & entry->mteTExStartup & MTE_EXIST_PRESENT) {
                for (vp1 = var; vp1; vp1=vp1->next_variable) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing initial existence test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire",
                                 " (present)\n"));;
                    entry->mteTriggerXOwner   = entry->mteTExObjOwner;
                    entry->mteTriggerXObjects = entry->mteTExObjects;
                    entry->mteTriggerFired    = vp1;
                    n = entry->mteTriggerValueID_len;
                    mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent,
                                  entry, vp1->name+n, vp1->name_length-n);
                }
            }
            /*
             * An initial 'absent(1)' test only makes sense when
             *   monitoring a non-wildcarded OID (how would we know
             *   which rows of the table "ought" to exist, but don't?)
             */
            if (entry->mteTExTest & entry->mteTExStartup & MTE_EXIST_ABSENT) {
                if (!(entry->flags & MTE_TRIGGER_FLAG_VWILD) &&
                        var->type == ASN_NULL ) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing initial existence test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 var->name, var->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire",
                                 " (absent)\n"));;
                    entry->mteTriggerXOwner   = entry->mteTExObjOwner;
                    entry->mteTriggerXObjects = entry->mteTExObjects;
                    /*
                     * It's unclear what value the 'mteHotValue' payload
                     *  should take when a monitored instance does not
                     *  exist on startup. The only sensible option is
                     *  to report a NULL value, but this clashes with
                     * the syntax of the mteHotValue MIB object.
                     */
                    entry->mteTriggerFired    = var;
                    n = entry->mteTriggerValueID_len;
                    mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent,
                                  entry, var->name+n, var->name_length-n);
                }
            }
        } /* !old_results */
        /*
         * Otherwise, compare the current set of results with
         * the previous ones, looking for changes.  We can
         * assume that the two lists match (see above).
         */
        else {
            for (vp1 = var, vp2 = entry->old_results;
                    vp1;
                    vp1=vp1->next_variable, vp2=vp2->next_variable) {

                /* Use this field to indicate that the trigger should fire */
                entry->mteTriggerFired = NULL;
                reason                 = NULL;

                if ((entry->mteTExTest & MTE_EXIST_PRESENT) &&
                        (vp1->type != ASN_NULL) &&
                        (vp2->type == ASN_NULL)) {
                    /* A new instance has appeared */
                    entry->mteTriggerFired = vp1;
                    reason = "(present)";

                } else if ((entry->mteTExTest & MTE_EXIST_ABSENT) &&
                           (vp1->type == ASN_NULL) &&
                           (vp2->type != ASN_NULL)) {

                    /*
                     * A previous instance has disappeared.
                     *
                     * It's unclear what value the 'mteHotValue' payload
                     *  should take when this happens - the previous
                     *  value (vp2), or a NULL value (vp1) ?
                     * NULL makes more sense logically, but clashes
                     *  with the syntax of the mteHotValue MIB object.
                     */
                    entry->mteTriggerFired = vp2;
                    reason = "(absent)";

                } else if ((entry->mteTExTest & MTE_EXIST_CHANGED) &&
                           ((vp1->val_len != vp2->val_len) ||
                            (memcmp( vp1->val.string, vp2->val.string,
                                     vp1->val_len) != 0 ))) {
                    /*
                     * This comparison detects changes in *any* type
                     *  of value, numeric or string (or even OID).
                     *
                     * Unfortunately, the default 'mteTriggerFired'
                     *  notification payload can't report non-numeric
                     *  changes properly (see syntax of 'mteHotValue')
                     */
                    entry->mteTriggerFired = vp1;
                    reason = "(changed)";
                }
                if ( entry->mteTriggerFired ) {
                    /*
                     * One of the above tests has matched,
                     *   so fire the trigger.
                     */
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing existence test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire",
                                 " %s\n", reason));;
                    entry->mteTriggerXOwner   = entry->mteTExObjOwner;
                    entry->mteTriggerXObjects = entry->mteTExObjects;
                    n = entry->mteTriggerValueID_len;
                    mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent,
                                  entry, vp1->name+n, vp1->name_length-n);
                }
            }
        } /* !old_results - end of else block */
    } /* MTE_TRIGGER_EXISTENCE */


    if (( entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN   ) ||
            ( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD )) {
        /*
         * Although Existence tests can work with any syntax values,
         * Boolean and Threshold tests are integer-only.  Ensure that
         * the returned value(s) are appropriate.
         *
         * Note that we only need to check the first value, since all
         *  instances of a given object should have the same syntax.
         */
        switch (var->type) {
        case ASN_INTEGER:
        case ASN_COUNTER:
        case ASN_GAUGE:
        case ASN_TIMETICKS:
        case ASN_UINTEGER:
        case ASN_COUNTER64:
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
        case ASN_OPAQUE_COUNTER64:
        case ASN_OPAQUE_U64:
        case ASN_OPAQUE_I64:
#endif
            /* OK */
            break;
        default:
            /*
             * Other syntax values can't be used for Boolean/Theshold
             * tests. Report this as an error, and then rotate the
             * results ready for the next run, (which will presumably
             * also detect this as an error once again!)
             */
            DEBUGMSGTL(( "disman:event:trigger:fire",
                         "Returned non-integer result(s): "));
            DEBUGMSGOID(("disman:event:trigger:fire",
                         var->name, var->name_length));
            DEBUGMSG((   "disman:event:trigger:fire",
                         " (boolean/threshold) %d\n", var->type));;
            snmp_free_varbind( entry->old_results );
            entry->old_results = var;
            return;
        }


        /*
         * Retrieve the discontinuity markers for delta-valued samples.
         * (including sysUpTime.0 if not specified explicitly).
         */
        if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) {
            /*
             * We'll need sysUpTime.0 regardless...
             */
            DEBUGMSGTL(("disman:event:delta", "retrieve sysUpTime.0\n"));
            memset( &sysUT_var, 0, sizeof( netsnmp_variable_list ));
            snmp_set_var_objid( &sysUT_var, _sysUpTime_instance,
                                _sysUpTime_inst_len );
            netsnmp_query_get(  &sysUT_var, entry->session );

            if (!(entry->flags & MTE_TRIGGER_FLAG_SYSUPT)) {
                /*
                 * ... but only retrieve the configured discontinuity
                 *      marker(s) if they refer to something different.
                 */
                DEBUGMSGTL(( "disman:event:delta",
                             "retrieve discontinuity marker(s): "));
                DEBUGMSGOID(("disman:event:delta", entry->mteDeltaDiscontID,
                             entry->mteDeltaDiscontID_len ));
                DEBUGMSG((   "disman:event:delta", " %s\n",
                             (entry->flags & MTE_TRIGGER_FLAG_DWILD ? " (wild)" : "")));

                dvar = (netsnmp_variable_list *)
                       SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                if (!dvar) {
                    _mteTrigger_failure(
                        "failed to create mteTrigger delta query varbind");
                    return;
                }
                snmp_set_var_objid( dvar, entry->mteDeltaDiscontID,
                                    entry->mteDeltaDiscontID_len );
                if ( entry->flags & MTE_TRIGGER_FLAG_DWILD ) {
                    n = netsnmp_query_walk( dvar, entry->session );
                } else {
                    n = netsnmp_query_get(  dvar, entry->session );
                }
                if ( n != SNMP_ERR_NOERROR ) {
                    _mteTrigger_failure( "failed to run mteTrigger delta query" );
                    snmp_free_varbind( dvar );
                    return;
                }
            }

            /*
             * We can't calculate delta values the first time through,
             *  so there's no point in evaluating the remaining tests.
             *
             * Save the results (and discontinuity markers),
             *   ready for the next run.
             */
            if ( !entry->old_results ) {
                entry->old_results =  var;
                entry->old_deltaDs = dvar;
                entry->sysUpTime   = *sysUT_var.val.integer;
                return;
            }
            /*
             * If the sysUpTime marker has been reset (or strictly,
             *   has advanced by less than the monitor frequency),
             *  there's no point in trying the remaining tests.
             */

            if (*sysUT_var.val.integer < entry->sysUpTime) {
                DEBUGMSGTL(( "disman:event:delta",
                             "single discontinuity: (sysUT)\n"));
                snmp_free_varbind( entry->old_results );
                snmp_free_varbind( entry->old_deltaDs );
                entry->old_results =  var;
                entry->old_deltaDs = dvar;
                entry->sysUpTime   = *sysUT_var.val.integer;
                return;
            }
            /*
             * Similarly if a separate (non-wildcarded) discontinuity
             *  marker has changed, then there's no
             *  point in trying to evaluate these tests either.
             */
            if (!(entry->flags & MTE_TRIGGER_FLAG_DWILD)  &&
                    !(entry->flags & MTE_TRIGGER_FLAG_SYSUPT) &&
                    (!entry->old_deltaDs ||
                     (entry->old_deltaDs->val.integer != dvar->val.integer))) {
                DEBUGMSGTL((  "disman:event:delta", "single discontinuity: ("));
                DEBUGMSGOID(( "disman:event:delta", entry->mteDeltaDiscontID,
                              entry->mteDeltaDiscontID_len));
                DEBUGMSG((    "disman:event:delta", ")\n"));
                snmp_free_varbind( entry->old_results );
                snmp_free_varbind( entry->old_deltaDs );
                entry->old_results =  var;
                entry->old_deltaDs = dvar;
                entry->sysUpTime   = *sysUT_var.val.integer;
                return;
            }

            /*
             * Ensure that the list of (wildcarded) discontinuity
             *  markers matches the list of monitored values
             *  (inserting/removing discontinuity varbinds as needed)
             *
             * XXX - An alternative approach would be to use the list
             *    of monitored values (instance subidentifiers) to build
             *    the exact list of delta markers to retrieve earlier.
             */
            if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                vp1      =  var;
                vp2      = dvar;
                vp2_prev = NULL;
                n  = entry->mteTriggerValueID_len;
                n2 = entry->mteDeltaDiscontID_len;
                while (vp1) {
                    /*
                     * For each monitored instance, check whether
                     *   there's a matching discontinuity entry.
                     */
                    cmp = snmp_oid_compare(vp1->name+n,  vp1->name_length-n,
                                           vp2->name+n2, vp2->name_length-n2 );
                    if ( cmp < 0 ) {
                        /*
                         * If a discontinuity entry is missing,
                         *   insert a (dummy) varbind.
                         * The corresponding delta calculation will
                         *   fail, but this simplifies the later code.
                         */
                        vtmp = (netsnmp_variable_list *)
                               SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                        if (!vtmp) {
                            _mteTrigger_failure(
                                "failed to create mteTrigger discontinuity varbind");
                            snmp_free_varbind(dvar);
                            return;
                        }
                        snmp_set_var_objid(vtmp, entry->mteDeltaDiscontID,
                                           entry->mteDeltaDiscontID_len);
                        /* XXX - append instance subids */
                        vtmp->next_variable     = vp2;
                        vp2_prev->next_variable = vtmp;
                        vp2_prev                = vtmp;
                        vp1 = vp1->next_variable;
                    } else if ( cmp == 0 ) {
                        /*
                         * Matching discontinuity entry -  all OK.
                         */
                        vp2_prev = vp2;
                        vp2      = vp2->next_variable;
                        vp1      = vp1->next_variable;
                    } else {
                        /*
                         * Remove unneeded discontinuity entry
                         */
                        vtmp = vp2;
                        vp2_prev->next_variable = vp2->next_variable;
                        vp2                     = vp2->next_variable;
                        vtmp->next_variable = NULL;
                        snmp_free_varbind( vtmp );
                    }
                }
                /*
                 * XXX - Now need to ensure that the old list of
                 *   delta discontinuity markers matches as well.
                 */
            }
        } /* delta samples */
    } /* Boolean/Threshold test checks */



    /*
     * Only run the Boolean tests if there's an event to be triggered
     */
    if ((entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN) &&
            (entry->mteTBoolEvent[0] != '\0' )) {

        if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
            vp2 = entry->old_results;
            if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                dv1 = dvar;
                dv2 = entry->old_deltaDs;
            }
        }
        for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
            /*
             * Determine the value to be monitored...
             */
            if ( !vp1->val.integer ) {  /* No value */
                if ( vp2 )
                    vp2 = vp2->next_variable;
                continue;
            }
            if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
                if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                    /*
                     * We've already checked any non-wildcarded
                     *   discontinuity markers (inc. sysUpTime.0).
                     * Validate this particular sample against
                     *   the relevant wildcarded marker...
                     */
                    if ((dv1->type == ASN_NULL)  ||
                            (dv1->type != dv2->type) ||
                            (*dv1->val.integer != *dv2->val.integer)) {
                        /*
                         * Bogus or changed discontinuity marker.
                         * Need to skip this sample.
                         */
                        DEBUGMSGTL(( "disman:event:delta", "discontinuity occurred: "));
                        DEBUGMSGOID(("disman:event:delta", vp1->name,
                                     vp1->name_length ));
                        DEBUGMSG((   "disman:event:delta", " \n" ));
                        vp2 = vp2->next_variable;
                        continue;
                    }
                }
                /*
                 * ... and check there is a previous sample to calculate
                 *   the delta value against (regardless of whether the
                 *   discontinuity marker was wildcarded or not).
                 */
                if (vp2->type == ASN_NULL) {
                    DEBUGMSGTL(( "disman:event:delta", "missing sample: "));
                    DEBUGMSGOID(("disman:event:delta", vp1->name,
                                 vp1->name_length ));
                    DEBUGMSG((   "disman:event:delta", " \n" ));
                    vp2 = vp2->next_variable;
                    continue;
                }
                value = (*vp1->val.integer - *vp2->val.integer);
                DEBUGMSGTL(( "disman:event:delta", "delta sample: "));
                DEBUGMSGOID(("disman:event:delta", vp1->name,
                             vp1->name_length ));
                DEBUGMSG((   "disman:event:delta", " (%ld - %ld) = %ld\n",
                             *vp1->val.integer,  *vp2->val.integer, value));
                vp2 = vp2->next_variable;
            } else {
                value = *vp1->val.integer;
            }

            /*
             * ... evaluate the comparison ...
             */
            switch (entry->mteTBoolComparison) {
            case MTE_BOOL_UNEQUAL:
                cmp = ( value != entry->mteTBoolValue );
                break;
            case MTE_BOOL_EQUAL:
                cmp = ( value == entry->mteTBoolValue );
                break;
            case MTE_BOOL_LESS:
                cmp = ( value <  entry->mteTBoolValue );
                break;
            case MTE_BOOL_LESSEQUAL:
                cmp = ( value <= entry->mteTBoolValue );
                break;
            case MTE_BOOL_GREATER:
                cmp = ( value >  entry->mteTBoolValue );
                break;
            case MTE_BOOL_GREATEREQUAL:
                cmp = ( value >= entry->mteTBoolValue );
                break;
            }
            DEBUGMSGTL(( "disman:event:delta", "Bool comparison: (%ld %s %ld) %d\n",
                         value, _ops[entry->mteTBoolComparison],
                         entry->mteTBoolValue, cmp));

            /*
             * ... and decide whether to trigger the event.
             *    (using the 'index' field of the varbind structure
             *     to remember whether the trigger has already fired)
             */
            if ( cmp ) {
                if (vp1->index & MTE_ARMED_BOOLEAN ) {
                    vp1->index &= ~MTE_ARMED_BOOLEAN;
                    /*
                     * NB: Clear the trigger armed flag even if the
                     *   (starting) event dosn't actually fire.
                     *   Otherwise initially true (but suppressed)
                     *   triggers will fire on the *second* probe.
                     */
                    if ( entry->old_results ||
                            (entry->flags & MTE_TRIGGER_FLAG_BSTART)) {
                        DEBUGMSGTL(( "disman:event:trigger:fire",
                                     "Firing boolean test: "));
                        DEBUGMSGOID(("disman:event:trigger:fire",
                                     vp1->name, vp1->name_length));
                        DEBUGMSG((   "disman:event:trigger:fire", "%s\n",
                                     (entry->old_results ? "" : " (startup)")));
                        entry->mteTriggerXOwner   = entry->mteTBoolObjOwner;
                        entry->mteTriggerXObjects = entry->mteTBoolObjects;
                        /*
                         * XXX - when firing a delta-based trigger, should
                         *   'mteHotValue' report the actual value sampled
                         *   (as here), or the delta that triggered the event ?
                         */
                        entry->mteTriggerFired    = vp1;
                        n = entry->mteTriggerValueID_len;
                        mteEvent_fire(entry->mteTBoolEvOwner, entry->mteTBoolEvent,
                                      entry, vp1->name+n, vp1->name_length-n);
                    }
                }
            } else {
                vp1->index |= MTE_ARMED_BOOLEAN;
            }
        }
    }


    /*
     * Only run the basic threshold tests if there's an event to
     *    be triggered.  (Either rising or falling will do)
     */
    if (( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) &&
            ((entry->mteTThRiseEvent[0] != '\0' ) ||
             (entry->mteTThFallEvent[0] != '\0' ))) {

        /*
         * The same delta-sample validation from Boolean
         *   tests also applies here too.
         */
        if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
            vp2 = entry->old_results;
            if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                dv1 = dvar;
                dv2 = entry->old_deltaDs;
            }
        }
        for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
            /*
             * Determine the value to be monitored...
             */
            if ( !vp1->val.integer ) {  /* No value */
                if ( vp2 )
                    vp2 = vp2->next_variable;
                continue;
            }
            if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
                if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                    /*
                     * We've already checked any non-wildcarded
                     *   discontinuity markers (inc. sysUpTime.0).
                     * Validate this particular sample against
                     *   the relevant wildcarded marker...
                     */
                    if ((dv1->type == ASN_NULL)  ||
                            (dv1->type != dv2->type) ||
                            (*dv1->val.integer != *dv2->val.integer)) {
                        /*
                         * Bogus or changed discontinuity marker.
                         * Need to skip this sample.
                         */
                        vp2 = vp2->next_variable;
                        continue;
                    }
                }
                /*
                 * ... and check there is a previous sample to calculate
                 *   the delta value against (regardless of whether the
                 *   discontinuity marker was wildcarded or not).
                 */
                if (vp2->type == ASN_NULL) {
                    vp2 = vp2->next_variable;
                    continue;
                }
                value = (*vp1->val.integer - *vp2->val.integer);
                vp2 = vp2->next_variable;
            } else {
                value = *vp1->val.integer;
            }

            /*
             * ... evaluate the single-value comparisons,
             *     and decide whether to trigger the event.
             */
            cmp = vp1->index;   /* working copy of 'armed' flags */
            if ( value >= entry->mteTThRiseValue ) {
                if (cmp & MTE_ARMED_TH_RISE ) {
                    cmp &= ~MTE_ARMED_TH_RISE;
                    cmp |=  MTE_ARMED_TH_FALL;
                    /*
                     * NB: Clear the trigger armed flag even if the
                     *   (starting) event dosn't actually fire.
                     *   Otherwise initially true (but suppressed)
                     *   triggers will fire on the *second* probe.
                     * Similarly for falling thresholds (see below).
                     */
                    if ( entry->old_results ||
                            (entry->mteTThStartup & MTE_THRESH_START_RISE)) {
                        DEBUGMSGTL(( "disman:event:trigger:fire",
                                     "Firing rising threshold test: "));
                        DEBUGMSGOID(("disman:event:trigger:fire",
                                     vp1->name, vp1->name_length));
                        DEBUGMSG((   "disman:event:trigger:fire", "%s\n",
                                     (entry->old_results ? "" : " (startup)")));
                        /*
                         * If no riseEvent is configured, we need still to
                         *  set the armed flags appropriately, but there's
                         *  no point in trying to fire the (missing) event.
                         */
                        if (entry->mteTThRiseEvent[0] != '\0' ) {
                            entry->mteTriggerXOwner   = entry->mteTThObjOwner;
                            entry->mteTriggerXObjects = entry->mteTThObjects;
                            entry->mteTriggerFired    = vp1;
                            n = entry->mteTriggerValueID_len;
                            mteEvent_fire(entry->mteTThRiseOwner,
                                          entry->mteTThRiseEvent,
                                          entry, vp1->name+n, vp1->name_length-n);
                        }
                    }
                }
            }

            if ( value <= entry->mteTThFallValue ) {
                if (cmp & MTE_ARMED_TH_FALL ) {
                    cmp &= ~MTE_ARMED_TH_FALL;
                    cmp |=  MTE_ARMED_TH_RISE;
                    /* Clear the trigger armed flag (see above) */
                    if ( entry->old_results ||
                            (entry->mteTThStartup & MTE_THRESH_START_FALL)) {
                        DEBUGMSGTL(( "disman:event:trigger:fire",
                                     "Firing falling threshold test: "));
                        DEBUGMSGOID(("disman:event:trigger:fire",
                                     vp1->name, vp1->name_length));
                        DEBUGMSG((   "disman:event:trigger:fire", "%s\n",
                                     (entry->old_results ? "" : " (startup)")));
                        /*
                         * Similarly, if no fallEvent is configured,
                         *  there's no point in trying to fire it either.
                         */
                        if (entry->mteTThRiseEvent[0] != '\0' ) {
                            entry->mteTriggerXOwner   = entry->mteTThObjOwner;
                            entry->mteTriggerXObjects = entry->mteTThObjects;
                            entry->mteTriggerFired    = vp1;
                            n = entry->mteTriggerValueID_len;
                            mteEvent_fire(entry->mteTThFallOwner,
                                          entry->mteTThFallEvent,
                                          entry, vp1->name+n, vp1->name_length-n);
                        }
                    }
                }
            }
            vp1->index = cmp;
        }
    }

    /*
     * The same processing also works for delta-threshold tests (if configured)
     */
    if (( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) &&
            ((entry->mteTThDRiseEvent[0] != '\0' ) ||
             (entry->mteTThDFallEvent[0] != '\0' ))) {

        /*
         * Delta-threshold tests can only be used with
         *   absolute valued samples.
         */
        vp2 = entry->old_results;
        if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
            DEBUGMSGTL(( "disman:event:trigger",
                         "Delta-threshold on delta-sample\n"));
        } else if ( vp2 != NULL ) {
            for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
                /*
                 * Determine the value to be monitored...
                 *  (similar to previous delta-sample processing,
                 *   but without the discontinuity marker checks)
                 */
                if (!vp2) {
                    break;   /* Run out of 'old' values */
                }
                if (( !vp1->val.integer ) ||
                        (vp2->type == ASN_NULL)) {
                    vp2 = vp2->next_variable;
                    continue;
                }
                value = (*vp1->val.integer - *vp2->val.integer);
                vp2 = vp2->next_variable;

                /*
                 * ... evaluate the single-value comparisons,
                 *     and decide whether to trigger the event.
                 */
                cmp = vp1->index;   /* working copy of 'armed' flags */
                if ( value >= entry->mteTThDRiseValue ) {
                    if (vp1->index & MTE_ARMED_TH_DRISE ) {
                        DEBUGMSGTL(( "disman:event:trigger:fire",
                                     "Firing rising delta threshold test: "));
                        DEBUGMSGOID(("disman:event:trigger:fire",
                                     vp1->name, vp1->name_length));
                        DEBUGMSG((   "disman:event:trigger:fire", "\n"));
                        cmp &= ~MTE_ARMED_TH_DRISE;
                        cmp |=  MTE_ARMED_TH_DFALL;
                        /*
                         * If no riseEvent is configured, we need still to
                         *  set the armed flags appropriately, but there's
                         *  no point in trying to fire the (missing) event.
                         */
                        if (entry->mteTThDRiseEvent[0] != '\0' ) {
                            entry->mteTriggerXOwner   = entry->mteTThObjOwner;
                            entry->mteTriggerXObjects = entry->mteTThObjects;
                            entry->mteTriggerFired    = vp1;
                            n = entry->mteTriggerValueID_len;
                            mteEvent_fire(entry->mteTThDRiseOwner,
                                          entry->mteTThDRiseEvent,
                                          entry, vp1->name+n, vp1->name_length-n);
                        }
                    }
                }

                if ( value <= entry->mteTThDFallValue ) {
                    if (vp1->index & MTE_ARMED_TH_DFALL ) {
                        DEBUGMSGTL(( "disman:event:trigger:fire",
                                     "Firing falling delta threshold test: "));
                        DEBUGMSGOID(("disman:event:trigger:fire",
                                     vp1->name, vp1->name_length));
                        DEBUGMSG((   "disman:event:trigger:fire", "\n"));
                        cmp &= ~MTE_ARMED_TH_DFALL;
                        cmp |=  MTE_ARMED_TH_DRISE;
                        /*
                         * Similarly, if no fallEvent is configured,
                         *  there's no point in trying to fire it either.
                         */
                        if (entry->mteTThDRiseEvent[0] != '\0' ) {
                            entry->mteTriggerXOwner   = entry->mteTThObjOwner;
                            entry->mteTriggerXObjects = entry->mteTThObjects;
                            entry->mteTriggerFired    = vp1;
                            n = entry->mteTriggerValueID_len;
                            mteEvent_fire(entry->mteTThDFallOwner,
                                          entry->mteTThDFallEvent,
                                          entry, vp1->name+n, vp1->name_length-n);
                        }
                    }
                }
                vp1->index = cmp;
            }
        }
    }

    /*
     * Finally, rotate the results - ready for the next run.
     */
    snmp_free_varbind( entry->old_results );
    entry->old_results = var;
    if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) {
        snmp_free_varbind( entry->old_deltaDs );
        entry->old_deltaDs = dvar;
        entry->sysUpTime   = *sysUT_var.val.integer;
    }
}
Esempio n. 26
0
void im_stop_flow_count(void)
{
	snmp_alarm_unregister(timer_flowcount);
	flow_count = 0;
}