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

📄 snmp_api.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************** * *           Copyright 1997 by Carnegie Mellon University *  *                       All Rights Reserved *  * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of CMU not be * used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. *  * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY 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 THIS * SOFTWARE. *  **********************************************************************/#include "config.h"#include <stdio.h>#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_SYS_TYPES_H#include <sys/types.h>#endif#if HAVE_CTYPE_H#include <ctype.h>#endif#if HAVE_GNUMALLOC_H#include <gnumalloc.h>#elif HAVE_MALLOC_H && !defined(_SQUID_FREEBSD_) && !defined(_SQUID_NEXT_)#include <malloc.h>#endif#if HAVE_MEMORY_H#include <memory.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#if HAVE_BSTRING_H#include <bstring.h>#endif#if HAVE_SYS_SOCKET_H#include <sys/socket.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_TIME_H#include <sys/time.h>#endif#if HAVE_NETDB_H#include <netdb.h>#endif#include "asn1.h"#include "snmp.h"#include "snmp-internal.h"#include "snmp_impl.h"#include "snmp_session.h"#if 0#include "mibii.h"#include "snmp_dump.h"#endif#include "snmp_error.h"#include "snmp_vars.h"#include "snmp_pdu.h"#include "snmp_msg.h"#include "snmp_api.h"#if 0#include "snmp_client.h"#endif#include "snmp_api_error.h"#include "snmp_api_util.h"#include "util.h"extern int snmp_errno;/*#define DEBUG_API 1 *//* * RFC 1906: Transport Mappings for SNMPv2 */oid default_enterprise[] ={1, 3, 6, 1, 4, 1, 3, 1, 1};	/* enterprises.cmu.systems.cmuSNMP */#define DEFAULT_COMMUNITY   "public"#define DEFAULT_RETRIES	    4#define DEFAULT_TIMEOUT	    1000000L#define DEFAULT_REMPORT	    SNMP_PORT#define DEFAULT_ENTERPRISE  default_enterprise#define DEFAULT_TIME	    0extern int snmp_errno;struct session_list *Sessions = NULL;#if 0/* * Get initial request ID for all transactions. */static int Reqid = 0;static void init_snmp(void){    struct timeval tv;    gettimeofday(&tv, (struct timezone *) 0);    squid_srandom(tv.tv_sec ^ tv.tv_usec);    Reqid = squid_random();}/* * Free each element in the input request list. */static void free_request_list(rp)     struct request_list *rp;{    struct request_list *orp;    while (rp) {	orp = rp;	rp = rp->next_request;	if (orp->pdu != NULL)	    snmp_free_pdu(orp->pdu);	xfree((char *) orp);    }}#endif/**********************************************************************//* * Sets up the session with the snmp_session information provided * by the user.  Then opens and binds the necessary UDP port. * A handle to the created session is returned (this is different than * the pointer passed to snmp_open()).  On any error, NULL is returned * and snmp_errno is set to the appropriate error code. */#if 0struct snmp_session *snmp_open(struct snmp_session *session){    struct session_list *slp;    struct snmp_internal_session *isp;    u_char *cp;    int sd;    u_int addr;    struct sockaddr_in me;    struct hostent *hp;    struct servent *servp;    if (Reqid == 0)	init_snmp();    /* Copy session structure and link into list */    slp = (struct session_list *) xmalloc(sizeof(struct session_list));    if (slp == NULL) {	snmp_set_api_error(SNMPERR_OS_ERR);	return (NULL);    }    /* Internal session */    isp = (struct snmp_internal_session *) xmalloc(sizeof(struct snmp_internal_session));    if (isp == NULL) {	xfree(slp);	snmp_set_api_error(SNMPERR_OS_ERR);	return (NULL);    }    slp->internal = isp;    memset((char *) isp, '\0', sizeof(struct snmp_internal_session));    slp->internal->sd = -1;	/* mark it not set */    /* The actual session */    slp->session = (struct snmp_session *) xmalloc(sizeof(struct snmp_session));    if (slp->session == NULL) {	xfree(isp);	xfree(slp);	snmp_set_api_error(SNMPERR_OS_ERR);	return (NULL);    }    xmemcpy((char *) slp->session, (char *) session, sizeof(struct snmp_session));    session = slp->session;    /* now link it in. */    slp->next = Sessions;    Sessions = slp;    /*     * session now points to the new structure that still contains pointers to     * data allocated elsewhere.  Some of this data is copied to space malloc'd     * here, and the pointer replaced with the new one.     */    if (session->peername != NULL) {	cp = (u_char *) xmalloc((unsigned) strlen(session->peername) + 1);	if (cp == NULL) {	    xfree(slp->session);	    xfree(isp);	    xfree(slp);	    snmp_set_api_error(SNMPERR_OS_ERR);	    return (NULL);	}	strcpy((char *) cp, session->peername);	session->peername = (char *) cp;    }    /* Fill in defaults if necessary */    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN) {	cp = (u_char *) xmalloc((unsigned) session->community_len);	if (cp)	    xmemcpy((char *) cp, (char *) session->community, session->community_len);    } else {	session->community_len = strlen(DEFAULT_COMMUNITY);	cp = (u_char *) xmalloc((unsigned) session->community_len);	if (cp)	    xmemcpy((char *) cp, (char *) DEFAULT_COMMUNITY,		session->community_len);    }    if (cp == NULL) {	xfree(session->peername);	xfree(slp->session);	xfree(isp);	xfree(slp);	snmp_set_api_error(SNMPERR_OS_ERR);	return (NULL);    }    session->community = cp;	/* replace pointer with pointer to new data */    if (session->retries == SNMP_DEFAULT_RETRIES)	session->retries = DEFAULT_RETRIES;    if (session->timeout == SNMP_DEFAULT_TIMEOUT)	session->timeout = DEFAULT_TIMEOUT;    isp->requests = NULL;    /* Set up connections */    sd = socket(AF_INET, SOCK_DGRAM, 0);    if (sd < 0) {	perror("socket");	snmp_set_api_error(SNMPERR_OS_ERR);	if (!snmp_close(session)) {	    snmplib_debug(5, "Couldn't abort session: %s. Exiting\n",		api_errstring(snmp_errno));	    exit(1);	}	return (NULL);    }#ifdef SO_BSDCOMPAT    /* Patch for Linux.  Without this, UDP packets that fail get an ICMP     * response.  Linux turns the failed ICMP response into an error message     * and return value, unlike all other OS's.     */    {	int one = 1;	setsockopt(sd, SOL_SOCKET, SO_BSDCOMPAT, &one, sizeof(one));    }#endif /* SO_BSDCOMPAT */    isp->sd = sd;    if (session->peername != SNMP_DEFAULT_PEERNAME) {	if ((addr = inet_addr(session->peername)) != -1) {	    xmemcpy((char *) &isp->addr.sin_addr, (char *) &addr,		sizeof(isp->addr.sin_addr));	} else {	    hp = gethostbyname(session->peername);	    if (hp == NULL) {		snmplib_debug(3, "unknown host: %s\n", session->peername);		snmp_errno = SNMPERR_BAD_ADDRESS;		if (!snmp_close(session)) {		    snmplib_debug(3, "Couldn't abort session: %s. Exiting\n",			api_errstring(snmp_errno));		    exit(2);		}		return (NULL);	    } else {		xmemcpy((char *) &isp->addr.sin_addr, (char *) hp->h_addr,		    hp->h_length);	    }	}	isp->addr.sin_family = AF_INET;	if (session->remote_port == SNMP_DEFAULT_REMPORT) {	    servp = getservbyname("snmp", "udp");	    if (servp != NULL) {		isp->addr.sin_port = servp->s_port;	    } else {		isp->addr.sin_port = htons(SNMP_PORT);	    }	} else {	    isp->addr.sin_port = htons(session->remote_port);	}    } else {	isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;    }    memset(&me, '\0', sizeof(me));    me.sin_family = AF_INET;    me.sin_addr.s_addr = INADDR_ANY;    me.sin_port = htons(session->local_port);    if (bind(sd, (struct sockaddr *) &me, sizeof(me)) != 0) {	perror("bind");	snmp_errno = SNMPERR_BAD_LOCPORT;	if (!snmp_close(session)) {	    snmplib_debug(3, "Couldn't abort session: %s. Exiting\n",		api_errstring(snmp_errno));	    exit(3);	}	return (NULL);    }    return (session);}/* * Close the input session.  Frees all data allocated for the session, * dequeues any pending requests, and closes any sockets allocated for * the session.  Returns 0 on error, 1 otherwise. */int snmp_close(struct snmp_session *session){    struct session_list *slp = NULL, *oslp = NULL;    if (Sessions->session == session) {		/* If first entry */	slp = Sessions;	Sessions = slp->next;    } else {	for (slp = Sessions; slp; slp = slp->next) {	    if (slp->session == session) {		if (oslp)	/* if we found entry that points here */		    oslp->next = slp->next;	/* link around this entry */		break;	    }	    oslp = slp;	}    }    /* If we found the session, free all data associated with it */    if (slp) {	if (slp->session->community != NULL)	    xfree((char *) slp->session->community);	if (slp->session->peername != NULL)	    xfree((char *) slp->session->peername);	xfree((char *) slp->session);	if (slp->internal->sd != -1)	    close(slp->internal->sd);	free_request_list(slp->internal->requests);	xfree((char *) slp->internal);	xfree((char *) slp);    } else {	snmp_errno = SNMPERR_BAD_SESSION;	return (0);    }    return (1);}#endif/* * Takes a session and a pdu and serializes the ASN PDU into the area * pointed to by packet.  out_length is the size of the data area available. * Returns the length of the encoded packet in out_length.  If an error * occurs, -1 is returned.  If all goes well, 0 is returned. */intsnmp_build(session, pdu, packet, out_length)     struct snmp_session *session;     struct snmp_pdu *pdu;     u_char *packet;     int *out_length;{    u_char *bufp;    bufp = snmp_msg_Encode(packet, out_length,	session->community, session->community_len,	session->Version,	pdu);    snmplib_debug(8, "LIBSNMP: snmp_build():  Packet len %d (requid %d)\n",	*out_length, pdu->reqid);    if (bufp == NULL)	return (-1);    return (0);}/* * Parses the packet recieved on the input session, and places the data into * the input pdu.  length is the length of the input packet.  If any errors * are encountered, NULL is returned.  If not, the community is. */u_char *snmp_parse(struct snmp_session * session,    struct snmp_pdu * pdu,    u_char * data,    int length){    u_char Community[128];    u_char *bufp;    int CommunityLen = 128;    /* Decode the entire message. */    data = snmp_msg_Decode(data, &length,	Community, &CommunityLen,	&session->Version, pdu);    if (data == NULL)	return (NULL);    bufp = (u_char *) xmalloc(CommunityLen + 1);    if (bufp == NULL)	return (NULL);    strcpy((char *) bufp, (char *) Community);    return (bufp);}/* * Sends the input pdu on the session after calling snmp_build to create * a serialized packet.  If necessary, set some of the pdu data from the * session defaults.  Add a request corresponding to this pdu to the list

⌨️ 快捷键说明

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