static int
_save_entry(certToTSN_entry *entry, void *app_type)
{
    char buf[SNMP_MAXBUF_SMALL], *hashType, *mapType, *data = NULL;

    if (NULL == entry)
        return SNMP_ERR_GENERR;

    hashType = se_find_label_in_slist("cert_hash_alg", entry->hashType);
    if (NULL == hashType) {
        snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n",
                 entry->hashType);
        return SNMP_ERR_GENERR;
    }
    mapType = se_find_label_in_slist("cert_map_type", entry->mapType);
    if (TSNM_tlstmCertSpecified == entry->mapType)
        data = entry->data;
    snprintf(buf, sizeof(buf), "%s %ld --%s %s --%s %s %d",
             MAP_MIB_CONFIG_TOKEN, entry->tlstmCertToTSNID, hashType,
             entry->fingerprint, mapType, data ? data : "", entry->rowStatus);

    DEBUGMSGTL(("tlstmCertToTSNTable:save", "saving '%s'\n", buf));
    read_config_store(app_type, buf);

    return SNMP_ERR_NOERROR;
}
static int
_save_map(netsnmp_cert_map *map, int row_status, void *app_type)
{
    char buf[SNMP_MAXBUF_SMALL], *hashType, *mapType, *data = NULL;

    if (NULL == map)
        return SNMP_ERR_GENERR;

    /** don't store values from conf files */
    if (! (map->flags & NSCM_NONVOLATILE)) {
        DEBUGMSGT(("tlstmCertToTSNTable:save", 
                   "skipping RO/permanent/volatile row\n"));
        return SNMP_ERR_NOERROR;
    }

    hashType = se_find_label_in_slist("cert_hash_alg", map->hashType);
    if (NULL == hashType) {
        snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n",
                 map->hashType);
        return SNMP_ERR_GENERR;
    }
    mapType = se_find_label_in_slist("cert_map_type", map->mapType);
    if (TSNM_tlstmCertSpecified == map->mapType)
        data = (char*)map->data;
    snprintf(buf, sizeof(buf), "%s %d --%s %s --%s %s %d",
             MAP_MIB_CONFIG_TOKEN, map->priority, hashType, map->fingerprint,
             mapType, data ? data : "", row_status);

    DEBUGMSGTL(("tlstmCertToTSNTable:save", "saving '%s'\n", buf));
    read_config_store(app_type, buf);

    return SNMP_ERR_NOERROR;
}
示例#3
0
/**
 * @retval NULL  index not found
 */
const char *
netsnmp_access_interface_name_find(oid index)
{
    DEBUGMSGTL(("access:interface:find", "name\n"));
    netsnmp_assert(1 == _access_interface_init);

    return se_find_label_in_slist("interfaces", index);
}
示例#4
0
netsnmp_variable_list *
nsVacmAccessTable_get_next_data_point(void **my_loop_context,
                                      void **my_data_context,
                                      netsnmp_variable_list *put_index_data,
                                      netsnmp_iterator_info *mydata)
{
    struct vacm_accessEntry *entry =
        (struct vacm_accessEntry *) *my_loop_context;
    netsnmp_variable_list *idx;
    int len;
    char *cp;

newView:
    idx = put_index_data;
    if ( nsViewIdx == VACM_MAX_VIEWS ) {
        entry = vacm_scanAccessNext();
        nsViewIdx = 0;
    }
    if (entry) {
        len = entry->groupName[0];
        snmp_set_var_value(idx, (u_char *)entry->groupName+1, len);
        idx = idx->next_variable;
        len = entry->contextPrefix[0];
        snmp_set_var_value(idx, (u_char *)entry->contextPrefix+1, len);
        idx = idx->next_variable;
        snmp_set_var_value(idx, (u_char *)&entry->securityModel,
                           sizeof(entry->securityModel));
        idx = idx->next_variable;
        snmp_set_var_value(idx, (u_char *)&entry->securityLevel,
                           sizeof(entry->securityLevel));
        /*
         * Find the next valid authType view - skipping unused entries
         */
        idx = idx->next_variable;
        for (; nsViewIdx < VACM_MAX_VIEWS; nsViewIdx++) {
            if ( entry->views[ nsViewIdx ][0] )
                break;
        }
        if ( nsViewIdx == VACM_MAX_VIEWS )
            goto newView;
        cp = se_find_label_in_slist(VACM_VIEW_ENUM_NAME, nsViewIdx++);
        DEBUGMSGTL(("nsVacm", "nextDP %s:%s (%d)\n", entry->groupName+1, cp, nsViewIdx-1));
        snmp_set_var_value(idx, (u_char *)cp, strlen(cp));
        idx = idx->next_variable;
        *my_data_context = (void *) entry;
        *my_loop_context = (void *) entry;
        return put_index_data;
    } else {
        return NULL;
    }
}
示例#5
0
int
register_sec_mod(int secmod, const char *modname,
                 struct snmp_secmod_def *newdef)
{
    int             result = 0;
    struct snmp_secmod_list *sptr;
    char           *othername, *modname2 = NULL;

    for (sptr = registered_services; sptr; sptr = sptr->next) {
        if (sptr->securityModel == secmod) {
            return SNMPERR_GENERR;
        }
    }
    sptr = SNMP_MALLOC_STRUCT(snmp_secmod_list);
    if (sptr == NULL)
        return SNMPERR_MALLOC;
    sptr->secDef = newdef;
    sptr->securityModel = secmod;
    sptr->next = registered_services;
    registered_services = sptr;
    modname2 = strdup(modname);
    if (!modname2)
        result = SE_NOMEM;
    else
        result = se_add_pair_to_slist("snmp_secmods", modname2, secmod);
    if (result != SE_OK) {
        switch (result) {
        case SE_NOMEM:
            snmp_log(LOG_CRIT, "snmp_secmod: no memory\n");
            break;

        case SE_ALREADY_THERE:
            othername = se_find_label_in_slist("snmp_secmods", secmod);
            if (strcmp(othername, modname) != 0) {
                snmp_log(LOG_ERR,
                         "snmp_secmod: two security modules %s and %s registered with the same security number\n",
                         modname, othername);
            }
            break;

        default:
            snmp_log(LOG_ERR,
                     "snmp_secmod: unknown error trying to register a new security module\n");
            break;
        }
        return SNMPERR_GENERR;
    }
    return SNMPERR_SUCCESS;
}
static int
_table_row_handler(netsnmp_mib_handler          *handler,
                   netsnmp_handler_registration *reginfo,
                   netsnmp_agent_request_info   *reqinfo,
                   netsnmp_request_info         *requests)
{
    int             rc = SNMP_ERR_NOERROR;
    netsnmp_request_info *req;
    void                 *row;

    /** sanity checks */
    netsnmp_assert((NULL != handler) && (NULL != handler->myvoid));
    netsnmp_assert((NULL != reginfo) && (NULL != reqinfo));

    DEBUGMSGTL(("table_row", "Mode %s, Got request:\n",
                se_find_label_in_slist("agent_mode",reqinfo->mode)));

    /*
     * First off, get our pointer from the handler.
     * This contains the row that was actually registered.
     * Make this available for each of the requests passed in.
     */
    row = handler->myvoid;
    for (req = requests; req; req=req->next)
        netsnmp_request_add_list_data(req,
                netsnmp_create_data_list(TABLE_ROW_DATA, row, NULL));

    /*
     * Then call the next handler, to actually process the request
     */
    rc = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
    if (rc != SNMP_ERR_NOERROR) {
        DEBUGMSGTL(("table_row", "next handler returned %d\n", rc));
    }

    return rc;
}
/** handles requests for the tlstmCertToTSNTable table */
static int
tlstmCertToTSNTable_handler(netsnmp_mib_handler *handler,
                            netsnmp_handler_registration *reginfo,
                            netsnmp_agent_request_info *reqinfo,
                            netsnmp_request_info *requests)
{
    oid tsnm[] = { SNMP_TLS_TM_BASE, 1, 1, 0 };
    static const int tsnm_pos = OID_LENGTH(tsnm) - 1;
    netsnmp_request_info *request = NULL;
    netsnmp_table_request_info *info;
    netsnmp_tdata  *table;
    netsnmp_tdata_row *row;
    certToTSN_entry *entry;
    int             ret = SNMP_ERR_NOERROR;

    DEBUGMSGTL(("tlstmCertToSN:handler", "Processing request (mode %s (%d))\n",
                se_find_label_in_slist("agent_mode", reqinfo->mode),
                reqinfo->mode));

    switch (reqinfo->mode) {
    /** ######################################################### GET #####
     *
     *   Read-support (also covers GetNext requests)
     */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;

            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);
            netsnmp_assert(entry && info);

            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
            {
                /*
                 * build SnmpTLSFingerprint
                 */
                u_char bin[42], *ptr = bin;
                size_t len = sizeof(bin);
                int    rc;
                rc = netsnmp_tls_fingerprint_build(entry->hashType,
                                                   entry->fingerprint,
                                                   &ptr, &len, 0);
                if (SNMPERR_SUCCESS != rc)
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_GENERR);
                else
                    snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                             bin, len);
            }
                break;          /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
                tsnm[tsnm_pos] = entry->mapType;
                snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID,
                                         tsnm, sizeof(tsnm));
                break;          /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         entry->data, entry->data_len);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_DATA */
            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->storageType);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->rowStatus);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */
            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                break;
            }                   /* switch colnum */
        }                       /* for requests */
        break;                  /* case MODE_GET */

        /*
         * Write-support
         */
    /** #################################################### RESERVE1 #####
     *
     *   In RESERVE1 we are just checking basic ASN.1 size/type restrictions.
     * You probably don't need to change any of this code. Don't change any
     * of the column values here. Save that for the ACTION phase.
     *
     *   The next phase is RESERVE2 or FREE.
     */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            netsnmp_assert(request->processed == 0);

            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);

            if ((NULL != entry) && (ST_READONLY == entry->storageType)) {
                ret = SNMP_ERR_NOTWRITABLE;
                break;
            }

            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OCTET_STR,
                     sizeof(entry->fingerprint));
                /** check len/algorithm MIB requirements */
                if (ret == SNMP_ERR_NOERROR)
                    ret = netsnmp_cert_check_vb_fingerprint(request->requestvb);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OBJECT_ID,
                     SNMPTLSTMCERTTOTSN_MAPTYPE_MAX_SIZE);
                if (ret == SNMP_ERR_NOERROR) {
                    if (_oid2type(request->requestvb->val.objid,
                                  request->requestvb->val_len) >
                        TSNM_tlstmCert_MAX)
                        ret = SNMP_ERR_WRONGVALUE;
                }
                break;          /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OCTET_STR, sizeof(entry->data));
                break;          /* case COL_SNMPTLSTMCERTTOTSN_DATA */
            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                ret = netsnmp_check_vb_storagetype
                    (request->requestvb,(entry ? entry->storageType : ST_NONE));
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                ret = netsnmp_check_vb_rowstatus_with_storagetype
                    (request->requestvb,
                     (entry ? entry->rowStatus :RS_NONEXISTENT),
                     (entry ? entry->storageType :ST_NONE));
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */
            default:
                ret = SNMP_ERR_NOTWRITABLE;
            }                   /* switch colnum */

            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* for requests */
        break;                  /* case MODE_SET_RESERVE1 */

    /** #################################################### RESERVE2 #####
     *
     *   RESERVE2 is for checking additional restrictions from the MIB.
     * Since these restrictions are often in the description of the object,
     * mib2c can't generate code. It's possible that you need to add
     * additional checks here. However, don't change any of the column
     * values here. Save that for the ACTION phase.
     *
     *   The next phase is ACTION or FREE.
     */
    case MODE_SET_RESERVE2:
        for (request = requests; request; request = request->next) {
            netsnmp_assert(request->processed == 0);

            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            table = netsnmp_tdata_extract_table(request);
            info = netsnmp_extract_table_info(request);
            /*
             * if no row, create one
             */
            if (!entry) {
                row = tlstmCertToTSNTable_createEntry
                    (table,*info->indexes->val.integer);
                if (!row) {
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
                entry = row->data;
                _allocUndo(entry);
                if (!entry->undo) {
                    tlstmCertToTSNTable_removeEntry(table, row);
                    row = NULL;
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
                entry->undo->fate = FATE_NEWLY_CREATED;
                /** associate row with requests */
                netsnmp_insert_tdata_row(request, row);
            }

            /** allocate undo structure, if needed */
            if (!entry->undo) {
                _allocUndo(entry);
                if (!entry->undo) {
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
            }

            /*
             * save request ptr for column. if we already
             * have a value, bail.
             */
            if (entry->undo->req[info->colnum]) {
                DEBUGMSGT(("tlstmCertToSN:reserve2",
                           "multiple sets to col %d in request\n",
                           info->colnum));
                if (FATE_NEWLY_CREATED == entry->undo->fate)
                    ret = SNMP_ERR_INCONSISTENTNAME;
                else
                    ret = SNMP_ERR_INCONSISTENTVALUE;
                break;
            }
            entry->undo->req[info->colnum] = request;
            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* for requests */

        if (ret == SNMP_ERR_NOERROR) {
            /** make sure rowstatus is used to create rows */
            for (request = requests; request; request = request->next) {
                if (request->processed)
                    continue;

                entry = (certToTSN_entry *)
                    netsnmp_tdata_extract_entry(request);
                if ((entry->undo->fate != FATE_NEWLY_CREATED) ||
                    (entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]))
                    continue;
                ret = SNMP_ERR_INCONSISTENTNAME;
                break;
            } /* creation for requests */
        } /* no error */
        break;                  /* case MODE_SET_RESERVE2 */

    /** ######################################################## FREE #####
     *
     *   FREE is for cleaning up after a failed request (during either
     * RESERVE1 or RESERVE2). So any allocated resources need to be
     * released.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_FREE:
        /*
         * release undo resources
         * remove any newly created rows
         */
        for (request = requests; request; request = request->next) {
            table = netsnmp_tdata_extract_table(request);
            row = netsnmp_tdata_extract_row(request);
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);

            if (!entry || !entry->undo)
                continue;

            /** disassociate row with requests */
            netsnmp_remove_tdata_row(request, row);

            if (FATE_NEWLY_CREATED == entry->undo->fate)
                tlstmCertToTSNTable_removeEntry(table, row);
            else
                _freeUndo(entry);
        }
        break;                  /* case MODE_SET_FREE */

    /** ###################################################### ACTION #####
     *
     *   In the ACTION phase, we perform any sets that can be undone.
     * (Save anything that can't be undone for the COMMIT phase.)
     *
     *   After individual columns have been done, you should check that the
     * row as a whole is consistent.
     *
     * The next phase is UNDO or COMMIT.
     */
    case MODE_SET_ACTION:
        for (request = requests; request; request = request->next) {
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);

            /** reserve2 should enforce this */
            netsnmp_assert(request == entry->undo->req[info->colnum]);

            /*
             * for each col, save old value and the set new value
             */
            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
            {
                u_char *tmp = (u_char*)entry->fingerprint;
                u_int size = sizeof(entry->fingerprint);
                netsnmp_variable_list *vb = request->requestvb;

                memcpy(entry->undo->fingerprint,
                       entry->fingerprint, sizeof(entry->fingerprint));
                entry->undo->fingerprint_len = entry->fingerprint_len;
                entry->undo->hashType = entry->hashType;
                memset(entry->fingerprint, 0, sizeof(entry->fingerprint));

                (void)netsnmp_tls_fingerprint_parse(vb->val.string, vb->val_len,
                                                    (char**)&tmp, &size, 0,
                                                    &entry->hashType);
                entry->fingerprint_len = size;
                if (0 == entry->fingerprint_len)
                    ret = SNMP_ERR_GENERR;
            }
                break;          /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
                entry->undo->mapType = entry->mapType;
                entry->mapType = _oid2type(request->requestvb->val.objid,
                                           request->requestvb->val_len);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                memcpy(entry->undo->data, entry->data, sizeof(entry->data));
                entry->undo->data_len = entry->data_len;
                memset(entry->data, 0, sizeof(entry->data));
                memcpy(entry->data, request->requestvb->val.string,
                       request->requestvb->val_len);
                entry->data_len = request->requestvb->val_len;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_DATA */
            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                entry->undo->storageType = entry->storageType;
                entry->storageType = *request->requestvb->val.integer;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                entry->undo->rowStatus = entry->rowStatus;
                entry->rowStatus = *request->requestvb->val.integer;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */
            }                   /* switch colnum */
        }                       /* set values for requests */

        if (ret != SNMP_ERR_NOERROR) 
            break; /* skip consistency if we've already got error */

        /*
         * All columns now have their final values set. check the
         * internal consistency of each row.
         */
        for (request = requests; request; request = request->next) {
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);

            if (entry->undo->is_consistent != -1)
                continue;       /* already checked */

            /** assume consistency */
            entry->undo->is_consistent = 1;

            /*
             * per mib, can't have empty fingerprint and must
             * have data if indicated by map type.
             */
            if (0 == entry->fingerprint_len) {
                DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent",
                            "fingerprint must not be empty\n"));
                entry->undo->is_consistent = 0;
            }
            else if ((TSNM_tlstmCertSpecified == entry->mapType) &&
                     (0 == entry->data_len)) {
                DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent",
                            "must specify Data for CertSpecified identity\n"));
                entry->undo->is_consistent = 0;
            }

            if ((RS_IS_ACTIVE(entry->rowStatus)) &&
                ((!entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]) ||
                 (RS_IS_ACTIVE(entry->undo->rowStatus)))) {
                /*
                 * per mib, can't modify these while row active
                 */
                char _cols[3] = { COL_SNMPTLSTMCERTTOTSN_FINGERPRINT,
                                  COL_SNMPTLSTMCERTTOTSN_MAPTYPE, COL_SNMPTLSTMCERTTOTSN_DATA };
                int i;
                for (i=0; i < 3; ++i ) {
                    if (!entry->undo->req[i])
                        continue;
                    DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent",
                                "can't modify row %d while active\n",
                                _cols[i]));
                    entry->undo->is_consistent = 0;
                    ret = SNMP_ERR_NOTWRITABLE;
                    request= entry->undo->req[i];
                    break;
                }
            } else if (RS_IS_GOING_ACTIVE(entry->rowStatus)) {
                /*
                 * if going active, inconsistency is fatal
                 */
                if (!entry->undo->is_consistent) {
                    netsnmp_assert(entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]);
                    if (FATE_NEWLY_CREATED == entry->undo->fate)
                        ret = SNMP_ERR_INCONSISTENTNAME;
                    else
                        ret = SNMP_ERR_INCONSISTENTVALUE;
                    request = entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS];
                }
            } else if (RS_DESTROY == entry->rowStatus) {
                /*
                 * can't destroy active row
                 */
                if (RS_IS_ACTIVE(entry->undo->rowStatus)) {
                    DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent",
                                "can't destroy active row\n"));
                    netsnmp_assert(entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]);
                    ret = SNMP_ERR_INCONSISTENTVALUE;
                    request = entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS];
                }
            }
            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* consistency for requests */
        break;                  /* case MODE_SET_ACTION */

    /** ######################################################## UNDO #####
     *
     *   UNDO is for cleaning up any failed requests that went through the
     * ACTION phase.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_UNDO:
        for (request = requests; request; request = request->next) {
            row = netsnmp_tdata_extract_row(request);
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);

            /*
             * skip newly created rows, as we're going to delete
             * them below anyways
             */
            if (FATE_NEWLY_CREATED == entry->undo->fate)
                continue;

            /*
             * restore values
             */
            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
                memcpy(entry->fingerprint, entry->undo->fingerprint,
                       sizeof(entry->fingerprint));
                entry->fingerprint_len = entry->undo->fingerprint_len;
                entry->hashType = entry->undo->hashType;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
                entry->mapType = entry->undo->mapType;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                memcpy(entry->data, entry->undo->data, sizeof(entry->data));
                entry->data_len = entry->undo->data_len;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_DATA */
            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                entry->storageType = entry->undo->storageType;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                entry->rowStatus = entry->undo->rowStatus;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */
            }                   /* switch colnum */
        }                       /* for requests */

        /*
         * release undo data
         * or remove any newly created rows
         */
        for (request = requests; request; request = request->next) {
            table = netsnmp_tdata_extract_table(request);
            row = netsnmp_tdata_extract_row(request);
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);

            if (!entry || !entry->undo)
                continue;

            /** disassociate row with requests */
            netsnmp_remove_tdata_row(request, row);

            if (FATE_NEWLY_CREATED == entry->undo->fate)
                tlstmCertToTSNTable_removeEntry(table, row);
            else
                _freeUndo(entry);
        }                       /* for requests */
        break;                  /* case MODE_SET_UNDO */

    /** ###################################################### COMMIT #####
     *
     *   COMMIT is the final success state, when all changes are finalized.
     * There is not recovery state should something faile here.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_COMMIT:
        for (request = requests; request; request = request->next) {
            row = netsnmp_tdata_extract_row(request);
            table = netsnmp_tdata_extract_table(request);
            info = netsnmp_extract_table_info(request);
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);

            if ((RS_NOTREADY == entry->rowStatus) && entry->undo->is_consistent)
                entry->rowStatus = RS_NOTINSERVICE;
            else if ((RS_NOTINSERVICE == entry->rowStatus) &&
                     (0 == entry->undo->is_consistent))
                entry->rowStatus = RS_NOTREADY;

            /** release undo data for requests with no rowstatus */
            if (entry->undo && !entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]) {
                _freeUndo(entry);
                if ((0 == entry->map_flags) && (entry->rowStatus == RS_ACTIVE))
                    _cert_map_add(entry);
                else if ((0 != entry->map_flags) &&
                         (entry->rowStatus == RS_DESTROY))
                    _cert_map_remove(entry);
            }

            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                switch (entry->rowStatus) {
                case RS_CREATEANDGO:
                    /** Fall-through */
                case RS_ACTIVE:
                    netsnmp_assert(entry->undo->is_consistent);
                    entry->rowStatus = RS_ACTIVE;
                    if (0 == entry->map_flags)
                        _cert_map_add(entry);
                    break;

                case RS_CREATEANDWAIT:
                    /** Fall-through */
                case RS_NOTINSERVICE:
                    /** simply set status based on consistency */
                    if (entry->undo->is_consistent)
                        entry->rowStatus = RS_NOTINSERVICE;
                    else
                        entry->rowStatus = RS_NOTREADY;
                    if (0 != entry->map_flags)
                        _cert_map_remove(entry);
                    break;

                case RS_DESTROY:
                    /** remove from cert map */
                    if (0 != entry->map_flags)
                        _cert_map_remove(entry);
                    /** disassociate row with requests */
                    netsnmp_remove_tdata_row(request, row);
                    tlstmCertToTSNTable_removeEntry(table, row);
                    row = NULL;
                    entry = NULL;
                }
                /** release undo data */
                _freeUndo(entry);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */

            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                if (RS_ACTIVE == entry->rowStatus)
                    _cert_map_tweak_storage(entry);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */

            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                break;
            }                   /* switch colnum */

        }                       /* for requests */

        /** update last changed */
        _last_changed = netsnmp_get_agent_uptime();

        /** set up to save persistent store */
        snmp_store_needed(NULL);

        break;                  /* case MODE_SET_COMMIT */
    }                           /* switch (reqinfo->mode) */

    if (ret != SNMP_ERR_NOERROR)
        netsnmp_set_request_error(reqinfo, request, ret);

    return SNMP_ERR_NOERROR;
}
示例#8
0
int
tcp_handler(netsnmp_mib_handler          *handler,
            netsnmp_handler_registration *reginfo,
            netsnmp_agent_request_info   *reqinfo,
            netsnmp_request_info         *requests)
{
    netsnmp_request_info  *request;
    netsnmp_variable_list *requestvb;
    long     ret_value = -1;
    oid      subid;
    int      type = ASN_COUNTER;

    /*
     * The cached data should already have been loaded by the
     *    cache handler, higher up the handler chain.
     * But just to be safe, check this and load it manually if necessary
     */
#if defined(_USE_FIRST_PROTOCOL)
    tcp_load(NULL, NULL);
#endif


    /*
     * 
     *
     */
    DEBUGMSGTL(("mibII/tcpScalar", "Handler - mode %s\n",
                    se_find_label_in_slist("agent_mode", reqinfo->mode)));
    switch (reqinfo->mode) {
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            requestvb = request->requestvb;
            subid = requestvb->name[OID_LENGTH(tcp_oid)];  /* XXX */

            DEBUGMSGTL(( "mibII/tcpScalar", "oid: "));
            DEBUGMSGOID(("mibII/tcpScalar", requestvb->name,
                                            requestvb->name_length));
            DEBUGMSG((   "mibII/tcpScalar", "\n"));
            switch (subid) {
#ifdef USES_SNMP_DESIGNED_TCPSTAT
    case TCPRTOALGORITHM:
        ret_value = tcpstat.tcpRtoAlgorithm;
        type = ASN_INTEGER;
        break;
    case TCPRTOMIN:
        ret_value = tcpstat.tcpRtoMin;
        type = ASN_INTEGER;
        break;
    case TCPRTOMAX:
        ret_value = tcpstat.tcpRtoMax;
        type = ASN_INTEGER;
        break;
    case TCPMAXCONN:
        ret_value = tcpstat.tcpMaxConn;
        type = ASN_INTEGER;
        break;
    case TCPACTIVEOPENS:
        ret_value = tcpstat.tcpActiveOpens;
        break;
    case TCPPASSIVEOPENS:
        ret_value = tcpstat.tcpPassiveOpens;
        break;
    case TCPATTEMPTFAILS:
        ret_value = tcpstat.tcpAttemptFails;
        break;
    case TCPESTABRESETS:
        ret_value = tcpstat.tcpEstabResets;
        break;
    case TCPCURRESTAB:
        ret_value = tcpstat.tcpCurrEstab;
        type = ASN_GAUGE;
        break;
    case TCPINSEGS:
        ret_value = tcpstat.tcpInSegs & 0xffffffff;
        break;
    case TCPOUTSEGS:
        ret_value = tcpstat.tcpOutSegs & 0xffffffff;
        break;
    case TCPRETRANSSEGS:
        ret_value = tcpstat.tcpRetransSegs;
        break;
    case TCPINERRS:
#ifdef solaris2
        ret_value = tcp_load(NULL, (void *)TCPINERRS);
	if (ret_value == -1) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        break;
#elif defined(linux)
        if (tcpstat.tcpInErrsValid) {
            ret_value = tcpstat.tcpInErrs;
            break;
	} else {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
#else			/* linux */
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif			/* solaris2 */
    case TCPOUTRSTS:
#ifdef linux
        if (tcpstat.tcpOutRstsValid) {
            ret_value = tcpstat.tcpOutRsts;
            break;
	}
#endif			/* linux */
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#elif defined(USES_TRADITIONAL_TCPSTAT) && !defined(_USE_FIRST_PROTOCOL)
#ifdef HAVE_SYS_TCPIPSTATS_H
    /*
     * This actually reads statistics for *all* the groups together,
     * so we need to isolate the TCP-specific bits.  
     */
#define tcpstat          tcpstat.tcpstat
#endif
    case TCPRTOALGORITHM:      /* Assume Van Jacobsen's algorithm */
        ret_value = 4;
        type = ASN_INTEGER;
        break;
    case TCPRTOMIN:
#ifdef TCPTV_NEEDS_HZ
        ret_value = TCPTV_MIN;
#else
        ret_value = TCPTV_MIN / PR_SLOWHZ * 1000;
#endif
        type = ASN_INTEGER;
        break;
    case TCPRTOMAX:
#ifdef TCPTV_NEEDS_HZ
        ret_value = TCPTV_REXMTMAX;
#else
        ret_value = TCPTV_REXMTMAX / PR_SLOWHZ * 1000;
#endif
        type = ASN_INTEGER;
        break;
    case TCPMAXCONN:
        ret_value = -1;		/* Dynamic maximum */
        type = ASN_INTEGER;
        break;
    case TCPACTIVEOPENS:
        ret_value = tcpstat.tcps_connattempt;
        break;
    case TCPPASSIVEOPENS:
        ret_value = tcpstat.tcps_accepts;
        break;
        /*
         * NB:  tcps_drops is actually the sum of the two MIB
         *      counters tcpAttemptFails and tcpEstabResets.
         */
    case TCPATTEMPTFAILS:
        ret_value = tcpstat.tcps_conndrops;
        break;
    case TCPESTABRESETS:
        ret_value = tcpstat.tcps_drops;
        break;
    case TCPCURRESTAB:
#ifdef NETSNMP_FEATURE_CHECKING
        netsnmp_feature_want(tcp_count_connections)
#endif
#ifndef NETSNMP_FEATURE_REMOVE_TCP_COUNT_CONNECTIONS
        ret_value = TCP_Count_Connections();
#else
        ret_value = 0;
#endif /* NETSNMP_FEATURE_REMOVE_TCP_COUNT_CONNECTIONS */
        type = ASN_GAUGE;
        break;
    case TCPINSEGS:
        ret_value = tcpstat.tcps_rcvtotal & 0xffffffff;
        break;
    case TCPOUTSEGS:
        /*
         * RFC 1213 defines this as the number of segments sent
         * "excluding those containing only retransmitted octets"
         */
        ret_value = (tcpstat.tcps_sndtotal - tcpstat.tcps_sndrexmitpack) & 0xffffffff;
        break;
    case TCPRETRANSSEGS:
        ret_value = tcpstat.tcps_sndrexmitpack;
        break;
    case TCPINERRS:
        ret_value = tcpstat.tcps_rcvbadsum + tcpstat.tcps_rcvbadoff
#ifdef HAVE_STRUCT_TCPSTAT_TCPS_RCVMEMDROP
            + tcpstat.tcps_rcvmemdrop
#endif
            + tcpstat.tcps_rcvshort;
        break;
    case TCPOUTRSTS:
        ret_value = tcpstat.tcps_sndctrl - tcpstat.tcps_closed;
        break;
#ifdef HAVE_SYS_TCPIPSTATS_H
#undef tcpstat
#endif
#elif defined(hpux11)
    case TCPRTOALGORITHM:
    case TCPRTOMIN:
    case TCPRTOMAX:
    case TCPMAXCONN:
    case TCPCURRESTAB:
        if (subid == TCPCURRESTAB)
           type = ASN_GAUGE;
	else
           type = ASN_INTEGER;
    case TCPACTIVEOPENS:
    case TCPPASSIVEOPENS:
    case TCPATTEMPTFAILS:
    case TCPESTABRESETS:
    case TCPINSEGS:
    case TCPOUTSEGS:
    case TCPRETRANSSEGS:
    case TCPINERRS:
    case TCPOUTRSTS:
	/*
	 * This is a bit of a hack, to shoehorn the HP-UX 11
	 * single-object retrieval approach into the caching
	 * architecture.
	 */
	if (tcp_load(NULL, (void*)subid) == -1 ) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        ret_value = tcpstat;
        break;
#elif defined (WIN32) || defined (cygwin)
    case TCPRTOALGORITHM:
        ret_value = tcpstat.dwRtoAlgorithm;
        type = ASN_INTEGER;
        break;
    case TCPRTOMIN:
        ret_value = tcpstat.dwRtoMin;
        type = ASN_INTEGER;
        break;
    case TCPRTOMAX:
        ret_value = tcpstat.dwRtoMax;
        type = ASN_INTEGER;
        break;
    case TCPMAXCONN:
        ret_value = tcpstat.dwMaxConn;
        type = ASN_INTEGER;
        break;
    case TCPACTIVEOPENS:
        ret_value = tcpstat.dwActiveOpens;
        break;
    case TCPPASSIVEOPENS:
        ret_value = tcpstat.dwPassiveOpens;
        break;
    case TCPATTEMPTFAILS:
        ret_value = tcpstat.dwAttemptFails;
        break;
    case TCPESTABRESETS:
        ret_value = tcpstat.dwEstabResets;
        break;
    case TCPCURRESTAB:
        ret_value = tcpstat.dwCurrEstab;
        type = ASN_GAUGE;
        break;
    case TCPINSEGS:
        ret_value = tcpstat.dwInSegs;
        break;
    case TCPOUTSEGS:
        ret_value = tcpstat.dwOutSegs;
        break;
    case TCPRETRANSSEGS:
        ret_value = tcpstat.dwRetransSegs;
        break;
    case TCPINERRS:
        ret_value = tcpstat.dwInErrs;
        break;
    case TCPOUTRSTS:
        ret_value = tcpstat.dwOutRsts;
        break;
#elif defined(_USE_FIRST_PROTOCOL)
    case TCPRTOALGORITHM:
        ret_value = 4;
        type = ASN_INTEGER;
        break;
    case TCPRTOMIN:
        ret_value = 0;
        type = ASN_INTEGER;
        break;
    case TCPRTOMAX:
        ret_value = 0;
        type = ASN_INTEGER;
        break;
    case TCPMAXCONN:
        ret_value = -1;
        type = ASN_INTEGER;
        break;
    case TCPACTIVEOPENS:
        ret_value = ps_proto.u.tcp.initiated;
        break;
    case TCPPASSIVEOPENS:
        ret_value = ps_proto.u.tcp.accepted;
        break;
    case TCPATTEMPTFAILS:
        ret_value = ps_proto.u.tcp.dropped;
        break;
    case TCPESTABRESETS:
        ret_value = ps_proto.u.tcp.dropped;
        break;
    case TCPCURRESTAB:
        /* this value is currently missing */
        ret_value = 0; /*ps_proto.u.tcp.established;*/
        type = ASN_GAUGE;
        break;
    case TCPINSEGS:
        ret_value = ps_proto.u.tcp.ipackets;
        break;
    case TCPOUTSEGS:
        ret_value = ps_proto.u.tcp.opackets;
        break;
    case TCPRETRANSSEGS:
        ret_value = 0;
        break;
    case TCPINERRS:
        ret_value = ps_proto.u.tcp.ierrors;
        break;
    case TCPOUTRSTS:
        ret_value = 0;
        break;
#endif			/* USES_SNMP_DESIGNED_TCPSTAT */

    case TCPCONNTABLE:
        /*
	 * This is not actually a valid scalar object.
	 * The table registration should take precedence,
	 *   so skip this subtree, regardless of architecture.
	 */
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;

	    }
	    snmp_set_var_typed_value(request->requestvb, (u_char)type,
			             (u_char *)&ret_value, sizeof(ret_value));
	}
        break;

    case MODE_GETNEXT:
    case MODE_GETBULK:
#ifndef NETSNMP_NO_WRITE_SUPPORT
    case MODE_SET_RESERVE1:
    case MODE_SET_RESERVE2:
    case MODE_SET_ACTION:
    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        snmp_log(LOG_WARNING, "mibII/tcp: Unsupported mode (%d)\n",
                               reqinfo->mode);
        break;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    default:
        snmp_log(LOG_WARNING, "mibII/tcp: Unrecognised mode (%d)\n",
                               reqinfo->mode);
        break;
    }

    return SNMP_ERR_NOERROR;
}
示例#9
0
文件: ip.c 项目: fenner/net-snmp
int
ip_handler(netsnmp_mib_handler          *handler,
           netsnmp_handler_registration *reginfo,
           netsnmp_agent_request_info   *reqinfo,
           netsnmp_request_info         *requests)
{
    netsnmp_request_info  *request;
    netsnmp_variable_list *requestvb;
    long     ret_value;
    oid      subid;
    int      type = ASN_COUNTER;

    /*
     * The cached data should already have been loaded by the
     *    cache handler, higher up the handler chain.
     */
#ifdef _USE_PERFSTAT_PROTOCOL
    ip_load(NULL, NULL);
#endif


    /*
     * 
     *
     */
    DEBUGMSGTL(("mibII/ip", "Handler - mode %s\n",
                    se_find_label_in_slist("agent_mode", reqinfo->mode)));
    switch (reqinfo->mode) {
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            requestvb = request->requestvb;
            subid = requestvb->name[OID_LENGTH(ip_oid)];  /* XXX */
            DEBUGMSGTL(( "mibII/ip", "oid: "));
            DEBUGMSGOID(("mibII/ip", requestvb->name,
                                     requestvb->name_length));
            DEBUGMSG((   "mibII/ip", "\n"));

            switch (subid) {
#ifdef USES_SNMP_DESIGNED_IPSTAT
    case IPFORWARDING:
        ret_value = ipstat.ipForwarding;
        type = ASN_INTEGER;
        break;
    case IPDEFAULTTTL:
        ret_value = ipstat.ipDefaultTTL;
        type = ASN_INTEGER;
        break;
    case IPINRECEIVES:
        ret_value = ipstat.ipInReceives & 0xffffffff;
        break;
    case IPINHDRERRORS:
        ret_value = ipstat.ipInHdrErrors;
        break;
    case IPINADDRERRORS:
        ret_value = ipstat.ipInAddrErrors;
        break;
    case IPFORWDATAGRAMS:
        ret_value = ipstat.ipForwDatagrams;
        break;
    case IPINUNKNOWNPROTOS:
        ret_value = ipstat.ipInUnknownProtos;
        break;
    case IPINDISCARDS:
        ret_value = ipstat.ipInDiscards;
        break;
    case IPINDELIVERS:
        ret_value = ipstat.ipInDelivers & 0xffffffff;
        break;
    case IPOUTREQUESTS:
        ret_value = ipstat.ipOutRequests & 0xffffffff;
        break;
    case IPOUTDISCARDS:
        ret_value = ipstat.ipOutDiscards;
        break;
    case IPOUTNOROUTES:
        ret_value = ipstat.ipOutNoRoutes;
        break;
    case IPREASMTIMEOUT:
        ret_value = ipstat.ipReasmTimeout;
        type = ASN_INTEGER;
        break;
    case IPREASMREQDS:
        ret_value = ipstat.ipReasmReqds;
        break;
    case IPREASMOKS:
        ret_value = ipstat.ipReasmOKs;
        break;
    case IPREASMFAILS:
        ret_value = ipstat.ipReasmFails;
        break;
    case IPFRAGOKS:
        ret_value = ipstat.ipFragOKs;
        break;
    case IPFRAGFAILS:
        ret_value = ipstat.ipFragFails;
        break;
    case IPFRAGCREATES:
        ret_value = ipstat.ipFragCreates;
        break;
    case IPROUTEDISCARDS:
        ret_value = ipstat.ipRoutingDiscards;
        break;

#elif defined(USES_TRADITIONAL_IPSTAT) && !defined(_USE_PERFSTAT_PROTOCOL)
#ifdef HAVE_SYS_TCPIPSTATS_H
    /*
     * This actually reads statistics for *all* the groups together,
     * so we need to isolate the IP-specific bits.  
     */
#define	ipstat		ipstat.ipstat
#endif
    case IPFORWARDING:
    case IPDEFAULTTTL:
        /* 
         * Query these two individually
         */
        ret_value = ip_load(NULL, (void *)subid);
        if (ret_value == -1 ) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        type = ASN_INTEGER;
        break;
    case IPINRECEIVES:
        ret_value = ipstat.ips_total & 0xffffffff;
        break;
    case IPINHDRERRORS:
        ret_value = ipstat.ips_badsum
            + ipstat.ips_tooshort
            + ipstat.ips_toosmall + ipstat.ips_badhlen + ipstat.ips_badlen;
        break;
    case IPINADDRERRORS:
        ret_value = ipstat.ips_cantforward;
        break;
    case IPFORWDATAGRAMS:
        ret_value = ipstat.ips_forward;
        break;
    case IPINUNKNOWNPROTOS:
#if HAVE_STRUCT_IPSTAT_IPS_NOPROTO
        ret_value = ipstat.ips_noproto;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPINDISCARDS:
#if HAVE_STRUCT_IPSTAT_IPS_FRAGDROPPED
        ret_value = ipstat.ips_fragdropped;   /* ?? */
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPINDELIVERS:
#if HAVE_STRUCT_IPSTAT_IPS_DELIVERED
        ret_value = ipstat.ips_delivered & 0xffffffff;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPOUTREQUESTS:
#if HAVE_STRUCT_IPSTAT_IPS_LOCALOUT
        ret_value = ipstat.ips_localout & 0xffffffff;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPOUTDISCARDS:
#if HAVE_STRUCT_IPSTAT_IPS_ODROPPED
        ret_value = ipstat.ips_odropped;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPOUTNOROUTES:
        /*
         * XXX: how to calculate this (counts dropped routes, not packets)?
         * ipstat.ips_cantforward isn't right, as it counts packets.
         * ipstat.ips_noroute is also incorrect.
         */
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
    case IPREASMTIMEOUT:
        ret_value = IPFRAGTTL;
        type = ASN_INTEGER;
        break;
    case IPREASMREQDS:
        ret_value = ipstat.ips_fragments;
        break;
    case IPREASMOKS:
#if HAVE_STRUCT_IPSTAT_IPS_REASSEMBLED
        ret_value = ipstat.ips_reassembled;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPREASMFAILS:
        ret_value = ipstat.ips_fragdropped + ipstat.ips_fragtimeout;
        break;
    case IPFRAGOKS:
#if HAVE_STRUCT_IPSTAT_IPS_FRAGMENTED
        ret_value = ipstat.ips_fragments;
        break;
#else            /* XXX */
        ret_value = ipstat.ips_fragments
            - (ipstat.ips_fragdropped + ipstat.ips_fragtimeout);
        break;
#endif
    case IPFRAGFAILS:
#if HAVE_STRUCT_IPSTAT_IPS_CANTFRAG
        ret_value = ipstat.ips_cantfrag;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPFRAGCREATES:
#if HAVE_STRUCT_IPSTAT_IPS_OFRAGMENTS
        ret_value = ipstat.ips_ofragments;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
    case IPROUTEDISCARDS:
#if HAVE_STRUCT_IPSTAT_IPS_NOROUTE
        ret_value = ipstat.ips_noroute;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif
#ifdef HAVE_SYS_TCPIPSTATS_H
#undef ipstat
#endif
#elif defined(hpux11)
    case IPFORWARDING:
    case IPDEFAULTTTL:
    case IPREASMTIMEOUT:
        type = ASN_INTEGER;
    case IPINRECEIVES:
    case IPINHDRERRORS:
    case IPINADDRERRORS:
    case IPFORWDATAGRAMS:
    case IPINUNKNOWNPROTOS:
    case IPINDISCARDS:
    case IPINDELIVERS:
    case IPOUTREQUESTS:
    case IPOUTDISCARDS:
    case IPOUTNOROUTES:
    case IPREASMREQDS:
    case IPREASMOKS:
    case IPREASMFAILS:
    case IPFRAGOKS:
    case IPFRAGFAILS:
    case IPFRAGCREATES:
    case IPROUTEDISCARDS:
	/*
	 * This is a bit of a hack, to shoehorn the HP-UX 11
	 * single-object retrieval approach into the caching
	 * architecture.
	 */
	if (ip_load(NULL, (void*)subid) == -1 ) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        ret_value = ipstat;
        break;
#elif defined (WIN32) || defined (cygwin)
    case IPFORWARDING:
        ipForwarding = ipstat.dwForwarding;
        ret_value    = ipstat.dwForwarding;
        type = ASN_INTEGER;
        break;
    case IPDEFAULTTTL:
        ipTTL     = ipstat.dwDefaultTTL;
        ret_value = ipstat.dwDefaultTTL;
        type = ASN_INTEGER;
        break;
    case IPINRECEIVES:
        ret_value = ipstat.dwInReceives;
        break;
    case IPINHDRERRORS:
        ret_value = ipstat.dwInHdrErrors;
        break;
    case IPINADDRERRORS:
        ret_value = ipstat.dwInAddrErrors;
        break;
    case IPFORWDATAGRAMS:
        ret_value = ipstat.dwForwDatagrams;
        break;
    case IPINUNKNOWNPROTOS:
        ret_value = ipstat.dwInUnknownProtos;
        break;
    case IPINDISCARDS:
        ret_value = ipstat.dwInDiscards;
        break;
    case IPINDELIVERS:
        ret_value = ipstat.dwInDelivers;
        break;
    case IPOUTREQUESTS:
        ret_value = ipstat.dwOutRequests;
        break;
    case IPOUTDISCARDS:
        ret_value = ipstat.dwOutDiscards;
        break;
    case IPOUTNOROUTES:
        ret_value = ipstat.dwOutNoRoutes;
        break;
    case IPREASMTIMEOUT:
        ret_value = ipstat.dwReasmTimeout;
        type = ASN_INTEGER;
        break;
    case IPREASMREQDS:
        ret_value = ipstat.dwReasmReqds;
        break;
    case IPREASMOKS:
        ret_value = ipstat.dwReasmOks;
        break;
    case IPREASMFAILS:
        ret_value = ipstat.dwReasmFails;
        break;
    case IPFRAGOKS:
        ret_value = ipstat.dwFragOks;
        break;
    case IPFRAGFAILS:
        ret_value = ipstat.dwFragFails;
        break;
    case IPFRAGCREATES:
        ret_value = ipstat.dwFragCreates;
        break;
    case IPROUTEDISCARDS:
        ret_value = ipstat.dwRoutingDiscards;
        break;
#elif defined(_USE_PERFSTAT_PROTOCOL)
    case IPFORWARDING:
        ret_value    = 0;
        type = ASN_INTEGER;
        break;
    case IPDEFAULTTTL:
        ret_value = 0;
        type = ASN_INTEGER;
        break;
    case IPINRECEIVES:
        ret_value = ps_proto.u.ip.ipackets;
        break;
    case IPINHDRERRORS:
    case IPINADDRERRORS:
    case IPFORWDATAGRAMS:
        ret_value = 0;
        break;
    case IPINUNKNOWNPROTOS:
        ret_value = ps_proto.u.ip.ierrors;
        break;
    case IPINDISCARDS:
        ret_value = 0;
        break;
    case IPINDELIVERS:
    case IPOUTREQUESTS:
        ret_value = ps_proto.u.ip.opackets;
        break;
    case IPOUTDISCARDS:
    case IPOUTNOROUTES:
        ret_value = 0;
        break;
    case IPREASMTIMEOUT:
        ret_value = 0;
        type = ASN_INTEGER;
        break;
    case IPREASMREQDS:
    case IPREASMOKS:
    case IPREASMFAILS:
    case IPFRAGOKS:
    case IPFRAGFAILS:
    case IPFRAGCREATES:
        ret_value = 0;
        break;
    case IPROUTEDISCARDS:
        ret_value = ps_proto.u.ip.oerrors;
        break;
#endif			/* USES_SNMP_DESIGNED_IPSTAT */

    case IPADDRTABLE:
    case IPROUTETABLE:
    case IPMEDIATABLE:
        /*
	 * These are not actually valid scalar objects.
	 * The relevant table registrations should take precedence,
	 *   so skip these three subtrees, regardless of architecture.
	 */
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;

	    }
	    snmp_set_var_typed_value(request->requestvb, (u_char)type,
			             (u_char *)&ret_value, sizeof(ret_value));
	}
        break;

    case MODE_GETNEXT:
    case MODE_GETBULK:
#ifndef NETSNMP_NO_WRITE_SUPPORT
    case MODE_SET_RESERVE1:
		/* XXX - Windows currently supports setting this */
    case MODE_SET_RESERVE2:
    case MODE_SET_ACTION:
    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        snmp_log(LOG_WARNING, "mibII/ip: Unsupported mode (%d)\n",
                               reqinfo->mode);
        break;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    default:
        snmp_log(LOG_WARNING, "mibII/ip: Unrecognised mode (%d)\n",
                               reqinfo->mode);
        break;
    }

    return SNMP_ERR_NOERROR;
}
示例#10
0
文件: icmp.c 项目: DYFeng/infinidb
int
icmp_handler(netsnmp_mib_handler          *handler,
             netsnmp_handler_registration *reginfo,
             netsnmp_agent_request_info   *reqinfo,
             netsnmp_request_info         *requests)
{
    netsnmp_request_info  *request;
    netsnmp_variable_list *requestvb;
    long     ret_value;
    oid      subid;
#ifdef USES_TRADITIONAL_ICMPSTAT
    int      i;
#endif

    /*
     * The cached data should already have been loaded by the
     *    cache handler, higher up the handler chain.
     * But just to be safe, check this and load it manually if necessary
     */
#ifndef hpux11
    if (!netsnmp_cache_is_valid(reqinfo, reginfo->handlerName)) {
        netsnmp_assert("cache" == "valid"); /* always false */
        icmp_load( NULL, NULL );	/* XXX - check for failure */
    }
#endif


    /*
     * 
     *
     */
    DEBUGMSGTL(("mibII/icmp", "Handler - mode %s\n",
                    se_find_label_in_slist("agent_mode", reqinfo->mode)));
    switch (reqinfo->mode) {
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            requestvb = request->requestvb;
            subid = requestvb->name[OID_LENGTH(icmp_oid)];  /* XXX */
            DEBUGMSGTL(( "mibII/icmp", "oid: "));
            DEBUGMSGOID(("mibII/icmp", requestvb->name,
                                       requestvb->name_length));
            DEBUGMSG((   "mibII/icmp", "\n"));

            switch (subid) {
#ifdef USES_SNMP_DESIGNED_ICMPSTAT
    case ICMPINMSGS:
        ret_value = icmpstat.icmpInMsgs;
        break;
    case ICMPINERRORS:
        ret_value = icmpstat.icmpInErrors;
        break;
    case ICMPINDESTUNREACHS:
        ret_value = icmpstat.icmpInDestUnreachs;
        break;
    case ICMPINTIMEEXCDS:
        ret_value = icmpstat.icmpInTimeExcds;
        break;
    case ICMPINPARMPROBS:
        ret_value = icmpstat.icmpInParmProbs;
        break;
    case ICMPINSRCQUENCHS:
        ret_value = icmpstat.icmpInSrcQuenchs;
        break;
    case ICMPINREDIRECTS:
        ret_value = icmpstat.icmpInRedirects;
        break;
    case ICMPINECHOS:
        ret_value = icmpstat.icmpInEchos;
        break;
    case ICMPINECHOREPS:
        ret_value = icmpstat.icmpInEchoReps;
        break;
    case ICMPINTIMESTAMPS:
        ret_value = icmpstat.icmpInTimestamps;
        break;
    case ICMPINTIMESTAMPREPS:
        ret_value = icmpstat.icmpInTimestampReps;
        break;
    case ICMPINADDRMASKS:
        ret_value = icmpstat.icmpInAddrMasks;
        break;
    case ICMPINADDRMASKREPS:
        ret_value = icmpstat.icmpInAddrMaskReps;
        break;
    case ICMPOUTMSGS:
        ret_value = icmpstat.icmpOutMsgs;
        break;
    case ICMPOUTERRORS:
        ret_value = icmpstat.icmpOutErrors;
        break;
    case ICMPOUTDESTUNREACHS:
        ret_value = icmpstat.icmpOutDestUnreachs;
        break;
    case ICMPOUTTIMEEXCDS:
        ret_value = icmpstat.icmpOutTimeExcds;
        break;
    case ICMPOUTPARMPROBS:
        ret_value = icmpstat.icmpOutParmProbs;
        break;
    case ICMPOUTSRCQUENCHS:
        ret_value = icmpstat.icmpOutSrcQuenchs;
        break;
    case ICMPOUTREDIRECTS:
        ret_value = icmpstat.icmpOutRedirects;
        break;
    case ICMPOUTECHOS:
        ret_value = icmpstat.icmpOutEchos;
        break;
    case ICMPOUTECHOREPS:
        ret_value = icmpstat.icmpOutEchoReps;
        break;
    case ICMPOUTTIMESTAMPS:
        ret_value = icmpstat.icmpOutTimestamps;
        break;
    case ICMPOUTTIMESTAMPREPS:
        ret_value = icmpstat.icmpOutTimestampReps;
        break;
    case ICMPOUTADDRMASKS:
        ret_value = icmpstat.icmpOutAddrMasks;
        break;
    case ICMPOUTADDRMASKREPS:
        ret_value = icmpstat.icmpOutAddrMaskReps;
        break;
#else                          /* USES_SNMP_DESIGNED_ICMPSTAT */

#ifdef USES_TRADITIONAL_ICMPSTAT
    case ICMPINMSGS:
        ret_value = icmpstat.icps_badcode +
            icmpstat.icps_tooshort +
            icmpstat.icps_checksum + icmpstat.icps_badlen;
        for (i = 0; i <= ICMP_MAXTYPE; i++)
            ret_value += icmpstat.icps_inhist[i];
        break;
    case ICMPINERRORS:
        ret_value = icmpstat.icps_badcode +
            icmpstat.icps_tooshort +
            icmpstat.icps_checksum + icmpstat.icps_badlen;
        break;
    case ICMPINDESTUNREACHS:
        ret_value = icmpstat.icps_inhist[ICMP_UNREACH];
        break;
    case ICMPINTIMEEXCDS:
        ret_value = icmpstat.icps_inhist[ICMP_TIMXCEED];
        break;
    case ICMPINPARMPROBS:
        ret_value = icmpstat.icps_inhist[ICMP_PARAMPROB];
        break;
    case ICMPINSRCQUENCHS:
        ret_value = icmpstat.icps_inhist[ICMP_SOURCEQUENCH];
        break;
    case ICMPINREDIRECTS:
        ret_value = icmpstat.icps_inhist[ICMP_REDIRECT];
        break;
    case ICMPINECHOS:
        ret_value = icmpstat.icps_inhist[ICMP_ECHO];
        break;
    case ICMPINECHOREPS:
        ret_value = icmpstat.icps_inhist[ICMP_ECHOREPLY];
        break;
    case ICMPINTIMESTAMPS:
        ret_value = icmpstat.icps_inhist[ICMP_TSTAMP];
        break;
    case ICMPINTIMESTAMPREPS:
        ret_value = icmpstat.icps_inhist[ICMP_TSTAMPREPLY];
        break;
    case ICMPINADDRMASKS:
        ret_value = icmpstat.icps_inhist[ICMP_MASKREQ];
        break;
    case ICMPINADDRMASKREPS:
        ret_value = icmpstat.icps_inhist[ICMP_MASKREPLY];
        break;
    case ICMPOUTMSGS:
        ret_value = icmpstat.icps_oldshort + icmpstat.icps_oldicmp;
        for (i = 0; i <= ICMP_MAXTYPE; i++)
            ret_value += icmpstat.icps_outhist[i];
        break;
    case ICMPOUTERRORS:
        ret_value = icmpstat.icps_oldshort + icmpstat.icps_oldicmp;
        break;
    case ICMPOUTDESTUNREACHS:
        ret_value = icmpstat.icps_outhist[ICMP_UNREACH];
        break;
    case ICMPOUTTIMEEXCDS:
        ret_value = icmpstat.icps_outhist[ICMP_TIMXCEED];
        break;
    case ICMPOUTPARMPROBS:
        ret_value = icmpstat.icps_outhist[ICMP_PARAMPROB];
        break;
    case ICMPOUTSRCQUENCHS:
        ret_value = icmpstat.icps_outhist[ICMP_SOURCEQUENCH];
        break;
    case ICMPOUTREDIRECTS:
        ret_value = icmpstat.icps_outhist[ICMP_REDIRECT];
        break;
    case ICMPOUTECHOS:
        ret_value = icmpstat.icps_outhist[ICMP_ECHO];
        break;
    case ICMPOUTECHOREPS:
        ret_value = icmpstat.icps_outhist[ICMP_ECHOREPLY];
        break;
    case ICMPOUTTIMESTAMPS:
        ret_value = icmpstat.icps_outhist[ICMP_TSTAMP];
        break;
    case ICMPOUTTIMESTAMPREPS:
        ret_value = icmpstat.icps_outhist[ICMP_TSTAMPREPLY];
        break;
    case ICMPOUTADDRMASKS:
        ret_value = icmpstat.icps_outhist[ICMP_MASKREQ];
        break;
    case ICMPOUTADDRMASKREPS:
        ret_value = icmpstat.icps_outhist[ICMP_MASKREPLY];
        break;
#else                          /* USES_TRADITIONAL_ICMPSTAT */

#ifdef hpux11
    case ICMPINMSGS:
    case ICMPINERRORS:
    case ICMPINDESTUNREACHS:
    case ICMPINTIMEEXCDS:
    case ICMPINPARMPROBS:
    case ICMPINSRCQUENCHS:
    case ICMPINREDIRECTS:
    case ICMPINECHOS:
    case ICMPINECHOREPS:
    case ICMPINTIMESTAMPS:
    case ICMPINTIMESTAMPREPS:
    case ICMPINADDRMASKS:
    case ICMPINADDRMASKREPS:
    case ICMPOUTMSGS:
    case ICMPOUTERRORS:
    case ICMPOUTDESTUNREACHS:
    case ICMPOUTTIMEEXCDS:
    case ICMPOUTPARMPROBS:
    case ICMPOUTSRCQUENCHS:
    case ICMPOUTREDIRECTS:
    case ICMPOUTECHOS:
    case ICMPOUTECHOREPS:
    case ICMPOUTTIMESTAMPS:
    case ICMPOUTTIMESTAMPREPS:
    case ICMPOUTADDRMASKS:
    case ICMPOUTADDRMASKREPS:
	/*
	 * This is a bit of a hack, to shoehorn the HP-UX 11
	 * single-object retrieval approach into the caching
	 * architecture.
	 */
	if (icmp_load(NULL, (void*)subid) == -1 ) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        ret_value = icmpstat;
        break;
#else                          /* hpux11 */

#ifdef WIN32
    case ICMPINMSGS:
        ret_value = icmpstat.stats.icmpInStats.dwMsgs;
        break;
    case ICMPINERRORS:
        ret_value = icmpstat.stats.icmpInStats.dwErrors;
        break;
    case ICMPINDESTUNREACHS:
        ret_value = icmpstat.stats.icmpInStats.dwDestUnreachs;
        break;
    case ICMPINTIMEEXCDS:
        ret_value = icmpstat.stats.icmpInStats.dwTimeExcds;
        break;
    case ICMPINPARMPROBS:
        ret_value = icmpstat.stats.icmpInStats.dwParmProbs;
        break;
    case ICMPINSRCQUENCHS:
        ret_value = icmpstat.stats.icmpInStats.dwSrcQuenchs;
        break;
    case ICMPINREDIRECTS:
        ret_value = icmpstat.stats.icmpInStats.dwRedirects;
        break;
    case ICMPINECHOS:
        ret_value = icmpstat.stats.icmpInStats.dwEchos;
        break;
    case ICMPINECHOREPS:
        ret_value = icmpstat.stats.icmpInStats.dwEchoReps;
        break;
    case ICMPINTIMESTAMPS:
        ret_value = icmpstat.stats.icmpInStats.dwTimestamps;
        break;
    case ICMPINTIMESTAMPREPS:
        ret_value = icmpstat.stats.icmpInStats.dwTimestampReps;
        break;
    case ICMPINADDRMASKS:
        ret_value = icmpstat.stats.icmpInStats.dwAddrMasks;
        break;
    case ICMPINADDRMASKREPS:
        ret_value = icmpstat.stats.icmpInStats.dwAddrMaskReps;
        break;
    case ICMPOUTMSGS:
        ret_value = icmpstat.stats.icmpOutStats.dwMsgs;
        break;
    case ICMPOUTERRORS:
        ret_value = icmpstat.stats.icmpOutStats.dwErrors;
        break;
    case ICMPOUTDESTUNREACHS:
        ret_value = icmpstat.stats.icmpOutStats.dwDestUnreachs;
        break;
    case ICMPOUTTIMEEXCDS:
        ret_value = icmpstat.stats.icmpOutStats.dwTimeExcds;
        break;
    case ICMPOUTPARMPROBS:
        ret_value = icmpstat.stats.icmpOutStats.dwParmProbs;
        break;
    case ICMPOUTSRCQUENCHS:
        ret_value = icmpstat.stats.icmpOutStats.dwSrcQuenchs;
        break;
    case ICMPOUTREDIRECTS:
        ret_value = icmpstat.stats.icmpOutStats.dwRedirects;
        break;
    case ICMPOUTECHOS:
        ret_value = icmpstat.stats.icmpOutStats.dwEchos;
        break;
    case ICMPOUTECHOREPS:
        ret_value = icmpstat.stats.icmpOutStats.dwEchoReps;
        break;
    case ICMPOUTTIMESTAMPS:
        ret_value = icmpstat.stats.icmpOutStats.dwTimestamps;
        break;
    case ICMPOUTTIMESTAMPREPS:
        ret_value = icmpstat.stats.icmpOutStats.dwTimestampReps;
        break;
    case ICMPOUTADDRMASKS:
        ret_value = icmpstat.stats.icmpOutStats.dwAddrMasks;
        break;
    case ICMPOUTADDRMASKREPS:
        ret_value = icmpstat.stats.icmpOutStats.dwAddrMaskReps;
        break;
#endif                          /* WIN32 */
#endif                          /* hpux11 */
#endif                          /* USES_TRADITIONAL_ICMPSTAT */
#endif                          /* USES_SNMP_DESIGNED_ICMPSTAT */
	    }
	    snmp_set_var_typed_value(request->requestvb, ASN_COUNTER,
			             (u_char *)&ret_value, sizeof(ret_value));
	}
        break;

    case MODE_GETNEXT:
    case MODE_GETBULK:
    case MODE_SET_RESERVE1:
    case MODE_SET_RESERVE2:
    case MODE_SET_ACTION:
    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        snmp_log(LOG_WARNING, "mibII/icmp: Unsupported mode (%d)\n",
                               reqinfo->mode);
        break;
    default:
        snmp_log(LOG_WARNING, "mibII/icmp: Unrecognised mode (%d)\n",
                               reqinfo->mode);
        break;
    }

    return SNMP_ERR_NOERROR;
}
示例#11
0
文件: sctpScalars.c 项目: 274914765/C
/**
 * Handle request for sctpParams.
 * Handles only one request at a time, serialize_handler is automatically added by netsnmp_register_scalar_group.
 */
int
sctp_params_handler (netsnmp_mib_handler * handler,
                     netsnmp_handler_registration * reginfo,
                     netsnmp_agent_request_info * reqinfo, netsnmp_request_info * request)
{
    netsnmp_variable_list *requestvb;

    int subid;

    DEBUGMSGTL (("sctp:scalars:params", "Handler - mode %s\n", se_find_label_in_slist ("agent_mode", reqinfo->mode)));
    if (reqinfo->mode != MODE_GET)
    {
        snmp_log (LOG_WARNING, "sctp/params: Unsupported mode (%d)\n", reqinfo->mode);
        return SNMP_ERR_NOERROR;
    }

    requestvb = request->requestvb;
    subid = requestvb->name[OID_LENGTH (sctp_stats_oid)];
    DEBUGMSGTL (("sctp:scalars:params", "oid: "));
    DEBUGMSGOID (("sctp:scalars:params", requestvb->name, requestvb->name_length));
    DEBUGMSG (("sctp:scalars:params", "\n"));

    switch (subid)
    {

        case SCTP_RTOALGORITHM:
            snmp_set_var_typed_value (request->requestvb, ASN_INTEGER,
                                      (u_char *) & sctp_params.rto_algorithm, sizeof (sctp_params.rto_algorithm));
            break;

        case SCTP_RTOMIN:
            snmp_set_var_typed_value (request->requestvb, ASN_UNSIGNED,
                                      (u_char *) & sctp_params.rto_min, sizeof (sctp_params.rto_min));
            break;

        case SCTP_RTOMAX:
            snmp_set_var_typed_value (request->requestvb, ASN_UNSIGNED,
                                      (u_char *) & sctp_params.rto_max, sizeof (sctp_params.rto_max));
            break;

        case SCTP_RTOINITIAL:
            snmp_set_var_typed_value (request->requestvb, ASN_UNSIGNED,
                                      (u_char *) & sctp_params.rto_initial, sizeof (sctp_params.rto_initial));
            break;

        case SCTP_MAXASSOCS:
            snmp_set_var_typed_value (request->requestvb, ASN_INTEGER,
                                      (u_char *) & sctp_params.max_assocs, sizeof (sctp_params.max_assocs));
            break;

        case SCTP_VALCOOKIELIFE:
            snmp_set_var_typed_value (request->requestvb, ASN_UNSIGNED,
                                      (u_char *) & sctp_params.val_cookie_life, sizeof (sctp_params.val_cookie_life));
            break;

        case SCTP_MAXINITRETR:
            snmp_set_var_typed_value (request->requestvb, ASN_UNSIGNED,
                                      (u_char *) & sctp_params.max_init_retr, sizeof (sctp_params.max_init_retr));
            break;

        default:
            snmp_log (LOG_WARNING, "sctp/params: Unsupported subid (%d)\n", subid);
            break;
    }
    return SNMP_ERR_NOERROR;
}
示例#12
0
                 " 8:" LONG_STRING " 9:" LONG_STRING "|"
                 "enum 1:1 10:" LONG_STRING "|");

OK(se_find_value(1, 1, "hi") == 1,
   "lookup by number #1 should be the proper string");
OK(strcmp(se_find_label(1, 1, 2), "there") == 0,
   "lookup by string #1 should be the proper number");


se_add_pair_to_slist("testing", strdup(STRING1), 42);
se_add_pair_to_slist("testing", strdup(STRING2), 2);
se_add_pair_to_slist("testing", strdup(STRING3), 2);
    
OK(se_find_value_in_slist("testing", STRING1) == 42,
   "lookup by number should be the proper string");
OK(strcmp(se_find_label_in_slist("testing", 2), STRING2) == 0,
   "lookup by string should be the proper number");

se_clear_slist("testing");


se_read_conf("enum",
             NETSNMP_REMOVE_CONST(char *, "2:3 1:apple 2:pear 3:kiwifruit"));
OK(se_find_list(2, 3), "list (2, 3) should be present");
if (se_find_list(2, 3)) {
  OK(se_find_value(2, 3, "kiwifruit") == 3,
     "lookup by string should return the proper value");
  se_find_result = se_find_label(2, 3, 2);
  OK(se_find_result && strcmp(se_find_result, "pear") == 0,
     "lookup by label should return the proper string");
}
示例#13
0
int
udp_handler(netsnmp_mib_handler          *handler,
            netsnmp_handler_registration *reginfo,
            netsnmp_agent_request_info   *reqinfo,
            netsnmp_request_info         *requests)
{
    netsnmp_request_info  *request;
    netsnmp_variable_list *requestvb;
    long     ret_value = -1;
    oid      subid;
    int      type = ASN_COUNTER;

    /*
     * The cached data should already have been loaded by the
     *    cache handler, higher up the handler chain.
     * But just to be safe, check this and load it manually if necessary
     */
#if defined(_USE_PERFSTAT_PROTOCOL)
    udp_load(NULL, NULL);
#endif


    /*
     * 
     *
     */
    DEBUGMSGTL(("mibII/udpScalar", "Handler - mode %s\n",
                    se_find_label_in_slist("agent_mode", reqinfo->mode)));
    switch (reqinfo->mode) {
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            requestvb = request->requestvb;
            subid = requestvb->name[OID_LENGTH(udp_oid)];  /* XXX */
            DEBUGMSGTL(( "mibII/udpScalar", "oid: "));
            DEBUGMSGOID(("mibII/udpScalar", requestvb->name,
                                            requestvb->name_length));
            DEBUGMSG((   "mibII/udpScalar", "\n"));

            switch (subid) {
#ifdef USES_SNMP_DESIGNED_UDPSTAT
    case UDPINDATAGRAMS:
        ret_value = udpstat.udpInDatagrams;
        break;
    case UDPNOPORTS:
#ifdef solaris2
        ret_value = udp_load(NULL, (void *)UDPNOPORTS);
	if (ret_value == -1) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        break;
#else
        ret_value = udpstat.udpNoPorts;
        break;
#endif
    case UDPOUTDATAGRAMS:
        ret_value = udpstat.udpOutDatagrams;
        break;
    case UDPINERRORS:
        ret_value = udpstat.udpInErrors;
        break;
#elif defined(USES_TRADITIONAL_UDPSTAT) && !defined(_USE_PERFSTAT_PROTOCOL)
#ifdef HAVE_SYS_TCPIPSTATS_H
    /*
     * This actually reads statistics for *all* the groups together,
     * so we need to isolate the UDP-specific bits.  
     */
#define udpstat          udpstat.udpstat
#endif
    case UDPINDATAGRAMS:
#if HAVE_STRUCT_UDPSTAT_UDPS_IPACKETS
        ret_value = udpstat.udps_ipackets;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif

    case UDPNOPORTS:
#if HAVE_STRUCT_UDPSTAT_UDPS_NOPORT
        ret_value = udpstat.udps_noport;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif

    case UDPOUTDATAGRAMS:
#if HAVE_STRUCT_UDPSTAT_UDPS_OPACKETS
        ret_value = udpstat.udps_opackets;
        break;
#else
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
        continue;
#endif

    case UDPINERRORS:
        ret_value = udpstat.udps_hdrops + udpstat.udps_badsum +
#ifdef HAVE_STRUCT_UDPSTAT_UDPS_DISCARD
            udpstat.udps_discard +
#endif
#ifdef HAVE_STRUCT_UDPSTAT_UDPS_FULLSOCK
            udpstat.udps_fullsock +
#endif
            udpstat.udps_badlen;
        break;
#ifdef HAVE_SYS_TCPIPSTATS_H
#undef udpstat
#endif
#elif defined(hpux11)
    case UDPINDATAGRAMS:
    case UDPNOPORTS:
    case UDPOUTDATAGRAMS:
    case UDPINERRORS:
	/*
	 * This is a bit of a hack, to shoehorn the HP-UX 11
	 * single-object retrieval approach into the caching
	 * architecture.
	 */
	if (udp_load(NULL, (void*)subid) == -1 ) {
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
            continue;
	}
        ret_value = udpstat;
        break;
#elif defined(WIN32)
    case UDPINDATAGRAMS:
        ret_value = udpstat.dwInDatagrams;
        break;
    case UDPNOPORTS:
        ret_value = udpstat.dwNoPorts;
        break;
    case UDPOUTDATAGRAMS:
        ret_value = udpstat.dwOutDatagrams;
        break;
    case UDPINERRORS:
        ret_value = udpstat.dwInErrors;
        break;
#elif defined(_USE_PERFSTAT_PROTOCOL)
    case UDPINDATAGRAMS:
        ret_value = ps_proto.u.udp.ipackets;
        break;
    case UDPNOPORTS:
        ret_value = ps_proto.u.udp.no_socket;
        break;
    case UDPOUTDATAGRAMS:
        ret_value = ps_proto.u.udp.opackets;
        break;
    case UDPINERRORS:
        ret_value = ps_proto.u.udp.ierrors;
        break;
#endif			/* USES_SNMP_DESIGNED_UDPSTAT */

	    }
	    snmp_set_var_typed_value(request->requestvb, (u_char)type,
			             (u_char *)&ret_value, sizeof(ret_value));
	}
        break;

    case MODE_GETNEXT:
    case MODE_GETBULK:
#ifndef NETSNMP_NO_WRITE_SUPPORT
    case MODE_SET_RESERVE1:
    case MODE_SET_RESERVE2:
    case MODE_SET_ACTION:
    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        snmp_log(LOG_WARNING, "mibII/udp: Unsupported mode (%d)\n",
                               reqinfo->mode);
        break;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    default:
        snmp_log(LOG_WARNING, "mibII/udp: Unrecognised mode (%d)\n",
                               reqinfo->mode);
        break;
    }

    return SNMP_ERR_NOERROR;
}
示例#14
0
文件: baby_steps.c 项目: odit/rv042
/** @internal Implements the baby_steps handler */
static int
_baby_steps_access_multiplexer(netsnmp_mib_handler *handler,
                               netsnmp_handler_registration *reginfo,
                               netsnmp_agent_request_info *reqinfo,
                               netsnmp_request_info *requests)
{
    void *temp_void;
    Netsnmp_Node_Handler *method = NULL;
    netsnmp_baby_steps_access_methods *access_methods;
    int rc = SNMP_ERR_NOERROR;

    /** call handlers should enforce these */
    netsnmp_assert((handler!=NULL) && (reginfo!=NULL) && (reqinfo!=NULL) &&
                   (requests!=NULL));

    DEBUGMSGT(("baby_steps_mux", "mode %s\n",
               se_find_label_in_slist("babystep_mode",reqinfo->mode)));

    access_methods = (netsnmp_baby_steps_access_methods *)handler->myvoid;
    if(!access_methods) {
        snmp_log(LOG_ERR,"baby_steps_access_multiplexer has no methods\n");
        return SNMPERR_GENERR;
    }

    switch(reqinfo->mode) {
        
    case MODE_BSTEP_PRE_REQUEST:
        if( access_methods->pre_request )
            method = access_methods->pre_request;
        break;
        
    case MODE_BSTEP_OBJECT_LOOKUP:
        if( access_methods->object_lookup )
            method = access_methods->object_lookup;
        break;

    case SNMP_MSG_GET:
    case SNMP_MSG_GETNEXT:
        if( access_methods->get_values )
            method = access_methods->get_values;
        break;
        
    case MODE_BSTEP_CHECK_VALUE:
        if( access_methods->object_syntax_checks )
            method = access_methods->object_syntax_checks;
        break;

    case MODE_BSTEP_ROW_CREATE:
        if( access_methods->row_creation )
            method = access_methods->row_creation;
        break;

    case MODE_BSTEP_UNDO_SETUP:
        if( access_methods->undo_setup )
            method = access_methods->undo_setup;
        break;

    case MODE_BSTEP_SET_VALUE:
        if( access_methods->set_values )
            method = access_methods->set_values;
        break;

    case MODE_BSTEP_CHECK_CONSISTENCY:
        if( access_methods->consistency_checks )
            method = access_methods->consistency_checks;
        break;

    case MODE_BSTEP_UNDO_SET:
        if( access_methods->undo_sets )
            method = access_methods->undo_sets;
        break;

    case MODE_BSTEP_COMMIT:
        if( access_methods->commit )
            method = access_methods->commit;
        break;

    case MODE_BSTEP_UNDO_COMMIT:
        if( access_methods->undo_commit )
            method = access_methods->undo_commit;
        break;

    case MODE_BSTEP_IRREVERSIBLE_COMMIT:
        if( access_methods->irreversible_commit )
            method = access_methods->irreversible_commit;
        break;

    case MODE_BSTEP_UNDO_CLEANUP:
        if( access_methods->undo_cleanup )
            method = access_methods->undo_cleanup;
        break;
        
    case MODE_BSTEP_POST_REQUEST:
        if( access_methods->post_request )
            method = access_methods->post_request;
        break;

    default:
        snmp_log(LOG_ERR,"unknown mode %d\n", reqinfo->mode);
        return SNMP_ERR_GENERR;
    }

    /*
     * if method exists, set up handler void and call method.
     */
    if(NULL != method) {
        temp_void = handler->myvoid;
        handler->myvoid = access_methods->my_access_void;
        rc = (*method)(handler, reginfo, reqinfo, requests);
        handler->myvoid = temp_void;
    }
    else {
        rc = SNMP_ERR_GENERR;
        snmp_log(LOG_ERR,"baby steps multiplexer handler called for a mode "
                 "with no handler\n");
        netsnmp_assert(NULL != method);
    }

    /*
     * don't call any lower handlers, it will be done for us 
     * since we set MIB_HANDLER_AUTO_NEXT
     */

    return rc;
}
示例#15
0
文件: sctpScalars.c 项目: 274914765/C
/**
 * Handle request for sctpStats.
 * Handles only one request at a time, serialize_handler is automatically added by netsnmp_register_scalar_group.
 */
int
sctp_stats_handler (netsnmp_mib_handler * handler,
                    netsnmp_handler_registration * reginfo,
                    netsnmp_agent_request_info * reqinfo, netsnmp_request_info * request)
{
    netsnmp_variable_list *requestvb;

    int subid;

    DEBUGMSGTL (("sctp:scalars:stats", "Handler - mode %s\n", se_find_label_in_slist ("agent_mode", reqinfo->mode)));
    if (reqinfo->mode != MODE_GET)
    {
        snmp_log (LOG_WARNING, "sctp/stats: Unsupported mode (%d)\n", reqinfo->mode);
        return SNMP_ERR_NOERROR;
    }

    requestvb = request->requestvb;
    subid = requestvb->name[OID_LENGTH (sctp_stats_oid)];
    DEBUGMSGTL (("sctp:scalars:stats", "oid: "));
    DEBUGMSGOID (("sctp:scalars:stats", requestvb->name, requestvb->name_length));
    DEBUGMSG (("sctp:scalars:stats", "\n"));

    switch (subid)
    {

        case SCTP_CURRESTAB:
            snmp_set_var_typed_value (request->requestvb, ASN_GAUGE,
                                      (u_char *) & sctp_stats.curr_estab, sizeof (sctp_stats.curr_estab));
            break;

        case SCTP_ACTIVEESTABS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER,
                                      (u_char *) & sctp_stats.active_estabs, sizeof (sctp_stats.active_estabs));
            break;

        case SCTP_PASSIVEESTABS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER,
                                      (u_char *) & sctp_stats.passive_estabs, sizeof (sctp_stats.passive_estabs));
            break;

        case SCTP_ABORTEDS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER,
                                      (u_char *) & sctp_stats.aborteds, sizeof (sctp_stats.aborteds));
            break;

        case SCTP_SHUTDOWNS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER,
                                      (u_char *) & sctp_stats.shutdowns, sizeof (sctp_stats.shutdowns));
            break;

        case SCTP_OUTOFBLUES:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER,
                                      (u_char *) & sctp_stats.out_of_blues, sizeof (sctp_stats.out_of_blues));
            break;

        case SCTP_CHECKSUMERRORS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER,
                                      (u_char *) & sctp_stats.checksum_errors, sizeof (sctp_stats.checksum_errors));
            break;

        case SCTP_OUTCTRLCHUNKS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.out_ctrl_chunks, sizeof (sctp_stats.out_ctrl_chunks));
            break;

        case SCTP_OUTORDERCHUNKS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.out_order_chunks, sizeof (sctp_stats.out_order_chunks));
            break;

        case SCTP_OUTUNORDERCHUNKS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) &
                                      sctp_stats.out_unorder_chunks, sizeof (sctp_stats.out_unorder_chunks));
            break;

        case SCTP_INCTRLCHUNKS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.in_ctrl_chunks, sizeof (sctp_stats.in_ctrl_chunks));
            break;

        case SCTP_INORDERCHUNKS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.in_order_chunks, sizeof (sctp_stats.in_order_chunks));
            break;

        case SCTP_INUNORDERCHUNKS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.in_unorder_chunks, sizeof (sctp_stats.in_unorder_chunks));
            break;

        case SCTP_FRAGUSRMSGS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.frag_usr_msgs, sizeof (sctp_stats.frag_usr_msgs));
            break;

        case SCTP_REASMUSRMSGS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.reasm_usr_msgs, sizeof (sctp_stats.reasm_usr_msgs));
            break;

        case SCTP_OUTSCTPPACKS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.out_sctp_packs, sizeof (sctp_stats.out_sctp_packs));
            break;

        case SCTP_INSCTPPACKS:
            snmp_set_var_typed_value (request->requestvb, ASN_COUNTER64,
                                      (u_char *) & sctp_stats.in_sctp_packs, sizeof (sctp_stats.in_sctp_packs));
            break;

        case SCTP_DISCONTINUITYTIME:
            snmp_set_var_typed_value (request->requestvb, ASN_TIMETICKS,
                                      (u_char *) &
                                      sctp_stats.discontinuity_time, sizeof (sctp_stats.discontinuity_time));
            break;

        default:
            snmp_log (LOG_WARNING, "sctp/stats: Unsupported subid (%d)\n", subid);
            break;
    }
    return SNMP_ERR_NOERROR;
}
示例#16
0
文件: baby_steps.c 项目: odit/rv042
/** @internal Implements the baby_steps handler */
static int
_baby_steps_helper(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *reqinfo,
                         netsnmp_request_info *requests)
{
    netsnmp_baby_steps_modes *bs_modes;
    int save_mode, i, rc = SNMP_ERR_NOERROR;
    u_short *mode_map_ptr;
    
    DEBUGMSGTL(("baby_steps", "Got request, mode %s\n",
                se_find_label_in_slist("agent_mode",reqinfo->mode)));

    bs_modes = handler->myvoid;
    netsnmp_assert(NULL != bs_modes);

    switch (reqinfo->mode) {

    case MODE_SET_RESERVE1:
        /*
         * clear completed modes
         * xxx-rks: this will break for pdus with set requests to different
         * rows in the same table when the handler is set up to use the row
         * merge helper as well (or if requests are serialized).
         */
        bs_modes->completed = 0;
        /** fall through */

    case MODE_SET_RESERVE2:
    case MODE_SET_ACTION:
    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        mode_map_ptr = set_mode_map[reqinfo->mode];
        break;
            
    default:
        /*
         * clear completed modes
         */
        bs_modes->completed = 0;

        mode_map_ptr = get_mode_map;
    }

    /*
     * NOTE: if you update this chart, please update the versions in
     *       local/mib2c-conf.d/parent-set.m2i
     *       agent/mibgroup/helpers/baby_steps.c
     * while you're at it.
     */
    /*
     ***********************************************************************
     * Baby Steps Flow Chart (2004.06.05)                                  *
     *                                                                     *
     * +--------------+    +================+    U = unconditional path    *
     * |optional state|    ||required state||    S = path for success      *
     * +--------------+    +================+    E = path for error        *
     ***********************************************************************
     *
     *                        +--------------+
     *                        |     pre      |
     *                        |   request    |
     *                        +--------------+
     *                               | U
     * +-------------+        +==============+
     * |    row    |f|<-------||  object    ||
     * |  create   |1|      E ||  lookup    ||
     * +-------------+        +==============+
     *     E |   | S                 | S
     *       |   +------------------>|
     *       |                +==============+
     *       |              E ||   check    ||
     *       |<---------------||   values   ||
     *       |                +==============+
     *       |                       | S
     *       |                +==============+
     *       |       +<-------||   undo     ||
     *       |       |      E ||   setup    ||
     *       |       |        +==============+
     *       |       |               | S
     *       |       |        +==============+
     *       |       |        ||    set     ||-------------------------->+
     *       |       |        ||   value    || E                         |
     *       |       |        +==============+                           |
     *       |       |               | S                                 |
     *       |       |        +--------------+                           |
     *       |       |        |    check     |-------------------------->|
     *       |       |        |  consistency | E                         |
     *       |       |        +--------------+                           |
     *       |       |               | S                                 |
     *       |       |        +==============+         +==============+  |
     *       |       |        ||   commit   ||-------->||     undo   ||  |
     *       |       |        ||            || E       ||    commit  ||  |
     *       |       |        +==============+         +==============+  |
     *       |       |               | S                     U |<--------+
     *       |       |        +--------------+         +==============+
     *       |       |        | irreversible |         ||    undo    ||
     *       |       |        |    commit    |         ||     set    ||
     *       |       |        +--------------+         +==============+
     *       |       |               | U                     U |
     *       |       +-------------->|<------------------------+
     *       |                +==============+
     *       |                ||   undo     ||
     *       |                ||  cleanup   ||
     *       |                +==============+
     *       +---------------------->| U
     *                               |
     *                          (err && f1)------------------->+
     *                               |                         |
     *                        +--------------+         +--------------+
     *                        |    post      |<--------|      row     |
     *                        |   request    |       U |    release   |
     *                        +--------------+         +--------------+
     *
     */
    /*
     * save original mode
     */
    save_mode = reqinfo->mode;
    for(i = 0; i < BABY_STEPS_PER_MODE_MAX; ++i ) {
        /*
         * break if we run out of baby steps for this mode
         */
        if(mode_map_ptr[i] == BABY_STEP_NONE)
            break;

        DEBUGMSGTL(("baby_steps", " baby step mode %s\n",
                    se_find_label_in_slist("babystep_mode",mode_map_ptr[i])));

        /*
         * skip modes the handler didn't register for
         */
        if (BSTEP_USE_ORIGINAL != mode_map_ptr[i]) {
            u_int    mode_flag;

            /*
             * skip undo commit if commit wasn't hit, and
             * undo_cleanup if undo_setup wasn't hit.
             */
            if((MODE_SET_UNDO == save_mode) &&
               (MODE_BSTEP_UNDO_COMMIT == mode_map_ptr[i]) &&
               !(BABY_STEP_COMMIT & bs_modes->completed)) {
                DEBUGMSGTL(("baby_steps",
                            "   skipping commit undo (no commit)\n"));
                continue;
            }
            else if((MODE_SET_FREE == save_mode) &&
               (MODE_BSTEP_UNDO_CLEANUP == mode_map_ptr[i]) &&
               !(BABY_STEP_UNDO_SETUP & bs_modes->completed)) {
                DEBUGMSGTL(("baby_steps",
                            "   skipping undo cleanup (no undo setup)\n"));
                continue;
            }

            reqinfo->mode = mode_map_ptr[i];
            mode_flag = netsnmp_baby_step_mode2flag( mode_map_ptr[i] );
            if((mode_flag & bs_modes->registered))
                bs_modes->completed |= mode_flag;
            else {
                DEBUGMSGTL(("baby_steps",
                            "   skipping mode (not registered)\n"));
                continue;
            }

        
        }
        else {
            reqinfo->mode = save_mode;
        }

#ifdef BABY_STEPS_NEXT_MODE
        /*
         * I can't remember why I wanted the next mode in the request,
         * but it's not used anywhere, so don't use this code. saved,
         * in case I remember why I thought needed it. - rstory 040911
         */
        if((BABY_STEPS_PER_MODE_MAX - 1) == i)
            reqinfo->next_mode_ok = BABY_STEP_NONE;
        else {
            if(BSTEP_USE_ORIGINAL == mode_map_ptr[i+1])
                reqinfo->next_mode_ok = save_mode;
            else
                reqinfo->next_mode_ok = mode_map_ptr[i+1];
        }
#endif

        /*
         * call handlers for baby step
         */
        rc = netsnmp_call_next_handler(handler, reginfo, reqinfo,
                                       requests);

        /*
         * check for error calling handler (unlikely, but...)
         */
        if(rc) {
            DEBUGMSGTL(("baby_steps", "   ERROR:handler error\n"));
            break;
        }

        /*
         * check for errors in any of the requests for GET-like, reserve1,
         * reserve2 and action. (there is no recovery from errors
         * in commit, free or undo.)
         */
        if (MODE_IS_GET(save_mode)
            || (save_mode < SNMP_MSG_INTERNAL_SET_COMMIT)) {
            rc = netsnmp_check_requests_error(requests);
            if(rc) {
                DEBUGMSGTL(("baby_steps", "   ERROR:request error\n"));
                break;
            }
        }
    }

    /*
     * restore original mode
     */
    reqinfo->mode = save_mode;

    
    return rc;
}
示例#17
0
int
udpTable_handler(netsnmp_mib_handler          *handler,
                 netsnmp_handler_registration *reginfo,
                 netsnmp_agent_request_info   *reqinfo,
                 netsnmp_request_info         *requests)
{
    netsnmp_request_info  *request;
    netsnmp_variable_list *requestvb;
    netsnmp_table_request_info *table_info;
    UDPTABLE_ENTRY_TYPE	  *entry;
    oid      subid;
    long     port,addr;

    DEBUGMSGTL(("mibII/udpTable", "Handler - mode %s\n",
                se_find_label_in_slist("agent_mode", reqinfo->mode)));
    switch (reqinfo->mode) {
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            requestvb = request->requestvb;
            DEBUGMSGTL(( "mibII/udpTable", "oid: "));
            DEBUGMSGOID(("mibII/udpTable", requestvb->name,
                         requestvb->name_length));
            DEBUGMSG((   "mibII/udpTable", "\n"));

            entry = (UDPTABLE_ENTRY_TYPE *)netsnmp_extract_iterator_context(request);
            if (!entry)
                continue;
            table_info = netsnmp_extract_table_info(request);
            subid      = table_info->colnum;

            switch (subid) {
            case UDPLOCALADDRESS:
#if defined(osf5) && defined(IN6_EXTRACT_V4ADDR)
                addr = ntohl(IN6_EXTRACT_V4ADDR(&entry->pcb.inp_laddr));
                snmp_set_var_typed_value(requestvb, ASN_IPADDRESS,
                                         (u_char*)&addr,
                                         sizeof(addr));
#else
                addr = UDP_ADDRESS_TO_HOST_ORDER(entry->UDPTABLE_LOCALADDRESS);
                snmp_set_var_typed_value(requestvb, ASN_IPADDRESS,
                                         (u_char *)&addr,
                                         sizeof(addr));
#endif
                break;
            case UDPLOCALPORT:
                port = UDP_PORT_TO_HOST_ORDER((u_short)entry->UDPTABLE_LOCALPORT);
                snmp_set_var_typed_value(requestvb, ASN_INTEGER,
                                         (u_char *)&port, sizeof(port));
                break;
            }
        }
        break;

    case MODE_GETNEXT:
    case MODE_GETBULK:
    case MODE_SET_RESERVE1:
    case MODE_SET_RESERVE2:
    case MODE_SET_ACTION:
    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        snmp_log(LOG_WARNING, "mibII/udpTable: Unsupported mode (%d)\n",
                 reqinfo->mode);
        break;
    default:
        snmp_log(LOG_WARNING, "mibII/udpTable: Unrecognised mode (%d)\n",
                 reqinfo->mode);
        break;
    }

    return SNMP_ERR_NOERROR;
}
示例#18
0
/** implements the table_iterator helper */
int
netsnmp_table_iterator_helper_handler(netsnmp_mib_handler *handler,
                                      netsnmp_handler_registration
                                      *reginfo,
                                      netsnmp_agent_request_info *reqinfo,
                                      netsnmp_request_info *requests)
{

    netsnmp_table_registration_info *tbl_info;
    oid             coloid[MAX_OID_LEN];
    size_t          coloid_len;
    int             ret;
    static oid      myname[MAX_OID_LEN];
    size_t	    myname_len;
    int             oldmode;
    netsnmp_iterator_info *iinfo;

    iinfo = (netsnmp_iterator_info *) handler->myvoid;
    if (!iinfo || !reginfo || !reqinfo)
        return SNMPERR_GENERR;

    tbl_info = iinfo->table_reginfo;

    /*
     * copy in the table registration oid for later use 
     */
    coloid_len = reginfo->rootoid_len + 2;
    memcpy(coloid, reginfo->rootoid, reginfo->rootoid_len * sizeof(oid));
    coloid[reginfo->rootoid_len] = 1;   /* table.entry node */

    /*
     * illegally got here if these functions aren't defined 
     */
    if (iinfo->get_first_data_point == NULL ||
        iinfo->get_next_data_point == NULL) {
        snmp_log(LOG_ERR,
                 "table_iterator helper called without data accessor functions\n");
        return SNMP_ERR_GENERR;
    }

    /*
     * XXXWWW: deal with SET caching 
     */

#ifdef NOT_SERIALIZED
    while (requests)            /* XXX: currently only serialized */
#endif
    {
        /*
         * XXXWWW: optimize by reversing loops (look through data only once) 
         */
        netsnmp_variable_list *results = NULL;
        netsnmp_variable_list *index_search = NULL;     /* WWW: move up? */
        netsnmp_variable_list *free_this_index_search = NULL;
        netsnmp_table_request_info *table_info =
            netsnmp_extract_table_info(requests);
        void           *callback_loop_context = NULL;
        void           *callback_data_context = NULL;
        void           *callback_data_keep = NULL;

        if (requests->processed != 0) {
#ifdef NOT_SERIALIZED
            continue;
#else
            return SNMP_ERR_NOERROR;
#endif
        }

        if (reqinfo->mode != MODE_GET && reqinfo->mode != MODE_GETNEXT && reqinfo->mode != MODE_GETBULK &&      /* XXX */
            reqinfo->mode != MODE_SET_RESERVE1) {
            goto skip_processing;
        }


        if (table_info->colnum > tbl_info->max_column) {
            requests->processed = 1;
#ifdef NOT_SERIALIZED
            break;
#else
            return SNMP_ERR_NOERROR;
#endif
        }

        /*
         * XXX: if loop through everything, these are never free'd
         * since iterator returns NULL and thus we forget about
         * these 
         */

        index_search = snmp_clone_varbind(table_info->indexes);
        if (!index_search) {
            /*
             * hmmm....  invalid table? 
             */
            snmp_log(LOG_WARNING,
                     "invalid index list or failed malloc for table %s\n",
                     reginfo->handlerName);
            return SNMP_ERR_NOERROR;
        }

        free_this_index_search = index_search;

        /*
         * below our minimum column? 
         */
        if (table_info->colnum < tbl_info->min_column) {
            results =
                (iinfo->get_first_data_point) (&callback_loop_context,
                                               &callback_data_context,
                                               index_search, iinfo);
            if (iinfo->free_loop_context) {
                (iinfo->free_loop_context) (callback_loop_context, iinfo);
		callback_loop_context = NULL;
	    }
            goto got_results;
        }

        /*
         * XXX: do "only got some indexes" 
         */

        /*
         * find the next legal result to return 
         */
        /*
         * find the first node 
         */
        index_search =
            (iinfo->get_first_data_point) (&callback_loop_context,
                                           &callback_data_context,
                                           index_search, iinfo);
        /*
         * table.entry.column node 
         */
        coloid[reginfo->rootoid_len + 1] = table_info->colnum;

        switch (reqinfo->mode) {
        case MODE_GETNEXT:
        case MODE_GETBULK:     /* XXXWWW */
            /*
             * loop through all data and find next one 
             */
            while (index_search) {
                /*
                 * compare the node with previous results 
                 */
                if (netsnmp_check_getnext_reply
                    (requests, coloid, coloid_len, index_search,
                     &results)) {

                    /*
                     * result is our current choice, so keep a pointer to
                     * the data that the lower handler wants us to
                     * remember (possibly freeing the last known "good"
                     * result data pointer) 
                     */
                    if (callback_data_keep && iinfo->free_data_context) {
                        (iinfo->free_data_context) (callback_data_keep,
                                                    iinfo);
                        callback_data_keep = NULL;
                    }
                    if (iinfo->make_data_context && !callback_data_context) {
                        callback_data_context =
                            (iinfo->
                             make_data_context) (callback_loop_context,
                                                 iinfo);

                    }
                    callback_data_keep = callback_data_context;
                    callback_data_context = NULL;
                } else {
                    if (callback_data_context && iinfo->free_data_context)
                        (iinfo->free_data_context) (callback_data_context,
                                                    iinfo);
                    callback_data_context = NULL;
                }

                /*
                 * get the next node in the data chain 
                 */
                index_search =
                    (iinfo->get_next_data_point) (&callback_loop_context,
                                                  &callback_data_context,
                                                  index_search, iinfo);

                if (!index_search && !results &&
                    tbl_info->max_column > table_info->colnum) {
                    /*
                     * restart loop.  XXX: Should cache this better 
                     */
                    table_info->colnum++;
                    coloid[reginfo->rootoid_len + 1] = table_info->colnum;
                    if (free_this_index_search != NULL)
                        snmp_free_varbind(free_this_index_search);
                    index_search = snmp_clone_varbind(table_info->indexes);
		    free_this_index_search = index_search;

                    if (callback_loop_context &&
                        iinfo->free_loop_context_at_end) {
                        (iinfo->free_loop_context_at_end)(callback_loop_context,
                                                          iinfo);
                        callback_loop_context = NULL;
                    }
                    if (iinfo->free_loop_context && callback_loop_context) {
                        (iinfo->free_loop_context) (callback_loop_context,
                                                    iinfo);
                        callback_loop_context = NULL;
                    }
                    if (callback_data_context && iinfo->free_data_context) {
                        (iinfo->free_data_context) (callback_data_context,
                                                    iinfo);
                        callback_data_context = NULL;
                    }
                    
                    index_search =
                        (iinfo->
                         get_first_data_point) (&callback_loop_context,
                                                &callback_data_context,
                                                index_search, iinfo);
                }
            }

            break;

        case MODE_GET:
        case MODE_SET_RESERVE1:
            /*
             * loop through all data till exact results are found 
             */

            while (index_search) {
                build_oid_noalloc(myname, MAX_OID_LEN, &myname_len,
                                  coloid, coloid_len, index_search);
                if (snmp_oid_compare(myname, myname_len,
                                     requests->requestvb->name,
                                     requests->requestvb->name_length) ==
                    0) {
                    /*
                     * found the exact match, so we're done 
                     */
                    if (iinfo->make_data_context && !callback_data_context) {
                        callback_data_context =
                            (iinfo->
                             make_data_context) (callback_loop_context,
                                                 iinfo);

                    }
                    callback_data_keep = callback_data_context;
                    callback_data_context = NULL;
                    results = snmp_clone_varbind(index_search);
                    snmp_set_var_objid(results, myname, myname_len);
                    goto got_results;
                } else {
                    /*
                     * free not-needed data context 
                     */
                    if (callback_data_context && iinfo->free_data_context) {
                        (iinfo->free_data_context) (callback_data_context,
                                                    iinfo);
                        callback_data_context = NULL;
                    }

                }

                /*
                 * get the next node in the data chain 
                 */
                index_search =
                    (iinfo->get_next_data_point) (&callback_loop_context,
                                                  &callback_data_context,
                                                  index_search, iinfo);
            }
            break;

        default:
            /*
             * the rest of the set states have been dealt with already 
             */
            goto got_results;
        }

        /*
         * XXX: free index_search? 
         */
        if (callback_loop_context && iinfo->free_loop_context) {
            (iinfo->free_loop_context) (callback_loop_context, iinfo);
            callback_loop_context = NULL;
        }

      got_results:             /* not milk */
   
       /*
        * This free_data_context call is required in the event that your
        * get_next_data_point method allocates new memory, even during the
        * calls where it eventually returns a NULL
        */
        if (callback_data_context && iinfo->free_data_context) {
               (iinfo->free_data_context) (callback_data_context,
                                           iinfo);
               callback_data_context = NULL;
        }

        if (!results && !MODE_IS_SET(reqinfo->mode)) {
            /*
             * no results found. 
             */
            /*
             * XXX: check for at least one entry at the very top 
             */
#ifdef NOT_SERIALIZED
            break;
#else
            if (callback_loop_context && iinfo->free_loop_context_at_end) {
                (iinfo->free_loop_context_at_end) (callback_loop_context,
                                                   iinfo);
		callback_loop_context = NULL;
	    }
            if (free_this_index_search != NULL) {
                snmp_free_varbind(free_this_index_search);
            }
            return SNMP_ERR_NOERROR;
#endif
        }

      skip_processing:
        /*
         * OK, here results should be a pointer to the data that we
         * actually need to GET 
         */
        oldmode = reqinfo->mode;
        if (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK) {   /* XXX */
            snmp_set_var_objid(requests->requestvb, results->name,
                               results->name_length);
            reqinfo->mode = MODE_GET;
        }
        if (reqinfo->mode == MODE_GET || reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK ||      /* XXX */
            reqinfo->mode == MODE_SET_RESERVE1) {
            /*
             * first (or only) pass stuff 
             */
            /*
             * let set requsets use previously constructed data 
             */
            snmp_free_varbind(results);
            if (callback_data_keep)
                netsnmp_request_add_list_data(requests,
                                              netsnmp_create_data_list
                                              (TABLE_ITERATOR_NAME,
                                               callback_data_keep, NULL));
            netsnmp_request_add_list_data(requests,
                                          netsnmp_create_data_list
                                          (TABLE_ITERATOR_LAST_CONTEXT,
                                           callback_loop_context, NULL));
        }

        DEBUGMSGTL(("table_iterator", "doing mode: %s\n",
                    se_find_label_in_slist("agent_mode", oldmode)));
        ret =
            netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
        if (oldmode == MODE_GETNEXT || oldmode == MODE_GETBULK) {       /* XXX */
            if (requests->requestvb->type == ASN_NULL ||
                requests->requestvb->type == SNMP_NOSUCHINSTANCE) {
                /*
                 * get next skipped this value for this column, we
                 * need to keep searching forward 
                 */
                requests->requestvb->type = ASN_PRIV_RETRY;
            }
            reqinfo->mode = oldmode;
        }

        callback_data_keep =
            netsnmp_request_get_list_data(requests, TABLE_ITERATOR_NAME);
        callback_loop_context =
            netsnmp_request_get_list_data(requests,
                                          TABLE_ITERATOR_LAST_CONTEXT);

        /* 
         * This has to be done to prevent a memory leak. Notice that on
         * SET_RESERVE1 we're assigning something to
         * 'free_this_index_search' at the beginning of this handler (right
         * above the line that says 'below our minimum column?'), 
         * but we're not given a chance to free it below with the other 
         * SET modes, hence our doing it here. 
         */
        if (reqinfo->mode == MODE_SET_RESERVE1) {
            if (free_this_index_search) {
                snmp_free_varbind(free_this_index_search);
                free_this_index_search = NULL;
            }
        }
        if (reqinfo->mode == MODE_GET || reqinfo->mode == MODE_GETNEXT ||
            reqinfo->mode == MODE_GETBULK ||      /* XXX */
            reqinfo->mode == MODE_SET_FREE ||
            reqinfo->mode == MODE_SET_UNDO ||
            reqinfo->mode == MODE_SET_COMMIT) {
            if (callback_data_keep && iinfo->free_data_context) {
                (iinfo->free_data_context) (callback_data_keep, iinfo);
                callback_data_keep = NULL;
            }

            if (free_this_index_search) {
                snmp_free_varbind(free_this_index_search);
                free_this_index_search = NULL;
            }
#ifndef NOT_SERIALIZED
            if (callback_loop_context && iinfo->free_loop_context_at_end) {
                (iinfo->free_loop_context_at_end) (callback_loop_context,
                                                   iinfo);
 		callback_loop_context = NULL;
            }
#endif
        }
#ifdef NOT_SERIALIZED
        return ret;
#else
        requests = requests->next;
#endif
    }
#ifdef NOT_SERIALIZED
    if (reqinfo->mode == MODE_GET || reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK ||  /* XXX */
        reqinfo->mode == MODE_SET_FREE ||
        reqinfo->mode == MODE_SET_UNDO ||
        reqinfo->mode == MODE_SET_COMMIT) {
        if (callback_loop_context && iinfo->free_loop_context_at_end) {
            (iinfo->free_loop_context_at_end) (callback_loop_context,
                                               iinfo);
	    callback_loop_context = NULL;
	}
    }
#endif
    return SNMP_ERR_NOERROR;
}
/**
 * Authorizes incoming notifications for further processing
 */
int
netsnmp_trapd_auth(netsnmp_pdu           *pdu,
                   netsnmp_transport     *transport,
                   netsnmp_trapd_handler *handler)
{
    int ret = 0;
    oid snmptrapoid[] = { 1,3,6,1,6,3,1,1,4,1,0 };
    size_t snmptrapoid_len = OID_LENGTH(snmptrapoid);
    int i;
    netsnmp_pdu *newpdu = pdu;
    netsnmp_variable_list *var;

    /* check to see if authorization was not disabled */
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_APP_NO_AUTHORIZATION)) {
        DEBUGMSGTL(("snmptrapd:auth",
                    "authorization turned off: not checking\n"));
        return NETSNMPTRAPD_HANDLER_OK;
    }

    /* bail early if called illegally */
    if (!pdu || !transport || !handler)
        return NETSNMPTRAPD_HANDLER_FINISH;
    
    /* convert to v2 so we can check it in a consistent manner */
#ifndef NETSNMP_DISABLE_SNMPV1
    if (pdu->version == SNMP_VERSION_1) {
        newpdu = convert_v1pdu_to_v2(pdu);
        if (!newpdu) {
            snmp_log(LOG_ERR, "Failed to duplicate incoming PDU.  Refusing to authorize.\n");
            return NETSNMPTRAPD_HANDLER_FINISH;
        }
    }
#endif

    if (!vacm_is_configured()) {
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        snmp_log(LOG_WARNING, "No access configuration - dropping trap.\n");
        return NETSNMPTRAPD_HANDLER_FINISH;
    }

    /* loop through each variable and find the snmpTrapOID.0 var
       indicating what the trap is we're staring at. */
    for (var = newpdu->variables; var != NULL; var = var->next_variable) {
        if (netsnmp_oid_equals(var->name, var->name_length,
                               snmptrapoid, snmptrapoid_len) == 0)
            break;
    }

    /* make sure we can continue: we found the snmpTrapOID.0 and its an oid */
    if (!var || var->type != ASN_OBJECT_ID) {
        snmp_log(LOG_ERR, "Can't determine trap identifier; refusing to authorize it\n");
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        return NETSNMPTRAPD_HANDLER_FINISH;
    }

#ifdef USING_MIBII_VACM_CONF_MODULE
    /* check the pdu against each typo of VACM access we may want to
       check up on later.  We cache the results for future lookup on
       each call to netsnmp_trapd_check_auth */
    for(i = 0; i < VACM_MAX_VIEWS; i++) {
        /* pass the PDU to the VACM routine for handling authorization */
        DEBUGMSGTL(("snmptrapd:auth", "Calling VACM for checking phase %d:%s\n",
                    i, se_find_label_in_slist(VACM_VIEW_ENUM_NAME, i)));
        if (vacm_check_view_contents(newpdu, var->val.objid,
                                     var->val_len/sizeof(oid), 0, i,
                                     VACM_CHECK_VIEW_CONTENTS_DNE_CONTEXT_OK)
            == VACM_SUCCESS) {
            DEBUGMSGTL(("snmptrapd:auth", "  result: authorized\n"));
            ret |= 1 << i;
        } else {
            DEBUGMSGTL(("snmptrapd:auth", "  result: not authorized\n"));
        }
    }
    DEBUGMSGTL(("snmptrapd:auth", "Final bitmask auth: %x\n", ret));
#endif

    if (ret) {
        /* we have policy to at least do "something".  Remember and continue. */
        lastlookup = ret;
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        return NETSNMPTRAPD_HANDLER_OK;
    }

    /* No policy was met, so we drop the PDU from further processing */
    DEBUGMSGTL(("snmptrapd:auth", "Dropping unauthorized message\n"));
#ifndef NETSNMP_DISABLE_SNMPV1
    if (newpdu != pdu)
        snmp_free_pdu(newpdu);
#endif
    return NETSNMPTRAPD_HANDLER_FINISH;
}
示例#20
0
/* implements the table_iterator helper */
int
netsnmp_table_iterator_helper_handler(netsnmp_mib_handler *handler,
                                      netsnmp_handler_registration *reginfo,
                                      netsnmp_agent_request_info *reqinfo,
                                      netsnmp_request_info *requests)
{
    netsnmp_table_registration_info *tbl_info;
    netsnmp_table_request_info *table_info = NULL;
    oid             coloid[MAX_OID_LEN];
    size_t          coloid_len;
    int             ret;
    static oid      myname[MAX_OID_LEN];
    size_t          myname_len;
    int             oldmode = 0;
    netsnmp_iterator_info *iinfo;
    int notdone;
    netsnmp_request_info *request, *reqtmp = NULL;
    netsnmp_variable_list *index_search = NULL;
    netsnmp_variable_list *free_this_index_search = NULL;
    void           *callback_loop_context = NULL, *last_loop_context;
    void           *callback_data_context = NULL;
    ti_cache_info  *ti_info = NULL;
    int             request_count = 0;
    netsnmp_oid_stash_node **cinfo = NULL;
    netsnmp_variable_list *old_indexes = NULL, *vb;
    netsnmp_table_registration_info *table_reg_info = NULL;
    int i;
    netsnmp_data_list    *ldata = NULL;
    
    iinfo = (netsnmp_iterator_info *) handler->myvoid;
    if (!iinfo || !reginfo || !reqinfo)
        return SNMPERR_GENERR;

    tbl_info = iinfo->table_reginfo;

    /*
     * copy in the table registration oid for later use 
     */
    coloid_len = reginfo->rootoid_len + 2;
    memcpy(coloid, reginfo->rootoid, reginfo->rootoid_len * sizeof(oid));
    coloid[reginfo->rootoid_len] = 1;   /* table.entry node */

    /*
     * illegally got here if these functions aren't defined 
     */
    if (iinfo->get_first_data_point == NULL ||
        iinfo->get_next_data_point == NULL) {
        snmp_log(LOG_ERR,
                 "table_iterator helper called without data accessor functions\n");
        return SNMP_ERR_GENERR;
    }

    /* preliminary analysis */
    switch (reqinfo->mode) {
    case MODE_GET_STASH:
        cinfo = netsnmp_extract_stash_cache(reqinfo);
        table_reg_info = netsnmp_find_table_registration_info(reginfo);

        /* XXX: move this malloc to stash_cache handler? */
        reqtmp = SNMP_MALLOC_TYPEDEF(netsnmp_request_info);
        reqtmp->subtree = requests->subtree;
        table_info = netsnmp_extract_table_info(requests);
        netsnmp_request_add_list_data(reqtmp,
                                      netsnmp_create_data_list
                                      (TABLE_HANDLER_NAME,
                                       (void *) table_info, NULL));

        /* remember the indexes that were originally parsed. */
        old_indexes = table_info->indexes;
        break;

    case MODE_GETNEXT:
        for(request = requests ; request; request = request->next) {
            if (request->processed)
                continue;
            table_info = netsnmp_extract_table_info(request);
            if (table_info->colnum < tbl_info->min_column - 1) {
                /* XXX: optimize better than this */
                /* for now, just increase to colnum-1 */
                /* we need to jump to the lowest result of the min_column
                   and take it, comparing to nothing from the request */
                table_info->colnum = tbl_info->min_column - 1;
            } else if (table_info->colnum > tbl_info->max_column) {
                request->processed = TABLE_ITERATOR_NOTAGAIN;
            }

            ti_info =
                netsnmp_request_get_list_data(request, TI_REQUEST_CACHE);
            if (!ti_info) {
                ti_info = SNMP_MALLOC_TYPEDEF(ti_cache_info);
                netsnmp_request_add_list_data(request,
                                              netsnmp_create_data_list
                                              (TI_REQUEST_CACHE,
                                               ti_info,
                                               netsnmp_free_ti_cache));
            }

            /* XXX: if no valid requests, don't even loop below */
        }
        break;
    }

    /*
     * collect all information for each needed row
     */
    if (reqinfo->mode == MODE_GET ||
        reqinfo->mode == MODE_GETNEXT ||
        reqinfo->mode == MODE_GET_STASH ||
        reqinfo->mode == MODE_SET_RESERVE1) {
        /*
         * Count the number of request in the list,
         *   so that we'll know when we're finished
         */
        for(request = requests ; request; request = request->next)
          if (!request->processed)
            request_count++;
        notdone = 1;
        while(notdone) {
            notdone = 0;

            /* find first data point */
            if (!index_search) {
                if (free_this_index_search) {
                    /* previously done */
                    index_search = free_this_index_search;
                } else {
                    for(request=requests ; request; request=request->next) {
                        table_info = netsnmp_extract_table_info(request);
                        if (table_info)
                            break;
                    }
                    if (!table_info) {
                        snmp_log(LOG_WARNING,
                                 "no valid requests for iterator table %s\n",
                                 reginfo->handlerName);
                        netsnmp_free_request_data_sets(reqtmp);
                        SNMP_FREE(reqtmp);
                        return SNMP_ERR_NOERROR;
                    }
                    index_search = snmp_clone_varbind(table_info->indexes);
                    free_this_index_search = index_search;

                    /* setup, malloc search data: */
                    if (!index_search) {
                        /*
                         * hmmm....  invalid table? 
                         */
                        snmp_log(LOG_WARNING,
                                 "invalid index list or failed malloc for table %s\n",
                                 reginfo->handlerName);
                        netsnmp_free_request_data_sets(reqtmp);
                        SNMP_FREE(reqtmp);
                        return SNMP_ERR_NOERROR;
                    }
                }
            }

            /* if sorted, pass in a hint */
            if (iinfo->flags & NETSNMP_ITERATOR_FLAG_SORTED) {
                callback_loop_context = table_info;
            }
            index_search =
                (iinfo->get_first_data_point) (&callback_loop_context,
                                               &callback_data_context,
                                               index_search, iinfo);

            /* loop over each data point */
            while(index_search) {

                /* remember to free this later */
                free_this_index_search = index_search;
            
                /* compare against each request*/
                for(request = requests ; request; request = request->next) {
                    if (request->processed)
                        continue;

                    /* XXX: store in an array for faster retrival */
                    table_info = netsnmp_extract_table_info(request);
                    coloid[reginfo->rootoid_len + 1] = table_info->colnum;

                    ti_info =
                        netsnmp_request_get_list_data(request, TI_REQUEST_CACHE);

                    switch(reqinfo->mode) {
                    case MODE_GET:
                    case MODE_SET_RESERVE1:
                        /* looking for exact matches */
                        build_oid_noalloc(myname, MAX_OID_LEN, &myname_len,
                                          coloid, coloid_len, index_search);
                        if (snmp_oid_compare(myname, myname_len,
                                             request->requestvb->name,
                                             request->requestvb->name_length) == 0) {
                            /* keep this */
                            netsnmp_iterator_remember(request,
                                                      myname, myname_len,
                                                      callback_data_context,
                                                      callback_loop_context, iinfo);
                            request_count--;   /* One less to look for */
                        } else {
                            if (iinfo->free_data_context && callback_data_context) {
                                (iinfo->free_data_context)(callback_data_context,
                                                           iinfo);
                            }
                        }
                        break;

                    case MODE_GET_STASH:
                        /* collect data for each column for every row */
                        build_oid_noalloc(myname, MAX_OID_LEN, &myname_len,
                                          coloid, coloid_len, index_search);
                        reqinfo->mode = MODE_GET;
                        if (reqtmp)
                            ldata =
                                netsnmp_get_list_node(reqtmp->parent_data,
                                                      TABLE_ITERATOR_NAME);
                        if (!ldata) {
                            netsnmp_request_add_list_data(reqtmp,
                                                          netsnmp_create_data_list
                                                          (TABLE_ITERATOR_NAME,
                                                           callback_data_context,
                                                           NULL));
                        } else {
                            /* may have changed */
                            ldata->data = callback_data_context;
                        }

                        table_info->indexes = index_search;
                        for(i = table_reg_info->min_column;
                            i <= (int)table_reg_info->max_column; i++) {
                            myname[reginfo->rootoid_len + 1] = i;
                            table_info->colnum = i;
                            vb = reqtmp->requestvb =
                                SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);
                            vb->type = ASN_NULL;
                            snmp_set_var_objid(vb, myname, myname_len);
                            netsnmp_call_next_handler(handler, reginfo,
                                                      reqinfo, reqtmp);
                            reqtmp->requestvb = NULL;
                            reqtmp->processed = 0;
                            if (vb->type != ASN_NULL) { /* XXX, not all */
                                netsnmp_oid_stash_add_data(cinfo, myname,
                                                           myname_len, vb);
                            } else {
                                snmp_free_var(vb);
                            }
                        }
                        reqinfo->mode = MODE_GET_STASH;
                        break;

                    case MODE_GETNEXT:
                        /* looking for "next" matches */
                        if (netsnmp_check_getnext_reply
                            (request, coloid, coloid_len, index_search,
                             &ti_info->results)) {
                            netsnmp_iterator_remember(request,
                                                      ti_info->results->name,
                                                      ti_info->results->name_length,
                                                      callback_data_context,
                                                      callback_loop_context, iinfo);
                            /*
                             *  If we've been told that the rows are sorted,
                             *   then the first valid one we find
                             *   must be the right one.
                             */
                            if (iinfo->flags & NETSNMP_ITERATOR_FLAG_SORTED)
                                request_count--;
                        
                        } else {
                            if (iinfo->free_data_context && callback_data_context) {
                                (iinfo->free_data_context)(callback_data_context,
                                                           iinfo);
                            }
                        }
                        break;

                    case MODE_SET_RESERVE2:
                    case MODE_SET_FREE:
                    case MODE_SET_UNDO:
                    case MODE_SET_COMMIT:
                        /* needed processing already done in RESERVE1 */
                        break;

                    default:
                        snmp_log(LOG_ERR,
                                 "table_iterator called with unsupported mode\n");
                        break;  /* XXX return */
                
                    }
                }

                /* Is there any point in carrying on? */
                if (!request_count)
                    break;
                /* get the next search possibility */
                last_loop_context = callback_loop_context;
                index_search =
                    (iinfo->get_next_data_point) (&callback_loop_context,
                                                  &callback_data_context,
                                                  index_search, iinfo);
                if (iinfo->free_loop_context && last_loop_context &&
                    callback_data_context != last_loop_context) {
                    (iinfo->free_loop_context) (last_loop_context, iinfo);
                    last_loop_context = NULL;
                }
            }

            /* free loop context before going on */
            if (callback_loop_context && iinfo->free_loop_context_at_end) {
                (iinfo->free_loop_context_at_end) (callback_loop_context,
                                                   iinfo);
                callback_loop_context = NULL;
            }

            /* decide which (GETNEXT) requests are not yet filled */
            if (reqinfo->mode == MODE_GETNEXT) {
                for(request = requests ; request; request = request->next) {
                    if (request->processed)
                        continue;
                    ti_info =
                        netsnmp_request_get_list_data(request,
                                                      TI_REQUEST_CACHE);
                    if (!ti_info->results) {
                      int nc;
                        table_info = netsnmp_extract_table_info(request);
                        nc = netsnmp_table_next_column(table_info);
                        if (0 == nc) {
                            coloid[reginfo->rootoid_len+1] = table_info->colnum+1;
                            snmp_set_var_objid(request->requestvb,
                                               coloid, reginfo->rootoid_len+2);
                            request->processed = TABLE_ITERATOR_NOTAGAIN;
                            break;
                        } else {
                          table_info->colnum = nc;
                            notdone = 1;
                        }
                    }
                }
            }
        }
    }

    if (reqinfo->mode == MODE_GET ||
        reqinfo->mode == MODE_GETNEXT ||
        reqinfo->mode == MODE_SET_RESERVE1) {
        /* per request last minute processing */
        for(request = requests ; request; request = request->next) {
            if (request->processed)
                continue;
            ti_info =
                netsnmp_request_get_list_data(request, TI_REQUEST_CACHE);
            table_info =
                netsnmp_extract_table_info(request);

            if (!ti_info)
                continue;
        
            switch(reqinfo->mode) {

            case MODE_GETNEXT:
                if (ti_info->best_match_len)
                    snmp_set_var_objid(request->requestvb, ti_info->best_match,
                                       ti_info->best_match_len);
                else {
                    coloid[reginfo->rootoid_len+1] = 
                        netsnmp_table_next_column(table_info);
                    if (0 == coloid[reginfo->rootoid_len+1]) {
                        /* out of range. */
                        coloid[reginfo->rootoid_len+1] = tbl_info->max_column + 1;
                        request->processed = TABLE_ITERATOR_NOTAGAIN;
                    }
                    snmp_set_var_objid(request->requestvb,
                                       coloid, reginfo->rootoid_len+2);
                    request->processed = 1;
                }
                snmp_free_varbind(table_info->indexes);
                table_info->indexes = snmp_clone_varbind(ti_info->results);
                /* FALL THROUGH */

            case MODE_GET:
            case MODE_SET_RESERVE1:
                if (ti_info->data_context)
                    /* we don't add a free pointer, since it's in the
                       TI_REQUEST_CACHE instead */
                    netsnmp_request_add_list_data(request,
                                                  netsnmp_create_data_list
                                                  (TABLE_ITERATOR_NAME,
                                                   ti_info->data_context,
                                                   NULL));
                break;
            
            default:
                break;
            }
        }
            
        /* we change all GETNEXT operations into GET operations.
           why? because we're just so nice to the lower levels.
           maybe someday they'll pay us for it.  doubtful though. */
        oldmode = reqinfo->mode;
        if (reqinfo->mode == MODE_GETNEXT) {
            reqinfo->mode = MODE_GET;
        }
    } else if (reqinfo->mode == MODE_GET_STASH) {
        netsnmp_free_request_data_sets(reqtmp);
        SNMP_FREE(reqtmp);
        table_info->indexes = old_indexes;
    }


    /* Finally, we get to call the next handler below us.  Boy, wasn't
       all that simple?  They better be glad they don't have to do it! */
    if (reqinfo->mode != MODE_GET_STASH) {
        DEBUGMSGTL(("table_iterator", "call subhandler for mode: %s\n",
                    se_find_label_in_slist("agent_mode", oldmode)));
        ret =
            netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
    }

    /* reverse the previously saved mode if we were a getnext */
    if (oldmode == MODE_GETNEXT) {
        reqinfo->mode = oldmode;
    }

    /* cleanup */
    if (free_this_index_search)
        snmp_free_varbind(free_this_index_search);

    return SNMP_ERR_NOERROR;
}
示例#21
0
void
vacm_create_simple(const char *token, char *confline,
                   int parsetype, int viewtypes)
{
    char            line[SPRINT_MAX_LEN];
    char            community[COMMUNITY_MAX_LEN];
    char            theoid[SPRINT_MAX_LEN];
    char            viewname[SPRINT_MAX_LEN];
    char           *view_ptr = viewname;
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
    char            addressname[SPRINT_MAX_LEN];
#endif
    const char     *rw = "none";
    char            model[SPRINT_MAX_LEN];
    char           *cp, *tmp;
    char            secname[SPRINT_MAX_LEN];
    char            grpname[SPRINT_MAX_LEN];
    char            authlevel[SPRINT_MAX_LEN];
    char            context[SPRINT_MAX_LEN];
    int             ctxprefix = 1;  /* Default to matching all contexts */
    static int      commcount = 0;
    /* Conveniently, the community-based security
       model values can also be used as bit flags */
    int             commversion = SNMP_SEC_MODEL_SNMPv1 |
                                  SNMP_SEC_MODEL_SNMPv2c;

    /*
     * init 
     */
    strcpy(model, "any");
    memset(context, 0, sizeof(context));
    memset(secname, 0, sizeof(secname));
    memset(grpname, 0, sizeof(grpname));

    /*
     * community name or user name 
     */
    cp = copy_nword(confline, community, sizeof(community));

    if (parsetype == VACM_CREATE_SIMPLE_V3) {
        /*
         * maybe security model type 
         */
        if (strcmp(community, "-s") == 0) {
            /*
             * -s model ... 
             */
            if (cp)
                cp = copy_nword(cp, model, sizeof(model));
            if (!cp) {
                config_perror("illegal line");
                return;
            }
            if (cp)
                cp = copy_nword(cp, community, sizeof(community));
        } else {
            strcpy(model, "usm");
        }
        /*
         * authentication level 
         */
        if (cp && *cp)
            cp = copy_nword(cp, authlevel, sizeof(authlevel));
        else
            strcpy(authlevel, "auth");
        DEBUGMSGTL((token, "setting auth level: \"%s\"\n", authlevel));
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
    } else {
        if (strcmp(community, "-v") == 0) {
            /*
             * -v version ... 
             */
            if (cp)
                cp = copy_nword(cp, model, sizeof(model));
            if (!cp) {
                config_perror("illegal line");
                return;
            }
            if ( strcasecmp( model,  "1" ) == 0 )
                strcpy(model, "v1");
            if ( strcasecmp( model, "v1" ) == 0 )
                commversion = SNMP_SEC_MODEL_SNMPv1;
            if ( strcasecmp( model,  "2c" ) == 0 )
                strcpy(model, "v2c");
            if ( strcasecmp( model, "v2c" ) == 0 )
                commversion = SNMP_SEC_MODEL_SNMPv2c;
            if (cp)
                cp = copy_nword(cp, community, sizeof(community));
        }
        /*
         * source address 
         */
        if (cp && *cp) {
            cp = copy_nword(cp, addressname, sizeof(addressname));
        } else {
            strcpy(addressname, "default");
        }
        /*
         * authlevel has to be noauth 
         */
        strcpy(authlevel, "noauth");
#endif /* support for community based SNMP */
    }

    /*
     * oid they can touch 
     */
    if (cp && *cp) {
        if (strncmp(cp, "-V ", 3) == 0) {
             cp = skip_token(cp);
             cp = copy_nword(cp, viewname, sizeof(viewname));
             view_ptr = NULL;
        } else {
             cp = copy_nword(cp, theoid, sizeof(theoid));
        }
    } else {
        strcpy(theoid, ".1");
        strcpy(viewname, "_all_");
        view_ptr = NULL;
    }
    /*
     * optional, non-default context
     */
    if (cp && *cp) {
        cp = copy_nword(cp, context, sizeof(context));
        tmp = (context + strlen(context)-1);
        if (tmp && *tmp == '*') {
            *tmp = '\0';
            ctxprefix = 1;
        } else {
            /*
             * If no context field is given, then we default to matching
             *   all contexts (for compatability with previous releases).
             * But if a field context is specified (not ending with '*')
             *   then this should be taken as an exact match.
             * Specifying a context field of "" will match the default
             *   context (and *only* the default context).
             */
            ctxprefix = 0;
        }
    }

    if (viewtypes & VACM_VIEW_WRITE_BIT)
        rw = viewname;

    commcount++;

#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
#ifdef NETSNMP_TRANSPORT_UDP_DOMAIN
    if (parsetype == VACM_CREATE_SIMPLE_COMIPV4 ||
        parsetype == VACM_CREATE_SIMPLE_COM) {
        vacm_gen_com2sec(commcount, community, addressname,
                         "com2sec", &netsnmp_udp_parse_security,
                         secname, sizeof(secname),
                         view_ptr, sizeof(viewname), commversion, context);
    }
#endif

#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
    if (parsetype == VACM_CREATE_SIMPLE_COMUNIX ||
        parsetype == VACM_CREATE_SIMPLE_COM) {
        if ( *context )
           snprintf(line, sizeof(line), "-Cn %s %s %s '%s'",
             context, secname, addressname, community);
        else
            snprintf(line, sizeof(line), "%s %s '%s'",
                 secname, addressname, community);
        line[ sizeof(line)-1 ] = 0;
        DEBUGMSGTL((token, "passing: %s %s\n", "com2secunix", line));
        netsnmp_unix_parse_security("com2secunix", line);
    }
#endif

#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    if (parsetype == VACM_CREATE_SIMPLE_COMIPV6 ||
        parsetype == VACM_CREATE_SIMPLE_COM) {
        vacm_gen_com2sec(commcount, community, addressname,
                         "com2sec6", &netsnmp_udp6_parse_security,
                         secname, sizeof(secname),
                         view_ptr, sizeof(viewname), commversion, context);
    }
#endif
#endif /* support for community based SNMP */

    if (parsetype == VACM_CREATE_SIMPLE_V3) {
        /* support for SNMPv3 user names */
        if (view_ptr) {
            sprintf(viewname,"viewUSM%d",commcount);
        }
        if ( strcmp( token, "authgroup" ) == 0 ) {
            strlcpy(grpname, community, sizeof(grpname));
        } else {
            strlcpy(secname, community, sizeof(secname));

            /*
             * sec->group mapping 
             */
            /*
             * group   anonymousGroupNameNUM  any      anonymousSecNameNUM 
             */
            snprintf(grpname, sizeof(grpname), "grp%.28s", secname);
            for (tmp=grpname; *tmp; tmp++)
                if (!isalnum((unsigned char)(*tmp)))
                    *tmp = '_';
            snprintf(line, sizeof(line),
                     "%s %s \"%s\"", grpname, model, secname);
            line[ sizeof(line)-1 ] = 0;
            DEBUGMSGTL((token, "passing: %s %s\n", "group", line));
            vacm_parse_group("group", line);
        }
    } else {
        snprintf(grpname, sizeof(grpname), "grp%.28s", secname);
        for (tmp=grpname; *tmp; tmp++)
            if (!isalnum((unsigned char)(*tmp)))
                *tmp = '_';
    }

    /*
     * view definition 
     */
    /*
     * view    anonymousViewNUM       included OID 
     */
    if (view_ptr) {
        snprintf(line, sizeof(line), "%s included %s", viewname, theoid);
        line[ sizeof(line)-1 ] = 0;
        DEBUGMSGTL((token, "passing: %s %s\n", "view", line));
        vacm_parse_view("view", line);
    }

    /*
     * map everything together 
     */
    if ((viewtypes == VACM_VIEW_READ_BIT) ||
        (viewtypes == (VACM_VIEW_READ_BIT | VACM_VIEW_WRITE_BIT))) {
        /* Use the simple line access command */
        /*
         * access  anonymousGroupNameNUM  "" MODEL AUTHTYPE prefix anonymousViewNUM [none/anonymousViewNUM] [none/anonymousViewNUM] 
         */
        snprintf(line, sizeof(line),
                 "%s %s %s %s %s %s %s %s",
                 grpname, context[0] ? context : "\"\"",
                 model, authlevel,
                (ctxprefix ? "prefix" : "exact"),
                 viewname, rw, rw);
        line[ sizeof(line)-1 ] = 0;
        DEBUGMSGTL((token, "passing: %s %s\n", "access", line));
        vacm_parse_access("access", line);
    } else {
        /* Use one setaccess line per access type */
        /*
         * setaccess  anonymousGroupNameNUM  "" MODEL AUTHTYPE prefix viewname viewval
         */
        int i;
        DEBUGMSGTL((token, " checking view levels for %x\n", viewtypes));
        for(i = 0; i <= VACM_MAX_VIEWS; i++) {
            if (viewtypes & (1 << i)) {
                snprintf(line, sizeof(line),
                         "%s %s %s %s %s %s %s",
                         grpname, context[0] ? context : "\"\"",
                         model, authlevel,
                        (ctxprefix ? "prefix" : "exact"),
                         se_find_label_in_slist(VACM_VIEW_ENUM_NAME, i),
                         viewname);
                line[ sizeof(line)-1 ] = 0;
                DEBUGMSGTL((token, "passing: %s %s\n", "setaccess", line));
                vacm_parse_setaccess("setaccess", line);
            }
        }
    }
}