📄 sendntfy.c
字号:
*/ pktp = SNMP_Create_Request_V3(tlp->ptype, tlp->mp_model, 0, 0, 0, tlp->sec_model, SNMP_Engine_Get_My_ID(), SNMP_Engine_Get_My_ID_Length(), con_name, con_name_len, 0, 0, 0, 0, 0, 0, 0, 0); break; } pktp = SNMP_Create_Request_V3(tlp->ptype, tlp->mp_model, 0, 0, msg_flags, tlp->sec_model, SNMP_Engine_Get_My_ID(), SNMP_Engine_Get_My_ID_Length(), con_name, con_name_len, sec_id, sec_id_len, EBufferStart(&tlp->sec_name), EBufferUsed(&tlp->sec_name), 0, vblp->vbl_count, 0, 0); break; default: pktp = (SNMP_PKT_T *) 0; break; } if (!pktp) continue; /* We've created the packet, and now we can grab the lock for a bit * so we can do view checking. */#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_GET_READ_LOCK(SNMP_CoarseLock);#endif /* Step 4b: Look up the group. */ group = SNMP_Group_Lookup(tlp->sec_model, EBufferStart(&tlp->sec_name), EBufferUsed(&tlp->sec_name)); if ((!group) || (SNMP_Group_Get_Status(group) != ETC_RS_ACTIVE)) goto cleanup; /* Step 4c: Look up the access model and get the notify view from it. */ access = SNMP_V3_Access_Find(SNMP_Group_Get_Group(group), SNMP_Group_Get_Group_Len(group), con_name, con_name_len, tlp->sec_model, tlp->sec_level); if ((!access) || (SNMP_V3_Access_Get_Status(access) != ETC_RS_ACTIVE)) goto cleanup; EBufferAllocateLoad(BFL_IS_ALLOC, &pktp->view_name, SNMP_V3_Access_Get_Notify(access), SNMP_V3_Access_Get_Notify_Len(access)); /* Step 4d: Do view checking. */ if ((error = SNMP_View_Find_Family(pktp)) != 0) /* No view */ goto cleanup; for (vb_cnt = 0, vbp = &(vblp->vblist[vb_cnt]), view_ok = 1; vb_cnt < vblp->vbl_count; vb_cnt++, vbp = &(vblp->vblist[vb_cnt])) { if (SNMP_View_Family_Check(pktp, vbp->vb_obj_id.component_list, vbp->vb_obj_id.num_components, VIEW_CHECK_DET) == VIEW_EXCLUDED) { view_ok = 0; break; } } /* We need to check the value of snmpTrapOID.0 as well */ vbp = &(vblp->vblist[1]); if (SNMP_View_Family_Check(pktp, (VB_GET_OBJECT_ID(vbp))->component_list, (VB_GET_OBJECT_ID(vbp))->num_components, VIEW_CHECK_DET) == VIEW_EXCLUDED) view_ok = 0;#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_RELEASE_READ_LOCK(SNMP_CoarseLock);#endif if (!view_ok) { SNMP_Free(pktp); continue; } /* Step 4e: View is OK, so bind in VarBinds from VarBindList */ bind_ok = 1; switch(pktp->snmp_version) {#if INSTALL_ENVOY_SNMP_COEXISTENCE#if INSTALL_ENVOY_SNMP_VERSION_1 case SNMP_VERSION_1: bind_ok = copyVarBindList(&(pktp->pdu.trap_pdu.trap_vbl), vblp, pktp->snmp_version); if (!bind_ok) { SNMP_Free(pktp); continue; } break;#endif /* #if INSTALL_ENVOY_SNMP_VERSION_1 */#if INSTALL_ENVOY_SNMP_VERSION_2 case SNMP_VERSION_2: bind_ok = copyVarBindList(&(pktp->pdu.std_pdu.std_vbl), vblp, pktp->snmp_version); if (!bind_ok) { SNMP_Free(pktp); continue; } break;#endif /* #if INSTALL_ENVOY_SNMP_VERSION_2 */#endif /* #if INSTALL_ENVOY_SNMP_COEXISTENCE */ case SNMP_VERSION_3: if (sec_id) bind_ok = copyVarBindList(&(pktp->pdu.std_pdu.std_vbl), vblp, pktp->snmp_version); else { new_vblp = VBList_Allocate(vblp->vbl_count); bind_ok = (new_vblp ? copyVarBindList(new_vblp, vblp, pktp->snmp_version) : 0); } if (bind_ok) break; /* otherwise fall through */ default: if (new_vblp) { SNMP_memory_free(new_vblp); new_vblp = 0; } SNMP_Free(pktp); continue; } /* Step 4f: So far, so good. Put all the remaining information * into the target_list object and continue. */ tlp->pktp = pktp; if (new_vblp) { tlp->vblp = new_vblp; new_vblp = 0; tlp->flags |= SNMP_TARGET_LIST_SEND_PROBE; } else tlp->flags |= SNMP_TARGET_LIST_SEND_NOTIFY; continue; cleanup:#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_RELEASE_READ_LOCK(SNMP_CoarseLock);#endif SNMP_Free(pktp); continue; }/* Step 5: We now proceed to send any packets we've successfully * constructed. */for (tlp = target_list; tlp; tlp = tlp->next) { if (tlp->pktp) {#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_GET_WRITE_LOCK(SNMP_V3_Retrans_Lock);#endif retrans_sent = 1; retrans_cookie = SNMP_memory_alloc(sizeof(RETRANS_COOKIE_T)); if (retrans_cookie) { retrans_cookie->next = root_retrans_cookie; root_retrans_cookie = retrans_cookie; retrans_cookie->ref_cnt = 1; retrans_cookie->cleanup_rtn = cleanup_rtn; retrans_cookie->cookie = cookie; }#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_RELEASE_WRITE_LOCK(SNMP_V3_Retrans_Lock);#endif break; } }if (retrans_cookie || !retrans_sent) { for (tlp = target_list; tlp; tlp = tlp->next) { if (tlp->pktp) { if (tlp->flags & SNMP_TARGET_LIST_SEND_NOTIFY) { SNMP_Send_Packet_Retransmit(tlp->pktp, &(tlp->for_addr), loc_addr, tlp->retry_count, tlp->timeout, io_complete, error_complete, retrans_cookie); } else if (tlp->flags & SNMP_TARGET_LIST_SEND_PROBE) { SNMP_Send_Packet_Probe(tlp, loc_addr, io_complete, error_complete, retrans_cookie); } } } }/* Step 6: Clean the target list and dereference the retrans_cookie */if (retrans_cookie) {#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_GET_WRITE_LOCK(SNMP_V3_Retrans_Lock);#endif retrans_cookie->ref_cnt--;#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_RELEASE_WRITE_LOCK(SNMP_V3_Retrans_Lock);#endif }#if INSTALL_ENVOY_SNMP_LOCKENVOY_SNMP_GET_WRITE_LOCK(SNMP_V3_Retrans_Lock);#endif/* a quick scan of the retrans_cookie list to clean up * anything that nobody cares about anymore. */for (retrans_clean = &root_retrans_cookie; *retrans_clean; ) { if ((*retrans_clean)->ref_cnt) { retrans_clean = &(*retrans_clean)->next; continue; } if ((*retrans_clean)->cleanup_rtn) (*retrans_clean)->cleanup_rtn((*retrans_clean)->cookie); dead_retrans_cookie = *retrans_clean; *retrans_clean = (*retrans_clean)->next; SNMP_memory_free(dead_retrans_cookie); }#if INSTALL_ENVOY_SNMP_LOCKENVOY_SNMP_RELEASE_WRITE_LOCK(SNMP_V3_Retrans_Lock);#endifclean_target_list(target_list);if ((!retrans_sent) && (cleanup_rtn)) cleanup_rtn(cookie);}/********************************************************************************* SNMP_Send_Notify - send the 'VarBindList' information to all appropriate targets* SYNOPSIS** \cs* void SNMP_Send_Notify * (* SNMP_NOTIFY_T * notify,* ALENGTH_T length,* 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.** \&NOTE: Do not use this routine for new applications. Use * SNMP_Send_Notify_Name().** PARAMETERS* \is* \i <*notify>* Specify an entry from the 'snmpNotifyTable' corresponding to the 'NOTIFY' * (either a 'TRAP' or an 'INFORM') being sent.* \i <length>* 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_Name(), 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(SNMP_NOTIFY_T *notify, 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 *ntfy_chk;bits8_t *notify_name;ALENGTH_T notify_name_len;#if INSTALL_ENVOY_SNMP_LOCKENVOY_SNMP_GET_READ_LOCK(SNMP_CoarseLock);#endif/* We do a basic sanity check on the notify object, but mostly * we're going to extract the name from it and pass our parameter * list to SNMP_Send_Notify_Name() instead. */for (ntfy_chk = root_notify; ntfy_chk; ntfy_chk = ntfy_chk->next) { if (ntfy_chk == notify) { notify_name_len = SNMP_Notify_Get_Name_Len(notify); if ((notify_name = SNMP_memory_alloc(notify_name_len)) == 0) break; MEMCPY(notify_name, SNMP_Notify_Get_Name(notify), notify_name_len);#if INSTALL_ENVOY_SNMP_LOCK ENVOY_SNMP_RELEASE_READ_LOCK(SNMP_CoarseLock);#endif SNMP_Send_Notify_Name(notify_name, notify_name_len, vblp, loc_addr, con_name, con_name_len, io_complete, error_complete, cleanup_rtn, cookie); SNMP_memory_free(notify_name); return; } }#if INSTALL_ENVOY_SNMP_LOCKENVOY_SNMP_RELEASE_READ_LOCK(SNMP_CoarseLock);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -