📄 snmp_api.c
字号:
//==========================================================================
//
// ./lib/current/src/snmp_api.c
//
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//####UCDSNMPCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from the UCD-SNMP
// project, <http://ucd-snmp.ucdavis.edu/> from the University of
// California at Davis, which was originally based on the Carnegie Mellon
// University SNMP implementation. Portions of this software are therefore
// covered by the appropriate copyright disclaimers included herein.
//
// The release used was version 4.1.2 of May 2000. "ucd-snmp-4.1.2"
// -------------------------------------------
//
//####UCDSNMPCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): hmt
// Contributors: hmt
// Date: 2000-05-30
// Purpose: Port of UCD-SNMP distribution to eCos.
// Description:
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
/********************************************************************
Copyright 1989, 1991, 1992 by Carnegie Mellon University
Derivative Work -
Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
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 appears in all copies and
that both that copyright notice and this permission notice appear in
supporting documentation, and that the name of CMU and The Regents of
the University of California not be used in advertising or publicity
pertaining to distribution of the software without specific written
permission.
CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CMU OR
THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
FROM THE 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.
*********************************************************************/
/******************************************************************
Copyright 1989, 1991, 1992 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.
******************************************************************/
/*
* snmp_api.c - API for access to snmp.
*/
#include <config.h>
#include <stdio.h>
#include <ctype.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 HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#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_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_WINSOCK_H
#include <winsock.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#ifdef __ECOS
# ifdef AF_UNIX
# undef AF_UNIX // eCos does not support local sockets
# endif // AF_UNIX
#endif // __ECOS
#endif
#if HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#if HAVE_NET_IF_DL_H
#include <net/if_dl.h>
#endif
#include <errno.h>
#if HAVE_LOCALE_H
#include <locale.h>
#endif
#if HAVE_DMALLOC_H
#include <dmalloc.h>
#endif
#include "asn1.h"
#include "snmp.h"
#define SNMP_NEED_REQUEST_LIST
#include "snmp_api.h"
#include "snmp_client.h"
#include "snmp_impl.h"
#include "parse.h"
#include "mib.h"
#include "system.h"
#include "int64.h"
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
#include "snmpv3.h"
#endif
#include "read_config.h"
#include "snmp_debug.h"
#include "callback.h"
#include "tools.h"
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
#include "snmpusm.h"
#include "keytools.h"
#include "lcd_time.h"
#endif
#include "snmp_alarm.h"
#include "snmp_logging.h"
#include "default_store.h"
#include "mt_support.h"
static void _init_snmp (void);
#include "transform_oids.h"
#ifndef timercmp
#define timercmp(tvp, uvp, cmp) \ /* CSTYLED */ \ ((tvp)->tv_sec cmp (uvp)->tv_sec || \ ((tvp)->tv_sec == (uvp)->tv_sec && \ /* CSTYLED */ \ (tvp)->tv_usec cmp (uvp)->tv_usec))
#endif
#ifndef timerclear
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif
/*
* Globals.
*/
#define PACKET_LENGTH (8 * 1024)
#define MAX_PACKET_LENGTH (32768)
#ifndef SNMP_STREAM_QUEUE_LEN
#define SNMP_STREAM_QUEUE_LEN 5
#endif
#ifndef BSD4_3
#define BSD4_2
#endif
#ifndef FD_SET
typedef 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
static oid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1};
/* enterprises.cmu.systems.cmuSNMP */
#define DEFAULT_COMMUNITY "public"
#define DEFAULT_RETRIES 5
#define DEFAULT_TIMEOUT 1000000L
#define DEFAULT_REMPORT SNMP_PORT
#define DEFAULT_ENTERPRISE default_enterprise
#define DEFAULT_TIME 0
/*
* Internal information about the state of the snmp session.
*/
struct snmp_internal_session {
int sd; /* socket descriptor for this connection */
snmp_ipaddr addr; /* address of connected peer */
snmp_ipaddr me; /* address of local socket */
struct request_list *requests;/* Info about outstanding requests */
struct request_list *requestsEnd; /* ptr to end of list */
int (*hook_pre) ( struct snmp_session*, snmp_ipaddr);
int (*hook_parse)( struct snmp_session *, struct snmp_pdu *, u_char *, size_t);
int (*hook_post) ( struct snmp_session*, struct snmp_pdu*, int );
int (*hook_build)( struct snmp_session *, struct snmp_pdu *, u_char *, size_t *);
int (*check_packet) ( u_char *, size_t );
u_char *packet;
long packet_len, proper_len;
size_t packet_size;
char newpkt;
};
/*
* The list of active/open sessions.
*/
struct session_list {
struct session_list *next;
struct snmp_session *session;
struct snmp_internal_session *internal;
};
static const char *api_errors[-SNMPERR_MAX+1] = {
"No error", /* SNMPERR_SUCCESS */
"Generic error", /* SNMPERR_GENERR */
"Invalid local port", /* SNMPERR_BAD_LOCPORT */
"Unknown host", /* SNMPERR_BAD_ADDRESS */
"Unknown session", /* SNMPERR_BAD_SESSION */
"Too long", /* SNMPERR_TOO_LONG */
"No socket", /* SNMPERR_NO_SOCKET */
"Cannot send V2 PDU on V1 session", /* SNMPERR_V2_IN_V1 */
"Cannot send V1 PDU on V2 session", /* SNMPERR_V1_IN_V2 */
"Bad value for non-repeaters", /* SNMPERR_BAD_REPEATERS */
"Bad value for max-repetitions", /* SNMPERR_BAD_REPETITIONS */
"Error building ASN.1 representation", /* SNMPERR_BAD_ASN1_BUILD */
"Failure in sendto", /* SNMPERR_BAD_SENDTO */
"Bad parse of ASN.1 type", /* SNMPERR_BAD_PARSE */
"Bad version specified", /* SNMPERR_BAD_VERSION */
"Bad source party specified", /* SNMPERR_BAD_SRC_PARTY */
"Bad destination party specified", /* SNMPERR_BAD_DST_PARTY */
"Bad context specified", /* SNMPERR_BAD_CONTEXT */
"Bad community specified", /* SNMPERR_BAD_COMMUNITY */
"Cannot send noAuth/desPriv", /* SNMPERR_NOAUTH_DESPRIV */
"Bad ACL definition", /* SNMPERR_BAD_ACL */
"Bad Party definition", /* SNMPERR_BAD_PARTY */
"Session abort failure", /* SNMPERR_ABORT */
"Unknown PDU type", /* SNMPERR_UNKNOWN_PDU */
"Timeout", /* SNMPERR_TIMEOUT */
"Failure in recvfrom", /* SNMPERR_BAD_RECVFROM */
"Unable to determine contextEngineID", /* SNMPERR_BAD_ENG_ID */
"Unable to determine securityName", /* SNMPERR_BAD_SEC_NAME */
"Unable to determine securityLevel", /* SNMPERR_BAD_SEC_LEVEL */
"ASN.1 parse error in message", /* SNMPERR_ASN_PARSE_ERR */
"Unknown security model in message", /* SNMPERR_UNKNOWN_SEC_MODEL */
"Invalid message (e.g. msgFlags)", /* SNMPERR_INVALID_MSG */
"Unknown engine ID", /* SNMPERR_UNKNOWN_ENG_ID */
"Unknown user name", /* SNMPERR_UNKNOWN_USER_NAME */
"Unsupported security level", /* SNMPERR_UNSUPPORTED_SEC_LEVEL */
"Authentication failure", /* SNMPERR_AUTHENTICATION_FAILURE */
"Not in time window", /* SNMPERR_NOT_IN_TIME_WINDOW */
"Decryption error", /* SNMPERR_DECRYPTION_ERR */
"SCAPI general failure", /* SNMPERR_SC_GENERAL_FAILURE */
"SCAPI sub-system not configured", /* SNMPERR_SC_NOT_CONFIGURED */
"Key tools not available", /* SNMPERR_KT_NOT_AVAILABLE */
"Unknown Report message", /* SNMPERR_UNKNOWN_REPORT */
"USM generic error", /* SNMPERR_USM_GENERICERROR */
"USM unknown security name", /* SNMPERR_USM_UNKNOWNSECURITYNAME */
"USM unsupported security level", /* SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL */
"USM encryption error", /* SNMPERR_USM_ENCRYPTIONERROR */
"USM authentication failure", /* SNMPERR_USM_AUTHENTICATIONFAILURE */
"USM parse error", /* SNMPERR_USM_PARSEERROR */
"USM unknown engineID", /* SNMPERR_USM_UNKNOWNENGINEID */
"USM not in time window", /* SNMPERR_USM_NOTINTIMEWINDOW */
"USM decryption error", /* SNMPERR_USM_DECRYPTIONERROR */
"MIB not initialized", /* SNMPERR_NOMIB */
"Value out of range", /* SNMPERR_RANGE */
"Sub-id out of range", /* SNMPERR_MAX_SUBID */
"Bad sub-id in object identifier", /* SNMPERR_BAD_SUBID */
"Object identifier too long", /* SNMPERR_LONG_OID */
"Bad value name", /* SNMPERR_BAD_NAME */
"Bad value notation", /* SNMPERR_VALUE */
"Unknown Object Identifier", /* SNMPERR_UNKNOWN_OBJID */
"No PDU in snmp_send", /* SNMPERR_NULL_PDU */
"Missing variables in PDU", /* SNMPERR_NO_VARS */
"Bad variable type", /* SNMPERR_VAR_TYPE */
"Out of memory (malloc failure)", /* SNMPERR_MALLOC */
};
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
static const char * usmSecLevelName[] =
{
"BAD_SEC_LEVEL",
"noAuthNoPriv",
"authNoPriv",
"authPriv"
};
#endif
/*
* Multiple threads may changes these variables.
* Suggest using the Single API, which does not use Sessions.
*
* Reqid may need to be protected. Time will tell...
*
*/
/*MTCRITICAL_RESOURCE*/
/* use token in comments to individually protect these resources */
struct session_list *Sessions = NULL; /* MT_LIB_SESSION */
static long Reqid = 0; /* MT_LIB_REQUESTID */
static long Msgid = 0; /* MT_LIB_MESSAGEID */
static long Sessid = 0; /* MT_LIB_SESSIONID */
static long Transid = 0; /* MT_LIB_TRANSID */
int snmp_errno = 0;
/*END MTCRITICAL_RESOURCE*/
/*struct timeval Now;*/
/*
* global error detail storage
*/
static char snmp_detail[192];
static int snmp_detail_f = 0;
/*
* Prototypes.
*/
int snmp_build (struct snmp_session *, struct snmp_pdu *, u_char *, size_t *);
static int snmp_parse (void *, struct snmp_session *, struct snmp_pdu *, u_char *, size_t);
static void * snmp_sess_pointer (struct snmp_session *);
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -