snmp_api.c

来自「eCos操作系统源码」· C语言 代码 · 共 2,082 行 · 第 1/5 页

C
2,082
字号
    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*/intcreate_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. */intsnmp_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);}intsnmp_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_SUPPORTstatic intsnmpv3_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);  }  return 0;}static voidsnmpv3_calc_msg_flags (int sec_level, int msg_command, u_char *flags){  *flags = 0;  if (sec_level == SNMP_SEC_LEVEL_AUTHNOPRIV)    *flags = SNMP_MSG_FLAG_AUTH_BIT;  else if (sec_level == SNMP_SEC_LEVEL_AUTHPRIV)    *flags = SNMP_MSG_FLAG_AUTH_BIT | SNMP_MSG_FLAG_PRIV_BIT;  if (SNMP_CMD_CONFIRMED(msg_command)) *flags |= SNMP_MSG_FLAG_RPRT_BIT;  return;}static intsnmpv3_verify_msg(struct request_list *rp, struct snmp_pdu *pdu){  struct snmp_pdu     *rpdu;    if (!rp || !rp->pdu || !pdu) return 0;  /* Reports don't have to match anything according to the spec */  if (pdu->command == SNMP_MSG_REPORT) return 1;  rpdu = rp->pdu;  if (rp->request_id != pdu->reqid || rpdu->reqid != pdu->reqid) return 0;  if (rpdu->version != pdu->version) return 0;  if (rpdu->securityModel != pdu->securityModel) return 0;  if (rpdu->securityLevel != pdu->securityLevel) return 0;  if (rpdu->contextEngineIDLen != pdu->contextEngineIDLen ||       memcmp(rpdu->contextEngineID, pdu->contextEngineID, 	     pdu->contextEngineIDLen))    return 0;  if (rpdu->contextNameLen != pdu->contextNameLen ||       memcmp(rpdu->contextName, pdu->contextName, pdu->contextNameLen))     return 0;  if (rpdu->securityEngineIDLen != pdu->securityEngineIDLen ||       memcmp(rpdu->securityEngineID, pdu->securityEngineID, 	     pdu->securityEngineIDLen))    return 0;  if (rpdu->securityNameLen != pdu->securityNameLen ||       memcmp(rpdu->securityName, pdu->securityName, pdu->securityNameLen))     return 0;  return 1;}

⌨️ 快捷键说明

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