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

📄 snmp_api.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }

    isp = (struct snmp_internal_session *)calloc(1,sizeof(struct snmp_internal_session));
    if (isp == NULL) { 
      snmp_sess_close(slp);
      in_session->s_snmp_errno = SNMPERR_MALLOC;
      return(NULL);
    }

    slp->internal = isp;
    slp->internal->sd = -1; /* mark it not set */
    slp->session = (struct snmp_session *)malloc(sizeof(struct snmp_session));
    if (slp->session == NULL) {
      snmp_sess_close(slp);
      in_session->s_snmp_errno = SNMPERR_MALLOC;
      return(NULL);
    }
    memmove(slp->session, in_session, sizeof(struct snmp_session));
    session = slp->session;

    /* zero out pointers so if we have to free the session we wont free mem
       owned by in_session */
    session->peername = NULL;
    session->community = NULL;
    session->contextEngineID = NULL;
    session->contextName = NULL;
    session->securityEngineID = NULL;
    session->securityName = NULL;
    session->securityAuthProto = NULL;
    session->securityPrivProto = NULL;
    /*
     * 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 (in_session->peername != NULL){
	session->peername = (char *)malloc(strlen(in_session->peername) + 1);
	if (session->peername == NULL) {
          snmp_sess_close(slp);
	  in_session->s_snmp_errno = SNMPERR_MALLOC;
          return(NULL);
        }
	strcpy(session->peername, in_session->peername);
    }

    /* Fill in defaults if necessary */
    if (in_session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
	ucp = (u_char *)malloc(in_session->community_len);
	if (ucp != NULL)
	    memmove(ucp, in_session->community, in_session->community_len);
    } else {
	if ((cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_COMMUNITY)) != NULL) {
	    session->community_len = strlen(cp);
	    ucp = (u_char *)malloc(session->community_len);
	    if (ucp)
		memmove(ucp, cp, session->community_len);
	}
	else {
#ifdef NO_ZEROLENGTH_COMMUNITY
	    session->community_len = strlen(DEFAULT_COMMUNITY);
	    ucp = (u_char *)malloc(session->community_len);
	    if (ucp)
		memmove(ucp, DEFAULT_COMMUNITY, session->community_len);
#else
	    ucp = (u_char *)strdup("");
#endif
	}
    }

    if (ucp == NULL) {
      snmp_sess_close(slp);
      in_session->s_snmp_errno = SNMPERR_MALLOC;
      return(NULL);
    }
    session->community = ucp;	/* replace pointer with pointer to new data */

#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
    if (session->securityLevel <= 0)
      session->securityLevel = ds_get_int(DS_LIBRARY_ID, DS_LIB_SECLEVEL);

    if (session->securityLevel == 0)
      session->securityLevel = SNMP_SEC_LEVEL_NOAUTH;

    if (in_session->securityAuthProtoLen > 0) {
      session->securityAuthProto = 
	(oid*)malloc(in_session->securityAuthProtoLen * sizeof(oid));
      if (session->securityAuthProto == NULL) {
	snmp_sess_close(slp);
	in_session->s_snmp_errno = SNMPERR_MALLOC;
	return(NULL);
      }
      memmove(session->securityAuthProto, in_session->securityAuthProto,
	      in_session->securityAuthProtoLen * sizeof(oid));
    } else if (get_default_authtype(&i) != NULL) {
        session->securityAuthProto =
          snmp_duplicate_objid(get_default_authtype(NULL), i);
        session->securityAuthProtoLen = i;
    }

    if (in_session->securityPrivProtoLen > 0) {
      session->securityPrivProto = 
	(oid*)malloc((unsigned)in_session->securityPrivProtoLen * sizeof(oid));
      if (session->securityPrivProto == NULL) {
	snmp_sess_close(slp);
	in_session->s_snmp_errno = SNMPERR_MALLOC;
	return(NULL);
      }
      memmove(session->securityPrivProto, in_session->securityPrivProto,
	      in_session->securityPrivProtoLen * sizeof(oid));
    } else if (get_default_privtype(&i) != NULL) {
        session->securityPrivProto =
          snmp_duplicate_objid(get_default_privtype(NULL), i);
        session->securityPrivProtoLen = i;
    }

    if (in_session->securityEngineIDLen > 0) {
      ucp = (u_char*)malloc((unsigned)in_session->securityEngineIDLen *
			   sizeof(u_char));
      if (ucp == NULL) {
	snmp_sess_close(slp);
	in_session->s_snmp_errno = SNMPERR_MALLOC;
	return(NULL);
      }
      memmove(ucp, in_session->securityEngineID,
	      in_session->securityEngineIDLen * sizeof(u_char));
      session->securityEngineID = ucp;

    }

    if (in_session->contextEngineIDLen > 0) {
      ucp = (u_char*)malloc((unsigned)in_session->contextEngineIDLen *
			   sizeof(u_char));
      if (ucp == NULL) {
	snmp_sess_close(slp);
	in_session->s_snmp_errno = SNMPERR_MALLOC;
	return(NULL);
      }
      memmove(ucp, in_session->contextEngineID,
	      in_session->contextEngineIDLen * sizeof(u_char));
      session->contextEngineID = ucp;
    } else if (in_session->securityEngineIDLen > 0) {
      /* default contextEngineID to securityEngineIDLen if defined */
      ucp = (u_char*)malloc((unsigned)in_session->securityEngineIDLen *
			   sizeof(u_char));
      if (ucp == NULL) {
	snmp_sess_close(slp);
	in_session->s_snmp_errno = SNMPERR_MALLOC;
	return(NULL);
      }
      memmove(ucp, in_session->securityEngineID,
	      in_session->securityEngineIDLen * sizeof(u_char));
      session->contextEngineID = ucp;
      session->contextEngineIDLen = in_session->securityEngineIDLen;
    }

    if (in_session->contextName) {
      session->contextName = strdup(in_session->contextName);
      if (session->contextName == NULL) {
	snmp_sess_close(slp);
	return(NULL);
      }
    } else if ((cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_CONTEXT)) != NULL) {
      cp = strdup(cp);
      if (cp == NULL) {
	snmp_sess_close(slp);
	return(NULL);
      }
      session->contextName = cp;
      session->contextNameLen = strlen(cp);
    } else {
      cp = strdup(SNMP_DEFAULT_CONTEXT);
      session->contextName = cp;
      session->contextNameLen = strlen(cp);
    }

    if (in_session->securityName) {
      session->securityName = strdup(in_session->securityName);
      if (session->securityName == NULL) {
	snmp_sess_close(slp);
	return(NULL);
      }
    } else if ((cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_SECNAME)) != NULL) {
      cp = strdup(cp);
      if (cp == NULL) {
	snmp_sess_close(slp);
	return(NULL);
      }
      session->securityName = cp;
      session->securityNameLen = strlen(cp);
    }

    if ((in_session->securityAuthKeyLen <= 0) &&
	(cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_AUTHPASSPHRASE))) {
      session->securityAuthKeyLen = USM_AUTH_KU_LEN;
      if (generate_Ku(session->securityAuthProto,
                      session->securityAuthProtoLen,
                      (u_char*)cp, strlen(cp),
                      session->securityAuthKey,
                      &session->securityAuthKeyLen) != SNMPERR_SUCCESS) {
        snmp_set_detail("Error generating Ku from authentication pass phrase.");
	snmp_sess_close(slp);
        return NULL;
      }
    }

    if ((in_session->securityPrivKeyLen <= 0) && 
	       (cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_PRIVPASSPHRASE))) {
      session->securityPrivKeyLen = USM_PRIV_KU_LEN;
      if (generate_Ku(session->securityAuthProto,
                      session->securityAuthProtoLen,
                      (u_char *)cp, strlen(cp),
                      session->securityPrivKey,
                      &session->securityPrivKeyLen) != SNMPERR_SUCCESS) {
        snmp_set_detail("Error generating Ku from privacy pass phrase.");
	snmp_sess_close(slp);
        return NULL;
      }
    }
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */

    if (session->retries == SNMP_DEFAULT_RETRIES)
	session->retries = DEFAULT_RETRIES;
    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
	session->timeout = DEFAULT_TIMEOUT;
    session->sessid = snmp_get_next_sessid();

    return( slp );
}

struct session_list *
snmp_sess_copy( struct snmp_session *pss)
{
    struct session_list * psl;
    psl = _sess_copy(pss);
    if ( !psl) {
        if ( !pss->s_snmp_errno)
	        pss->s_snmp_errno = SNMPERR_GENERR;
	    SET_SNMP_ERROR(pss->s_snmp_errno);
    }
    return psl;
}

/*******************************************************************-o-******
 * snmp_sess_open
 *
 * Parameters:
 *	*in_session
 *
 * Returns:
 *      Pointer to a session in the session list   -OR-		FIX -- right?
 *	NULL on failure.
 *
 * The "spin-free" version of snmp_open.
 */
static void *
_sess_open(struct snmp_session *in_session)
{
    struct session_list *slp;
    struct snmp_internal_session *isp;
    struct snmp_session *session;
    int sd;
    in_addr_t addr;
    struct sockaddr_in *isp_addr, *meIp;
#ifdef HAVE_GETHOSTBYNAME
    struct hostent *hp;
#endif
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
    struct snmp_pdu *pdu, *response;
    int status;
#endif
    size_t i, addr_size;
    char *cp = NULL;

    in_session->s_snmp_errno = 0;
    in_session->s_errno = 0;

    if (Reqid == 0)
      _init_snmp();

    if ((slp = snmp_sess_copy( in_session )) == NULL )
        return( NULL );
    isp     = slp->internal;
    session = slp->session;

    if ( isp->addr.sa_family == AF_UNSPEC ) {
        if ( session->peername && session->peername[0] == '/' ) {
#ifdef AF_UNIX
            isp->addr.sa_family = AF_UNIX;
            strcpy( isp->addr.sa_data, session->peername);
#else /* AF_UNIX */
            snmp_log(LOG_ERR,"%s:%d: _sess_open invalid session name %s- unix sockets not supported  \n",
                    __FILE__,__LINE__,
                    session->peername);
            return(NULL);
#endif /* AF_UNIX */
            
        } else {
            isp->addr.sa_family = AF_INET;
            isp_addr = (struct sockaddr_in *)&(isp->addr);
            if (session->peername != SNMP_DEFAULT_PEERNAME) {

			/* Try and extract an appended port number */
		cp = strchr( session->peername, ':' );
		if ( cp ) {
		    *cp = '\0';
		    cp++;
		    session->remote_port = atoi( cp );
		    if ( session->local_port )	/* i.e. server */
			session->local_port = session->remote_port;
		}

			/* Interpret the peername as an IP port ... */
		cp = strchr( session->peername, '.' );
		if ( !cp && (( i = atoi( session->peername )) != 0 )) {
		    session->remote_port = i;
		    if ( session->local_port )	/* i.e. server */
			session->local_port = session->remote_port;
		}

			/* ... failing that, as an IP address ... */
                else if ((int)(addr = inet_addr(session->peername)) != -1){
                    memmove(&isp_addr->sin_addr, &addr, sizeof(isp_addr->sin_addr));
                } else {
			/* .... failing that, as a hostname */
#ifdef HAVE_GETHOSTBYNAME
                    hp = gethostbyname(session->peername);
                    if (hp == NULL){
                        in_session->s_snmp_errno = SNMPERR_BAD_ADDRESS;
                        in_session->s_errno = errno;
                        snmp_set_detail(session->peername);
                        snmp_sess_close(slp);
                        return 0;
                    } else {
                        memmove(&isp_addr->sin_addr, hp->h_addr, hp->h_length);
                    }

#else /* HAVE_GETHOSTBYNAME */
                    snmp_log(LOG_ERR,"%s:%d: _sess_open do not have get host by name - cannot resolve %s \n",
                            __FILE__,__LINE__,
                            session->peername);
                    return(0);
#endif /* HAVE_GETHOSTBYNAME */

                }
                if (session->remote_port == SNMP_DEFAULT_REMPORT){
                    short iport = ds_get_int(DS_LIBRARY_ID, DS_LIB_DEFAULT_PORT);
                    isp_addr->sin_port = htons(iport);
                } else {
                    isp_addr->sin_port = htons(session->remote_port);
                }
            } else {
                isp_addr->sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
            }
        }
    }


    if ( session->local_port ) {
	/*
	 *  If the session structure includes a non-null value for
	 *    local_port, then this session is intended as a server.
	 *    This means that the isp->addr structure will not be 
	 *    needed to contact a remote entity.
	 *
	 *  By using this address as the local address to bind to,
	 *    we can provide a facility for listening on selected
	 *    (rather than all) interfaces.
	 */
	memcpy( &isp->me, &isp->addr, sizeof(isp->me));

	if ( isp->addr.sa_family == AF_INET ) {
			/*
			 * Remember to use the specified local port,
			 *   rather than the (default?) remote one.
			 * If no local interface address is specified,
			 *   default to listening on all interfaces,
			 *   rather than the default connection host
			 *   (SNMP_DEFAULT_ADDRESS)
			 */
	    meIp = (struct sockaddr_in*)&(isp->me);
	    meIp->sin_port = htons(session->local_port);
            if (session->peername == SNMP_DEFAULT_PEERNAME)
                meIp->sin_addr.s_addr = INADDR_ANY;
	}
    }
    else {
        memset(&isp->me, '\0', sizeof(isp->me));
        isp->me.sa_family = isp->addr.sa_family;
        if ( isp->me.sa_family == AF_INET ) {
	    meIp = (struct sockaddr_in*)&(isp->me);
            meIp->sin_addr.s_addr = INADDR_ANY;
            meIp->sin_port = htons(session->local_port);
        }
#ifdef AF_UNIX
        else if ( isp->me.sa_family == AF_UNIX ) {
    		/* Need a unique socket name */
#ifndef UNIX_SOCKET_BASE_NAME
#define UNIX_SOCKET_BASE_NAME  "/tmp/s."
#endif
    
#ifndef WIN32
                strcpy( isp->me.sa_data, UNIX_SOCKET_BASE_NAME );
                strcat( isp->me.sa_data, "XXXXXX" );
                mktemp( isp->me.sa_data );

⌨️ 快捷键说明

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