📄 nextpdu.c
字号:
RETURNS: int 0 this stage of processing is finished continue onward. -1 An (error) packet needs to be sent the caller should do so and then free pktp. 1 Several nextprocs were restarted we need to redo this stage****************************************************************************/int SNMP_Process_Next_Redo(SNMP_PKT_T *pktp){VBL_T *vblp;VB_T *vbp, *tvbp, *oldvbp;int count, indx, eret, restart_flag = 0, redo_flag = 1;OBJ_ID_T target;sbits32_t *err_stat;/* If somebody has already set up an error, then we don't need to do anything here except return an error indication to our caller */err_stat = &(pktp->pdu.std_pdu.error_status);if (*err_stat != NO_ERROR) return(-1);/* Get some initial information. We need to determine which var bind list to use. Nexts have only one but bulks may have several chained together. We want the last one as it will be the only one with variables that may need to be redone. We also get a pointer to the object list as the base for this round. We will need this pointer in the case of a v2 end of mib exception as we are suppossed to send back the object we attempted a next from. */vblp = &(pktp->pdu.std_pdu.std_vbl);if (vblp->vblp == 0) oldvbp = pktp->pdu.std_pdu.saved_vbl.vblist;else for(oldvbp = vblp->vblist + pktp->pdu.std_pdu.non_reps, vblp = vblp->vblp; vblp->vblp; oldvbp = vblp->vblist, vblp = vblp->vblp) ;if (((vbp = vblp->vblist) == 0) || ((count = vblp->vbl_count) == 0)) return(0);/* Try to get the infrastructure lock, we release it using the ENVOY_AX_MA_RELEASE_WRITE_LOCK macro */#if (INSTALL_ENVOY_AGENTX_MASTER && INSTALL_ENVOY_SNMP_LOCK)DYNCFG_IFCFGVBL_BEGIN(agentx_master_component)if (ENVOY_SNMP_GET_WRITE_LOCK(SNMP_infrastructure_lock)) { BUG(BUG_ENVOY_LOCKING, BUG_CONTINUABLE, 0, (BUG_OUT, "SNMP_Process_Next_Redo: infrastructure lock broken", 0)); *err_stat = GEN_ERR; return(-1); }DYNCFG_IFCFGVBL_END(agentx_master_component)#endif/* If necessary try to find the view index structure, if we want to do rfc1445 view checking find_object_node will expect this routine to have been run and to have inserted a pointer into pktp */#if (INSTALL_ENVOY_SNMP_DYNAMIC_VIEWS)if (SNMP_View_Find_Family(pktp) && (pktp->snmp_version == SNMP_VERSION_3)) { ENVOY_AX_MA_RELEASE_WRITE_LOCK(SNMP_infrastructure_lock); *err_stat = AUTHORIZATION_ERROR; return(-1); }#endif/* Note: if we find an error we set indx = count to break the loop */for(tvbp = vbp, indx = 0; indx < count; tvbp++, indx++) { if (!(tvbp->vb_flags & VFLAG_NEXT_REDO)) {#if (INSTALL_ENVOY_SNMP_DYNAMIC_VIEWS) /* If we are using the rfc1445 view scheme we may need to redo the view check now that we know the instance of the variable */ if (((tvbp->vb_flags & VFLAG_NEXT_VCBITS) == VFLAG_NEXT_VCREQ) && (SNMP_View_Family_Check(pktp, tvbp->vb_obj_id.component_list, tvbp->vb_obj_id.num_components, VIEW_CHECK_DET) != VIEW_INCLUDED)) { /* Reset any flags that were set and free any space that was allocated by the method routines */ tvbp->vb_flags &= ~VFLAG_NEXT_FLAGS | VFLAG_NEXT_VCREQ; Clean_vb_data(tvbp); restart_flag = 1;#if INSTALL_ENVOY_AGENTX_MASTER DYNCFG_IFCFGVBL_BEGIN(agentx_master_component) /* Reset the include flag as we don't won't to get the current object, that's the one we just found was not in the view */ tvbp->ax_flags &= ~ENVOY_AX_FLAGS_INCLUDE; DYNCFG_IFCFGVBL_END(agentx_master_component)#endif } else tvbp->vb_flags |= VFLAG_NEXT_VCDONE;#endif /* (INSTALL_ENVOY_SNMP_DYNAMIC_VIEWS) */ continue; } /* if (!(tvbp->vb_flags & VFLAG_NEXT_REDO)) { */ /* We need to redo the given vbp */#if INSTALL_ENVOY_AGENTX_MASTER DYNCFG_IFCFGVBL_BEGIN(agentx_master_component) /* We set the include flag in case the object we find is an agentx object. The include flag will inform the sub agent that it should try a get of the object id before trying a next */ tvbp->ax_flags |= ENVOY_AX_FLAGS_INCLUDE; /* if agentx is installed and this is an agentx leaf we use the boundary oid as the start of the next search. we need to free what is currently in the vb_obj_id and move the boundary info into the target oid */ if (tvbp->vb_ml.ml_node->node_type & AGENTX_LEAF) { Clean_Obj_ID(&tvbp->vb_obj_id); target.num_components = tvbp->ax_search_end.num_components; target.component_list = tvbp->ax_search_end.component_list; tvbp->ax_search_end.num_components = 0; tvbp->ax_search_end.component_list = 0; tvbp->vb_ml.ml_leaf->ref_count--; if (tvbp->vb_ml.ml_leaf->ref_count == 0) SNMP_memory_free(tvbp->vb_ml.ml_leaf); tvbp->vb_ml.ml_leaf = 0; redo_flag = 0; } DYNCFG_IFCFGVBL_END(agentx_master_component)#endif /* INSTALL_ENVOY_AGENTX_MASTER */ if (redo_flag) { /* Redo is required, next proc was unable to find anything, go to next obj. Chop off any instance qualifier and increment the last subid of the object id */ target.num_components = tvbp->vb_obj_id.num_components - tvbp->vb_ml.ml_remaining_objid.num_components; target.component_list = tvbp->vb_obj_id.component_list; tvbp->vb_obj_id.component_list = 0; tvbp->vb_obj_id.num_components = 0; while(1) { if (target.num_components == 0) break; target.component_list[target.num_components-1]++; if (target.component_list[target.num_components-1]) break; target.num_components--; } } tvbp->vb_flags &= ~VFLAG_NEXT_FLAGS; if (target.num_components == 0) eret = 0; else eret = find_next_object(tvbp, &target, pktp, 1); Clean_Obj_ID(&target); switch(eret) { case 0: switch(pktp->snmp_version) {#if (INSTALL_ENVOY_SNMP_VERSION_1) case SNMP_VERSION_1: /* For version 1 we send back a NO_SUCH_NAME error */ *err_stat = NO_SUCH_NAME; pktp->pdu.std_pdu.error_index = SNMP_ERROR_INDEX(indx); indx = count; break;#endif /* (INSTALL_ENVOY_SNMP_VERSION_1) */#if (ENVOY_USE_V2_PROTOS) case SNMP_VERSION_2: case SNMP_VERSION_3: default: DYNCFG_IFCFGVBL_BEGIN(envoy_use_v2_protos) /* For version 2 we send back an END_OF_MIB exception. We set the data_flags_n_type of the current vbp to END_OF_MIB, clone the object id and tag the vbp as having been done and continue with the rest */ tvbp->vb_data_flags_n_type = VT_ENDOFMIB; tvbp->vb_flags |= VFLAG_NEXT_STARTED | VFLAG_NEXT_DONE; if (clone_object_id((&(oldvbp + indx)->vb_obj_id), &tvbp->vb_obj_id)) { /* We were unable to clone an object so we return a gen err */ *err_stat = GEN_ERR; indx = count; } DYNCFG_IFCFGVBL_END(envoy_use_v2_protos) break;#endif /* #if (ENVOY_USE_V2_PROTOS) */ } /* switch(pktp->snmp_version) { */ break; case -1: /* An internal error occurred send back a generr */ Clean_Obj_ID(&target); *err_stat = GEN_ERR; indx = count; break; default: restart_flag = 1; break; } /* switch(eret) { */ } /* for(tvbp = vbp, indx = 0; indx < count; tvbp++, indx++) { */ENVOY_AX_MA_RELEASE_WRITE_LOCK(SNMP_infrastructure_lock);if (*err_stat) return(-1);/* If necessary we loop through the vblist again and start all the nexts */if (restart_flag) { for(indx = 0, tvbp = vbp; indx < count; indx++, tvbp++) { /* If the next started flag is set then either we set it above or the nextproc of some other var bind has claimed responsibility for this var bind. In either case we skip this var bind and continue */ if (tvbp->vb_flags & (VFLAG_NEXT_STARTED | VFLAG_NEXT_DONE)) continue; ((tvbp->vb_ml.ml_leaf)->nextproc) (tvbp->vb_ml.ml_last_match, tvbp->vb_ml.ml_remaining_objid.num_components, tvbp->vb_ml.ml_remaining_objid.component_list, pktp, tvbp); tvbp->vb_flags |= VFLAG_NEXT_STARTED; } return(1); }return(0);}#if (ENVOY_USE_V2_PROTOS)/****************************************************************************NAME: SNMP_Process_Bulk_RedoPURPOSE: This is the third stage of bulk processing. To get here we have successfully finished getting information about one repetition's objects. We do a size check to determine if we need to remove some of the objects. If we have enough space we check to see if we want to try another round (if maxreps > 1 && some variable doesn't have an end of mib exception)PARAMETERS: SNMP_PKT_T * The decoded NEXT/BULK PDURETURNS: int 0 The caller should send and free the packet 1 Several nextprocs were started we need to redo this stage****************************************************************************/int SNMP_Process_Bulk_Redo(SNMP_PKT_T *pktp){VBL_T *vblp;VB_T *vbp, *tvbp, *newvbp;int count, indx, nonreps, restart_flag = 0;ALENGTH_T bufsize;sbits32_t *err_stat;/* Find the correct vblist to work with. Bulks may have several vblists chained togther, we want the last one (the only one that may have ops outstanding). The other pdus only have one vblist */for(vblp = &(pktp->pdu.std_pdu.std_vbl); vblp->vblp; vblp = vblp->vblp) ;if (((vbp = vblp->vblist) == 0) || ((count = vblp->vbl_count) == 0)) return(0);if (vblp == &(pktp->pdu.std_pdu.std_vbl)) nonreps = pktp->pdu.std_pdu.non_reps;else nonreps = 0;/* Do the size check, if the packet would exceed the maximum start removing vbs until the packet is smaller than the max. At that point we are done and can return 0 */bufsize = SNMP_Bufsize_For_Packet(pktp);if (bufsize > pktp->maxpkt) { for(indx = count, tvbp = vbp + indx - 1; indx; indx--, tvbp--) { Clean_vb(tvbp); /* Recalculate the bufsize, 2 is for the tag and length fields, the length field may be greater than 1 but that is ok, the only thing that will happen is we may put less than the maximum in a buffer */ bufsize -= 2 + tvbp->vb_seq_size; if (bufsize <= pktp->maxpkt) { vblp->vbl_count = indx - 1; return(0); } } return(0); }/* Determine if we want to try another round of nexts */if (pktp->pdu.std_pdu.max_reps <= 1) return(0);for(indx = count - nonreps, tvbp = vbp + nonreps; indx; indx--, tvbp++) if (tvbp->vb_data_flags_n_type != VT_ENDOFMIB) break;if (indx == 0) return(0);/* set up the err_stat as we shall use it several times */err_stat = &(pktp->pdu.std_pdu.error_status);/* So we want to try another round, start by decrementing the reps number then set up the next vblist in the chain */pktp->pdu.std_pdu.max_reps--; if ((vblp->vblp = VBList_Allocate(count - nonreps)) == 0) { *err_stat = GEN_ERR; return(0); }/* Attempt to find the correct object for each of the repeaters. Currently we copy all of the objs and then start any required nexts. Eventually we should copy objects tagged as ENDOFMIB (we aren't going to find anything new) and tabular objects. We will run find_next_object on scalar objects as there won't be anymore instances. *//* Try to get the infrastructure lock, we release it using the ENVOY_AX_MA_RELEASE_WRITE_LOCK macro */#if (INSTALL_ENVOY_AGENTX_MASTER && INSTALL_ENVOY_SNMP_LOCK)DYNCFG_IFCFGVBL_BEGIN(agentx_master_component)if (ENVOY_SNMP_GET_WRITE_LOCK(SNMP_infrastructure_lock)) { BUG(BUG_ENVOY_LOCKING, BUG_CONTINUABLE, 0, (BUG_OUT, "SNMP_Process_Bulk_Redo: infrastructure lock broken", 0)); *err_stat = GEN_ERR; return(0); }DYNCFG_IFCFGVBL_END(agentx_master_component)#endif/* Note: if we find an error we set indx = 0 to break the loop */for(indx = count - nonreps, tvbp = vbp + nonreps, newvbp = vblp->vblp->vblist; indx > 0; indx--, tvbp++, newvbp++) { newvbp->vb_flags = tvbp->vb_flags & VFLAG_NEXT_VCREQ; if (clone_object_id((&tvbp->vb_obj_id), (&newvbp->vb_obj_id))) { /* We were unable to clone an object so we return a gen err */ *err_stat = GEN_ERR; indx = 0; } if (tvbp->vb_data_flags_n_type == VT_ENDOFMIB) { newvbp->vb_data_flags_n_type = VT_ENDOFMIB; newvbp->vb_flags |= VFLAG_NEXT_STARTED | VFLAG_NEXT_DONE; } else { restart_flag = 1; /* And copy the mib leaf information */ newvbp->vb_ml.ml_node = tvbp->vb_ml.ml_node; newvbp->vb_ml.ml_flags = ML_IS_LEAF; newvbp->vb_ml.ml_last_match = tvbp->vb_ml.ml_last_match; newvbp->vb_ml.ml_remaining_objid.num_components = tvbp->vb_ml.ml_remaining_objid.num_components; newvbp->vb_ml.ml_remaining_objid.component_list = newvbp->vb_obj_id.component_list + newvbp->vb_obj_id.num_components - newvbp->vb_ml.ml_remaining_objid.num_components;#if INSTALL_ENVOY_AGENTX_MASTER DYNCFG_IFCFGVBL_BEGIN(agentx_master_component) /* if agentx is installed we need to move the boundary object id */ if (tvbp->vb_ml.ml_node->node_type & AGENTX_LEAF) { newvbp->ax_search_end.num_components = tvbp->ax_search_end.num_components; newvbp->ax_search_end.component_list = tvbp->ax_search_end.component_list; tvbp->ax_search_end.num_components = 0; tvbp->ax_search_end.component_list = 0; /* if possible update the reference counts */ if (tvbp->vb_ml.ml_leaf->ref_count == AX_MAX_REF_COUNT) { *err_stat = GEN_ERR; indx = 0; } tvbp->vb_ml.ml_leaf->ref_count++; } DYNCFG_IFCFGVBL_END(agentx_master_component)#endif /* INSTALL_ENVOY_AGENTX_MASTER */ } }ENVOY_AX_MA_RELEASE_WRITE_LOCK(SNMP_infrastructure_lock);if (*err_stat) return(0);if (restart_flag) { for(indx = count - nonreps, newvbp = vblp->vblp->vblist; indx; indx--, newvbp++) { /* If the next started flag is set then either we set it above or the nextproc of some other var bind has claimed responsibility for this var bind. In either case we skip this var bind and continue */ if (newvbp->vb_flags & (VFLAG_NEXT_STARTED | VFLAG_NEXT_DONE)) continue; ((newvbp->vb_ml.ml_leaf)->nextproc) (newvbp->vb_ml.ml_last_match, newvbp->vb_ml.ml_remaining_objid.num_components, newvbp->vb_ml.ml_remaining_objid.component_list, pktp, newvbp); newvbp->vb_flags |= VFLAG_NEXT_STARTED; } return(1); }else return(0);}#endif /* #if (ENVOY_USE_V2_PROTOS) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -