📄 snmp_api.c
字号:
static void snmpv3_calc_msg_flags (int, int, u_char *);
static int snmpv3_verify_msg (struct request_list *, struct snmp_pdu *);
static int snmpv3_build_probe_pdu (struct snmp_pdu **);
static int snmpv3_build (struct snmp_session *, struct snmp_pdu *,
u_char *, size_t *);
#endif
static int snmp_parse_version (u_char *, size_t);
static int snmp_resend_request (struct session_list *slp,
struct request_list *rp,
int incr_retries);
#ifndef HAVE_STRERROR
const char *strerror(int err)
{
extern const char *sys_errlist[];
extern int sys_nerr;
if (err < 0 || err >= sys_nerr) return "Unknown error";
return sys_errlist[err];
}
#endif
long
snmp_get_next_reqid (void)
{
long retVal;
snmp_res_lock(MT_LIBRARY_ID, MT_LIB_REQUESTID);
retVal = 1 + Reqid; /*MTCRITICAL_RESOURCE*/
if (!retVal) retVal = 2;
Reqid = retVal;
snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_REQUESTID);
return retVal;
}
long
snmp_get_next_msgid (void)
{
long retVal;
snmp_res_lock(MT_LIBRARY_ID, MT_LIB_MESSAGEID);
retVal = 1 + Msgid; /*MTCRITICAL_RESOURCE*/
if (!retVal) retVal = 2;
Msgid = retVal;
snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_MESSAGEID);
return retVal;
}
long
snmp_get_next_sessid (void)
{
long retVal;
snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSIONID);
retVal = 1 + Sessid; /*MTCRITICAL_RESOURCE*/
if (!retVal) retVal = 2;
Sessid = retVal;
snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_SESSIONID);
return retVal;
}
long
snmp_get_next_transid (void)
{
long retVal;
snmp_res_lock(MT_LIBRARY_ID, MT_LIB_TRANSID);
retVal = 1 + Transid; /*MTCRITICAL_RESOURCE*/
if (!retVal) retVal = 2;
Transid = retVal;
snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_TRANSID);
return retVal;
}
void
snmp_perror(const char *prog_string)
{
const char *str;
int xerr;
xerr = snmp_errno; /*MTCRITICAL_RESOURCE*/
str = snmp_api_errstring(xerr);
snmp_log(LOG_ERR,"%s: %s\n",prog_string, str);
}
void
snmp_set_detail(const char *detail_string)
{
if (detail_string != NULL) {
strncpy((char *)snmp_detail, detail_string, sizeof(snmp_detail));
snmp_detail[sizeof(snmp_detail)-1] = '\0';
snmp_detail_f = 1;
}
}
/* returns pointer to static data */
/* results not guaranteed in multi-threaded use */
const char *
snmp_api_errstring(int snmp_errnumber)
{
const char *msg = "";
static char msg_buf [256];
if (snmp_errnumber >= SNMPERR_MAX && snmp_errnumber <= SNMPERR_GENERR){
msg = api_errors[-snmp_errnumber];
} else if (snmp_errnumber != SNMPERR_SUCCESS) {
msg = "Unknown Error";
}
if (snmp_detail_f) {
sprintf (msg_buf, "%s (%s)", msg, snmp_detail);
snmp_detail_f = 0;
}
else
strcpy(msg_buf,msg);
return (msg_buf);
}
/*
* snmp_error - return error data
* Inputs : address of errno, address of snmp_errno, address of string
* Caller must free the string returned after use.
*/
void
snmp_error(struct snmp_session *psess,
int *p_errno,
int *p_snmp_errno,
char **p_str)
{
char buf[SPRINT_MAX_LEN];
int snmp_errnumber;
if (p_errno) *p_errno = psess->s_errno;
if (p_snmp_errno) *p_snmp_errno = psess->s_snmp_errno;
if (p_str == NULL) return;
strcpy(buf, "");
snmp_errnumber = psess->s_snmp_errno;
if (snmp_errnumber >= SNMPERR_MAX && snmp_errnumber <= SNMPERR_GENERR){
strcpy(buf, api_errors[-snmp_errnumber]);
} else {
if (snmp_errnumber)
sprintf(buf, "Unknown Error %d", snmp_errnumber);
}
/* append a useful system errno interpretation. */
if (psess->s_errno)
sprintf (&buf[strlen(buf)], " (%s)", strerror(psess->s_errno));
*p_str = strdup(buf);
}
/*
* snmp_sess_error - same as snmp_error for single session API use.
*/
void
snmp_sess_error(void *sessp,
int *p_errno,
int *p_snmp_errno,
char **p_str)
{
struct session_list *slp = (struct session_list*)sessp;
if ((slp) && (slp->session))
snmp_error(slp->session, p_errno, p_snmp_errno, p_str);
}
/* snmp_sess_perror(): print a error stored in a session pointer */
void
snmp_sess_perror(const char *prog_string, struct snmp_session *ss) {
char *err;
snmp_error(ss, NULL, NULL, &err);
snmp_log(LOG_ERR, "%s: %s\n", prog_string, err);
free(err);
}
/*
* Primordial SNMP library initialization.
* Initializes mutex locks.
* Invokes minimum required initialization for displaying MIB objects.
* Gets initial request ID for all transactions,
* and finds which port SNMP over UDP uses.
* SNMP over AppleTalk or IPX is not currently supported.
*
* Warning: no debug messages here.
*/
static void
_init_snmp (void)
{
#ifdef HAVE_GETSERVBYNAME
struct servent *servp;
#endif
struct timeval tv;
long tmpReqid, tmpMsgid;
u_short s_port = SNMP_PORT;
if (Reqid) return;
Reqid = 1; /* quick set to avoid multiple inits */
snmp_res_init(); /* initialize the mt locking structures */
init_mib_internals();
gettimeofday(&tv,(struct timezone *)0);
/*Now = tv;*/
/* get pseudo-random values for request ID and message ID */
/* don't allow zero value to repeat init */
#ifdef SVR4
srand48(tv.tv_sec ^ tv.tv_usec);
tmpReqid = lrand48();
tmpMsgid = lrand48();
#else
srandom(tv.tv_sec ^ tv.tv_usec);
tmpReqid = random();
tmpMsgid = random();
#endif
if (tmpReqid == 0) tmpReqid = 1;
if (tmpMsgid == 0) tmpMsgid = 1;
Reqid = tmpReqid;
Msgid = tmpMsgid;
#ifdef HAVE_GETSERVBYNAME
servp = getservbyname("snmp", "udp");
if (servp) {
/* store it in host byte order */
s_port = ntohs(servp->s_port);
}
#endif
ds_set_int(DS_LIBRARY_ID, DS_LIB_DEFAULT_PORT, s_port);
}
/*
* Initializes the session structure.
* May perform one time minimal library initialization.
* No MIB file processing is done via this call.
*/
void
snmp_sess_init(struct snmp_session *session)
{
_init_snmp();
/* initialize session to default values */
memset(session, 0, sizeof(struct snmp_session));
session->remote_port = SNMP_DEFAULT_REMPORT;
session->timeout = SNMP_DEFAULT_TIMEOUT;
session->retries = SNMP_DEFAULT_RETRIES;
session->version = SNMP_DEFAULT_VERSION;
}
void
register_default_handlers(void) {
ds_register_config(ASN_BOOLEAN, "snmp","dumpPacket",
DS_LIBRARY_ID, DS_LIB_DUMP_PACKET);
ds_register_config(ASN_INTEGER, "snmp","defaultPort",
DS_LIBRARY_ID, DS_LIB_DEFAULT_PORT);
ds_register_config(ASN_OCTET_STR, "snmp","defCommunity",
DS_LIBRARY_ID, DS_LIB_COMMUNITY);
ds_register_premib(ASN_BOOLEAN, "snmp", "noTokenWarnings",
DS_LIBRARY_ID, DS_LIB_NO_TOKEN_WARNINGS);
ds_register_config(ASN_OCTET_STR, "snmp","noRangeCheck",
DS_LIBRARY_ID, DS_LIB_DONT_CHECK_RANGE );
}
/*******************************************************************-o-******
* init_snmp
*
* Parameters:
* *type Label for the config file "type" used by calling entity.
*
* Call appropriately the functions to do config file loading and
* mib module parsing in the correct order.
*/
void
init_snmp(const char *type)
{
static int done_init = 0; /* To prevent double init's. */
if (done_init) {
return;
}
done_init = 1;
_init_snmp();
/* set our current locale properly to initialize isprint() type functions */
#ifdef HAVE_SETLOCALE
setlocale(LC_CTYPE, "");
#endif
snmp_debug_init(); /* should be done first, to turn on debugging ASAP */
if ( type != NULL )
ds_set_string(DS_LIBRARY_ID, DS_LIB_APPTYPE, type);
init_callbacks();
init_snmp_logging();
snmp_init_statistics();
register_mib_handlers();
register_default_handlers();
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
init_snmpv3(type);
#endif
init_snmp_alarm();
read_premib_configs();
init_mib();
read_configs();
} /* end init_snmp() */
void
snmp_store(const char *type) {
DEBUGMSGTL(("snmp_store","storing stuff...\n"));
snmp_save_persistent(type);
snmp_call_callbacks(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, NULL);
snmp_clean_persistent(type);
}
/* snmp_shutdown(const char *type):
Parameters:
*type Label for the config file "type" used by calling entity.
Does the appropriate shutdown calls for the library, saving
persistent data, clean up, etc...
*/
void
snmp_shutdown(const char *type) {
snmp_store(type);
snmp_call_callbacks(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN, NULL);
snmp_close_sessions();
}
/*
* 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.
*/
struct snmp_session *
snmp_open(struct snmp_session *session)
{
struct session_list *slp;
slp = (struct session_list *)snmp_sess_open(session);
if (!slp) return NULL;
snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSION);
slp->next = Sessions;
Sessions = slp;
snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_SESSION);
return (slp->session);
}
/* extended open */
struct snmp_session *snmp_open_ex (
struct snmp_session *session,
int (*fpre_parse) (struct snmp_session *, snmp_ipaddr),
int (*fparse) (struct snmp_session *, struct snmp_pdu *, u_char *, size_t),
int (*fpost_parse) (struct snmp_session *, struct snmp_pdu *, int),
int (*fbuild) (struct snmp_session *, struct snmp_pdu *, u_char *, size_t *),
int (*fcheck) (u_char *, size_t )
)
{
struct session_list *slp;
slp = (struct session_list *)snmp_sess_open(session);
if (!slp) return NULL;
slp->internal->hook_pre = fpre_parse;
slp->internal->hook_parse = fparse;
slp->internal->hook_post = fpost_parse;
slp->internal->hook_build = fbuild;
slp->internal->check_packet = fcheck;
snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSION);
slp->next = Sessions;
Sessions = slp;
snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_SESSION);
return (slp->session);
}
static struct session_list *
_sess_copy( struct snmp_session *in_session)
{
struct session_list *slp;
struct snmp_internal_session *isp;
struct snmp_session *session;
char *cp;
u_char *ucp;
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
size_t i;
#endif
in_session->s_snmp_errno = 0;
in_session->s_errno = 0;
/* Copy session structure and link into list */
slp = (struct session_list *)calloc(1,sizeof(struct session_list));
if (slp == NULL) {
in_session->s_snmp_errno = SNMPERR_MALLOC;
return(NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -