📄 snmp_api.c
字号:
* 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; netsnmp_transport *transport; struct snmp_internal_session *isp; netsnmp_session *sesp = NULL; struct snmp_secmod_def *sptr; if (slp == NULL) { return 0; } if ((sptr = find_sec_mod(slp->session->securityModel)) != NULL && sptr->session_close != NULL) { (*sptr->session_close) (slp->session); } isp = slp->internal; slp->internal = 0; if (isp) { netsnmp_request_list *rp, *orp; SNMP_FREE(isp->packet); /* * 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); } transport = slp->transport; slp->transport = 0; if (transport) { transport->f_close(transport); netsnmp_transport_free(transport); } sesp = slp->session; slp->session = 0; /* * The following is necessary to avoid memory leakage when closing AgentX * sessions that may have multiple subsessions. These hang off the main * session at ->subsession, and chain through ->next. */ if (sesp != NULL && sesp->subsession != NULL) { netsnmp_session *subsession = sesp->subsession, *tmpsub; while (subsession != NULL) { DEBUGMSGTL(("snmp_sess_close", "closing session %p, subsession %p\n", sesp, subsession)); tmpsub = subsession->next; snmp_free_session(subsession); subsession = tmpsub; } } snmp_free_session(sesp); free((char *) slp); return 1;}intsnmp_close(netsnmp_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;}static intsnmpv3_build_probe_pdu(netsnmp_pdu **pdu){ struct usmUser *user; /* * create the pdu */ if (!pdu) return -1; *pdu = snmp_pdu_create(SNMP_MSG_GET); if (!(*pdu)) return -1; (*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)); if (user == NULL) { snmp_free_pdu(*pdu); *pdu = (netsnmp_pdu *) NULL; return -1; } 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(netsnmp_request_list *rp, netsnmp_pdu *pdu){ netsnmp_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;}/* * SNMPv3 * * Takes a session and a pdu and serializes the ASN PDU into the area * * pointed to by packet. out_length is the size of the data area available. * * Returns the length of the completed packet in out_length. If any errors * * occur, -1 is returned. If all goes well, 0 is returned. */static intsnmpv3_build(u_char ** pkt, size_t * pkt_len, size_t * offset, netsnmp_session * session, netsnmp_pdu *pdu){ int ret; session->s_snmp_errno = 0; session->s_errno = 0; /* * do validation for PDU types */ switch (pdu->command) { case SNMP_MSG_RESPONSE: case SNMP_MSG_TRAP2: case SNMP_MSG_REPORT: pdu->flags &= (~UCD_MSG_FLAG_EXPECT_RESPONSE); /* * Fallthrough */ case SNMP_MSG_GET: case SNMP_MSG_GETNEXT: case SNMP_MSG_SET: case SNMP_MSG_INFORM: if (pdu->errstat == SNMP_DEFAULT_ERRSTAT) pdu->errstat = 0; if (pdu->errindex == SNMP_DEFAULT_ERRINDEX) pdu->errindex = 0; break; case SNMP_MSG_GETBULK: if (pdu->max_repetitions < 0) { session->s_snmp_errno = SNMPERR_BAD_REPETITIONS; return -1; } if (pdu->non_repeaters < 0) { session->s_snmp_errno = SNMPERR_BAD_REPEATERS; return -1; } break; case SNMP_MSG_TRAP: session->s_snmp_errno = SNMPERR_V1_IN_V2; return -1; default: session->s_snmp_errno = SNMPERR_UNKNOWN_PDU; return -1; } if (pdu->securityEngineIDLen == 0) { if (session->securityEngineIDLen) { snmpv3_clone_engineID(&pdu->securityEngineID, &pdu->securityEngineIDLen, session->securityEngineID, session->securityEngineIDLen); } } if (pdu->contextEngineIDLen == 0) { if (session->contextEngineIDLen) { snmpv3_clone_engineID(&pdu->contextEngineID, &pdu->contextEngineIDLen, session->contextEngineID, session->contextEngineIDLen); } else if (pdu->securityEngineIDLen) { snmpv3_clone_engineID(&pdu->contextEngineID, &pdu->contextEngineIDLen, pdu->securityEngineID, pdu->securityEngineIDLen); } } if (pdu->contextName == NULL) { if (!session->contextName) { session->s_snmp_errno = SNMPERR_BAD_CONTEXT; return -1; } pdu->contextName = strdup(session->contextName); if (pdu->contextName == NULL) { session->s_snmp_errno = SNMPERR_GENERR; return -1; } pdu->contextNameLen = session->contextNameLen; } if (pdu->securityModel == SNMP_DEFAULT_SECMODEL) { pdu->securityModel = session->securityModel; if (pdu->securityModel == SNMP_DEFAULT_SECMODEL) { pdu->securityModel = SNMP_SEC_MODEL_USM; } } if (pdu->securityNameLen == 0 && pdu->securityName == 0) { if (session->securityNameLen == 0) { session->s_snmp_errno = SNMPERR_BAD_SEC_NAME; return -1; } pdu->securityName = strdup(session->securityName); if (pdu->securityName == NULL) { session->s_snmp_errno = SNMPERR_GENERR; return -1; } pdu->securityNameLen = session->securityNameLen; } if (pdu->securityLevel == 0) { if (session->securityLevel == 0) { session->s_snmp_errno = SNMPERR_BAD_SEC_LEVEL; return -1; } pdu->securityLevel = session->securityLevel; } DEBUGMSGTL(("snmp_build", "Building SNMPv3 message (secName:\"%s\", secLevel:%s)...\n", ((session->securityName) ? (char *) session->securityName : ((pdu->securityName) ? (char *) pdu->securityName : "ERROR: undefined")), secLevelName[pdu->securityLevel])); DEBUGDUMPSECTION("send", "SNMPv3 Message");#ifdef USE_REVERSE_ASNENCODING if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_REVERSE_ENCODE)) { ret = snmpv3_packet_realloc_rbuild(pkt, pkt_len, offset, session, pdu, NULL, 0); } else {#endif ret = snmpv3_packet_build(session, pdu, *pkt, pkt_len, NULL, 0);#ifdef USE_REVERSE_ASNENCODING }#endif DEBUGINDENTLESS(); if (-1 != ret) { session->s_snmp_errno = ret; } return ret;} /* end snmpv3_build() */static u_char *snmpv3_header_build(netsnmp_session * session, netsnmp_pdu *pdu, u_char * packet, size_t * out_length, size_t length, u_char ** msg_hdr_e){ u_char *global_hdr, *global_hdr_e; u_char *cp; u_char msg_flags; long max_size; long sec_model; u_char *pb, *pb0e; /* * Save current location and build SEQUENCE tag and length placeholder * * for SNMP message sequence (actual length inserted later) */ cp = asn_build_sequence(packet, out_length, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), length); if (cp == NULL) return NULL; if (msg_hdr_e != NULL) *msg_hdr_e = cp; pb0e = cp; /* * store the version field - msgVersion */ DEBUGDUMPHEADER("send", "SNMP Version Number"); cp = asn_build_int(cp, out_length, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), (long *) &pdu->version, sizeof(pdu->version)); DEBUGINDENTLESS(); if (cp == NULL) return NULL; global_hdr = cp; /* * msgGlobalData HeaderData */ DEBUGDUMPSECTION("send", "msgGlobalData"); cp = asn_build_sequence(cp, out_length, (u_char) (ASN_SEQUENCE | ASN_CONSTR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -