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

📄 snmp_api.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
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 + -