📄 rpktasy.c
字号:
/* strip the vbl */ Clean_vb_list(&pktp->pdu.std_pdu.std_vbl); pktp->pdu.std_pdu.std_vbl.vblist = 0; pktp->pdu.std_pdu.std_vbl.vbl_count = 0; pktp->pdu.std_pdu.error_status = TOO_BIG; pktp->pdu.std_pdu.error_index = 0; bufsize = SNMP_Bufsize_For_Packet(pktp); if (bufsize > pktp->maxpkt) { SGRPv2_INC_COUNTER(snmp_stats.snmpSilentDrops); pktp->error_complete(&pktp->pkt_src, &pktp->pkt_dst, 1, pktp->async_cookie); return; } } }DYNCFG_IFCFGVBL_END(envoy_use_v2_types)#endif /* #if ENVOY_USE_V2_TYPES *//* Call the routine to count the stuff in the packet then call the io_complete routine, which should call the encode routine then send the packet */snmp_finish_counters(pktp);pktp->io_complete(&pktp->pkt_src, &pktp->pkt_dst, (PTR_T)pktp, bufsize, pktp->async_cookie);return;}/****************************************************************************\NOMANUALNAME: ENVOY_Send_SNMP_PacketPURPOSE: Attempt to build and send a packet, if the error status is set or we find an error we call Envoy_Send_SNMP_Error_Packet, otherwise we attempt to do the encoding and transmit the packet using the io completion routine if we can't we call the error completion routine PARAMETERS: SNMP_PKT_T * The decoded PDURETURNS: void****************************************************************************/void ENVOY_Send_SNMP_Packet(SNMP_PKT_T *pktp){ALENGTH_T bufsize;if (pktp->pdu.std_pdu.error_status != NO_ERROR) { /* if we had an error we send it */ ENVOY_Send_SNMP_Error_Packet(pktp, pktp->pdu.std_pdu.error_status, pktp->pdu.std_pdu.error_index); return; }/* get the size of the packet which we will need several times */bufsize = SNMP_Bufsize_For_Packet(pktp);/* For gets and nexts we need to test the size of the packet, if it would be too large we set the too_big error otherwise we don't need to do anything, the outgoing buffer will be built at the end of the routine. */if (((pktp->pdu_type == GET_REQUEST_PDU) || (pktp->pdu_type == GET_NEXT_REQUEST_PDU)) && (bufsize > pktp->maxpkt)) { ENVOY_Send_SNMP_Error_Packet(pktp, TOO_BIG, 0); return; }/* If the stats group is installed count up the objects we have processed we do it here so we now what type of packet we are dealing with */#if INSTALL_ENVOY_SNMP_GROUP_V1if (pktp->pdu.std_pdu.error_status == 0) { VBL_T *vbl; VB_T *vbp; int i; switch(pktp->pdu_type) { case GET_REQUEST_PDU: case GET_NEXT_REQUEST_PDU: case GET_BULK_REQUEST_PDU: inc_counter(snmp_stats.snmpOutGetResponses); for(vbl = &pktp->pdu.std_pdu.std_vbl; vbl; vbl = vbl->vblp) { for(vbp = vbl->vblist, i = vbl->vbl_count; i; i--, vbp++) { switch(vbp->vb_data_flags_n_type) { case VT_NOSUCHINS: case VT_NOSUCHOBJ: case VT_ENDOFMIB: break; default: inc_counter(snmp_stats.snmpInTotalReqVars); break; } } } break; case SET_REQUEST_PDU: inc_counter(snmp_stats.snmpOutGetResponses); add_counter(snmp_stats.snmpInTotalSetVars, pktp->pdu.std_pdu.std_vbl.vbl_count); break; } }#endif/* If we made it here we make the packet a response then try and encode it, if we can't we toss it otherwise we try and send the reply */if (pktp->pdu_type != REPORT_PDU) pktp->pdu_type = GET_RESPONSE_PDU;snmp_finish_counters(pktp);pktp->io_complete(&pktp->pkt_src, &pktp->pkt_dst, (PTR_T)pktp, bufsize, pktp->async_cookie);return;}/********************************************************************************* SNMP_Continue - continue processing a packet* SYNOPSIS** \cs* void SNMP_Continue* (* SNMP_PKT_T * pktp * )* \ce** DESCRIPTION** After 'Process_Rcvd_SNMP_Packet_Async() 'starts the method routines needed to * fulfill a request, SNMP_Continue() determines if the current set of method * routines have finished and either starts more method routines or calls a * completion routine.* Since multi-threaded method routines can return before all tasks are * completed, when you write your method routines remember to lock the last * thread, check for the final 'VarBind', call any completion routines, and call * SNMP_Continue(). It is also a good idea to call this routine when a foreign * proxy completes processing the packet.* If the 'ENVOY_CONTINUE_REENTRANT' installation option is installed, this * routine also attempts to release the per packet write lock.** PARAMETERS* \is* \i <*pktp>* Point to the packet being processed.* \ie** RETURNS: None.** ERRNO: N/A** SEE ALSO: 'ENVOY_CONTINUE_REENTRANT', Process_Rcvd_SNMP_Packet_Async(), * SNMP_Process_Finish()*/void SNMP_Continue_function(SNMP_PKT_T *pktp){VB_T *vbp;int count;/* For gets, nexts & bulks we check to see if the current set of ops are done. This is a straight forward check of the flags word. Then we do other work as required for gets we simply call the send routine. For nexts we may need to redo any requests that didn't find an acceptable next instance. For bulks we need to do the next check and if that succceeds we may need to do another repetition. For sets we just call the set routine as the test to see what to do is more complicated then a simple flag check. */switch(pktp->pdu_type) { case GET_REQUEST_PDU: /* Walk through the vblist to see if all ops have been completed */ vbp = pktp->pdu.std_pdu.std_vbl.vblist; count = pktp->pdu.std_pdu.std_vbl.vbl_count; for(; count; count--, vbp++) { if (!(vbp->vb_flags & VFLAG_GET_DONE)) goto cont_continue; } goto cont_finish; case GET_NEXT_REQUEST_PDU: /* we put the next request in a while loop so we can catch a redo that finished immmediately and didn't set up a call back */ while(1) { /* Walk through the vblist to see if all ops have been completed */ vbp = pktp->pdu.std_pdu.std_vbl.vblist; count = pktp->pdu.std_pdu.std_vbl.vbl_count; for(; count; count--, vbp++) { if (!(vbp->vb_flags & VFLAG_NEXT_DONE)) goto cont_continue; } switch(SNMP_Process_Next_Redo(pktp)) { case -1: case 0: goto cont_finish; } } case SET_REQUEST_PDU: /* Sets may also require examining the packet to see if we are done or are waiting for a callback, but the function will be handled by the Process_Set_Pdu_Async routine. */ if (SNMP_Process_Set_PDU(pktp) == 0) goto cont_finish; goto cont_continue;#if (ENVOY_USE_V2_PROTOS) case GET_BULK_REQUEST_PDU: DYNCFG_IFCFGVBL_BEGIN(envoy_use_v2_protos) { VBL_T *vblp; /* we put the bulk request in a while loop so we can catch a redo or new repetition that finished immmediately and didn't set up a call back */ while(1) { /* Find the correct vblist to work with. Bulks may have several vblists chained togther, we want the last one which is the only one that may have ops outstanding. */ for(vblp = &(pktp->pdu.std_pdu.std_vbl); vblp->vblp; vblp = vblp->vblp) ; /* Walk through the vblist to see if all ops have been completed */ vbp = vblp->vblist; count = vblp->vbl_count; for(; count; count--, vbp++) { if (!(vbp->vb_flags & VFLAG_NEXT_DONE)) goto cont_continue; } /* First we test to see if we need to do any more work for the current repetition, if not (case 0) we see if there are more repetitions to do if not (case 0) we attempt to send the response packet. Case -1 indicates an already handeled error. */ switch(SNMP_Process_Next_Redo(pktp)) { case -1: goto cont_finish; case 0: if (SNMP_Process_Bulk_Redo(pktp) == 0) goto cont_finish; break; } } /* while(1) */ } DYNCFG_IFCFGVBL_END(envoy_use_v2_protos)#endif /* #if (ENVOY_USE_V2_PROTOS) */ } /* switch(pktp->pdu_type) *//* If CONTINUE_REENTRANT is installed this routine assumes that the calling routine has acquired the write lock for this packet. This routine will always release the write lock. */cont_finish:#if (INSTALL_ENVOY_CONTINUE_REENTRANT)ENVOY_SNMP_RELEASE_WRITE_LOCK(pktp->continue_lock);#endifENVOY_Send_SNMP_Packet(pktp);SNMP_Free(pktp);#if (INSTALL_ENVOY_SNMP_SERIALIZE)GateRunDeferreds();#endif /* (INSTALL_ENVOY_SNMP_SERIALIZE) */return;cont_continue:#if (INSTALL_ENVOY_CONTINUE_REENTRANT)ENVOY_SNMP_RELEASE_WRITE_LOCK(pktp->continue_lock);#endifreturn;}/****************************************************************************\NOMANUALNAME: process_packet_twoPURPOSE: A routine to do the mid stage processing for an snmp packet, this will allow us to have one block of code called by the main processing branch or the deferral routine in serial.cPARAMETERS: SNMP_PKT_T * The packet being processedRETURNS: void****************************************************************************/void process_packet_two(PTR_T dptr){SNMP_PKT_T *rp = (SNMP_PKT_T *)dptr;#if (INSTALL_ENVOY_CONTINUE_REENTRANT)/* If necessary we acquire the packet continue write lock here It gets freed when we call the continue routine. Any user routines that defer processing of a request should also use the write lock, this will stop us from stepping on each other when modifying the packet. We don't have any good options if we can't get the lock. The user shouldn't do that, if they do we generate a bug report and if they don't handle that we return which is the least bad thing to do. */if (ENVOY_SNMP_GET_WRITE_LOCK(rp->continue_lock)) { BUG(BUG_ENVOY_LOCKING, BUG_FATAL, 0, (BUG_OUT, "process_packet_two(): packet continue lock is broken", 0)); return; }#endifswitch(rp->pdu_type) { case GET_REQUEST_PDU: if (SNMP_Process_Get_PDU(rp)) { goto proc2_error; } break; case GET_NEXT_REQUEST_PDU: case GET_BULK_REQUEST_PDU: if (SNMP_Process_Next_PDU(rp)) { goto proc2_error; } break; case SET_REQUEST_PDU: if (SNMP_Process_Test_PDU(rp)) { goto proc2_error; } break; }SNMP_Continue_function(rp);return;proc2_error:#if (INSTALL_ENVOY_CONTINUE_REENTRANT)ENVOY_SNMP_RELEASE_WRITE_LOCK(rp->continue_lock);#endifSNMP_Free(rp);#if (INSTALL_ENVOY_SNMP_SERIALIZE)GateRunDeferreds();#endif /* (INSTALL_ENVOY_SNMP_SERIALIZE) */return;}/****************************************************************************NAME: process_packet_onePURPOSE: Manage the execution of an internal SNMP packet (one that is already in an snmp_pkt_t structure) in an async fashion.PARAMETERS: SNMP_PKT_T * The packet, in its c-structure format, to processRETURNS: void****************************************************************************/static void process_packet_one(SNMP_PKT_T *rp){#if INSTALL_ENVOY_SNMP_V3_PROXYint error_code;SNMP_PKT_T *new_rp;#endif/* First handle statistics. */switch(rp->pdu_type) { case GET_REQUEST_PDU: SGRPv1_INC_COUNTER(snmp_stats.snmpInGetRequests); break; case GET_NEXT_REQUEST_PDU: SGRPv1_INC_COUNTER(snmp_stats.snmpInGetNexts); break; case SET_REQUEST_PDU: SGRPv1_INC_COUNTER(snmp_stats.snmpInSetRequests); break; case GET_BULK_REQUEST_PDU: break;#if (INSTALL_ENVOY_SNMP_V3_NOTIFY) || (INSTALL_ENVOY_USE_SNMP_PROXY) case GET_RESPONSE_PDU:#if INSTALL_COMMON_DYNAMIC_COMP_CONFIG if (DYNCFG_VBL(envoy_snmp_notify) || DYNCFG_VBL(envoy_snmp_proxy))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -