Beispiel #1
0
/************************************************************
 *
 * Initialize the saHpiWatchdogTable table by defining its contents and how it's structured
 */
void
initialize_table_saHpiWatchdogTable(void)
{
    netsnmp_table_registration_info *table_info;

    if (my_handler) {
        snmp_log(LOG_ERR,
                 "initialize_table_saHpiWatchdogTable_handler called again\n");
        return;
    }

    memset(&cb, 0x00, sizeof(cb));

    /** create the table structure itself */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);

    /*
     * if your table is read only, it's easiest to change the
     * HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY 
     */
    my_handler = netsnmp_create_handler_registration("saHpiWatchdogTable",
                                                     netsnmp_table_array_helper_handler,
                                                     saHpiWatchdogTable_oid,
                                                     saHpiWatchdogTable_oid_len,
                                                     HANDLER_CAN_RWRITE);

    if (!my_handler || !table_info) {
        snmp_log(LOG_ERR, "malloc failed in "
                 "initialize_table_saHpiWatchdogTable_handler\n");
        return; /** mallocs failed */
    }

    /***************************************************
     * Setting up the table's definition
     */
    /*
     * TODO: add any external indexes here.
     */

    /*
     * internal indexes
     */
        /** index: saHpiWatchdogNum */
    netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED);

    table_info->min_column = saHpiWatchdogTable_COL_MIN;
    table_info->max_column = saHpiWatchdogTable_COL_MAX;

    /***************************************************
     * registering the table with the master agent
     */
    cb.get_value = saHpiWatchdogTable_get_value;
    cb.container = netsnmp_container_find("saHpiWatchdogTable_primary:"
                                          "saHpiWatchdogTable:"
                                          "table_container");
#ifdef saHpiWatchdogTable_IDX2
    /*
    netsnmp_container_add_index(cb.container,
                                netsnmp_container_find
                                ("saHpiWatchdogTable_secondary:"
                                 "saHpiWatchdogTable:" "table_container"));
     cb.container->next->compare = saHpiWatchdogTable_cmp;
    */
#endif

    cb.can_set = 1;

    cb.create_row = (UserRowMethod *) saHpiWatchdogTable_create_row;

    cb.duplicate_row = (UserRowMethod *) saHpiWatchdogTable_duplicate_row;
    cb.delete_row = (UserRowMethod *) saHpiWatchdogTable_delete_row;
    cb.row_copy =
        (Netsnmp_User_Row_Operation *) saHpiWatchdogTable_row_copy;

    cb.can_delete =
        (Netsnmp_User_Row_Action *) saHpiWatchdogTable_can_delete;

    cb.set_reserve1 = saHpiWatchdogTable_set_reserve1;
    cb.set_reserve2 = saHpiWatchdogTable_set_reserve2;
    cb.set_action = saHpiWatchdogTable_set_action;
    cb.set_commit = saHpiWatchdogTable_set_commit;
    cb.set_free = saHpiWatchdogTable_set_free;
    cb.set_undo = saHpiWatchdogTable_set_undo;

    DEBUGMSGTL(("initialize_table_saHpiWatchdogTable",
                "Registering table saHpiWatchdogTable "
                "as a table array\n"));
    netsnmp_table_container_register(my_handler, table_info, &cb,
                                     cb.container, 1);

 netsnmp_register_read_only_counter32_instance("watchdoig_count",
						  saHpiWatchdogCount_oid,
						  OID_LENGTH(saHpiWatchdogCount_oid),
						  &watchdog_count,
						  NULL);


}
Beispiel #2
0
/************************************************************
 *
 * Initialize the saHpiHotSwapTable table by defining its contents and how it's structured
 */
void
initialize_table_saHpiHotSwapTable(void)
{
    netsnmp_table_registration_info *table_info;

    if(my_handler) {
        snmp_log(LOG_ERR, "initialize_table_saHpiHotSwapTable_handler called again\n");
        return;
    }

    memset(&cb, 0x00, sizeof(cb));

    /** create the table structure itself */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);

    /* if your table is read only, it's easiest to change the
       HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */
    my_handler = netsnmp_create_handler_registration("saHpiHotSwapTable",
                                             netsnmp_table_array_helper_handler,
                                             saHpiHotSwapTable_oid,
                                             saHpiHotSwapTable_oid_len,
                                             HANDLER_CAN_RWRITE);
            
    if (!my_handler || !table_info) {
        snmp_log(LOG_ERR, "malloc failed in "
                 "initialize_table_saHpiHotSwapTable_handler\n");
        return; /** mallocs failed */
    }

    /***************************************************
     * Setting up the table's definition
     */
    /*
     * TODO: add any external indexes here.
     */
        /** TODO: add code for external index(s)! */

    /*
     * internal indexes
     */
        /** index: saHpiDomainId */
        netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED);
        /** index: saHpiResourceId */
        netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED);
        /** index: saHpiResourceIsHistorical */
        netsnmp_table_helper_add_index(table_info, ASN_INTEGER);

    table_info->min_column = saHpiHotSwapTable_COL_MIN;
    table_info->max_column = saHpiHotSwapTable_COL_MAX;

    /***************************************************
     * registering the table with the master agent
     */
    cb.get_value = saHpiHotSwapTable_get_value;
    cb.container = netsnmp_container_find("saHpiHotSwapTable_primary:"
                                          "saHpiHotSwapTable:"
                                          "table_container");
#ifdef saHpiHotSwapTable_IDX2
    netsnmp_container_add_index(cb.container,
                                netsnmp_container_find("saHpiHotSwapTable_secondary:"
                                                       "saHpiHotSwapTable:"
                                                       "table_container"));
    cb.container->next->compare = saHpiHotSwapTable_cmp;
#endif
#ifdef saHpiHotSwapTable_SET_HANDLING
    cb.can_set = 1;
#ifdef saHpiHotSwapTable_ROW_CREATION
    cb.create_row = (UserRowMethod*)saHpiHotSwapTable_create_row;
#endif
    cb.duplicate_row = (UserRowMethod*)saHpiHotSwapTable_duplicate_row;
    cb.delete_row = (UserRowMethod*)saHpiHotSwapTable_delete_row;
    cb.row_copy = (Netsnmp_User_Row_Operation *)saHpiHotSwapTable_row_copy;

    cb.can_activate = (Netsnmp_User_Row_Action *)saHpiHotSwapTable_can_activate;
    cb.can_deactivate = (Netsnmp_User_Row_Action *)saHpiHotSwapTable_can_deactivate;
    cb.can_delete = (Netsnmp_User_Row_Action *)saHpiHotSwapTable_can_delete;

    cb.set_reserve1 = saHpiHotSwapTable_set_reserve1;
    cb.set_reserve2 = saHpiHotSwapTable_set_reserve2;
    cb.set_action = saHpiHotSwapTable_set_action;
    cb.set_commit = saHpiHotSwapTable_set_commit;
    cb.set_free = saHpiHotSwapTable_set_free;
    cb.set_undo = saHpiHotSwapTable_set_undo;
#endif
    DEBUGMSGTL(("initialize_table_saHpiHotSwapTable",
                "Registering table saHpiHotSwapTable "
                "as a table array\n"));
    netsnmp_table_container_register(my_handler, table_info, &cb,
                                     cb.container, 1);
}
void
group_requests(netsnmp_agent_request_info *agtreq_info,
               netsnmp_request_info *requests,
               netsnmp_container *request_group, table_container_data * tad)
{
    netsnmp_table_request_info *tblreq_info;
    netsnmp_variable_list *var;
    netsnmp_index *row, *tmp, index;
    netsnmp_request_info *current;
    netsnmp_request_group *g;
    netsnmp_request_group_item *i;

    for (current = requests; current; current = current->next) {

        var = current->requestvb;

        /*
         * skip anything that doesn't need processing.
         */
        if (current->processed != 0) {
            DEBUGMSGTL(("table_array:group",
                        "already processed\n"));
            continue;
        }

        /*
         * 3.2.1 Setup and paranoia
         * *
         * * Get pointer to the table information for this request. This
         * * information was saved by table_helper_handler. When
         * * debugging, we double check a few assumptions. For example,
         * * the table_helper_handler should enforce column boundaries.
         */
        row = NULL;
        tblreq_info = netsnmp_extract_table_info(current);
        netsnmp_assert(tblreq_info->colnum <= tad->tblreg_info->max_column);

        /*
         * search for index
         */
        index.oids = tblreq_info->index_oid;
        index.len = tblreq_info->index_oid_len;
        tmp = (netsnmp_index*)CONTAINER_FIND(request_group, &index);
        if (tmp) {
            DEBUGMSGTL(("table_array:group",
                        "    existing group:"));
            DEBUGMSGOID(("table_array:group", index.oids,
                         index.len));
            DEBUGMSG(("table_array:group", "\n"));
            g = (netsnmp_request_group *) tmp;
            i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item);
            if (i == NULL)
                return;
            i->ri = current;
            i->tri = tblreq_info;
            i->next = g->list;
            g->list = i;

            /** xxx-rks: store map of colnum to request */
            continue;
        }

        DEBUGMSGTL(("table_array:group", "    new group"));
        DEBUGMSGOID(("table_array:group", index.oids,
                     index.len));
        DEBUGMSG(("table_array:group", "\n"));
        g = SNMP_MALLOC_TYPEDEF(netsnmp_request_group);
        i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item);
        if (i == NULL || g == NULL)
            return;
        g->list = i;
        g->table = tad->table;
        i->ri = current;
        i->tri = tblreq_info;
        /** xxx-rks: store map of colnum to request */

        /*
         * search for row. all changes are made to the original row,
         * later, we'll make a copy in undo_info before we start processing.
         */
        row = g->existing_row = (netsnmp_index*)CONTAINER_FIND(tad->table, &index);
        if (!g->existing_row) {
            if (!tad->cb->create_row) {
                if(MODE_IS_SET(agtreq_info->mode))
                    netsnmp_set_request_error(agtreq_info, current,
                                              SNMP_ERR_NOTWRITABLE);
                else
                    netsnmp_set_request_error(agtreq_info, current,
                                              SNMP_NOSUCHINSTANCE);
                free(g);
                free(i);
                continue;
            }
            /** use undo_info temporarily */
            row = g->existing_row = tad->cb->create_row(&index);
            if (!row) {
                /* xxx-rks : parameter to create_row to allow
                 * for better error reporting. */
                netsnmp_set_request_error(agtreq_info, current,
                                          SNMP_ERR_GENERR);
                free(g);
                free(i);
                continue;
            }
            g->row_created = 1;
        }

        g->index.oids = row->oids;
        g->index.len = row->len;

        CONTAINER_INSERT(request_group, g);

    } /** for( current ... ) */
}
netsnmp_container*
netsnmp_container_iterator_get(void *iterator_user_ctx,
                               netsnmp_container_compare * compare,
                               Netsnmp_Iterator_Loop_Key * get_first,
                               Netsnmp_Iterator_Loop_Key * get_next,
                               Netsnmp_Iterator_Loop_Data * get_data,
                               Netsnmp_Iterator_Ctx_Dup * save_pos,
                               Netsnmp_Iterator_Ctx * init_loop_ctx,
                               Netsnmp_Iterator_Ctx * cleanup_loop_ctx,
                               Netsnmp_Iterator_Data * free_user_ctx,
                               int sorted)
{
    iterator_info *ii;

    /*
     * sanity checks
     */
    if(get_data && ! save_pos) {
        snmp_log(LOG_ERR, "save_pos required with get_data\n");
        return NULL;
    }

    /*
     * allocate memory
     */
    ii = SNMP_MALLOC_TYPEDEF(iterator_info);
    if (NULL==ii) {
        snmp_log(LOG_ERR, "couldn't allocate memory\n");
        return NULL;
    }

    /*
     * init container structure with iterator functions
     */
    ii->c.cfree = (netsnmp_container_rc*)_iterator_free;
    ii->c.compare = compare;
    ii->c.get_size = (netsnmp_container_size*)_iterator_size;
    ii->c.init = NULL;
    ii->c.insert = (netsnmp_container_op*)_iterator_insert;
    ii->c.remove = (netsnmp_container_op*)_iterator_remove;
    ii->c.release = (netsnmp_container_op*)_iterator_release;
    ii->c.find = (netsnmp_container_rtn*)_iterator_find;
    ii->c.find_next = (netsnmp_container_rtn*)_iterator_find_next;
    ii->c.get_subset = NULL;
    ii->c.get_iterator = NULL;
    ii->c.for_each = (netsnmp_container_func*)_iterator_for_each;
    ii->c.clear = _iterator_clear;

    /*
     * init iterator structure with user functions
     */
    ii->get_first = get_first;
    ii->get_next = get_next;
    ii->get_data = get_data;
    ii->save_pos = save_pos;
    ii->init_loop_ctx = init_loop_ctx;
    ii->cleanup_loop_ctx = cleanup_loop_ctx;
    ii->free_user_ctx = free_user_ctx;
    ii->sorted = sorted;

    ii->user_ctx = iterator_user_ctx;

    return (netsnmp_container*)ii;
}
Beispiel #5
0
/** Initialize the cpqSasPhyDrvTable table by defining its contents and how it's structured */
void
initialize_table_cpqSasPhyDrvTable(void)
{
    netsnmp_handler_registration *reg = NULL;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;
    netsnmp_table_registration_info *table_info = NULL;
    netsnmp_cache  *cache = NULL;

    int reg_tbl_ret = SNMPERR_SUCCESS;

    DEBUGMSGTL(("cpqSasPhyDrvTable:init",
                "initializing table cpqSasPhyDrvTable\n"));

    reg =
        netsnmp_create_handler_registration("cpqSasPhyDrvTable",
                                            cpqSasPhyDrvTable_handler,
                                            cpqSasPhyDrvTable_oid,
                                            cpqSasPhyDrvTable_oid_len,
                                            HANDLER_CAN_RONLY);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for cpqSasPhyDrvTable\n");
        goto bail;
    }

    container =
        netsnmp_container_find("cpqSasPhyDrvTable:table_container");
    if (NULL == container) {
        snmp_log(LOG_ERR,
                 "error creating container for cpqSasPhyDrvTable\n");
        goto bail;
    }

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for cpqSasPhyDrvTable\n");
        goto bail;
    }
    netsnmp_table_helper_add_indexes(table_info, 
                                     ASN_INTEGER,   /* index: cpqSasPhyDrvHbaIndex */
                                     ASN_INTEGER,       /* index: cpqSasPhyDrvIndex */
                                     0);
    table_info->min_column = COLUMN_CPQSASPHYDRVHBAINDEX;
    table_info->max_column = COLUMN_CPQSASPHYDRVTEMPERATURETHRESHOLD;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, container,
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for cpqSasPhyDrvTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for cpqSasPhyDrvTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it, will reuse below */

    /*************************************************
     *
     * inject cache helper
     */
    cache = netsnmp_cache_create(300,    /* timeout in seconds */
                                 _cache_load, _cache_free,
                                 cpqSasPhyDrvTable_oid,
                                 cpqSasPhyDrvTable_oid_len);

    if (NULL == cache) {
        snmp_log(LOG_ERR, "error creating cache for cpqSasPhyDrvTable\n");
        goto bail;
    }
    cache->flags = NETSNMP_CACHE_PRELOAD |
                   NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD |
                   NETSNMP_CACHE_DONT_FREE_EXPIRED |
                   NETSNMP_CACHE_DONT_AUTO_RELEASE |
                   NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    cache->magic = container;

    handler = netsnmp_cache_handler_get(cache);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error creating cache handler for cpqSasPhyDrvTable\n");
        goto bail;
    }

    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting cache handler for cpqSasPhyDrvTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it */

    /*
     * register the table
     */
    reg_tbl_ret = netsnmp_register_table(reg, table_info);
    if (reg_tbl_ret != SNMPERR_SUCCESS) {
        snmp_log(LOG_ERR,
                 "error registering table handler for cpqSasPhyDrvTable\n");
        goto bail;
    }

    /*
     * Initialise the contents of the table here
     */

    return;                     /* ok */

    /*
     * Some error occurred during registration. Clean up and bail.
     */
  bail:                        /* not ok */

    if (handler)
        netsnmp_handler_free(handler);

    if (cache)
        netsnmp_cache_free(cache);

    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (container)
        CONTAINER_FREE(container);

    if (reg_tbl_ret == SNMPERR_SUCCESS)
        if (reg)
            netsnmp_handler_registration_free(reg);
}
int   perl_trapd_handler( netsnmp_pdu           *pdu,
                          netsnmp_transport     *transport,
                          netsnmp_trapd_handler *handler)
{
    trapd_cb_data *cb_data;
    SV *pcallback;
    netsnmp_variable_list *vb;
    netsnmp_oid *o;
    SV *arg;
    SV *rarg;
    SV **tmparray;
    int i, c = 0;
    u_char *outbuf;
    size_t ob_len = 0, oo_len = 0;
    AV *varbinds;
    HV *pduinfo;

    dSP;
    ENTER;
    SAVETMPS;

    if (!pdu || !handler)
        return 0;

    /* nuke v1 PDUs */
    if (pdu->command == SNMP_MSG_TRAP)
        pdu = convert_v1pdu_to_v2(pdu);

    cb_data = handler->handler_data;
    if (!cb_data || !cb_data->perl_cb)
        return 0;

    pcallback = cb_data->perl_cb;

    /* get PDU related info */
    pduinfo = newHV();
#define STOREPDU(n, v) hv_store(pduinfo, n, strlen(n), v, 0)
#define STOREPDUi(n, v) STOREPDU(n, newSViv(v))
#define STOREPDUs(n, v) STOREPDU(n, newSVpv(v, 0))
    STOREPDUi("version", pdu->version);
    STOREPDUs("notificationtype", ((pdu->command == SNMP_MSG_INFORM) ? "INFORM":"TRAP"));
    STOREPDUi("requestid", pdu->reqid);
    STOREPDUi("messageid", pdu->msgid);
    STOREPDUi("transactionid", pdu->transid);
    STOREPDUi("errorstatus", pdu->errstat);
    STOREPDUi("errorindex", pdu->errindex);
    if (pdu->version == 3) {
        STOREPDUi("securitymodel", pdu->securityModel);
        STOREPDUi("securitylevel", pdu->securityLevel);
        STOREPDU("contextName",
                 newSVpv(pdu->contextName, pdu->contextNameLen));
        STOREPDU("contextEngineID",
                 newSVpv(pdu->contextEngineID,
                                    pdu->contextEngineIDLen));
        STOREPDU("securityEngineID",
                 newSVpv(pdu->securityEngineID,
                                    pdu->securityEngineIDLen));
        STOREPDU("securityName",
                 newSVpv(pdu->securityName, pdu->securityNameLen));
    } else {
        STOREPDU("community",
                 newSVpv(pdu->community, pdu->community_len));
    }

    if (transport && transport->f_fmtaddr) {
        char *tstr = transport->f_fmtaddr(transport, pdu->transport_data,
                                          pdu->transport_data_length);
        STOREPDUs("receivedfrom", tstr);
        free(tstr);
    }


    /*
     * collect OID objects in a temp array first
     */
    /* get VARBIND related info */
    i = count_varbinds(pdu->variables);
    tmparray = malloc(sizeof(*tmparray) * i);

    for(vb = pdu->variables; vb; vb = vb->next_variable) {

        /* get the oid */
        o = SNMP_MALLOC_TYPEDEF(netsnmp_oid);
        o->name = o->namebuf;
        o->len = vb->name_length;
        memcpy(o->name, vb->name, vb->name_length * sizeof(oid));

#undef CALL_EXTERNAL_OID_NEW

#ifdef CALL_EXTERNAL_OID_NEW
        PUSHMARK(sp);

        rarg = sv_2mortal(newSViv((IV) 0));
        arg = sv_2mortal(newSVrv(rarg, "netsnmp_oidPtr"));
        sv_setiv(arg, (IV) o);
        XPUSHs(rarg);

        PUTBACK;
        i = perl_call_pv("NetSNMP::OID::newwithptr", G_SCALAR);
        SPAGAIN;

        if (i != 1) {
            snmp_log(LOG_ERR, "unhandled OID error.\n");
            /* ack XXX */
        }
        /* get the value */
        tmparray[c++] = POPs;
        SvREFCNT_inc(tmparray[c-1]);
        PUTBACK;
#else /* build it and bless ourselves */
        {
            HV *hv = newHV();
            SV *rv = newRV_noinc((SV *) hv);
            SV *rvsub = newRV_noinc((SV *) newSViv((UV) o));
            SV *sv;
            rvsub = sv_bless(rvsub, gv_stashpv("netsnmp_oidPtr", 1));
            hv_store(hv, "oidptr", 6,  rvsub, 0);
            rv = sv_bless(rv, gv_stashpv("NetSNMP::OID", 1));
            tmparray[c++] = rv;
        }
        
#endif /* build oid ourselves */
    }

    /*
     * build the varbind lists
     */
    varbinds = newAV();
    for(vb = pdu->variables, i = 0; vb; vb = vb->next_variable, i++) {
        /* push the oid */
        AV *vba;
        vba = newAV();


        /* get the value */
        outbuf = NULL;
        ob_len = 0;
        oo_len = 0;
	sprint_realloc_by_type(&outbuf, &ob_len, &oo_len, 1,
                               vb, 0, 0, 0);

        av_push(vba,tmparray[i]);
        av_push(vba,newSVpvn(outbuf, oo_len));
        free(outbuf);
        av_push(vba,newSViv(vb->type));
        av_push(varbinds, (SV *) newRV_noinc((SV *) vba));
    }

    PUSHMARK(sp);

    /* store the collected information on the stack */
    XPUSHs(sv_2mortal(newRV_noinc((SV*) pduinfo)));
    XPUSHs(sv_2mortal(newRV_noinc((SV*) varbinds)));

    /* put the stack back in order */
    PUTBACK;

    /* actually call the callback function */
    if (SvTYPE(pcallback) == SVt_PVCV) {
        perl_call_sv(pcallback, G_DISCARD);
        /* XXX: it discards the results, which isn't right */
    } else if (SvROK(pcallback) && SvTYPE(SvRV(pcallback)) == SVt_PVCV) {
        /* reference to code */
        perl_call_sv(SvRV(pcallback), G_DISCARD);
    } else {
        snmp_log(LOG_ERR, " tried to call a perl function but failed to understand its type: (ref = %x, svrok: %lu, SVTYPE: %lu)\n", (uintptr_t)pcallback, SvROK(pcallback), SvTYPE(pcallback));
    }

#ifdef DUMPIT
    fprintf(stderr, "DUMPDUMPDUMPDUMPDUMPDUMP\n");
    sv_dump(pduinfo);
    fprintf(stderr, "--------------------\n");
    sv_dump(varbinds);
#endif
    
    /* svREFCNT_dec((SV *) pduinfo); */
#ifdef NOT_THIS
    {
        SV *vba;
        while(vba = av_pop(varbinds)) {
            av_undef((AV *) vba);
        }
    }
    av_undef(varbinds);
#endif    
    free(tmparray);

    /* Not needed because of the G_DISCARD flag (I think) */
    /* SPAGAIN; */
    /* PUTBACK; */
#ifndef __x86_64__
    FREETMPS; /* FIXME: known to cause a segfault on x86-64 */
#endif
    LEAVE;
    return NETSNMPTRAPD_HANDLER_OK;
}
static int
_ssll_insert(netsnmp_container *c, const void *data)
{
    sl_container *sl = (sl_container*)c;
    sl_node  *new_node, *curr = sl->head;
    
    if(NULL == c)
        return -1;
    
    new_node = SNMP_MALLOC_TYPEDEF(sl_node);
    if(NULL == new_node)
        return -1;
    new_node->data = NETSNMP_REMOVE_CONST(void *, data);
    ++sl->count;
    ++c->sync;

    /*
     * first node?
     */
    if(NULL == sl->head) {
        sl->head = new_node;
        return 0;
    }

    /*
     * sorted or unsorted insert?
     */
    if (1 == sl->unsorted) {
        /*
         * unsorted: fifo, or lifo?
         */
        if (1 == sl->fifo) {
            /*
             * fifo: insert at tail
             */
            while(NULL != curr->next)
                curr = curr->next;
            curr->next = new_node;
        }
        else {
            /*
             * lifo: insert at head
             */
            new_node->next = sl->head;
            sl->head = new_node;
        }
    }
    else {
        /*
         * sorted
         */
        sl_node *last = NULL;
        for( ; curr; last = curr, curr = curr->next) {
            if(sl->c.compare(curr->data, data) > 0)
                break;
        }
        if(NULL == last) {
            new_node->next = sl->head;
            sl->head = new_node;
        }
        else {
            new_node->next = last->next;
            last->next = new_node;
        }
    }
    
    return 0;
}
Beispiel #8
0
void
init_testhandler(void)
{
    /*
     * we're registering at .1.2.3.4 
     */
    netsnmp_handler_registration *my_test;
    netsnmp_table_registration_info *table_info;
    u_long          ind1;
    netsnmp_table_data *table;
    netsnmp_table_data_set *table_set;
    netsnmp_table_row *row;

    DEBUGMSGTL(("testhandler", "initializing\n"));

    /*
     * basic handler test
     */
    netsnmp_register_handler(netsnmp_create_handler_registration
                             ("myTest", my_test_handler, my_test_oid, 4,
                              HANDLER_CAN_RONLY));

    /*
     * instance handler test
     */

    netsnmp_register_instance(netsnmp_create_handler_registration
                              ("myInstance", my_test_instance_handler,
                               my_instance_oid, 5, HANDLER_CAN_RWRITE));

    netsnmp_register_ulong_instance("myulong",
                                    my_data_ulong_instance, 4,
                                    &my_ulong, NULL);

    /*
     * table helper test
     */

    my_test = netsnmp_create_handler_registration("myTable",
                                                  my_test_table_handler,
                                                  my_table_oid, 4,
                                                  HANDLER_CAN_RONLY);
    if (!my_test)
        return;

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (table_info == NULL)
        return;

    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, ASN_INTEGER,
                                     0);
    table_info->min_column = 3;
    table_info->max_column = 3;
    netsnmp_register_table(my_test, table_info);

    /*
     * data table helper test
     */
    /*
     * we'll construct a simple table here with two indexes: an
     * integer and a string (why not).  It'll contain only one
     * column so the data pointer is merely the data in that
     * column. 
     */

    table = netsnmp_create_table_data("data_table_test");

    netsnmp_table_data_add_index(table, ASN_INTEGER);
    netsnmp_table_data_add_index(table, ASN_OCTET_STR);

    /*
     * 1 partridge in a pear tree 
     */
    row = netsnmp_create_table_data_row();
    ind1 = 1;
    netsnmp_table_row_add_index(row, ASN_INTEGER, &ind1, sizeof(ind1));
    netsnmp_table_row_add_index(row, ASN_OCTET_STR, "partridge",
                                strlen("partridge"));
    row->data = (void *) "pear tree";
    netsnmp_table_data_add_row(table, row);

    /*
     * 2 turtle doves 
     */
    row = netsnmp_create_table_data_row();
    ind1 = 2;
    netsnmp_table_row_add_index(row, ASN_INTEGER, &ind1, sizeof(ind1));
    netsnmp_table_row_add_index(row, ASN_OCTET_STR, "turtle",
                                strlen("turtle"));
    row->data = (void *) "doves";
    netsnmp_table_data_add_row(table, row);

    /*
     * we're going to register it as a normal table too, so we get the
     * automatically parsed column and index information 
     */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (table_info == NULL)
        return;

    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,
                                     ASN_OCTET_STR, 0);
    table_info->min_column = 3;
    table_info->max_column = 3;

    netsnmp_register_read_only_table_data
        (netsnmp_create_handler_registration
         ("12days", my_data_table_handler, my_data_table_oid, 4,
          HANDLER_CAN_RONLY), table, table_info);

}
/** Initialize the cpqLinOsProcessorTable table by defining its contents 
 * and how it's structured 
 */
void
initialize_table_cpqLinOsProcessorTable(void)
{
    netsnmp_handler_registration *reg = NULL;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;
    netsnmp_table_registration_info *table_info = NULL;
    netsnmp_cache  *cache = NULL;

    DEBUGMSGTL(("cpqLinOsProcessorTable:init",
                "initializing table cpqLinOsProcessorTable\n"));

    reg =
        netsnmp_create_handler_registration("cpqLinOsProcessorTable",
                                            cpqLinOsProcessorTable_handler,
                                            cpqLinOsProcessorTable_oid,
                                            cpqLinOsProcessorTable_oid_len,
                                            HANDLER_CAN_RONLY);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for cpqLinOsProcessorTable\n");
        goto bail;
    }

    container = netsnmp_container_find("cpqLinOsProcessorTable:table_container");
    if (NULL == container) {
        snmp_log(LOG_ERR, "error creating container for cpqLinOsProcessorTable\n");
        goto bail;
    }
    container->container_name = strdup("cpqLinOsProcessorTable container");

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for cpqLinOsProcessorTable\n");
        goto bail;
    }
    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index: cpqLinOsCpuIndex */
                                     0);
    table_info->min_column = COLUMN_CPQLINOSCPUINDEX;
    table_info->max_column = COLUMN_CPQLINOSCPUPRIVILEGEDTIMEPERCENT;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, container,
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for cpqLinOsProcessorTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for cpqLinOsProcessorTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it, will reuse below */

    /*************************************************
     *
     * inject cache helper
     */
    cache = netsnmp_cache_create(5,    /* timeout in seconds */
                                 _cache_load, _cache_free,
                                 cpqLinOsProcessorTable_oid,
                                 cpqLinOsProcessorTable_oid_len);

    if (NULL == cache) {
        snmp_log(LOG_ERR,
                 "error creating cache for cpqLinOsProcessorTable\n");
        goto bail;
    }
    cache->flags = NETSNMP_CACHE_PRELOAD |
                   NETSNMP_CACHE_DONT_FREE_EXPIRED |
                   NETSNMP_CACHE_DONT_AUTO_RELEASE |
                   NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD |
                   NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    cache->magic = container;

    handler = netsnmp_cache_handler_get(cache);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error creating cache handler for cpqLinOsProcessorTable\n");
        goto bail;
    }

    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting cache handler for cpqLinOsProcessorTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it */

    /*
     * register the table
     */
    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,
                 "error registering table handler for cpqLinOsProcessorTable\n");
        reg = NULL;             /* it was freed inside netsnmp_register_table */
        goto bail;
    }

    return;                     /* ok */

    /*
     * Some error occurred during registration. Clean up and bail.
     */
  bail:                        /* not ok */

    if (handler)
        netsnmp_handler_free(handler);

    if (cache)
        netsnmp_cache_free(cache);

    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (container)
        CONTAINER_FREE(container);

    if (reg)
        netsnmp_handler_registration_free(reg);
}
Beispiel #10
0
/** creates and returns a pointer to table data set */
netsnmp_table_row *
netsnmp_create_table_data_row(void)
{
    netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row);
    return row;
}
/** Initialize the sctpLookupLocalPortTable table by defining its contents and how it's structured */
void
initialize_table_sctpLookupLocalPortTable(void)
{
    static oid      sctpLookupLocalPortTable_oid[] =
        { 1, 3, 6, 1, 2, 1, 104, 1, 6 };
    size_t          sctpLookupLocalPortTable_oid_len =
        OID_LENGTH(sctpLookupLocalPortTable_oid);
    netsnmp_handler_registration *reg = NULL;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;

    reg =
        netsnmp_create_handler_registration("sctpLookupLocalPortTable",
                                            sctpLookupLocalPortTable_handler,
                                            sctpLookupLocalPortTable_oid,
                                            sctpLookupLocalPortTable_oid_len,
                                            HANDLER_CAN_RONLY);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for sctpLookupLocalPortTable\n");
        goto bail;
    }

    container =
        netsnmp_container_find("sctpLookupLocalPortTable:table_container");
    if (NULL == container) {
        snmp_log(LOG_ERR,
                 "error creating container for sctpLookupLocalPortTable\n");
        goto bail;
    }
    sctpLookupLocalPortTable_container = container;

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for sctpLookupLocalPortTable\n");
        goto bail;
    }
    netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED,  /* index: sctpAssocLocalPort */
                                     ASN_UNSIGNED,      /* index: sctpAssocId */
                                     0);
    table_info->min_column = COLUMN_SCTPLOOKUPLOCALPORTSTARTTIME;
    table_info->max_column = COLUMN_SCTPLOOKUPLOCALPORTSTARTTIME;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, container,
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for sctpLookupLocalPortTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for sctpLookupLocalPortTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it, will reuse below */

    /*
     * register the table
     */
    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,
                 "error registering table handler for sctpLookupLocalPortTable\n");
        goto bail;
    }

    /*
     * Initialise the contents of the table here
     */


    return;                     /* ok */

    /*
     * Some error occurred during registration. Clean up and bail.
     */
  bail:                        /* not ok */

    if (handler)
        netsnmp_handler_free(handler);

    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (container)
        CONTAINER_FREE(container);

    if (reg)
        netsnmp_handler_registration_free(reg);
}
/************************************************************
 *
 * Initialize the saHpiSensorThdPosHysteresisTable table by defining its contents and how it's structured
 */
void
initialize_table_saHpiSensorThdPosHysteresisTable (void)
{
  netsnmp_table_registration_info *table_info;

  if (my_handler)
    {
      snmp_log (LOG_ERR,
		"initialize_table_saHpiSensorThdPosHysteresisTable_handler called again\n");
      return;
    }

  memset (&cb, 0x00, sizeof (cb));

    /** create the table structure itself */
  table_info = SNMP_MALLOC_TYPEDEF (netsnmp_table_registration_info);

  /*
   * if your table is read only, it's easiest to change the
   * HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY 
   */
  my_handler =
    netsnmp_create_handler_registration
    ("saHpiSensorThdPosHysteresisTable",
     netsnmp_table_array_helper_handler,
     saHpiSensorThdPosHysteresisTable_oid,
     saHpiSensorThdPosHysteresisTable_oid_len, HANDLER_CAN_RWRITE);

  if (!my_handler || !table_info)
    {
      snmp_log (LOG_ERR, "malloc failed in "
		"initialize_table_saHpiSensorThdPosHysteresisTable_handler\n");
      return;	/** mallocs failed */
    }

    /***************************************************
     * Setting up the table's definition
     */

  /*
   * internal indexes
   */
	/** index: saHpiDomainID */
  netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED);
	/** index: saHpiResourceID */
  netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED);
	/** index: saHpiSensorIndex */
  netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED);

  table_info->min_column = saHpiSensorThdPosHysteresisTable_COL_MIN;
  table_info->max_column = saHpiSensorThdPosHysteresisTable_COL_MAX;

    /***************************************************
     * registering the table with the master agent
     */
  cb.get_value = saHpiSensorThdPosHysteresisTable_get_value;
  cb.container =
    netsnmp_container_find ("saHpiSensorThdPosHysteresisTable_primary:"
			    "saHpiSensorThdPosHysteresisTable:"
			    "table_container");


  cb.create_row = (UserRowMethod *) saHpiSensorThdPosHysteresisTable_create_row;

  cb.duplicate_row =
    (UserRowMethod *) saHpiSensorThdPosHysteresisTable_duplicate_row;
  cb.delete_row = (UserRowMethod *) saHpiSensorThdPosHysteresisTable_delete_row;
  cb.row_copy =
    (Netsnmp_User_Row_Operation *) saHpiSensorThdPosHysteresisTable_row_copy;

  cb.can_delete =
    (Netsnmp_User_Row_Action *) saHpiSensorThdPosHysteresisTable_can_delete;

  cb.set_reserve1 = saHpiSensorThdPosHysteresisTable_set_reserve1;
  cb.set_reserve2 = saHpiSensorThdPosHysteresisTable_set_reserve2;
  cb.set_action = saHpiSensorThdPosHysteresisTable_set_action;
  cb.set_commit = saHpiSensorThdPosHysteresisTable_set_commit;
  cb.set_free = saHpiSensorThdPosHysteresisTable_set_free;
  cb.set_undo = saHpiSensorThdPosHysteresisTable_set_undo;

  DEBUGMSGTL (("initialize_table_saHpiSensorThdPosHysteresisTable",
	       "Registering table saHpiSensorThdPosHysteresisTable "
	       "as a table array\n"));
  netsnmp_table_container_register (my_handler, table_info, &cb,
				    cb.container, 1);
}
Beispiel #13
0
/** Initialize the hrSWRunTable table by defining its contents and how it's structured */
void
initialize_table_hrSWRunTable(void)
{
    netsnmp_handler_registration *reg;
    netsnmp_mib_handler *handler = NULL;
#ifndef NETSNMP_NO_WRITE_SUPPORT
#ifdef NETSNMP_INCLUDE_HRSWRUN_WRITE_SUPPORT
#  define SWRUN_ACCESS_LEVEL HANDLER_CAN_RWRITE
#else
#  define SWRUN_ACCESS_LEVEL HANDLER_CAN_RONLY
#endif
#else /* !NETSNMP_NO_WRITE_SUPPORT */ 
#  define SWRUN_ACCESS_LEVEL HANDLER_CAN_RONLY
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    reg =
        netsnmp_create_handler_registration(MYTABLE,
                                            hrSWRunTable_handler,
                                            hrSWRunTable_oid,
                                            hrSWRunTable_oid_len,
                                            SWRUN_ACCESS_LEVEL);
    if (NULL == reg) {
        snmp_log(LOG_ERR,"error creating handler registration for "
                 MYTABLE "\n");
        goto bail;
    }
    reg->modes |= HANDLER_CAN_NOT_CREATE;

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,"error allocating table registration for "
                 MYTABLE "\n");
        goto bail;
    }

    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index: hrSWRunIndex */
                                     0);
    table_info->min_column = COLUMN_HRSWRUNINDEX;
    table_info->max_column = COLUMN_HRSWRUNSTATUS;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, netsnmp_swrun_container(),
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,"error allocating table registration for "
                 MYTABLE "\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,"error injecting container_table handler for "
                 MYTABLE "\n");
        goto bail;
    }
    handler = NULL; /* reg has it, will reuse below */

    /*************************************************
     *
     * inject cache helper
     */
    handler = netsnmp_cache_handler_get(netsnmp_swrun_cache());
    if (NULL == handler) {
        snmp_log(LOG_ERR, "error creating cache handler for " MYTABLE "\n");
        goto bail;
    }

    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,"error injecting cache handler for "
                 MYTABLE "\n");
        goto bail;
    }
    handler = NULL; /* reg has it*/

    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,"error registering table handler for "
                 MYTABLE "\n");
        reg = NULL; /* it was freed inside netsnmp_register_table */
        goto bail;
    }

    return; /* ok */


  bail: /* not ok */
    
    if (handler)
        netsnmp_handler_free(handler);

    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (reg) 
        netsnmp_handler_registration_free(reg);

}
Beispiel #14
0
/** Initialize the sctpAssocTable table by defining its contents and how it's structured */
void
initialize_table_sctpAssocTable(void)
{
    static oid      sctpAssocTable_oid[] = { 1, 3, 6, 1, 2, 1, 104, 1, 3 };
    size_t          sctpAssocTable_oid_len =
        OID_LENGTH(sctpAssocTable_oid);
    netsnmp_handler_registration *reg = NULL;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;
    netsnmp_table_registration_info *table_info = NULL;
    netsnmp_cache  *cache = NULL;

    reg =
        netsnmp_create_handler_registration("sctpAssocTable",
                                            sctpAssocTable_handler,
                                            sctpAssocTable_oid,
                                            sctpAssocTable_oid_len,
                                            HANDLER_CAN_RWRITE);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for sctpAssocTable\n");
        goto bail;
    }
    /** should a set on a non-existent row create a new one? */
    /** reg->modes |= HANDLER_CAN_NOT_CREATE; */

    container = netsnmp_container_find("sctpAssocTable:table_container");
    if (NULL == container) {
        snmp_log(LOG_ERR, "error creating container for sctpAssocTable\n");
        goto bail;
    }
    sctpAssocTable_container = container;

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for sctpAssocTable\n");
        goto bail;
    }
    netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED,  /* index: sctpAssocId */
                                     0);
    table_info->min_column = COLUMN_SCTPASSOCREMHOSTNAME;
    table_info->max_column = COLUMN_SCTPASSOCDISCONTINUITYTIME;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, container,
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for sctpAssocTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for sctpAssocTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it, will reuse below */

    /*************************************************
     *
     * inject cache helper
     */
    cache = netsnmp_cache_create(SCTP_TABLES_CACHE_TIMEOUT,     /* timeout in seconds */
                                 _cache_load, _cache_free,
                                 sctpAssocTable_oid,
                                 sctpAssocTable_oid_len);

    if (NULL == cache) {
        snmp_log(LOG_ERR, "error creating cache for sctpAssocTable\n");
        goto bail;
    }
    cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET
        | NETSNMP_CACHE_AUTO_RELOAD | NETSNMP_CACHE_PRELOAD;
    cache->magic = container;

    handler = netsnmp_cache_handler_get(cache);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error creating cache handler for sctpAssocTable\n");
        goto bail;
    }

    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting cache handler for sctpAssocTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it */

    /*
     * register the table
     */
    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,
                 "error registering table handler for sctpAssocTable\n");
        goto bail;
    }

    /*
     * Initialise the contents of the table here
     */


    return;                     /* ok */

    /*
     * Some error occurred during registration. Clean up and bail.
     */
  bail:                        /* not ok */

    if (handler)
        netsnmp_handler_free(handler);

    if (container)
        CONTAINER_FREE(container);

    if (reg)
        netsnmp_handler_registration_free(reg);
}
Beispiel #15
0
/**
 * update entry stats (checking for counter wrap)
 *
 * @retval  0 : success
 * @retval <0 : error
 */
int
netsnmp_access_systemstats_entry_update_stats(netsnmp_systemstats_entry * prev_vals,
                                              netsnmp_systemstats_entry * new_vals)
{
    DEBUGMSGTL(("access:systemstats", "check_wrap\n"));
    
    /*
     * sanity checks
     */
    if ((NULL == prev_vals) || (NULL == new_vals) ||
        (prev_vals->index[0] != new_vals->index[0])
        || (prev_vals->index[1] != new_vals->index[1]))
        return -1;

    /*
     * if we've determined that we have 64 bit counters, just copy them.
     */
    if (0 == need_wrap_check) {
        memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats));
        _calculate_entries(prev_vals);
        return 0;
    }

    if (NULL == prev_vals->old_stats) {
        /*
         * if we don't have old stats, they can't have wrapped, so just copy
         */
        prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_ipstats);
        if (NULL == prev_vals->old_stats) {
            return -2;
        }
    }
    else {
        /*
         * update straight 32 bit counters
         */
        memcpy(&prev_vals->stats.columnAvail[0], &new_vals->stats.columnAvail[0], sizeof(new_vals->stats.columnAvail));
        prev_vals->stats.InHdrErrors = new_vals->stats.InHdrErrors;
        prev_vals->stats.InAddrErrors = new_vals->stats.InAddrErrors;
        prev_vals->stats.InUnknownProtos = new_vals->stats.InUnknownProtos;
        prev_vals->stats.InTruncatedPkts = new_vals->stats.InTruncatedPkts;
        prev_vals->stats.ReasmReqds = new_vals->stats.ReasmReqds;
        prev_vals->stats.ReasmOKs = new_vals->stats.ReasmOKs;
        prev_vals->stats.ReasmFails = new_vals->stats.ReasmFails;
        prev_vals->stats.InDiscards = new_vals->stats.InDiscards;

        /*
         * update 64bit counters
         */
        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInNoRoutes,
                                       &new_vals->stats.HCInNoRoutes,
                                       &prev_vals->old_stats->HCInNoRoutes,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInNoRoutes to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutNoRoutes,
                                       &new_vals->stats.HCOutNoRoutes,
                                       &prev_vals->old_stats->HCOutNoRoutes,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutNoRoutes to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutDiscards,
                                       &new_vals->stats.HCOutDiscards,
                                       &prev_vals->old_stats->HCOutDiscards,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutDiscards to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragReqds,
                                       &new_vals->stats.HCOutFragReqds,
                                       &prev_vals->old_stats->HCOutFragReqds,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutFragReqds to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragOKs,
                                       &new_vals->stats.HCOutFragOKs,
                                       &prev_vals->old_stats->HCOutFragOKs,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutFragOKs to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragFails,
                                       &new_vals->stats.HCOutFragFails,
                                       &prev_vals->old_stats->HCOutFragFails,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutFragFails to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragCreates,
                                       &new_vals->stats.HCOutFragCreates,
                                       &prev_vals->old_stats->HCOutFragCreates,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutFragCreates to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInReceives,
                                       &new_vals->stats.HCInReceives,
                                       &prev_vals->old_stats->HCInReceives,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInReceives to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInOctets,
                                       &new_vals->stats.HCInOctets,
                                       &prev_vals->old_stats->HCInOctets,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInOctets to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInForwDatagrams,
                                       &new_vals->stats.HCInForwDatagrams,
                                       &prev_vals->old_stats->HCInForwDatagrams,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInForwDatagrams to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInDelivers,
                                       &new_vals->stats.HCInDelivers,
                                       &prev_vals->old_stats->HCInDelivers,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInDelivers to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutRequests,
                                       &new_vals->stats.HCOutRequests,
                                       &prev_vals->old_stats->HCOutRequests,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutRequests to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutForwDatagrams,
                                       &new_vals->stats.HCOutForwDatagrams,
                                       &prev_vals->old_stats->HCOutForwDatagrams,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutForwDatagrams to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutTransmits,
                                       &new_vals->stats.HCOutTransmits,
                                       &prev_vals->old_stats->HCOutTransmits,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutTransmits to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutOctets,
                                       &new_vals->stats.HCOutOctets,
                                       &prev_vals->old_stats->HCOutOctets,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutOctets to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInMcastPkts,
                                       &new_vals->stats.HCInMcastPkts,
                                       &prev_vals->old_stats->HCInMcastPkts,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInMcastPkts to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInMcastOctets,
                                       &new_vals->stats.HCInMcastOctets,
                                       &prev_vals->old_stats->HCInMcastOctets,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInMcastOctets to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutMcastPkts,
                                       &new_vals->stats.HCOutMcastPkts,
                                       &prev_vals->old_stats->HCOutMcastPkts,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutMcastPkts to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutMcastOctets,
                                       &new_vals->stats.HCOutMcastOctets,
                                       &prev_vals->old_stats->HCOutMcastOctets,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutMcastOctets to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInBcastPkts,
                                       &new_vals->stats.HCInBcastPkts,
                                       &prev_vals->old_stats->HCInBcastPkts,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInBcastPkts to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutBcastPkts,
                                       &new_vals->stats.HCOutBcastPkts,
                                       &prev_vals->old_stats->HCOutBcastPkts,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutBcastPkts to 64bits in %s\n",
                    prev_vals->tableName));
    }

    /*
     * if we've decided we no longer need to check wraps, free old stats
     */
    if (0 == need_wrap_check) {
        SNMP_FREE(prev_vals->old_stats);
    } else {
        /*
         * update old stats from new stats.
         * careful - old_stats is a pointer to stats...
         */
        memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats));
    }

    _calculate_entries(prev_vals);

    return 0;
}
Beispiel #16
0
/** Initialize the dot1dBasePortTable table by defining its contents and how it's structured */
void
initialize_table_dot1dBasePortTable(void) {
  static oid dot1dBasePortTable_oid[] = {1,3,6,1,2,1,17,1,4};
  netsnmp_table_registration_info *table_info;
  netsnmp_handler_registration *my_handler;
  netsnmp_iterator_info *iinfo;

  /** create the table registration information structures */
  table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
  iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);

  my_handler = netsnmp_create_handler_registration("dot1dBasePortTable",
               dot1dBasePortTable_handler,
               dot1dBasePortTable_oid,
               OID_LENGTH(dot1dBasePortTable_oid),
               HANDLER_CAN_RONLY
                                                  );

  if (!my_handler || !table_info || !iinfo) {
    snmp_log(LOG_ERR, "malloc failed in initialize_table_dot1dBasePortTable");
    if (my_handler != NULL) {
      SNMP_FREE(my_handler);
    }
    if (table_info != NULL) {
      SNMP_FREE(table_info);
    }
    if (iinfo != NULL) {
      SNMP_FREE(iinfo);
    }
    return; /** Serious error. */
  }

  /***************************************************
   * Setting up the table's definition
   */
  netsnmp_table_helper_add_indexes(table_info,
                                   ASN_INTEGER, /** index: dot1dBasePort */
                                   0);

  /** Define the minimum and maximum accessible columns.  This
      optimizes retrival. */
  table_info->min_column = 1;
  table_info->max_column = 5;

  /** iterator access routines */
  iinfo->get_first_data_point = dot1dBasePortTable_get_first_data_point;
  iinfo->get_next_data_point = dot1dBasePortTable_get_next_data_point;

  /* iinfo->make_data_context = dot1dBasePortTable_context_convert_function; */
  iinfo->free_data_context = dot1dBasePortTable_data_free;

  /** pick *only* one of these if you use them */
  /* iinfo->free_loop_context = dot1dBasePortTable_loop_free; */
  iinfo->free_loop_context_at_end = dot1dBasePortTable_loop_free;

  /** tie the two structures together */
  iinfo->table_reginfo = table_info;

  /***************************************************
   * registering the table with the master agent
   */
  DEBUGMSGTL(("initialize_table_dot1dBasePortTable",
              "Registering table dot1dBasePortTable as a table iterator\n"));
  netsnmp_register_table_iterator(my_handler, iinfo);
}
Beispiel #17
0
void
init_nsDebug(void)
{
    /*
     * OIDs for the debugging control scalar objects
     *
     * Note that these we're registering the full object rather
     *  than the (sole) valid instance in each case, in order
     *  to handle requests for invalid instances properly.
     */
    const oid nsDebugEnabled_oid[]    = { nsConfigDebug, 1};
    const oid nsDebugOutputAll_oid[]  = { nsConfigDebug, 2};
    const oid nsDebugDumpPdu_oid[]    = { nsConfigDebug, 3};

    /*
     * ... and for the token table.
     */

#define  DBGTOKEN_PREFIX	2
#define  DBGTOKEN_ENABLED	3
#define  DBGTOKEN_STATUS	4
    const oid nsDebugTokenTable_oid[] = { nsConfigDebug, 4};

    netsnmp_table_registration_info *table_info;
    netsnmp_iterator_info           *iinfo;

    /*
     * Register the scalar objects...
     */
    DEBUGMSGTL(("nsDebugScalars", "Initializing\n"));
    netsnmp_register_scalar(
        netsnmp_create_handler_registration(
            "nsDebugEnabled", handle_nsDebugEnabled,
            nsDebugEnabled_oid, OID_LENGTH(nsDebugEnabled_oid),
            HANDLER_CAN_RWRITE)
        );
    netsnmp_register_scalar(
        netsnmp_create_handler_registration(
            "nsDebugOutputAll", handle_nsDebugOutputAll,
            nsDebugOutputAll_oid, OID_LENGTH(nsDebugOutputAll_oid),
            HANDLER_CAN_RWRITE)
        );
    netsnmp_register_scalar(
        netsnmp_create_handler_registration(
            "nsDebugDumpPdu", handle_nsDebugDumpPdu,
            nsDebugDumpPdu_oid, OID_LENGTH(nsDebugDumpPdu_oid),
            HANDLER_CAN_RWRITE)
        );

    /*
     * ... and the table.
     * We need to define the column structure and indexing....
     */

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (!table_info) {
        return;
    }
    netsnmp_table_helper_add_indexes(table_info, ASN_PRIV_IMPLIED_OCTET_STR, 0);
    table_info->min_column = DBGTOKEN_STATUS;
    table_info->max_column = DBGTOKEN_STATUS;


    /*
     * .... and the iteration information ....
     */
    iinfo      = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
    if (!iinfo) {
        return;
    }
    iinfo->get_first_data_point = get_first_debug_entry;
    iinfo->get_next_data_point = get_next_debug_entry;
    iinfo->table_reginfo        = table_info;


    /*
     * .... and register the table with the agent.
     */
    netsnmp_register_table_iterator2(
        netsnmp_create_handler_registration(
            "tzDebugTable", handle_nsDebugTable,
            nsDebugTokenTable_oid, OID_LENGTH(nsDebugTokenTable_oid),
            HANDLER_CAN_RWRITE),
        iinfo);
}
Beispiel #18
0
/**
 * update stats
 *
 * @retval  0 : success
 * @retval -1 : error
 */
int
netsnmp_access_interface_entry_update_stats(netsnmp_interface_entry * prev_vals,
                                            netsnmp_interface_entry * new_vals)
{
    DEBUGMSGTL(("access:interface", "check_wrap\n"));
    
    /*
     * sanity checks
     */
    if ((NULL == prev_vals) || (NULL == new_vals) ||
        (NULL == prev_vals->name) || (NULL == new_vals->name) ||
        (0 != strncmp(prev_vals->name, new_vals->name, strlen(prev_vals->name))))
        return -1;

    /*
     * if we've determined that we have 64 bit counters, just copy them.
     */
    if (0 == need_wrap_check) {
        memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats));
        return 0;
    }

    if (NULL == prev_vals->old_stats) {
        /*
         * if we don't have old stats, copy previous stats
         */
        prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_interface_stats);
        if (NULL == prev_vals->old_stats) {
            return -2;
        }
        memcpy(prev_vals->old_stats, &prev_vals->stats, sizeof(prev_vals->stats));
    }

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.ibytes,
                                       &new_vals->stats.ibytes,
                                       &prev_vals->old_stats->ibytes,
                                       &need_wrap_check))
            DEBUGMSGTL(("access:interface",
                    "Error expanding ifHCInOctets to 64bits\n"));

        if (new_vals->ns_flags & NETSNMP_INTERFACE_FLAGS_CALCULATE_UCAST) {
            if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iall,
                                           &new_vals->stats.iall,
                                           &prev_vals->old_stats->iall,
                                           &need_wrap_check))
                DEBUGMSGTL(("access:interface",
                        "Error expanding packet count to 64bits\n"));
        } else {
            if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iucast,
                                           &new_vals->stats.iucast,
                                           &prev_vals->old_stats->iucast,
                                           &need_wrap_check))
                DEBUGMSGTL(("access:interface",
                        "Error expanding ifHCInUcastPkts to 64bits\n"));
        }

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iucast,
                                       &new_vals->stats.iucast,
                                       &prev_vals->old_stats->iucast,
                                       &need_wrap_check))
            DEBUGMSGTL(("access:interface",
                    "Error expanding ifHCInUcastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.imcast,
                                       &new_vals->stats.imcast,
                                       &prev_vals->old_stats->imcast,
                                       &need_wrap_check))
            DEBUGMSGTL(("access:interface",
                    "Error expanding ifHCInMulticastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.ibcast,
                                       &new_vals->stats.ibcast,
                                       &prev_vals->old_stats->ibcast,
                                       &need_wrap_check))
            DEBUGMSGTL(("access:interface",
                    "Error expanding ifHCInBroadcastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.obytes,
                                       &new_vals->stats.obytes,
                                       &prev_vals->old_stats->obytes,
                                       &need_wrap_check))
            DEBUGMSGTL(("access:interface",
                    "Error expanding ifHCOutOctets to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.oucast,
                                       &new_vals->stats.oucast,
                                       &prev_vals->old_stats->oucast,
                                       &need_wrap_check))
            DEBUGMSGTL(("access:interface",
                    "Error expanding ifHCOutUcastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.omcast,
                                       &new_vals->stats.omcast,
                                       &prev_vals->old_stats->omcast,
                                       &need_wrap_check))
            DEBUGMSGTL(("access:interface",
                    "Error expanding ifHCOutMulticastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.obcast,
                                       &new_vals->stats.obcast,
                                       &prev_vals->old_stats->obcast,
                                       &need_wrap_check))
            DEBUGMSGTL(("access:interface",
                    "Error expanding ifHCOutBroadcastPkts to 64bits\n"));

    /*
     * Copy 32 bit counters
     */
    prev_vals->stats.ierrors = new_vals->stats.ierrors;
    prev_vals->stats.idiscards = new_vals->stats.idiscards;
    prev_vals->stats.iunknown_protos = new_vals->stats.iunknown_protos;
    prev_vals->stats.inucast = new_vals->stats.inucast;
    prev_vals->stats.oerrors = new_vals->stats.oerrors;
    prev_vals->stats.odiscards = new_vals->stats.odiscards;
    prev_vals->stats.oqlen = new_vals->stats.oqlen;
    prev_vals->stats.collisions = new_vals->stats.collisions;
    prev_vals->stats.onucast = new_vals->stats.onucast;

    /*
     * if we've decided we no longer need to check wraps, free old stats
     */
    if (0 == need_wrap_check) {
        SNMP_FREE(prev_vals->old_stats);
    }
    else {
        /*
         * update old stats from new stats.
         * careful - old_stats is a pointer to stats...
         */
        memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats));
    }
    
    return 0;
}
Beispiel #19
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;
    }
}
/** Initialize the LHANodeTable table by defining its contents and how it's structured */
void
initialize_table_LHANodeTable(void)
{
    static oid LHANodeTable_oid[] = {1,3,6,1,4,1,4682,2};
    netsnmp_table_registration_info *table_info;
    netsnmp_handler_registration *my_handler;
    netsnmp_iterator_info *iinfo;

    /** create the table registration information structures */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);

    /** if your table is read only, it's easiest to change the
        HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */
    my_handler = netsnmp_create_handler_registration("LHANodeTable",
                                             LHANodeTable_handler,
                                             LHANodeTable_oid,
                                             OID_LENGTH(LHANodeTable_oid),
                                             HANDLER_CAN_RONLY);
            
    if (!my_handler || !table_info || !iinfo) {
        snmp_log(LOG_ERR, "malloc failed in initialize_table_LHANodeTable");
	SNMP_FREE(iinfo);
	SNMP_FREE(table_info);
        return; /* Serious error. */
    }

    /***************************************************
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(table_info,
                                  ASN_INTEGER, /* index: LHANodeIndex */
                             0);

    /** Define the minimum and maximum accessible columns.  This
        optimizes retrival. */
    table_info->min_column = 2;
    table_info->max_column = 6;

    /* iterator access routines */
    iinfo->get_first_data_point = LHANodeTable_get_first_data_point;
    iinfo->get_next_data_point = LHANodeTable_get_next_data_point;

    /** tie the two structures together */
    iinfo->table_reginfo = table_info;

    /***************************************************
     * registering the table with the master agent
     */
    DEBUGMSGTL(("initialize_table_LHANodeTable",
                "Registering table LHANodeTable as a table iterator\n"));		 
    netsnmp_register_table_iterator(my_handler, iinfo);

    /*
     * .... with a local cache
     */
    netsnmp_inject_handler(my_handler,
	 netsnmp_get_cache_handler(snmp_cache_time_out, 
				   LHANodeTable_load,
				   LHANodeTable_free,
				   LHANodeTable_oid,
				   OID_LENGTH(LHANodeTable_oid)));
}
/** Initialize the hrSWInstalledTable table by defining its contents and how it's structured */
void
initialize_table_hrSWInstalledTable(void)
{
    static oid      hrSWInstalledTable_oid[] =
        { 1, 3, 6, 1, 2, 1, 25, 6, 3 };
    size_t          hrSWInstalledTable_oid_len =
        OID_LENGTH(hrSWInstalledTable_oid);
    netsnmp_handler_registration *reg;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;
    netsnmp_cache *cache = NULL;

    DEBUGMSGTL(("hrSWInstalled", "initialize\n"));

    reg =
        netsnmp_create_handler_registration("hrSWInstalledTable",
                                            hrSWInstalledTable_handler,
                                            hrSWInstalledTable_oid,
                                            hrSWInstalledTable_oid_len,
                                            HANDLER_CAN_RONLY);
    if (NULL == reg) {
        snmp_log(LOG_ERR,"error creating handler registration for "
                 MYTABLE "\n");
        goto bail;
    }

    container = netsnmp_container_find("hrSWInstalledTable:table_container");
    if (NULL == container) {
        snmp_log(LOG_ERR,"error creating container for "
                 MYTABLE "\n");
        goto bail;
    }

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,"error allocating table registration for "
                 MYTABLE "\n");
        goto bail;
    }

    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index: hrSWInstalledIndex */
                                     0);
    table_info->min_column = COLUMN_HRSWINSTALLEDINDEX;
    table_info->max_column = COLUMN_HRSWINSTALLEDDATE;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, container,
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,"error allocating table registration for "
                 MYTABLE "\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,"error injecting container_table handler for "
                 MYTABLE "\n");
        goto bail;
    }
    handler = NULL; /* reg has it, will reuse below */

    /*************************************************
     *
     * inject cache helper
     */
    cache = netsnmp_cache_create(30,    /* timeout in seconds */
                                 _cache_load, _cache_free,
                                 hrSWInstalledTable_oid,
                                 hrSWInstalledTable_oid_len);

    if (NULL == cache) {
        snmp_log(LOG_ERR, "error creating cache for "
                 MYTABLE "\n");
        goto bail;
    }
    cache->magic = container;

    handler = netsnmp_cache_handler_get(cache);
    if (NULL == handler) {
        snmp_log(LOG_ERR, "error creating cache handler for "
                 MYTABLE "\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,"error injecting cache handler for "
                 MYTABLE "\n");
        goto bail;
    }
    handler = NULL; /* reg has it*/

    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,"error registering table handler for "
                 MYTABLE "\n");
        reg = NULL; /* it was freed inside netsnmp_register_table */
        goto bail;
    }

    return; /* ok */


  bail: /* not ok */
    
    if (handler)
        netsnmp_handler_free(handler);

    if (cache)
        netsnmp_cache_free(cache);

    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (container)
        CONTAINER_FREE(container);

    if (reg) 
        netsnmp_handler_registration_free(reg);

}
void
netsnmp_parse_override(const char *token, char *line)
{
    char           *cp;
    char            buf[SNMP_MAXBUF], namebuf[SNMP_MAXBUF];
    int             readwrite = 0;
    oid             oidbuf[MAX_OID_LEN];
    size_t          oidbuf_len = MAX_OID_LEN;
    int             type;
    override_data  *thedata;
    netsnmp_handler_registration *the_reg;

    cp = copy_nword(line, namebuf, sizeof(namebuf) - 1);
    if (strcmp(namebuf, "-rw") == 0) {
        readwrite = 1;
        cp = copy_nword(cp, namebuf, sizeof(namebuf) - 1);
    }

    if (!cp) {
        config_perror("no oid specified");
        return;
    }

    if (!snmp_parse_oid(namebuf, oidbuf, &oidbuf_len)) {
        config_perror("illegal oid");
        return;
    }
    cp = copy_nword(cp, buf, sizeof(buf) - 1);

    if (!cp && strcmp(buf, "null") != 0) {
        config_perror("no variable value specified");
        return;
    }

    {
        struct { const char* key; int value; } const strings[] = {
            { "counter", ASN_COUNTER },
            { "counter64", ASN_COUNTER64 },
            { "integer", ASN_INTEGER },
            { "ipaddress", ASN_IPADDRESS },
            { "nsap", ASN_NSAP },
            { "null", ASN_NULL },
            { "object_id", ASN_OBJECT_ID },
            { "octet_str", ASN_OCTET_STR },
            { "opaque", ASN_OPAQUE },
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
            { "opaque_counter64", ASN_OPAQUE_COUNTER64 },
            { "opaque_double", ASN_OPAQUE_DOUBLE },
            { "opaque_float", ASN_OPAQUE_FLOAT },
            { "opaque_i64", ASN_OPAQUE_I64 },
            { "opaque_u64", ASN_OPAQUE_U64 },
#endif
            { "timeticks", ASN_TIMETICKS },
            { "uinteger", ASN_GAUGE },
            { "unsigned", ASN_UNSIGNED },
            { NULL, 0 }
        }, * run;
        for(run = strings; run->key && strcasecmp(run->key, buf) < 0; ++run);
        if(run->key && strcasecmp(run->key, buf) == 0)
            type = run->value;
        else {
            config_perror("unknown type specified");
            return;
        }
    }

    if (cp)
        copy_nword(cp, buf, sizeof(buf) - 1);
    else
        buf[0] = 0;

    thedata = SNMP_MALLOC_TYPEDEF(override_data);
    if (!thedata) {
        config_perror("memory allocation failure");
        return;
    }
    thedata->type = type;

    switch (type) {
    case ASN_INTEGER:
        MALLOC_OR_DIE(sizeof(long));
        *((long *) thedata->value) = strtol(buf, NULL, 0);
        break;

    case ASN_COUNTER:
    case ASN_TIMETICKS:
    case ASN_UNSIGNED:
        MALLOC_OR_DIE(sizeof(u_long));
        *((u_long *) thedata->value) = strtoul(buf, NULL, 0);
        break;

    case ASN_OCTET_STR:
    case ASN_BIT_STR:
        if (buf[0] == '0' && buf[1] == 'x') {
            /*
             * hex 
             */
            thedata->value_len =
                hex_to_binary2((u_char *)(buf + 2), strlen(buf) - 2,
                               (char **) &thedata->value);
        } else {
            thedata->value = strdup(buf);
            thedata->value_len = strlen(buf);
        }
        break;

    case ASN_OBJECT_ID:
        read_config_read_objid(buf, (oid **) & thedata->value,
                               &thedata->value_len);
        break;

    case ASN_NULL:
        thedata->value_len = 0;
        break;

    default:
        SNMP_FREE(thedata);
        config_perror("illegal/unsupported type specified");
        return;
    }

    if (!thedata->value && thedata->type != ASN_NULL) {
        config_perror("memory allocation failure");
        free(thedata);
        return;
    }

    the_reg = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
    if (!the_reg) {
        config_perror("memory allocation failure");
        free(thedata);
        return;
    }

    the_reg->handlerName = strdup(namebuf);
    the_reg->priority = 255;
    the_reg->modes = (readwrite) ? HANDLER_CAN_RWRITE : HANDLER_CAN_RONLY;
    the_reg->handler =
        netsnmp_create_handler("override", override_handler);
    the_reg->rootoid = snmp_duplicate_objid(oidbuf, oidbuf_len);
    the_reg->rootoid_len = oidbuf_len;
    if (!the_reg->rootoid || !the_reg->handler || !the_reg->handlerName) {
        if (the_reg->handler)
            SNMP_FREE(the_reg->handler->handler_name);
        SNMP_FREE(the_reg->handler);
        SNMP_FREE(the_reg->handlerName);
        SNMP_FREE(the_reg);
        config_perror("memory allocation failure");
        free(thedata);
        return;
    }
    the_reg->handler->myvoid = thedata;

    if (netsnmp_register_instance(the_reg)) {
        config_perror("oid registration failed within the agent");
        SNMP_FREE(thedata->value);
        free(thedata);
        return;
    }
}
Beispiel #23
0
void
init_tcpTable(void)
{
    const oid tcpTable_oid[] = { SNMP_OID_MIB2, 6, 13 };

    netsnmp_table_registration_info *table_info;
    netsnmp_iterator_info           *iinfo;
    netsnmp_handler_registration    *reginfo;
    int                              rc;

    DEBUGMSGTL(("mibII/tcpTable", "Initialising TCP Table\n"));
    /*
     * Create the table data structure, and define the indexing....
     */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (!table_info) {
        return;
    }
    netsnmp_table_helper_add_indexes(table_info, ASN_IPADDRESS,
                                                 ASN_INTEGER,
                                                 ASN_IPADDRESS,
                                                 ASN_INTEGER, 0);
    table_info->min_column = TCPCONNSTATE;
    table_info->max_column = TCPCONNREMOTEPORT;


    /*
     * .... and iteration information ....
     */
    iinfo      = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
    if (!iinfo) {
        return;
    }
    iinfo->get_first_data_point = tcpTable_first_entry;
    iinfo->get_next_data_point  = tcpTable_next_entry;
    iinfo->table_reginfo        = table_info;
#if defined (WIN32) || defined (cygwin)
    iinfo->flags               |= NETSNMP_ITERATOR_FLAG_SORTED;
#endif /* WIN32 || cygwin */


    /*
     * .... and register the table with the agent.
     */
    reginfo = netsnmp_create_handler_registration("tcpTable",
            tcpTable_handler,
            tcpTable_oid, OID_LENGTH(tcpTable_oid),
            HANDLER_CAN_RONLY),
    rc = netsnmp_register_table_iterator2(reginfo, iinfo);
    if (rc != SNMPERR_SUCCESS)
        return;

    /*
     * .... with a local cache
     *    (except for Solaris, which uses a different approach)
     */
    netsnmp_inject_handler( reginfo,
		    netsnmp_get_cache_handler(TCP_STATS_CACHE_TIMEOUT,
			   		tcpTable_load, tcpTable_free,
					tcpTable_oid, OID_LENGTH(tcpTable_oid)));
}
Beispiel #24
0
/** implements the table data helper.  This is the routine that takes
 *  care of all SNMP requests coming into the table. */
int
netsnmp_table_data_set_helper_handler(netsnmp_mib_handler *handler,
                                      netsnmp_handler_registration
                                      *reginfo,
                                      netsnmp_agent_request_info *reqinfo,
                                      netsnmp_request_info *requests)
{

    netsnmp_table_data_set_storage *data = NULL;
    newrow_stash   *newrowstash = NULL;
    netsnmp_table_row *row, *newrow = NULL;
    netsnmp_table_request_info *table_info;
    netsnmp_request_info *request;
    oid            *suffix;
    size_t          suffix_len;
    netsnmp_oid_stash_node **stashp = NULL;

    if (!handler)
        return SNMPERR_GENERR;
        
    DEBUGMSGTL(("netsnmp_table_data_set", "handler starting\n"));
    for (request = requests; request; request = request->next) {
        netsnmp_table_data_set *datatable =
            (netsnmp_table_data_set *) handler->myvoid;
        if (request->processed)
            continue;

        /*
         * extract our stored data and table info 
         */
        row = netsnmp_extract_table_row(request);
        table_info = netsnmp_extract_table_info(request);
        suffix = requests->requestvb->name + reginfo->rootoid_len + 2;
        suffix_len = requests->requestvb->name_length -
            (reginfo->rootoid_len + 2);

        if (MODE_IS_SET(reqinfo->mode)) {

            char buf[256]; /* is this reasonable size?? */
            int  rc;
            size_t len;

            /*
             * use a cached copy of the row for modification 
             */

            /*
             * cache location: may have been created already by other
             * SET requests in the same master request. 
             */
            rc = snprintf(buf, sizeof(buf), "dataset_row_stash:%s:",
                          datatable->table->name);
            if ((-1 == rc) || (rc >= sizeof(buf))) {
                snmp_log(LOG_ERR,"%s handler name too long\n",
                         datatable->table->name);
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_GENERR);
                continue;
            }
            len = sizeof(buf) - rc;
            rc = snprint_objid(&buf[rc], len, table_info->index_oid,
                               table_info->index_oid_len);
            if (-1 == rc) {
                snmp_log(LOG_ERR,"%s oid or name too long\n",
                         datatable->table->name);
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_GENERR);
                continue;
            }
            stashp = (netsnmp_oid_stash_node **)
                netsnmp_table_get_or_create_row_stash(reqinfo, buf);

            newrowstash
                = netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len);

            if (!newrowstash) {
                if (!row) {
                    if (datatable->allow_creation) {
                        /*
                         * entirely new row.  Create the row from the template 
                         */
                        newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                        newrow = newrowstash->newrow;
                    } else if (datatable->rowstatus_column == 0) {
                        /*
                         * A RowStatus object may be used to control the
                         *  creation of a new row.  But if this object
                         *  isn't declared (and the table isn't marked as
                         *  'auto-create'), then we can't create a new row.
                         */
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_NOCREATION);
                        continue;
                    }
                } else {
                    /*
                     * existing row that needs to be modified 
                     */
                    newrowstash = SNMP_MALLOC_TYPEDEF(newrow_stash);
                    newrow = netsnmp_table_data_set_clone_row(row);
                    newrowstash->newrow = newrow;
                }
                netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                           newrowstash);
            } else {
                newrow = newrowstash->newrow;
            }
            /*
             * all future SET data modification operations use this
             * temp pointer 
             */
            if (reqinfo->mode == MODE_SET_RESERVE1 ||
                reqinfo->mode == MODE_SET_RESERVE2)
                row = newrow;
        }

        if (row)
            data = (netsnmp_table_data_set_storage *) row->data;

        if (!row || !table_info || !data) {
            if (!MODE_IS_SET(reqinfo->mode)) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
        }

        data =
            netsnmp_table_data_set_find_column(data, table_info->colnum);

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
        case MODE_GETBULK:     /* XXXWWW */
            if (data && data->data.voidp)
                netsnmp_table_data_build_result(reginfo, reqinfo, request,
                                                row,
                                                table_info->colnum,
                                                data->type,
                                                data->data.voidp,
                                                data->data_len);
            break;

        case MODE_SET_RESERVE1:
            if (data) {
                /*
                 * Can we modify the existing row?
                 */
                if (!data->writable) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOTWRITABLE);
                } else if (request->requestvb->type != data->type) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                }
            } else if (datatable->rowstatus_column == table_info->colnum) {
                /*
                 * Otherwise, this is where we create a new row using
                 * the RowStatus object (essentially duplicating the
                 * steps followed earlier in the 'allow_creation' case)
                 */
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                    newrow = newrowstash->newrow;
                    row    = newrow;
                    netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                               newrowstash);
                }
            }
            break;

        case MODE_SET_RESERVE2:
            /*
             * If the agent receives a SET request for an object in a non-existant
             *  row, then the RESERVE1 pass will create the row automatically.
             *
             * But since the row doesn't exist at that point, the test for whether
             *  the object is writable or not will be skipped.  So we need to check
             *  for this possibility again here.
             *
             * Similarly, if row creation is under the control of the RowStatus
             *  object (i.e. allow_creation == 0), but this particular request
             *  doesn't include such an object, then the row won't have been created,
             *  and the writable check will also have been skipped.  Again - check here.
             */
            if (data && data->writable == 0) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                continue;
            }
            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_ACTIVE:
                case RS_NOTINSERVICE:
                    /*
                     * Can only operate on pre-existing rows.
                     */
                    if (!newrowstash || newrowstash->created) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    /*
                     * Can only operate on newly created rows.
                     */
                    if (!(newrowstash && newrowstash->created)) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_DESTROY:
                    /*
                     * Can operate on new or pre-existing rows.
                     */
                    break;

                case RS_NOTREADY:
                default:
                    /*
                     * Not a valid value to Set 
                     */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    continue;
                }
            }
            if (!data ) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOCREATION);
                continue;
            }

            /*
             * modify row and set new value 
             */
            SNMP_FREE(data->data.string);
            data->data.string =
                netsnmp_strdup_and_null(request->requestvb->val.string,
                                        request->requestvb->val_len);
            if (!data->data.string) {
                netsnmp_set_request_error(reqinfo, requests,
                                          SNMP_ERR_RESOURCEUNAVAILABLE);
            }
            data->data_len = request->requestvb->val_len;

            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_ACTIVE;
                    break;

                case RS_CREATEANDWAIT:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_NOTINSERVICE;
                    break;

                case RS_DESTROY:
                    newrowstash->deleted = 1;
                    break;
                }
            }
            break;

        case MODE_SET_ACTION:

            /*
             * Install the new row into the stored table.
	     * Do this only *once* per row ....
             */
            if (newrowstash->state != STATE_ACTION) {
                newrowstash->state = STATE_ACTION;
		if (newrowstash->created) {
                    netsnmp_table_dataset_add_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      row, newrow);
                }
            }
            /*
             * ... but every (relevant) varbind in the request will
	     * need to know about this new row, so update the
	     * per-request row information regardless
             */
            if (newrowstash->created) {
		netsnmp_request_add_list_data(request,
			netsnmp_create_data_list(TABLE_DATA_NAME,
						 newrow, NULL));
            }
            break;

        case MODE_SET_UNDO:
            /*
             * extract the new row, replace with the old or delete 
             */
            if (newrowstash->state != STATE_UNDO) {
                newrowstash->state = STATE_UNDO;
                if (newrowstash->created) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      newrow, row);
                    netsnmp_table_dataset_delete_row(newrow);
                }
            }
            break;

        case MODE_SET_COMMIT:
            if (newrowstash->state != STATE_COMMIT) {
                newrowstash->state = STATE_COMMIT;
                if (!newrowstash->created) {
                    netsnmp_table_dataset_delete_row(row);
                }
                if (newrowstash->deleted) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                }
            }
            break;

        case MODE_SET_FREE:
            if (newrowstash && newrowstash->state != STATE_FREE) {
                newrowstash->state = STATE_FREE;
                netsnmp_table_dataset_delete_row(newrow);
            }
            break;
        }
    }

    /* next handler called automatically - 'AUTO_NEXT' */
    return SNMP_ERR_NOERROR;
}
/*
 * Initialize the openserSIPStatusCodesTable table by defining how it is
 * structured. 
 *
 * This function is mostly auto-generated.
 */
void initialize_table_openserSIPStatusCodesTable(void)
{
	netsnmp_table_registration_info *table_info;

	if(my_handler) {
		snmp_log(LOG_ERR, "initialize_table_openserSIPStatusCodes"
				"Table_handler called again\n");
		return;
	}

	memset(&cb, 0x00, sizeof(cb));

	/** create the table structure itself */
	table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);

	my_handler = netsnmp_create_handler_registration(
			"openserSIPStatusCodesTable",
			netsnmp_table_array_helper_handler,
			openserSIPStatusCodesTable_oid,
			openserSIPStatusCodesTable_oid_len,
			HANDLER_CAN_RWRITE);
			
	if (!my_handler || !table_info) {
		snmp_log(LOG_ERR, "malloc failed in initialize_table_openserSIP"
				"StatusCodesTable_handler\n");
		return; /** mallocs failed */
	}

	/** index: openserSIPStatusCodeMethod */
	netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED);
	/** index: openserSIPStatusCodeValue */
	netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED);

	table_info->min_column = openserSIPStatusCodesTable_COL_MIN;
	table_info->max_column = openserSIPStatusCodesTable_COL_MAX;

	/***************************************************
	 * registering the table with the master agent
	 */
	cb.get_value = openserSIPStatusCodesTable_get_value;

	cb.container = 
		netsnmp_container_find("openserSIPStatusCodesTable_primary:"
				"openserSIPStatusCodesTable:"
				"table_container");

#ifdef openserSIPStatusCodesTable_CUSTOM_SORT
	netsnmp_container_add_index(cb.container,
			netsnmp_container_find(
				"openserSIPStatusCodesTable_custom:"
				"openserSIPStatusCodesTable:"
				"table_container"));

	cb.container->next->compare = openserSIPStatusCodesTable_cmp;
#endif
	cb.can_set = 1;

	cb.create_row    =
		(UserRowMethod*)openserSIPStatusCodesTable_create_row;

	cb.duplicate_row = 
		(UserRowMethod*)openserSIPStatusCodesTable_duplicate_row;

	cb.delete_row    = 
		(UserRowMethod*)openserSIPStatusCodesTable_delete_row;

	cb.row_copy      = (Netsnmp_User_Row_Operation *)
		openserSIPStatusCodesTable_row_copy;

	cb.can_activate  = (Netsnmp_User_Row_Action *)
		openserSIPStatusCodesTable_can_activate;

	cb.can_deactivate = (Netsnmp_User_Row_Action *)
		openserSIPStatusCodesTable_can_deactivate;

	cb.can_delete     = 
		(Netsnmp_User_Row_Action *)openserSIPStatusCodesTable_can_delete;

	cb.set_reserve1   = openserSIPStatusCodesTable_set_reserve1;
	cb.set_reserve2   = openserSIPStatusCodesTable_set_reserve2;
	
	cb.set_action = openserSIPStatusCodesTable_set_action;
	cb.set_commit = openserSIPStatusCodesTable_set_commit;
	
	cb.set_free = openserSIPStatusCodesTable_set_free;
	cb.set_undo = openserSIPStatusCodesTable_set_undo;
	
	DEBUGMSGTL(("initialize_table_openserSIPStatusCodesTable",
				"Registering table openserSIPStatusCodesTable "
				"as a table array\n"));
	
	netsnmp_table_container_register(my_handler, table_info, &cb,
			cb.container, 1);
}
Beispiel #26
0
/* General initialization */
void init_custom_queries(void)
{
    netsnmp_table_registration_info *table_info;
    pgsnmpd_query *curquery;
    int i;
    PGresult *res;

    if (custom_query_config_file == NULL) 
        return;

    /*
        ASN_INTEGER = 0
        ASN_FLOAT = 1
        ASN_BOOLEAN = 2
        ASN_OCTET_STR = 3
    */

    res = PQprepare(dbconn, "TYPEQUERY", 
        "SELECT CASE "
            "WHEN typname LIKE 'int%' OR typname = 'xid' OR typname = 'oid'"
                "THEN 0 "
            "WHEN typname LIKE 'float%' THEN 1 "
            "WHEN typname = 'bool' THEN 2 "
            "ELSE 3 "
        "END "
        "FROM pg_catalog.pg_type WHERE oid = $1", 1, NULL);
    if (PQresultStatus(res) != PGRES_COMMAND_OK) {
        snmp_log(LOG_ERR, "Failed to prepare statement (error: %s)\n", PQresStatus(PQresultStatus(res)));
        return;
    }
    PQclear(res);

    head = parse_config(custom_query_config_file);
    if (head == NULL) {
        snmp_log(LOG_INFO, "No custom queries initialized\n");
        return;
    }

    for (curquery = head; curquery != NULL; curquery = curquery->next) {
        run_query(curquery);
        if (curquery->typeslen < curquery->colcount)
            curquery->types = realloc(curquery->types, sizeof(u_char) * curquery->colcount);
        if (curquery->types == NULL) {
            snmp_log(LOG_ERR, "Memory allocation problem");
            return;
        }
        init_types_array(curquery->types, curquery->typeslen, curquery->colcount);
        fill_query_column_types(curquery);
        if (curquery->my_handler) {
            snmp_log(LOG_ERR,
                "init_custom_queries called again for query %s\n",
                curquery->table_name);
            return;
        }

        memset(&(curquery->cb), 0x00, sizeof(curquery->cb));

        /** create the table structure itself */
        snmp_log(LOG_INFO, "Initializing table name %s\n", curquery->table_name);
        table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
        curquery->my_handler = netsnmp_create_handler_registration(
            curquery->table_name,
            netsnmp_table_array_helper_handler,
            curquery->table_oid,
            curquery->oid_len,
            HANDLER_CAN_RONLY
        );

        if (!curquery->my_handler || !table_info) {
            snmp_log(LOG_ERR, "malloc failed in init_custom_queries\n");
            return; /** mallocs failed */
        }

        netsnmp_table_helper_add_index(table_info, ASN_INTEGER); /* pgsnmpdConnID */
        netsnmp_table_helper_add_index(table_info, ASN_INTEGER); /* rdbmsDbIndex */
        for (i = 0; i < curquery->num_indexes; i++)
            netsnmp_table_helper_add_index(table_info, curquery->types[i]);

        table_info->min_column = curquery->min_colnum;
        table_info->max_column = curquery->colcount;

        curquery->cb.get_value = custom_query_get_value;
        curquery->cb.container = netsnmp_container_find("table_container");

        DEBUGMSGTL(("init_custom_queries",
                    "Registering table for query "
                    "as a table array\n"));
        switch (netsnmp_table_container_register(curquery->my_handler,
                    table_info, &curquery->cb,
                    curquery->cb.container, 1)) {
            case MIB_REGISTRATION_FAILED:
                snmp_log(LOG_INFO, "Failed to register table %s\n", curquery->table_name);
                break;
            case MIB_DUPLICATE_REGISTRATION:
                snmp_log(LOG_INFO, "Duplicate registration for table %s\n", curquery->table_name);
                break;
            case MIB_REGISTERED_OK:
                DEBUGMSGTL(("init_custom_queries",
                            "Successfully registered table %s\n", curquery->table_name));
                break;
            default:
                snmp_log(LOG_INFO, "Unknown registration result for table %s\n", curquery->table_name);
        }

        /* Having set everything up, fill the table's container with data */
        fill_query_container(curquery);
    }
    snmp_log(LOG_DEBUG, "Finished intializing queries\n");
}
netsnmp_transport *
netsnmp_std_transport(const char *instring, size_t instring_len,
		      const char *default_target)
{
    netsnmp_transport *t;

    t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
    if (t == NULL) {
        return NULL;
    }
    memset(t, 0, sizeof(netsnmp_transport));

    t->domain = netsnmp_snmpSTDDomain;
    t->domain_length =
        sizeof(netsnmp_snmpSTDDomain) / sizeof(netsnmp_snmpSTDDomain[0]);

    t->sock = 0;
    t->flags = NETSNMP_TRANSPORT_FLAG_STREAM | NETSNMP_TRANSPORT_FLAG_TUNNELED;

    /*
     * Message size is not limited by this transport (hence msgMaxSize
     * is equal to the maximum legal size of an SNMP message).  
     */

    t->msgMaxSize = 0x7fffffff;
    t->f_recv     = netsnmp_std_recv;
    t->f_send     = netsnmp_std_send;
    t->f_close    = netsnmp_std_close;
    t->f_accept   = netsnmp_std_accept;
    t->f_fmtaddr  = netsnmp_std_fmtaddr;

    /*
     * if instring is not null length, it specifies a path to a prog
     * XXX: plus args
     */
    if (instring_len == 0 && default_target != NULL) {
	instring = default_target;
	instring_len = strlen(default_target);
    }

    if (instring_len != 0) {
        int infd[2], outfd[2];  /* sockets to and from the client */
        int childpid;

        if (pipe(infd) || pipe(outfd)) {
            snmp_log(LOG_ERR,
                     "Failed to create needed pipes for a STD transport");
            netsnmp_transport_free(t);
            return NULL;
        }

        childpid = fork();
        /* parentpid => childpid */
        /* infd[1]   => infd[0] */
        /* outfd[0]  <= outfd[1] */

        if (childpid) {
            netsnmp_std_data *data;
            
            /* we're in the parent */
            close(infd[0]);
            close(outfd[1]);

            data = SNMP_MALLOC_TYPEDEF(netsnmp_std_data);
            if (!data) {
                snmp_log(LOG_ERR, "snmpSTDDomain: memdup failed");
                netsnmp_transport_free(t);
                return NULL;
            }
            t->data = data;
            t->data_length = sizeof(netsnmp_std_data);
            t->sock = outfd[0];
            data->prog = strdup(instring);
            data->outfd = infd[1];
            data->childpid = childpid;
            DEBUGMSGTL(("domain:std","parent.  data=%x\n", t->data));
        } else {
            /* we're in the child */

            /* close stdin */
            close(0);
            /* copy pipe output to stdout */
            dup(infd[0]);

            /* close stdout */
            close(1);
            /* copy pipe output to stdin */
            dup(outfd[1]);
            
            /* close all the pipes themselves */
            close(infd[0]);
            close(infd[1]);
            close(outfd[0]);
            close(outfd[1]);

            /* call exec */
            system(instring);
            /* XXX: TODO: use exec form instead; needs args */
            /* execv(instring, NULL); */
            exit(0);

            /* ack...  we should never ever get here */
            snmp_log(LOG_ERR, "STD transport returned after execv()\n");
        }
    }            

    return t;
}
Beispiel #28
0
void fill_query_container(pgsnmpd_query *query)
{
    /* TODO: Make this work */
    cust_query_row *row;
    int i, j, string_idx_count, string_idx_len;
    netsnmp_variable_list var_rdbmsDbIndex, var_pgsnmpdConnID, *var_otherIndexes;
    int err = SNMP_ERR_NOERROR;
    char *val;

    memset( &var_pgsnmpdConnID, 0x00, sizeof(var_pgsnmpdConnID) );
    var_pgsnmpdConnID.type = ASN_INTEGER;
    memset( &var_rdbmsDbIndex, 0x00, sizeof(var_rdbmsDbIndex) );
    var_rdbmsDbIndex.type = ASN_INTEGER;

    var_otherIndexes = malloc(sizeof(netsnmp_variable_list) * query->num_indexes);
    if (var_otherIndexes == NULL) {
        snmp_log(LOG_ERR, "Memory allocation error\n");
        return;
    }
    memset(var_otherIndexes, 0, sizeof(netsnmp_variable_list) * query->num_indexes);

    string_idx_count = 0;
    for (i = 0; i < query->num_indexes; i++) {
        if (i < query->num_indexes - 1)
            var_otherIndexes[i].next_variable = &var_otherIndexes[i+1];
        var_otherIndexes[i].type = query->types[i];
        if (query->types[i] == ASN_OCTET_STR)
            string_idx_count++;
    }

    var_pgsnmpdConnID.next_variable    = &var_rdbmsDbIndex;
    var_rdbmsDbIndex.next_variable     = var_otherIndexes;

    snmp_set_var_typed_value(&var_rdbmsDbIndex, ASN_INTEGER, (u_char *) &rdbmsDbIndex, sizeof(int));
    snmp_set_var_typed_value(&var_pgsnmpdConnID, ASN_INTEGER, (u_char *) &pgsnmpdConnID, sizeof(int));

    for (i = 0; i < query->rowcount; i++) {
        string_idx_len = 0;
        for (j = 0; j < query->num_indexes; j++) {
            val = PQgetvalue(query->result, i, j);
            /* TODO: Floats and OIDs also need more than the usual memory.
             * Learn to handle them. Until then we can expect problems using
             * OIDs and Floats as indexes  */
            if (query->types[j] == ASN_OCTET_STR) string_idx_len += strlen(val);
            set_val_from_string(&var_otherIndexes[j], query->types[j], val);
        }
        row = SNMP_MALLOC_TYPEDEF(cust_query_row);
        row->myoids = malloc(sizeof(oid) * 
            (query->num_indexes + extra_idx_count + string_idx_count + string_idx_len));
        if (row->myoids == NULL) {
            snmp_log(LOG_ERR, "memory allocation problem \n");
            return;
        }

        row->row_index.len = query->num_indexes + extra_idx_count + string_idx_len + string_idx_count;
        row->row_index.oids = row->myoids;

        err = build_oid_noalloc(row->row_index.oids, row->row_index.len,
                     (size_t *) &(row->row_index.len), NULL, 0, &var_pgsnmpdConnID);
        if (err)
            snmp_log(LOG_ERR,"error %d converting index to oid, query %s\n", err,
                query->table_name);

        row->query = query;
        row->rownum = i;

        CONTAINER_INSERT(query->cb.container, row);
    }
}
/*
 *  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);
    }
}
Beispiel #30
0
/*
 * Make a deep copy of an netsnmp_transport.
 */
netsnmp_transport *
netsnmp_transport_copy(netsnmp_transport *t)
{
    netsnmp_transport *n = NULL;

    if (t == NULL) {
        return NULL;
    }

    n = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
    if (n == NULL) {
        return NULL;
    }

    if (t->domain != NULL) {
        n->domain = t->domain;
        n->domain_length = t->domain_length;
    } else {
        n->domain = NULL;
        n->domain_length = 0;
    }

    if (t->local != NULL) {
        n->local = (u_char *) malloc(t->local_length);
        if (n->local == NULL) {
            netsnmp_transport_free(n);
            return NULL;
        }
        n->local_length = t->local_length;
        memcpy(n->local, t->local, t->local_length);
    } else {
        n->local = NULL;
        n->local_length = 0;
    }

    if (t->remote != NULL) {
        n->remote = (u_char *) malloc(t->remote_length);
        if (n->remote == NULL) {
            netsnmp_transport_free(n);
            return NULL;
        }
        n->remote_length = t->remote_length;
        memcpy(n->remote, t->remote, t->remote_length);
    } else {
        n->remote = NULL;
        n->remote_length = 0;
    }

    if (t->data != NULL && t->data_length > 0) {
        n->data = malloc(t->data_length);
        if (n->data == NULL) {
            netsnmp_transport_free(n);
            return NULL;
        }
        n->data_length = t->data_length;
        memcpy(n->data, t->data, t->data_length);
    } else {
        n->data = NULL;
        n->data_length = 0;
    }

    n->msgMaxSize = t->msgMaxSize;
    n->f_accept = t->f_accept;
    n->f_recv = t->f_recv;
    n->f_send = t->f_send;
    n->f_close = t->f_close;
    n->f_copy = t->f_copy;
    n->f_config = t->f_config;
    n->f_fmtaddr = t->f_fmtaddr;
    n->sock = t->sock;
    n->flags = t->flags;
    n->base_transport = netsnmp_transport_copy(t->base_transport);

    /* give the transport a chance to do "special things" */
    if (t->f_copy)
        t->f_copy(t, n);

    return n;
}