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 + -
显示快捷键?