📄 sendntfy.c
字号:
#endifretrans->time_sent = ENVOY_NOW();retrans->ref_cnt--;/* restart the timer, if necessary */retrans_timer_update();#if INSTALL_ENVOY_SNMP_LOCKENVOY_SNMP_RELEASE_WRITE_LOCK(SNMP_V3_Retrans_Lock);#endif}/********************************************************************************* SNMP_Send_Notify_Name - send the 'VarBindList' information to all appropriate targets* SYNOPSIS** \cs* void SNMP_Send_Notify_Name * ( * bits8_t * notify_name,* ALENGTH_T notify_name_len,* VBL_T * vblp,* SNMPADDR_T * loc_addr,* bits8_t * con_name,* ALENGTH_T con_name_len,* IO_COMPLETE_T * io_complete,* ERR_COMPLETE_T * error_complete,* RETRANS_CLEANUP_T * cleanup_rtn,* PTR_T cookie* )* \ce** DESCRIPTION** This routine sends the information in the 'VarBindList' to all appropriate * targets according to the details of the particular notify. The notify * corresponding to this notify name must already be installed in the global * notify table. All objects in an outgoing notify must be available in the * 'NOTIFY' 'VIEW' for the user that you intend as the target of the notify. Use * this routine to send RFC 2573 compliant Notification-Class PDUs. You must * implement timers to use this routine.** PARAMETERS* \is* \i <*notify_name>* Specify an entry from the 'snmpNotifyTable' corresponding to the 'NOTIFY' * (either a 'TRAP' or an 'INFORM') being sent.* \i <notify_name_len>* Specify the length in bytes of the notify name.* \i <*vblp>* Point to the 'VarBindList' containing the information to be transmitted in * the 'NOTIFY'. It should have been previously allocated with the * VBList_Allocate() routine and had the various information bound into it using * API calls.* \i <*loc_addr>* Specify the local address, in 'SNMPADDR_T' format. Always include the IP * address and port. Depending on the requirements of your completion routine, * this value may be all zeros.* \i <*con_name>* Specify the context string. This value is often the empty string.* \i <con_name_len>* Specify the length of the context string.* \i <*io_complete>* Specify the function that is called to send all notifies originating from * this call. Do not perform resource cleanup in this function. <io_complete> is * passed an 'SNMP_PKT_T' and a <cookie>. These must not be freed by * <io_complete>.* \i <*error_complete>* Specify the function that will be called if an error occurs.* \i <*cleanup_rtn>* Specify the function that will be called when all notifies have been sent or * the routine times out. Its primary function is to allow the customer a chance * to free the <cookie>. Envoy cleans up the 'SNMP_PKT_T' structure.* \i <cookie>* Specify an extra pointer that customers can use to store important * information.* \ie** RETURNS: None.** ERRNO: N/A** SEE ALSO: SNMP_Send_Notify(), VBList_Allocate(), VBList_Allocate(), * VBL_Bind_Counter(), VBL_Bind_Gauge(), VBL_Bind_Integer(), * VBL_Bind_IP_Address(), VBL_Bind_Null(), VBL_Bind_Object_ID(), * VBL_Bind_Opaque(), VBL_Bind_String(), VBL_Bind_64_Unsigned_Integer(), * VBL_Bind_Timeticks(), VBL_Bind_Unsigned_Integer()*/void SNMP_Send_Notify_Name(bits8_t *notify_name, ALENGTH_T notify_name_len, VBL_T *vblp, SNMPADDR_T *loc_addr, bits8_t *con_name, ALENGTH_T con_name_len, IO_COMPLETE_T *io_complete, ERR_COMPLETE_T *error_complete, RETRANS_CLEANUP_T *cleanup_rtn, PTR_T cookie){SNMP_NOTIFY_T *notify;TARGET_LIST_T *target_list, *tlp;SNMP_TARGET_PARAMS_T *params;SNMP_GROUP_T *group;SNMP_ACCESS_T *access;SNMP_PKT_T *pktp;RETRANS_COOKIE_T *retrans_cookie = 0, *dead_retrans_cookie;RETRANS_COOKIE_T **retrans_clean;VB_T *vbp;VBL_T *new_vblp = 0;bits8_t *sec_id;ALENGTH_T sec_id_len;int msg_flags = 0;int ptype = 0, error, vb_cnt, view_ok, bind_ok, retrans_sent = 0;#if INSTALL_ENVOY_SNMP_COEXISTENCESNMP_COMMUNITY_T *community;SNMP_TARGET_ADDR_T *comm_taddr;OBJ_ID_T enterprise;int convert_ok = 0;int generic;sbits32_t specific;bits32_t timestamp;OBJ_ID_T agentip_tdomain;EBUFFER_T agentip_taddress;bits8_t agent_zero[6] = { 0, 0, 0, 0, 0, 0 };MEMSET(&agentip_tdomain, 0, sizeof(OBJ_ID_T));EBufferInitialize(&agentip_taddress);#endif#if INSTALL_ENVOY_SNMP_LOCKENVOY_SNMP_GET_READ_LOCK(SNMP_CoarseLock);#endif/* Step 1: Look up the notify and make sure that it's active. */if (((notify = SNMP_Notify_Lookup(notify_name, notify_name_len)) == 0) || (SNMP_Notify_Get_Status(notify) != ETC_RS_ACTIVE)) { if (cleanup_rtn) cleanup_rtn(cookie);#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_RELEASE_READ_LOCK(SNMP_CoarseLock);#endif return; }/* Step 2: Build a list of valid targets */if ((target_list = build_target_list(notify, vblp)) == 0) { if (cleanup_rtn) cleanup_rtn(cookie);#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_RELEASE_READ_LOCK(SNMP_CoarseLock);#endif return; }/* Step 3: For each target in the target list, extract the necessary * information from the target addr and params objects. We can then * safely release the lock and build packets. */for (tlp = target_list; tlp; tlp = tlp->next, ptype = 0) { /* Step 3a: Convert the TAddress field of the target * into an SNMPADDR_T, if possible. */ if (ENVOY_TADDRESS_TO_SNMPADDR(&(tlp->for_addr), &(tlp->target->tdomain), &(tlp->target->taddress))) continue; sec_id = 0; sec_id_len = 0; /* Step 3b: Look up the target_params object. */ params = SNMP_Target_Params_Lookup(SNMP_Target_Addr_Get_Params(tlp->target), SNMP_Target_Addr_Get_Params_Len(tlp->target)); if ((!params) || (SNMP_Target_Params_Get_Status(params) != ETC_RS_ACTIVE)) continue; /* Step 3c: Put all of the target and params information into the * TARGET_LIST_T object so that we can safely call our creation * routines later. */ if (build_object_id(SNMP_Target_Addr_Get_TDomain(tlp->target)->num_components, SNMP_Target_Addr_Get_TDomain(tlp->target)->component_list, &(tlp->tdomain))) continue; if (EBufferAllocateLoad(BFL_IS_ALLOC, &(tlp->taddress), SNMP_Target_Addr_Get_TAddress(tlp->target), SNMP_Target_Addr_Get_TAddress_Len(tlp->target))) continue; /* Convert the timeout into milliseconds */ tlp->timeout = ((SNMP_Notify_Get_Type(notify) == 1) ? 0 : (SNMP_Target_Addr_Get_Timeout(tlp->target) * 10)); tlp->retry_count = SNMP_Target_Addr_Get_Retry_Count(tlp->target); tlp->ptype = (SNMP_Target_Params_Get_MP_Model(params) == SNMP_VERSION_1 ? TRAP_PDU : ((SNMP_Notify_Get_Type(notify) == 1) ? TRAP2_PDU : INFORM_REQUEST_PDU)); tlp->mp_model = SNMP_Target_Params_Get_MP_Model(params); tlp->sec_model = SNMP_Target_Params_Get_Sec_Model(params); if (EBufferAllocateLoad(BFL_IS_ALLOC, &(tlp->context), con_name, con_name_len)) continue; if (EBufferAllocateLoad(BFL_IS_ALLOC, &(tlp->sec_name), SNMP_Target_Params_Get_Sec_Name(params), SNMP_Target_Params_Get_Sec_Name_Len(params))) continue; tlp->sec_level = SNMP_Target_Params_Get_Sec_Level(params);#if INSTALL_ENVOY_SNMP_COEXISTENCE /* Step 3d: Look up the community object for targets expecting * v1 and v2c notifications. */ if (tlp->mp_model == SNMP_VERSION_3) { tlp->flags = SNMP_TARGET_LIST_INFOK; continue; } for (community = root_community; community; community = community->next) { /* Do security names match? */ if ((SNMP_Community_Get_Sec_Name_Len(community) != SNMP_Target_Params_Get_Sec_Name_Len(params)) || (MEMCMP(SNMP_Community_Get_Sec_Name(community), SNMP_Target_Params_Get_Sec_Name(params), SNMP_Community_Get_Sec_Name_Len(community)) != 0)) continue; /* Does context engine ID match? */ if ((SNMP_Community_Get_Con_ID_Len(community) != SNMP_Engine_Get_My_ID_Length()) || (MEMCMP(SNMP_Community_Get_Con_ID(community), SNMP_Engine_Get_My_ID(), SNMP_Engine_Get_My_ID_Length()) != 0)) continue; /* Does the context name match? */ if ((SNMP_Community_Get_Con_Name_Len(community) != con_name_len) || (MEMCMP_NULLOK(SNMP_Community_Get_Con_Name(community), con_name, con_name_len) != 0)) continue; /* Is the tag field empty? */ if (SNMP_Community_Get_Tag_Len(community) == 0) break; /* We need to find a valid entry in the target addr table. */ comm_taddr = find_target_by_community(&(community->comm_tag), &(tlp->target->tdomain), &(tlp->target->taddress)); if (comm_taddr) break; } if (community == 0) continue; tlp->mms = SNMP_Target_Addr_Get_MMS(tlp->target); if (EBufferAllocateLoad(BFL_IS_ALLOC, &(tlp->context), SNMP_Community_Get_Name(community), SNMP_Community_Get_Name_Len(community))) continue;#endif /* #if INSTALL_ENVOY_SNMP_COEXISTENCE */ tlp->flags = SNMP_TARGET_LIST_INFOK; }#if INSTALL_ENVOY_SNMP_LOCKENVOY_SNMP_RELEASE_READ_LOCK(SNMP_CoarseLock);#endif/* Step 4: Create a preliminary SNMP_PKT_T to use in view checking. */for (tlp = target_list; tlp; tlp = tlp->next, ptype = 0) { if ((tlp->flags & SNMP_TARGET_LIST_INFOK) == 0) continue; switch(tlp->mp_model) {#if INSTALL_ENVOY_SNMP_COEXISTENCE#if INSTALL_ENVOY_SNMP_VERSION_1 case SNMP_VERSION_1: /* If ptype is not TRAP_PDU, stop right now. */ if ((tlp->ptype != TRAP_PDU) || /* We only need to do these conversions once... */ ((convert_ok == 0) && ((error = SNMP_Convert_VB(vblp, &enterprise, &generic, &specific, ×tamp)) == 0))) { pktp = (SNMP_PKT_T *) 0; break; } ENVOY_SNMPADDR_TO_TADDRESS(loc_addr, &agentip_tdomain, &agentip_taddress); convert_ok = 1; if (oidcmp(agentip_tdomain.num_components, agentip_tdomain.component_list, sizeof_snmpUDPDomain, snmpUDPDomain) == 0) { EBufferClean(&agentip_taddress); EBufferPreLoad(BFL_IS_STATIC, &agentip_taddress, agent_zero, 6); } pktp = SNMP_Create_Trap(tlp->mp_model, EBufferUsed(&tlp->context), (sbits8_t *) EBufferStart(&tlp->context), enterprise.num_components, enterprise.component_list, EBufferStart(&agentip_taddress), generic, specific, timestamp, vblp->vbl_count - 2); Clean_Obj_ID(&agentip_tdomain); EBufferClean(&agentip_taddress); /* Community string is by default a static reference. */ if (pktp != 0) { EBufferClean(&pktp->community); EBufferAllocateLoad(BFL_IS_ALLOC, &(pktp->community), EBufferStart(&tlp->context), EBufferUsed(&tlp->context)); } break;#endif /* #if INSTALL_ENVOY_SNMP_VERSION_1 */#if INSTALL_ENVOY_SNMP_VERSION_2 case SNMP_VERSION_2: pktp = SNMP_Create_Request2(tlp->ptype, tlp->mp_model, EBufferUsed(&tlp->context), (sbits8_t *) EBufferStart(&tlp->context), 0, vblp->vbl_count, 0, 0); /* Community string is by default a static reference. */ if (pktp != 0) { EBufferClean(&pktp->community); EBufferAllocateLoad(BFL_IS_ALLOC, &(pktp->community), EBufferStart(&tlp->context), EBufferUsed(&tlp->context)); } break;#endif /* #if INSTALL_ENVOY_SNMP_VERSION_2 */#endif /* #if INSTALL_ENVOY_SNMP_COEXISTENCE */ case SNMP_VERSION_3: /* If this Notify is a Trap, we set the securityEngineID to * the originator's snmpEngineID. */ if (tlp->ptype == TRAP2_PDU) { sec_id = SNMP_Engine_Get_My_ID(); sec_id_len = SNMP_Engine_Get_My_ID_Length(); } else { sec_id = 0; sec_id_len = 0; SNMP_Find_Matching_Engine_ID(&(tlp->tdomain), &(tlp->taddress), &sec_id, &sec_id_len); } msg_flags = 0; switch(tlp->sec_level) { case ETC_SEC_LEVEL_PRIV: msg_flags |= ETC_V3_PRIV; /* fall through... */ case ETC_SEC_LEVEL_AUTH: msg_flags |= ETC_V3_AUTH; /* fall through... */ case ETC_SEC_LEVEL_NONE: break; default: continue; } /* Step 4a: Create the packet. Either it's a probe packet, * (and we stop here), or it's a regular packet and we do * view checking. */ if (!sec_id) { /* We can't proceed yet as we don't have a securityEngineID * to build the packet with. This means we have to send a * probe to the target in question and wait for a response.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -