⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table_container.c

📁 开发snmp的开发包有两个开放的SNMP开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
     * structure with the same index values as the request     * passed in (which includes that one!).     *     * So construct an OID based on these index values.     */    table_info = netsnmp_extract_table_info(request);    this_index = table_info->indexes;    build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len,                      base_oid, 2, this_index);    /*     * We need to look through the whole of the request list     * (as received by the current handler), as there's no     * guarantee that this routine will be called by the first     * varbind that refers to this row.     *   In particular, a RowStatus controlled row creation     * may easily occur later in the variable list.     *     * So first, we rewind to the head of the list....     */    for (req=request; req->prev; req=req->prev)        ;    /*     * ... and then start looking for matching indexes     * (by constructing OIDs from these index values)     */    for (; req; req=req->next) {        if (req->processed)             continue;                table_info = netsnmp_extract_table_info(req);        that_index = table_info->indexes;        build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len,                          base_oid, 2, that_index);              /*         * This request has the same index values,         * so add the newly-created row information.         */        if (snmp_oid_compare(this_oid, this_oid_len,                             that_oid, that_oid_len) == 0) {            netsnmp_request_add_list_data(req,                netsnmp_create_data_list(TABLE_CONTAINER_ROW, row, NULL));        }    }}/** @cond *//********************************************************************** ********************************************************************** *                                                                    * *                                                                    * * DATA LOOKUP functions                                              * *                                                                    * *                                                                    * ********************************************************************** **********************************************************************/NETSNMP_STATIC_INLINE void_set_key( container_table_data * tad, netsnmp_request_info *request,          netsnmp_table_request_info *tblreq_info,          void **key, netsnmp_index *index ){    if (TABLE_CONTAINER_KEY_NETSNMP_INDEX == tad->key_type) {        index->oids = tblreq_info->index_oid;        index->len = tblreq_info->index_oid_len;        *key = index;    }    else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) {        *key = tblreq_info->indexes;    }#if 0    else if (TABLE_CONTAINER_KEY_VARBIND_RAW == tad->key_type) {        *key = request->requestvb;    }#endif    else        *key = NULL;}NETSNMP_STATIC_INLINE void_data_lookup(netsnmp_handler_registration *reginfo,            netsnmp_agent_request_info *agtreq_info,            netsnmp_request_info *request, container_table_data * tad){    netsnmp_index *row = NULL;    netsnmp_table_request_info *tblreq_info;    netsnmp_variable_list *var;    netsnmp_index index;    void *key;    var = request->requestvb;    DEBUGIF("table_container") {        DEBUGMSGTL(("table_container", "  data_lookup oid:"));        DEBUGMSGOID(("table_container", var->name, var->name_length));        DEBUGMSG(("table_container", "\n"));    }    /*     * Get pointer to the table information for this request. This     * information was saved by table_helper_handler.     */    tblreq_info = netsnmp_extract_table_info(request);    /** the table_helper_handler should enforce column boundaries. */    netsnmp_assert((NULL != tblreq_info) &&                   (tblreq_info->colnum <= tad->tblreg_info->max_column));        if ((agtreq_info->mode == MODE_GETNEXT) ||        (agtreq_info->mode == MODE_GETBULK)) {        /*         * find the row. This will automatically move to the next         * column, if necessary.         */        _set_key( tad, request, tblreq_info, &key, &index );        row = _find_next_row(tad->table, tblreq_info, key);        if (row) {            /*             * update indexes in tblreq_info (index & varbind),             * then update request varbind oid             */            if(TABLE_CONTAINER_KEY_NETSNMP_INDEX == tad->key_type) {                tblreq_info->index_oid_len = row->len;                memcpy(tblreq_info->index_oid, row->oids,                       row->len * sizeof(oid));                netsnmp_update_variable_list_from_index(tblreq_info);            }            else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) {                /** xxx-rks: shouldn't tblreq_info->indexes be updated                    before we call this?? */                netsnmp_update_indexes_from_variable_list(tblreq_info);            }            if (TABLE_CONTAINER_KEY_VARBIND_RAW != tad->key_type) {                netsnmp_table_build_oid_from_index(reginfo, request,                                                   tblreq_info);            }        }        else {            /*             * no results found. Flag the request so lower handlers will             * ignore it, but it is not an error - getnext will move             * on to another handler to process this request.             */            netsnmp_set_request_error(agtreq_info, request, SNMP_ENDOFMIBVIEW);            DEBUGMSGTL(("table_container", "no row found\n"));        }    } /** GETNEXT/GETBULK */    else {        _set_key( tad, request, tblreq_info, &key, &index );        row = CONTAINER_FIND(tad->table, key);        if (NULL == row) {            /*             * not results found. For a get, that is an error             */            DEBUGMSGTL(("table_container", "no row found\n"));            if((agtreq_info->mode != MODE_SET_RESERVE1) || /* get */               (reginfo->modes & HANDLER_CAN_NOT_CREATE)) { /* no create */                netsnmp_set_request_error(agtreq_info, request,                                          SNMP_NOSUCHINSTANCE);            }        }    } /** GET/SET */        /*     * save the data and table in the request.     */    if (SNMP_ENDOFMIBVIEW != request->requestvb->type) {        if (NULL != row)            netsnmp_request_add_list_data(request,                                          netsnmp_create_data_list                                          (TABLE_CONTAINER_ROW,                                           row, NULL));        netsnmp_request_add_list_data(request,                                      netsnmp_create_data_list                                      (TABLE_CONTAINER_CONTAINER,                                       tad->table, NULL));    }}/********************************************************************** ********************************************************************** *                                                                    * *                                                                    * * netsnmp_table_container_helper_handler()                           * *                                                                    * *                                                                    * ********************************************************************** **********************************************************************/static int_container_table_handler(netsnmp_mib_handler *handler,                         netsnmp_handler_registration *reginfo,                         netsnmp_agent_request_info *agtreq_info,                         netsnmp_request_info *requests){    int             rc = SNMP_ERR_NOERROR;    int             oldmode, need_processing = 0;    container_table_data *tad;    /** sanity checks */    netsnmp_assert((NULL != handler) && (NULL != handler->myvoid));    netsnmp_assert((NULL != reginfo) && (NULL != agtreq_info));    DEBUGMSGTL(("table_container", "Mode %s, Got request:\n",                se_find_label_in_slist("agent_mode",agtreq_info->mode)));    /*     * First off, get our pointer from the handler. This     * lets us get to the table registration information we     * saved in get_table_container_handler(), as well as the     * container where the actual table data is stored.     */    tad = (container_table_data *)handler->myvoid;    /*     * only do data lookup for first pass     *     * xxx-rks: this should really be handled up one level. we should     * be able to say what modes we want to be called for during table     * registration.     */    oldmode = agtreq_info->mode;    if(MODE_IS_GET(oldmode) || (MODE_SET_RESERVE1 == oldmode)) {        netsnmp_request_info *curr_request;        /*         * Loop through each of the requests, and         * try to find the appropriate row from the container.         */        for (curr_request = requests; curr_request; curr_request = curr_request->next) {            /*             * skip anything that doesn't need processing.             */            if (curr_request->processed != 0) {                DEBUGMSGTL(("table_container", "already processed\n"));                continue;            }                        /*             * find data for this request             */            _data_lookup(reginfo, agtreq_info, curr_request, tad);            if(curr_request->processed)                continue;            ++need_processing;        } /** for ( ... requests ... ) */    }        /*     * send GET instead of GETNEXT to sub-handlers     * xxx-rks: again, this should be handled further up.     */    if ((oldmode == MODE_GETNEXT) && (handler->next)) {        /*         * tell agent handlder not to auto call next handler         */        handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;        /*         * if we found rows to process, pretend to be a get request         * and call handler below us.         */        if(need_processing > 0) {            agtreq_info->mode = MODE_GET;            rc = netsnmp_call_next_handler(handler, reginfo, agtreq_info,                                           requests);            if (rc != SNMP_ERR_NOERROR) {                DEBUGMSGTL(("table_container",                            "next handler returned %d\n", rc));            }            agtreq_info->mode = oldmode; /* restore saved mode */        }    }    return rc;}/** @endcond *//* ================================== * * Container Table API: Row operations * * ================================== */static void *_find_next_row(netsnmp_container *c,               netsnmp_table_request_info *tblreq,               void * key){    void *row = NULL;    if (!c || !tblreq || !tblreq->reg_info ) {        snmp_log(LOG_ERR,"_find_next_row param error\n");        return NULL;    }    /*     * table helper should have made sure we aren't below our minimum column     */    netsnmp_assert(tblreq->colnum >= tblreq->reg_info->min_column);    /*     * if no indexes then use first row.     */    if(tblreq->number_indexes == 0) {        row = CONTAINER_FIRST(c);    } else {        if(NULL == key) {            netsnmp_index index;            index.oids = tblreq->index_oid;            index.len = tblreq->index_oid_len;            row = CONTAINER_NEXT(c, &index);        }        else            row = CONTAINER_NEXT(c, key);        /*         * we don't have a row, but we might be at the end of a         * column, so try the next column.         */        if (NULL == row) {            /*             * don't set tblreq next_col unless we know there is one,             * so we don't mess up table handler sparse table processing.             */            oid next_col = netsnmp_table_next_column(tblreq);            if (0 != next_col) {                tblreq->colnum = next_col;                row = CONTAINER_FIRST(c);            }        }    }        return row;}/** * deprecated, backwards compatability only * * expected impact to remove: none *  - used between helpers, shouldn't have been used by end users * * replacement: none *  - never should have been a public method in the first place */netsnmp_index *netsnmp_table_index_find_next_row(netsnmp_container *c,                                  netsnmp_table_request_info *tblreq){    return _find_next_row(c, tblreq, NULL );}/* ================================== * * Container Table API: Index operations * * ================================== *//** @} */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -