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

📄 snmp_api.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif
        }
#endif /* AF_UNIX */
    }
    addr_size = snmp_socket_length(isp->me.sa_family);

    /* Set up connections */
    if ( session->flags & SNMP_FLAGS_STREAM_SOCKET ) {
        if ( session->local_port != 0 )
            session->flags |= SNMP_FLAGS_LISTENING;
        sd = socket(isp->me.sa_family, SOCK_STREAM, 0);
    }
    else
        sd = socket(isp->me.sa_family, SOCK_DGRAM, 0);
    if (sd < 0){
	in_session->s_snmp_errno = SNMPERR_NO_SOCKET;
	in_session->s_errno = errno;
	snmp_set_detail(strerror(errno));
	snmp_sess_close(slp);
	return 0;
    }
    isp->sd = sd;

#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 */

//#ifndef __ECOS
#ifndef SERVER_REQUIRES_CLIENT_SOCKET
    if (!(( session->flags & SNMP_FLAGS_STREAM_SOCKET ) &&
#ifdef AF_UNIX
        ( isp->me.sa_family == AF_UNIX ) &&
#endif /* AF_UNIX */
        ( session->local_port == 0 ))) {

		/* Client Unix-domain stream sockets don't need to 'bind' */
#endif
        if (bind(sd, (struct sockaddr *)&isp->me, addr_size) != 0){
            in_session->s_snmp_errno = SNMPERR_BAD_LOCPORT;
            in_session->s_errno = errno;
            snmp_set_detail(strerror(errno));
            snmp_sess_close(slp);
            return 0;
        }
#ifndef SERVER_REQUIRES_CLIENT_SOCKET
    }
#endif
//#endif // not __ECOS

    if ( session->flags & SNMP_FLAGS_STREAM_SOCKET ) {
        if ( session->local_port == 0 ) {	/* Client session */

            if ( connect( sd, (struct sockaddr *)&(isp->addr),
                               snmp_socket_length(isp->addr.sa_family)) != 0 ) {
	        in_session->s_snmp_errno = SNMPERR_BAD_LOCPORT;
	        in_session->s_errno = errno;
	        snmp_set_detail(strerror(errno));
	        snmp_sess_close(slp);
	        return 0;
            }
        } else {				/* Server session */

            if ( listen( sd, SNMP_STREAM_QUEUE_LEN ) != 0 ) {
	        in_session->s_snmp_errno = SNMPERR_BAD_LOCPORT;
	        in_session->s_errno = errno;
	        snmp_set_detail(strerror(errno));
	        snmp_sess_close(slp);
	        return 0;
            }
        }
    }

    /* if we are opening a V3 session and we don't know engineID
       we must probe it - this must be done after the session is
       created and inserted in the list so that the response can
       handled correctly */

#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT

    if (session->version == SNMP_VERSION_3) {
      if (session->securityEngineIDLen == 0 &&
          (session->securityEngineIDLen & SNMP_FLAGS_DONT_PROBE) !=
          SNMP_FLAGS_DONT_PROBE) {
	snmpv3_build_probe_pdu(&pdu);
	DEBUGMSGTL(("snmp_api","probing for engineID...\n"));
	status = snmp_sess_synch_response(slp, pdu, &response);

	if ((response == NULL) && (status == STAT_SUCCESS)) status = STAT_ERROR;

	switch (status) {
	case STAT_SUCCESS:
	  in_session->s_snmp_errno = SNMPERR_INVALID_MSG; /* XX?? */
	  DEBUGMSGTL(("snmp_sess_open",
                      "error: expected Report as response to probe: %s (%d)\n",
                      snmp_errstring(response->errstat), response->errstat));
	  break;
	case STAT_ERROR: /* this is what we expected -> Report == STAT_ERROR */
	  in_session->s_snmp_errno = SNMPERR_UNKNOWN_ENG_ID;
	  break; 
	case STAT_TIMEOUT:
	  in_session->s_snmp_errno = SNMPERR_TIMEOUT;
	default:
	  DEBUGMSGTL(("snmp_sess_open",
                      "unable to connect with remote engine: %s (%d)\n",
                      snmp_api_errstring(session->s_snmp_errno),
                      session->s_snmp_errno));
	  break;
	}
	if (slp->session->securityEngineIDLen == 0) {
	  DEBUGMSGTL(("snmp_api","unable to determine remote engine ID\n"));
	  snmp_sess_close(slp);
	  return NULL;
	}
	in_session->s_snmp_errno = SNMPERR_SUCCESS;
	if (snmp_get_do_debugging()) {
          DEBUGMSGTL(("snmp_sess_open", "  probe found engineID:  "));
	  for(i = 0; i < slp->session->securityEngineIDLen; i++)
	    DEBUGMSG(("snmp_sess_open", "%02x",
                      slp->session->securityEngineID[i]));
	  DEBUGMSG(("snmp_sess_open","\n"));
	}
      }
      /* if boot/time supplied set it for this engineID */
      if (session->engineBoots || session->engineTime) {
	set_enginetime(session->securityEngineID, session->securityEngineIDLen,
		       session->engineBoots, session->engineTime, TRUE);
      }
      if (create_user_from_session(slp->session) != SNMPERR_SUCCESS) {
	  in_session->s_snmp_errno = SNMPERR_UNKNOWN_USER_NAME; /* XX?? */
	DEBUGMSGTL(("snmp_api","snmp_sess_open(): failed(2) to create a new user from session\n"));
	  snmp_sess_close(slp);
	  return NULL;
      }
    }
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */


    return (void *)slp;
}  /* end snmp_sess_open() */

void *
snmp_sess_open(struct snmp_session *pss)
{
    void * pvoid;
    pvoid = _sess_open(pss);
    if ( !pvoid) {
        SET_SNMP_ERROR(pss->s_snmp_errno);
    }
    return pvoid;
}



#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
/* create_user_from_session(struct snmp_session *session):

   creates a user in the usm table from the information in a session

   Parameters:
        session -- IN: pointer to the session to use when creating the user.

   Returns:
        SNMPERR_SUCCESS
        SNMPERR_GENERR
*/
int
create_user_from_session(struct snmp_session *session)
{
  struct usmUser *user;


  /* now that we have the engineID, create an entry in the USM list
     for this user using the information in the session */
  user = usm_get_user_from_list(session->securityEngineID,
                                session->securityEngineIDLen,
                                session->securityName,
                                usm_get_userList(), 0);
  if (user == NULL) {
    DEBUGMSGTL(("snmp_api","Building user %s...\n",session->securityName));
    /* user doesn't exist so we create and add it */
    user = (struct usmUser *) calloc(1,sizeof(struct usmUser));
    if (user == NULL)
      return SNMPERR_GENERR;

    /* copy in the securityName */
    if (session->securityName) {
      user->name = strdup(session->securityName);
      user->secName = strdup(session->securityName);
      if (user->name == NULL || user->secName == NULL) {
        usm_free_user(user);
        return SNMPERR_GENERR;
      }
    }

    /* copy in the engineID */
    if (memdup(&user->engineID, session->securityEngineID,
               session->securityEngineIDLen) != SNMPERR_SUCCESS) {
      usm_free_user(user);
      return SNMPERR_GENERR;
    }
    user->engineIDLen = session->securityEngineIDLen;

    /* copy the auth protocol */
    if (session->securityAuthProto != NULL) {
      user->authProtocol =
        snmp_duplicate_objid(session->securityAuthProto,
                             session->securityAuthProtoLen);
      if (user->authProtocol == NULL) {
        usm_free_user(user);
        return SNMPERR_GENERR;
      }
      user->authProtocolLen = session->securityAuthProtoLen;
    }

    /* copy the priv protocol */
    if (session->securityPrivProto != NULL) {
      user->privProtocol =
        snmp_duplicate_objid(session->securityPrivProto,
                             session->securityPrivProtoLen);
      if (user->privProtocol == NULL) {
        usm_free_user(user);
        return SNMPERR_GENERR;
      }
      user->privProtocolLen = session->securityPrivProtoLen;
    }

    /* copy in the authentication Key, and convert to the localized version */
    if (session->securityAuthKey != NULL && session->securityAuthKeyLen != 0) {
      user->authKey = (u_char *)malloc (USM_LENGTH_KU_HASHBLOCK);
      user->authKeyLen = USM_LENGTH_KU_HASHBLOCK;
      if (generate_kul( user->authProtocol, user->authProtocolLen,
                        session->securityEngineID, session->securityEngineIDLen,
                        session->securityAuthKey, session->securityAuthKeyLen,
                        user->authKey, &user->authKeyLen ) != SNMPERR_SUCCESS) {
        usm_free_user(user);
        return SNMPERR_GENERR;
      }
    }

    /* copy in the privacy Key, and convert to the localized version */
    if (session->securityPrivKey != NULL && session->securityPrivKeyLen != 0) {
      user->privKey = (u_char *)malloc (USM_LENGTH_KU_HASHBLOCK);
      user->privKeyLen = USM_LENGTH_KU_HASHBLOCK;
      if (generate_kul( user->authProtocol, user->authProtocolLen,
                        session->securityEngineID, session->securityEngineIDLen,
                        session->securityPrivKey, session->securityPrivKeyLen,
                        user->privKey, &user->privKeyLen ) != SNMPERR_SUCCESS) {
        usm_free_user(user);
        return SNMPERR_GENERR;
      }
    }

    /* add the user into the database */
    usm_add_user(user);
  }

  return  SNMPERR_SUCCESS;


}  /* end create_user_from_session() */
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */

/*
 * 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_sess_close(void *sessp)
{
    struct session_list *slp = (struct session_list *)sessp;
    struct snmp_internal_session *isp;
    struct snmp_session *sesp;

    if (slp == NULL)
	return 0;

    isp = slp->internal; slp->internal = 0;
    if (isp) {
	struct request_list *rp, *orp;

        SNMP_FREE(isp->packet);

	if (isp->sd != -1)
	{
#ifndef HAVE_CLOSESOCKET
	    close(isp->sd);
#else
	    closesocket(isp->sd);
#endif
#ifdef AF_UNIX
            if ( isp->me.sa_family == AF_UNIX )
                unlink( isp->me.sa_data );
#endif /* AF_UNIX */
	}

	/* Free each element in the input request list.  */
	rp = isp->requests;
	while(rp){
	    orp = rp;
	    rp = rp->next_request;
		snmp_free_pdu(orp->pdu);
	    free((char *)orp);
	}

    	free((char *)isp);
    }

    sesp = slp->session; slp->session = 0;
    if (sesp) {
        SNMP_FREE(sesp->peername);
        SNMP_FREE(sesp->community);
        SNMP_FREE(sesp->contextEngineID);
        SNMP_FREE(sesp->contextName);
        SNMP_FREE(sesp->securityEngineID);
        SNMP_FREE(sesp->securityName);
        SNMP_FREE(sesp->securityAuthProto);
        SNMP_FREE(sesp->securityPrivProto);
        free((char *)sesp);
    }

    free((char *)slp);

    return 1;
}

int 
snmp_close(struct snmp_session *session)
{
    struct session_list *slp = NULL, *oslp = NULL;

    { /*MTCRITICAL_RESOURCE*/
	snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSION);
    if (Sessions && 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;
	}
    }
	snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_SESSION);
    } /*END MTCRITICAL_RESOURCE*/
    if (slp == NULL){
	return 0;
    }
    return snmp_sess_close((void *)slp);
}

int
snmp_close_sessions( void )
{
    struct session_list *slp;

    snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSION);
    while ( Sessions ) {
        slp = Sessions;
        Sessions = Sessions->next;
        snmp_sess_close((void *)slp);
    }
    snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_SESSION);
    return 1;
}

#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
static int
snmpv3_build_probe_pdu (struct snmp_pdu **pdu)
{
  struct usmUser *user;

  /* create the pdu */
  if (!pdu) return -1;
  *pdu = snmp_pdu_create(SNMP_MSG_GET);
  (*pdu)->version = SNMP_VERSION_3;
  (*pdu)->securityName = strdup("");
  (*pdu)->securityNameLen = strlen((*pdu)->securityName);
  (*pdu)->securityLevel = SNMP_SEC_LEVEL_NOAUTH;
  (*pdu)->securityModel = SNMP_SEC_MODEL_USM;

  /* create the empty user */
  user = usm_get_user(NULL, 0, (*pdu)->securityName);
  if (user == NULL) {
    user = (struct usmUser *) calloc(1,sizeof(struct usmUser));
    user->name = strdup((*pdu)->securityName);
    user->secName = strdup((*pdu)->securityName);
    user->authProtocolLen = sizeof(usmNoAuthProtocol)/sizeof(oid);
    user->authProtocol =
      snmp_duplicate_objid(usmNoAuthProtocol, user->authProtocolLen);
    user->privProtocolLen = sizeof(usmNoPrivProtocol)/sizeof(oid);
    user->privProtocol =
      snmp_duplicate_objid(usmNoPrivProtocol, user->privProtocolLen);
    usm_add_user(user);
  }

⌨️ 快捷键说明

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