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

📄 snmp_client.c

📁 snmp up 2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * snmp_client.c - a toolkit of common functions for an SNMP client. * *//**********************************************************************	Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University                      All Rights ReservedPermission to use, copy, modify, and distribute this software and itsdocumentation for any purpose and without fee is hereby granted,provided that the above copyright notice appear in all copies and thatboth that copyright notice and this permission notice appear insupporting documentation, and that the name of CMU not beused in advertising or publicity pertaining to distribution of thesoftware without specific, written prior permission.CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDINGALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALLCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ORANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THISSOFTWARE.******************************************************************/#include <net-snmp/net-snmp-config.h>#include <stdio.h>#include <errno.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#include <sys/types.h>#if TIME_WITH_SYS_TIME# ifdef WIN32#  include <sys/timeb.h># else#  include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#if HAVE_SYS_SELECT_H#include <sys/select.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#if HAVE_WINSOCK_H#include <winsock.h>#endif#include <net-snmp/types.h>#include <net-snmp/library/snmp_api.h>#include <net-snmp/library/snmp_client.h>#include <net-snmp/library/snmp_secmod.h>#include <net-snmp/library/mib.h>#ifndef BSD4_3#define BSD4_2#endif#ifndef FD_SETtypedef long    fd_mask;#define NFDBITS	(sizeof(fd_mask) * NBBY)        /* bits per mask */#define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))#define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))#define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))#define FD_ZERO(p)	memset((p), 0, sizeof(*(p)))#endif/* * Prototype definitions  */static int      snmp_synch_input(int op, netsnmp_session * session,                                 int reqid, netsnmp_pdu *pdu, void *magic);netsnmp_pdu    *snmp_pdu_create(int command){    netsnmp_pdu    *pdu;    pdu = (netsnmp_pdu *) calloc(1, sizeof(netsnmp_pdu));    if (pdu) {        pdu->version = SNMP_DEFAULT_VERSION;        pdu->command = command;        pdu->errstat = SNMP_DEFAULT_ERRSTAT;        pdu->errindex = SNMP_DEFAULT_ERRINDEX;        pdu->securityModel = SNMP_DEFAULT_SECMODEL;        pdu->transport_data = NULL;        pdu->transport_data_length = 0;        pdu->securityNameLen = 0;        pdu->contextNameLen = 0;        pdu->time = 0;        pdu->reqid = snmp_get_next_reqid();        pdu->msgid = snmp_get_next_msgid();    }    return pdu;}/* * Add a null variable with the requested name to the end of the list of * variables for this pdu. */netsnmp_variable_list *snmp_add_null_var(netsnmp_pdu *pdu, oid * name, size_t name_length){    return snmp_pdu_add_variable(pdu, name, name_length, ASN_NULL, NULL, 0);}static intsnmp_synch_input(int op,                 netsnmp_session * session,                 int reqid, netsnmp_pdu *pdu, void *magic){    struct synch_state *state = (struct synch_state *) magic;    int             rpt_type;    if (reqid != state->reqid && pdu && pdu->command != SNMP_MSG_REPORT) {        return 0;    }    state->waiting = 0;    if (op == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {        if (pdu->command == SNMP_MSG_REPORT) {            rpt_type = snmpv3_get_report_type(pdu);            if (SNMPV3_IGNORE_UNAUTH_REPORTS ||                rpt_type == SNMPERR_NOT_IN_TIME_WINDOW) {                state->waiting = 1;            }            state->pdu = NULL;            state->status = STAT_ERROR;            session->s_snmp_errno = rpt_type;            SET_SNMP_ERROR(rpt_type);        } else if (pdu->command == SNMP_MSG_RESPONSE) {            /*             * clone the pdu to return to snmp_synch_response              */            state->pdu = snmp_clone_pdu(pdu);            state->status = STAT_SUCCESS;            session->s_snmp_errno = SNMPERR_SUCCESS;        }    } else if (op == NETSNMP_CALLBACK_OP_TIMED_OUT) {        state->pdu = NULL;        state->status = STAT_TIMEOUT;        session->s_snmp_errno = SNMPERR_TIMEOUT;        SET_SNMP_ERROR(SNMPERR_TIMEOUT);    } else if (op == NETSNMP_CALLBACK_OP_DISCONNECT) {        state->pdu = NULL;        state->status = STAT_ERROR;        session->s_snmp_errno = SNMPERR_ABORT;        SET_SNMP_ERROR(SNMPERR_ABORT);    }    return 1;}/* * Clone an SNMP variable data structure. * Sets pointers to structure private storage, or * allocates larger object identifiers and values as needed. * * Caller must make list association for cloned variable. * * Returns 0 if successful. */intsnmp_clone_var(netsnmp_variable_list * var, netsnmp_variable_list * newvar){    if (!newvar || !var)        return 1;    memmove(newvar, var, sizeof(netsnmp_variable_list));    newvar->next_variable = 0;    newvar->name = 0;    newvar->val.string = 0;    newvar->data = 0;    newvar->dataFreeHook = 0;    newvar->index = 0;    /*     * Clone the object identifier and the value.     * Allocate memory iff original will not fit into local storage.     */    if (snmp_set_var_objid(newvar, var->name, var->name_length))        return 1;    /*     * need a pointer and a length to copy a string value.      */    if (var->val.string && var->val_len) {        if (var->val.string != &var->buf[0]) {            if (var->val_len <= sizeof(var->buf))                newvar->val.string = newvar->buf;            else {                newvar->val.string = (u_char *) malloc(var->val_len);                if (!newvar->val.string)                    return 1;            }            memmove(newvar->val.string, var->val.string, var->val_len);        } else {                /* fix the pointer to new local store */            newvar->val.string = newvar->buf;        }    } else {        newvar->val.string = 0;        newvar->val_len = 0;    }    return 0;}/* * Possibly make a copy of source memory buffer. * Will reset destination pointer if source pointer is NULL. * Returns 0 if successful, 1 if memory allocation fails. */intsnmp_clone_mem(void **dstPtr, void *srcPtr, unsigned len){    *dstPtr = 0;    if (srcPtr) {        *dstPtr = malloc(len + 1);        if (!*dstPtr) {            return 1;        }        memmove(*dstPtr, srcPtr, len);        /*         * this is for those routines that expect 0-terminated strings!!!         * someone should rather have called strdup         */        ((char *) *dstPtr)[len] = 0;    }    return 0;}/* * Walks through a list of varbinds and frees and allocated memory, * restoring pointers to local buffers */voidsnmp_reset_var_buffers(netsnmp_variable_list * var){    while (var) {        if (var->name != var->name_loc) {            free(var->name);            var->name = var->name_loc;            var->name_length = 0;        }        if (var->val.string != var->buf) {            free(var->val.string);            var->val.string = var->buf;            var->val_len = 0;        }        var = var->next_variable;    }}/* * Creates and allocates a clone of the input PDU, * but does NOT copy the variables. * This function should be used with another function, * such as _copy_pdu_vars. * * Returns a pointer to the cloned PDU if successful. * Returns 0 if failure. */staticnetsnmp_pdu    *_clone_pdu_header(netsnmp_pdu *pdu){    netsnmp_pdu    *newpdu;    struct snmp_secmod_def *sptr;    newpdu = (netsnmp_pdu *) malloc(sizeof(netsnmp_pdu));    if (!newpdu)        return 0;    memmove(newpdu, pdu, sizeof(netsnmp_pdu));    /*     * reset copied pointers if copy fails      */    newpdu->variables = 0;    newpdu->enterprise = 0;    newpdu->community = 0;    newpdu->securityEngineID = 0;    newpdu->securityName = 0;    newpdu->contextEngineID = 0;    newpdu->contextName = 0;    newpdu->transport_data = 0;    /*     * copy buffers individually. If any copy fails, all are freed.      */    if (snmp_clone_mem((void **) &newpdu->enterprise, pdu->enterprise,                       sizeof(oid) * pdu->enterprise_length) ||        snmp_clone_mem((void **) &newpdu->community, pdu->community,                       pdu->community_len) ||        snmp_clone_mem((void **) &newpdu->contextEngineID,                       pdu->contextEngineID, pdu->contextEngineIDLen)        || snmp_clone_mem((void **) &newpdu->securityEngineID,                          pdu->securityEngineID, pdu->securityEngineIDLen)        || snmp_clone_mem((void **) &newpdu->contextName, pdu->contextName,                          pdu->contextNameLen)        || snmp_clone_mem((void **) &newpdu->securityName,                          pdu->securityName, pdu->securityNameLen)        || snmp_clone_mem((void **) &newpdu->transport_data,                          pdu->transport_data,                          pdu->transport_data_length)) {        snmp_free_pdu(newpdu);        return 0;    }    if ((sptr = find_sec_mod(newpdu->securityModel)) != NULL &&        sptr->pdu_clone != NULL) {        /*         * call security model if it needs to know about this          */        (*sptr->pdu_clone) (pdu, newpdu);    }    return newpdu;}staticnetsnmp_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;}/* * Copy some or all variables from source PDU to target PDU. * This function consolidates many of the needs of PDU variables: * Clone PDU : copy all the variables. * Split PDU : skip over some variables to copy other variables. * Fix PDU   : remove variable associated with error index. * * Designed to work with _clone_pdu_header. * * If drop_err is set, drop any variable associated with errindex. * If skip_count is set, skip the number of variable in pdu's list. * While copy_count is greater than zero, copy pdu variables to newpdu. * * If an error occurs, newpdu is freed and pointer is set to 0. * * Returns a pointer to the cloned PDU if successful. * Returns 0 if failure. */staticnetsnmp_pdu    *_copy_pdu_vars(netsnmp_pdu *pdu,        /* source PDU */               netsnmp_pdu *newpdu,     /* target PDU */               int drop_err,    /* !=0 drop errored variable */               int skip_count,  /* !=0 number of variables to skip */               int copy_count){                               /* !=0 number of variables to copy */    netsnmp_variable_list *var, *oldvar;    int             ii, copied, drop_idx;    if (!newpdu)        return 0;               /* where is PDU to copy to ? */    if (drop_err)        drop_idx = pdu->errindex - skip_count;    else        drop_idx = 0;    var = pdu->variables;    while (var && (skip_count-- > 0))   /* skip over pdu variables */        var = var->next_variable;    oldvar = 0;    ii = 0;    copied = 0;    if (pdu->flags & UCD_MSG_FLAG_FORCE_PDU_COPY)        copied = 1;             /* We're interested in 'empty' responses too */    newpdu->variables = _copy_varlist(var, drop_idx, copy_count);    if (newpdu->variables)        copied = 1;#if ALSO_TEMPORARILY_DISABLED    /*     * Error if bad errindex or if target PDU has no variables copied      */

⌨️ 快捷键说明

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