コード例 #1
0
int
agentx_unregister_index(netsnmp_session * ss,
                        netsnmp_variable_list * varbind)
{
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *varbind2;

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return -1;
    }

    /*
     * Make a copy of the index request varbind
     *    for the AgentX request PDU
     *    (since the pdu structure will be freed)
     */
    varbind2 =
        (netsnmp_variable_list *) malloc(sizeof(netsnmp_variable_list));
    if (varbind2 == NULL)
        return -1;
    if (snmp_clone_var(varbind, varbind2)) {
        snmp_free_varbind(varbind2);
        return -1;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_INDEX_DEALLOCATE);
    if (pdu == NULL) {
        snmp_free_varbind(varbind2);
        return -1;
    }
    pdu->time = 0;
    pdu->sessid = ss->sessid;

    /*
     *  Just send a single index release varbind.
     *      (as above)
     */
    pdu->variables = varbind2;

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return -1;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return -1;              /* XXX - say why */
    }

    snmp_free_pdu(response);
    return SNMP_ERR_NOERROR;
}
コード例 #2
0
ファイル: master_admin.c プロジェクト: WimObiwan/net-snmp
int
allocate_idx_list(netsnmp_session * session, netsnmp_pdu *pdu)
{
    netsnmp_session *sp;
    netsnmp_variable_list *vp, *vp2, *next, *res;
    int             flags = 0;

    sp = find_agentx_session(session, pdu->sessid);
    if (sp == NULL)
        return AGENTX_ERR_NOT_OPEN;

    if (pdu->flags & AGENTX_MSG_FLAG_ANY_INSTANCE)
        flags |= ALLOCATE_ANY_INDEX;
    if (pdu->flags & AGENTX_MSG_FLAG_NEW_INSTANCE)
        flags |= ALLOCATE_NEW_INDEX;

    /*
     * XXX - what about errors?
     *
     *  If any allocations fail, then we need to
     *    *fully* release the earlier ones.
     *  (i.e. remove them completely from the index registry,
     *    not simply mark them as available for re-use)
     *
     * For now - assume they all succeed.
     */
    for (vp = pdu->variables; vp != NULL; vp = next) {
        next = vp->next_variable;
        res = register_index(vp, flags, session);
        if (res == NULL) {
            /*
             *  If any allocations fail, we need to *fully* release
             *      all previous ones (i.e. remove them completely
             *      from the index registry)
             */
            for (vp2 = pdu->variables; vp2 != vp; vp2 = vp2->next_variable) {
                remove_index(vp2, session);
            }
            return AGENTX_ERR_INDEX_NONE_AVAILABLE;     /* XXX */
        } else {
            (void) snmp_clone_var(res, vp);
            free(res);
        }
        vp->next_variable = next;
    }
    return AGENTX_ERR_NOERROR;
}
コード例 #3
0
ファイル: snmp_client.c プロジェクト: AllardJ/Tomato
static
netsnmp_variable_list *
_copy_varlist(netsnmp_variable_list * var,      /* source varList */
              int errindex,     /* index of variable to drop (if any) */
              int copy_count)
{                               /* !=0 number variables to copy */
    netsnmp_variable_list *newhead, *newvar, *oldvar;
    int             ii = 0;

    newhead = NULL;
    oldvar = NULL;

    while (var && (copy_count-- > 0)) {
        /*
         * Drop the specified variable (if applicable) 
         */
        if (++ii == errindex) {
            var = var->next_variable;
            continue;
        }

        /*
         * clone the next variable. Cleanup if alloc fails 
         */
        newvar = (netsnmp_variable_list *)
            malloc(sizeof(netsnmp_variable_list));
        if (snmp_clone_var(var, newvar)) {
            if (newvar)
                free((char *) newvar);
            snmp_free_varbind(newhead);
            return 0;
        }

        /*
         * add cloned variable to new list  
         */
        if (0 == newhead)
            newhead = newvar;
        if (oldvar)
            oldvar->next_variable = newvar;
        oldvar = newvar;

        var = var->next_variable;
    }
    return newhead;
}
コード例 #4
0
netsnmp_variable_list *
agentx_register_index(netsnmp_session * ss,
                      netsnmp_variable_list * varbind, int flags)
{
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *varbind2;

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return NULL;
    }

    /*
     * Make a copy of the index request varbind
     *    for the AgentX request PDU
     *    (since the pdu structure will be freed)
     */
    varbind2 =
        (netsnmp_variable_list *) malloc(sizeof(netsnmp_variable_list));
    if (varbind2 == NULL)
        return NULL;
    if (snmp_clone_var(varbind, varbind2)) {
        snmp_free_varbind(varbind2);
        return NULL;
    }
    if (varbind2->val.string == NULL)
        varbind2->val.string = varbind2->buf;   /* ensure it points somewhere */

    pdu = snmp_pdu_create(AGENTX_MSG_INDEX_ALLOCATE);
    if (pdu == NULL) {
        snmp_free_varbind(varbind2);
        return NULL;
    }
    pdu->time = 0;
    pdu->sessid = ss->sessid;
    if (flags == ALLOCATE_ANY_INDEX)
        pdu->flags |= AGENTX_MSG_FLAG_ANY_INSTANCE;
    if (flags == ALLOCATE_NEW_INDEX)
        pdu->flags |= AGENTX_MSG_FLAG_NEW_INSTANCE;

    /*
     *  Just send a single index request varbind.
     *  Although the AgentX protocol supports
     *    multiple index allocations in a single
     *    request, the model used in the net-snmp agent
     *    doesn't currently take advantage of this.
     *  I believe this is our prerogative - just as
     *    long as the master side Index request handler
     *    can cope with multiple index requests.
     */
    pdu->variables = varbind2;

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
        return NULL;

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_free_pdu(response);
        return NULL;
    }

    /*
     * Unlink the (single) response varbind to return
     *  to the main driving index request routine.
     *
     * This is a memory leak, as nothing will ever
     *  release this varbind.  If this becomes a problem,
     *  we'll need to keep a list of these here, and
     *  free the memory in the "index release" routine.
     * But the master side never frees these either (by
     *  design, since it still needs them), so expecting
     *  the subagent to is discrimination, pure & simple :-)
     */
    varbind2 = response->variables;
    response->variables = NULL;
    snmp_free_pdu(response);
    return varbind2;
}
コード例 #5
0
int mp_snmp_subtree_query(netsnmp_session *ss,
                           const oid *subtree_oid,
                           const size_t subtree_len,
                           mp_snmp_subtree *subtree) {

    oid last_oid[MAX_OID_LEN];
    size_t last_len;
    netsnmp_pdu *request  = NULL;
    netsnmp_pdu *response = NULL;
    netsnmp_variable_list *var;
    size_t alloc_size = 0;
    int rc;

    /* prepare result */
    memset(subtree, '\0', sizeof(*subtree));
    subtree->vars = NULL;

    memcpy(last_oid, subtree_oid, subtree_len * sizeof(oid));
    last_len = subtree_len;

    for (;;) {
        /*
         * setup request
         */
        if (ss->version == SNMP_VERSION_1) {
            request = snmp_pdu_create(SNMP_MSG_GETNEXT);
        } else {
            request = snmp_pdu_create(SNMP_MSG_GETBULK);
            request->non_repeaters   = 0;
            request->max_repetitions = 16;
        }
        snmp_add_null_var(request, last_oid, last_len);

        /*
         * commence request
         */
        if (response) {
            snmp_free_pdu(response);
            response = NULL;
        }

        if (mp_verbose > 2) {
            char buf[128];

            snprint_objid((char *) &buf, sizeof(buf), last_oid, last_len);
            printf("Fetching next from OID %s\n", buf);
        }

        rc = snmp_synch_response(ss, request, &response);

        if (mp_verbose > 3)
            printf("snmp_synch_response(): rc=%d, errstat=%ld\n",
                   rc, response->errstat);

        if ((rc == STAT_SUCCESS) && response) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * loop over results (may only be one result in case of SNMP v1)
                 */
                for (var = response->variables; var; var = var->next_variable) {

                    /*
                     * check, if OIDs are incresing to prevent infinite
                     * loop with broken SNMP agents
                     */
                    if (snmp_oidtree_compare(var->name, var->name_length,
                                             last_oid, last_len) < 0) {
                        if (response)
                            snmp_free_pdu(response);

                        mp_snmp_deinit();

                        critical("SNMP error: OIDs are not incresing");
                    }

                    /*
                     * terminate, if oid does not belong to subtree anymore
                     */
                    if ((var->type == SNMP_ENDOFMIBVIEW) ||
                        (snmp_oidtree_compare(subtree_oid,
                                              subtree_len,
                                              var->name,
                                              var->name_length) != 0)) {
                        snmp_free_pdu(response);
                        return rc;
                    }

                    if (mp_verbose > 2)
                        print_variable(var->name, var->name_length, var);

                    if (var->type != SNMP_NOSUCHOBJECT ||
                        var->type != SNMP_NOSUCHINSTANCE) {
                        if (alloc_size <= subtree->size) {
                            alloc_size += 16;
                            subtree->vars =
                                mp_realloc(subtree->vars,
                                           alloc_size *
                                           sizeof(netsnmp_variable_list*));
                        }

                        subtree->vars[subtree->size] =
                            mp_malloc(sizeof(netsnmp_variable_list));
                        snmp_clone_var(var, subtree->vars[subtree->size]);
                        subtree->size++;
                    }

                    /*
                     * save last fetched oid
                     */
                    memcpy(last_oid, var->name,
                           var->name_length * sizeof(oid));
                    last_len = var->name_length;
                } /* for */
            } else if ((ss->version == SNMP_VERSION_1) &&
                       (response->errstat == SNMP_ERR_NOSUCHNAME)) {
                if (mp_verbose > 3)
                    printf("SNMP-V1: end of tree\n");
            } else {
                /*
                 * some other error occured
                 */
                if (mp_verbose > 0)
                    printf("SNMP error: respose->errstat = %ld",
                           response->errstat);

                rc = STAT_ERROR;
                //goto done;
                break;
            }
        } else {
            /* no response, assume an error */
            rc = STAT_ERROR;
            break;
        }
    }

    if (response)
        snmp_free_pdu(response);

    return rc;
}
コード例 #6
0
ファイル: agent_index.cpp プロジェクト: duniansampa/SigLog
netsnmp_variable_list *
register_index(netsnmp_variable_list * varbind, int flags,
               netsnmp_session * ss)
{
    netsnmp_variable_list *rv = NULL;
    struct snmp_index *new_index, *idxptr, *idxptr2;
    struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
    int             res, res2, i;

    DEBUGMSGTL(("register_index", "register "));
    DEBUGMSGVAR(("register_index", varbind));
    DEBUGMSG(("register_index", "for session %8p\n", ss));

#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_ROLE) == SUB_AGENT) {
        return (agentx_register_index(ss, varbind, flags));
    }
#endif
    /*
     * Look for the requested OID entry 
     */
    prev_oid_ptr = NULL;
    prev_idx_ptr = NULL;
    res = 1;
    res2 = 1;
    for (idxptr = snmp_index_head; idxptr != NULL;
         prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
        if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
                                    idxptr->varbind->name,
                                    idxptr->varbind->name_length)) <= 0)
            break;
    }

    /*
     * Found the OID - now look at the registered indices 
     */
    if (res == 0 && idxptr) {
        if (varbind->type != idxptr->varbind->type)
            return NULL;        /* wrong type */

        /*
         * If we've been asked for an arbitrary new value,
         *      then find the end of the list.
         * If we've been asked for any arbitrary value,
         *      then look for an unused entry, and use that.
         *      If there aren't any, continue as for new.
         * Otherwise, locate the given value in the (sorted)
         *      list of already allocated values
         */
        if (flags & ALLOCATE_ANY_INDEX) {
            for (idxptr2 = idxptr; idxptr2 != NULL;
                 prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {

                if (flags == ALLOCATE_ANY_INDEX && !(idxptr2->allocated)) {
                    if ((rv =
                         snmp_clone_varbind(idxptr2->varbind)) != NULL) {
                        idxptr2->session = ss;
                        idxptr2->allocated = 1;
                    }
                    return rv;
                }
            }
        } else {
            for (idxptr2 = idxptr; idxptr2 != NULL;
                 prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
                switch (varbind->type) {
                case ASN_INTEGER:
                    res2 =
                        (*varbind->val.integer -
                         *idxptr2->varbind->val.integer);
                    break;
                case ASN_OCTET_STR:
                    i = SNMP_MIN(varbind->val_len,
                                 idxptr2->varbind->val_len);
                    res2 =
                        memcmp(varbind->val.string,
                               idxptr2->varbind->val.string, i);
                    break;
                case ASN_OBJECT_ID:
                    res2 =
                        snmp_oid_compare(varbind->val.objid,
                                         varbind->val_len / sizeof(oid),
                                         idxptr2->varbind->val.objid,
                                         idxptr2->varbind->val_len /
                                         sizeof(oid));
                    break;
                default:
                    return NULL;        /* wrong type */
                }
                if (res2 <= 0)
                    break;
            }
            if (res2 == 0) {
                if (idxptr2->allocated) {
                    /*
                     * No good: the index is in use.  
                     */
                    return NULL;
                } else {
                    /*
                     * Okay, it's unallocated, we can just claim ownership
                     * here.  
                     */
                    if ((rv =
                         snmp_clone_varbind(idxptr2->varbind)) != NULL) {
                        idxptr2->session = ss;
                        idxptr2->allocated = 1;
                    }
                    return rv;
                }
            }
        }
    }

    /*
     * OK - we've now located where the new entry needs to
     *      be fitted into the index registry tree          
     * To recap:
     *      'prev_oid_ptr' points to the head of the OID index
     *          list prior to this one.  If this is null, then
     *          it means that this is the first OID in the list.
     *      'idxptr' points either to the head of this OID list,
     *          or the next OID (if this is a new OID request)
     *          These can be distinguished by the value of 'res'.
     *
     *      'prev_idx_ptr' points to the index entry that sorts
     *          immediately prior to the requested value (if any).
     *          If an arbitrary value is required, then this will
     *          point to the last allocated index.
     *          If this pointer is null, then either this is a new
     *          OID request, or the requested value is the first
     *          in the list.
     *      'idxptr2' points to the next sorted index (if any)
     *          but is not actually needed any more.
     *
     *  Clear?  Good!
     *      I hope you've been paying attention.
     *          There'll be a test later :-)
     */

    /*
     *      We proceed by creating the new entry
     *         (by copying the entry provided)
     */
    new_index = (struct snmp_index *) calloc(1, sizeof(struct snmp_index));
    if (new_index == NULL)
        return NULL;

    if (NULL == snmp_varlist_add_variable(&new_index->varbind,
                                          varbind->name,
                                          varbind->name_length,
                                          varbind->type,
                                          varbind->val.string,
                                          varbind->val_len)) {
        /*
         * if (snmp_clone_var( varbind, new_index->varbind ) != 0 ) 
         */
        free(new_index);
        return NULL;
    }
    new_index->session = ss;
    new_index->allocated = 1;

    if (varbind->type == ASN_OCTET_STR && flags == ALLOCATE_THIS_INDEX)
        new_index->varbind->val.string[new_index->varbind->val_len] = 0;

    /*
     * If we've been given a value, then we can use that, but
     *    otherwise, we need to create a new value for this entry.
     * Note that ANY_INDEX and NEW_INDEX are both covered by this
     *   test (since NEW_INDEX & ANY_INDEX = ANY_INDEX, remember?)
     */
    if (flags & ALLOCATE_ANY_INDEX) {
        if (prev_idx_ptr) {
            if (snmp_clone_var(prev_idx_ptr->varbind, new_index->varbind)
                != 0) {
                free(new_index);
                return NULL;
            }
        } else
            new_index->varbind->val.string = new_index->varbind->buf;

        switch (varbind->type) {
        case ASN_INTEGER:
            if (prev_idx_ptr) {
                (*new_index->varbind->val.integer)++;
            } else
                *(new_index->varbind->val.integer) = 1;
            new_index->varbind->val_len = sizeof(long);
            break;
        case ASN_OCTET_STR:
            if (prev_idx_ptr) {
                i = new_index->varbind->val_len - 1;
                while (new_index->varbind->buf[i] == 'z') {
                    new_index->varbind->buf[i] = 'a';
                    i--;
                    if (i < 0) {
                        i = new_index->varbind->val_len;
                        new_index->varbind->buf[i] = 'a';
                        new_index->varbind->buf[i + 1] = 0;
                    }
                }
                new_index->varbind->buf[i]++;
            } else
                strcpy((char *) new_index->varbind->buf, "aaaa");
            new_index->varbind->val_len =
                strlen((char *) new_index->varbind->buf);
            break;
        case ASN_OBJECT_ID:
            if (prev_idx_ptr) {
                i = prev_idx_ptr->varbind->val_len / sizeof(oid) - 1;
                while (new_index->varbind->val.objid[i] == 255) {
                    new_index->varbind->val.objid[i] = 1;
                    i--;
                    if (i == 0 && new_index->varbind->val.objid[0] == 2) {
                        new_index->varbind->val.objid[0] = 1;
                        i = new_index->varbind->val_len / sizeof(oid);
                        new_index->varbind->val.objid[i] = 0;
                        new_index->varbind->val_len += sizeof(oid);
                    }
                }
                new_index->varbind->val.objid[i]++;
            } else {
                /*
                 * If the requested OID name is small enough,
                 * *   append another OID (1) and use this as the
                 * *   default starting value for new indexes.
                 */
                if ((varbind->name_length + 1) * sizeof(oid) <= 40) {
                    for (i = 0; i < (int) varbind->name_length; i++)
                        new_index->varbind->val.objid[i] =
                            varbind->name[i];
                    new_index->varbind->val.objid[varbind->name_length] =
                        1;
                    new_index->varbind->val_len =
                        (varbind->name_length + 1) * sizeof(oid);
                } else {
                    /*
                     * Otherwise use '.1.1.1.1...' 
                     */
                    i = 40 / sizeof(oid);
                    if (i > 4)
                        i = 4;
                    new_index->varbind->val_len = i * (sizeof(oid));
                    for (i--; i >= 0; i--)
                        new_index->varbind->val.objid[i] = 1;
                }
            }
            break;
        default:
            snmp_free_var(new_index->varbind);
            free(new_index);
            return NULL;        /* Index type not supported */
        }
    }

    /*
     * Try to duplicate the new varbind for return.  
     */

    if ((rv = snmp_clone_varbind(new_index->varbind)) == NULL) {
        snmp_free_var(new_index->varbind);
        free(new_index);
        return NULL;
    }

    /*
     * Right - we've set up the new entry.
     * All that remains is to link it into the tree.
     * There are a number of possible cases here,
     *   so watch carefully.
     */
    if (prev_idx_ptr) {
        new_index->next_idx = prev_idx_ptr->next_idx;
        new_index->next_oid = prev_idx_ptr->next_oid;
        prev_idx_ptr->next_idx = new_index;
    } else {
        if (res == 0 && idxptr) {
            new_index->next_idx = idxptr;
            new_index->next_oid = idxptr->next_oid;
        } else {
            new_index->next_idx = NULL;
            new_index->next_oid = idxptr;
        }

        if (prev_oid_ptr) {
            while (prev_oid_ptr) {
                prev_oid_ptr->next_oid = new_index;
                prev_oid_ptr = prev_oid_ptr->next_idx;
            }
        } else
            snmp_index_head = new_index;
    }
    return rv;
}