📄 ax_mhlpf.c
字号:
/* * Copyright 2001-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//* * $Log: ax_mhlpf.c,v $ * Revision 1.2 2001/11/06 21:20:02 josh * revised new path hacking * * Revision 1.1.1.1 2001/11/05 17:47:41 tneale * Tornado shuffle * * Revision 1.1.2.4 2001/08/17 20:45:12 meister * Add function prototypes * * Revision 1.1.2.3 2001/08/16 19:45:59 josh * fix handling of nodes that aren't in the current view and * how AgentX skips over them. * * Revision 1.1.2.2 2001/08/07 21:53:30 meister * reworked to use dynamic component configuration macros, to allow * separate vxworks agentx components * *//* [clearcase]modification history-------------------01b,18apr05,job update copyright notices01a,24nov03,job update copyright information*//* moved the ax helper routines for find next object here from mibnext.c * to separate out ax code into a separate ax component */#include <wrn/wm/snmp/engine/asn1conf.h>#include <wrn/wm/snmp/engine/asn1.h>#include <wrn/wm/snmp/engine/snmpdefs.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/mib.h>#include <wrn/wm/snmp/engine/objectid.h>#include <wrn/wm/snmp/engine/view.h>#include <wrn/wm/snmp/engine/agentx.h>/* in mib_next.c */extern int _snmp_leaf_check(SNMP_PKT_T *, VB_T *, MIBLEAF_T *, OBJ_ID_T *, int, int);#if INSTALL_ENVOY_AGENTX_MASTER#define AX_HELP_ERROR -1#define AX_HELP_FOUND 0#define AX_HELP_SKIP 1#define AX_HELP_USE 2#define AX_HELP_LM 3/* _snmp_find_next_helper_ax is used when find_next_helper encounters an interior leaf node. It determines if there are any useable leaf nodes under the interior leaf or the instance for use with the parent node. return codes: -1 error, 0 leaf found, 1 skip this branch, 2 use leaf, 3 needs last match */int _snmp_find_next_helper_ax(MIBNODE_T *np, int tcount, OIDC_T *tlist, OBJ_ID_T *robj, int rcount, VB_T *vbp, SNMP_PKT_T *pktp, int check_flag){int eret;MIBLEAF_T *lp;if (rcount > robj->num_components) { OIDC_T *nlist; nlist = (OIDC_T *)SNMP_memory_alloc((robj->num_components + 4) * sizeof(OIDC_T)); if (nlist == 0) return(AX_HELP_ERROR); MEMCPY(nlist, robj->component_list, robj->num_components * sizeof(OIDC_T)); SNMP_memory_free(robj->component_list); robj->component_list = nlist; robj->num_components = robj->num_components + 4; }/* We have a leaf node, if it is in our view we set up the info we want to return. Finish building the object by attaching any remaining target information (this will be instance info). We don't worry about running out of space in the result buffer as the only way we have instance information is if we didn't modify the target oid and we allocated enough space to hold the entire target oid. */if ((np->node_type & NODE_TYPE) == LEAF_NODE) { /* Cast the structure so it's easier to work with */ lp = (MIBLEAF_T *)np; switch(_snmp_leaf_check(pktp, vbp, lp, robj, rcount, check_flag)) { case VIEW_EXCLUDED: return(AX_HELP_SKIP); case VIEW_INDETERMINATE: vbp->vb_flags |= VFLAG_NEXT_VCREQ; break; } if (tcount) { MEMCPY(robj->component_list + rcount, tlist, tcount * sizeof(OIDC_T)); vbp->vb_ml.ml_remaining_objid.component_list = robj->component_list + rcount; } else { vbp->vb_ml.ml_remaining_objid.component_list = 0; } vbp->vb_ml.ml_remaining_objid.num_components = tcount; robj->num_components = rcount + tcount; vbp->vb_ml.ml_node = np; vbp->vb_ml.ml_flags = ML_IS_LEAF; return(AX_HELP_LM); }else { /* inner node */ MIBARC_T *ap = np->arcs; OIDC_T node_id, *temp_list; int temp_count, vc = 0; if (np->leaf) { vc = _snmp_leaf_check(pktp, vbp, np->leaf, robj, rcount, check_flag); if (vc == VIEW_EXCLUDED) return(AX_HELP_SKIP); } if (tcount > 0) { for(; ap->nodep && (ap->id < *tlist); ap++) ; node_id = *tlist; temp_count = tcount - 1; temp_list = tlist + 1; } else { node_id = 0; temp_count = 0; temp_list = 0; /* set the include flag so that we will get this item if its both an agentx and instance object */ vbp->ax_flags |= ENVOY_AX_FLAGS_INCLUDE; } if (ap->nodep && (node_id == ap->id)) { eret = 0; for(; ap->nodep && (ap->id == node_id); ap++) { robj->component_list[rcount] = node_id; eret = _snmp_find_next_helper_ax((MIBNODE_T *)ap->nodep, temp_count, temp_list, robj, rcount + 1, vbp, pktp, check_flag); if ((eret == AX_HELP_ERROR) || (eret == AX_HELP_FOUND)) return(eret); if (eret == AX_HELP_LM) { vbp->vb_ml.ml_last_match = node_id; return(AX_HELP_FOUND); } if (eret == AX_HELP_USE) { if (tcount || node_id || vbp->vb_ml.ml_remaining_objid.num_components) vbp->vb_ml.ml_remaining_objid.num_components++; vbp->vb_ml.ml_remaining_objid.component_list--; break; } node_id++; if (node_id == 0) return(AX_HELP_SKIP); if (eret == AX_HELP_SKIP) robj->component_list[rcount] = node_id; /* set the include flag so that we will get this item if its both an agentx and instance object */ vbp->ax_flags |= ENVOY_AX_FLAGS_INCLUDE; temp_count = 0; temp_list = 0; eret = 0; } if (eret == 0) { vbp->vb_ml.ml_remaining_objid.num_components = 1; vbp->vb_ml.ml_remaining_objid.component_list = robj->component_list + rcount; robj->num_components = rcount + 1; } } else { if (tcount) { MEMCPY(robj->component_list + rcount, tlist, tcount * sizeof(OIDC_T)); } vbp->vb_ml.ml_remaining_objid.num_components = tcount; /* The following line must be done even if we have no remaining objects to allow the routine to determine remaining objects by backing up on the list (comp_list--) */ vbp->vb_ml.ml_remaining_objid.component_list = robj->component_list + rcount; robj->num_components = rcount + tcount; } if (np->leaf) { if (vc == VIEW_INDETERMINATE) vbp->vb_flags |= VFLAG_NEXT_VCREQ; vbp->vb_ml.ml_leaf = np->leaf; vbp->vb_ml.ml_flags = ML_IS_LEAF; return(AX_HELP_LM); } else { return(AX_HELP_USE); } }}/****************************************************************************NAME: find_bound_helperPURPOSE: recursivly descend the tree looking for any bounds on the current object.PARAMETERS: MIBNODE_T * node to process bits32_t id of session for the original leaf OBJ_ID_T * return object int how many levels down we are int number of target subids left OIDC_T * pointer to list of unused target subidsRETURNS: int -1 - error, 0 no bound found, 1 bound found****************************************************************************/#define AX_BOUND_HELP_ERROR -1#define AX_BOUND_HELP_NOBOUND 0#define AX_BOUND_HELP_BOUND 1static int find_bound_helper(MIBNODE_T *mibnode, bits32_t session_id, OBJ_ID_T *robj, int num_comp, int tcount, OIDC_T *tlist){MIBARC_T *ap;MIBLEAF_T *mibleaf;OIDC_T *clist;/* Try to find a leaf */if ((mibnode->node_type & NODE_TYPE) == LEAF_NODE) mibleaf = (MIBLEAF_T *)mibnode;else mibleaf = mibnode->leaf;/* If we have a leaf that isn't for the current session we build the return object id, which will be filled in by the calling routine(s). then return indicating a bound. If we aren't bounded and this is a true leaf node we indicate no bound to our caller otherwise we fall through and test any children for bounding */ if (mibleaf) { if (mibleaf->session_id != session_id) { if (num_comp == 0) return(AX_BOUND_HELP_BOUND); clist = (OIDC_T *)SNMP_memory_alloc(num_comp * sizeof(OIDC_T)); if (clist == 0) return(-1); robj->component_list = clist; robj->num_components = num_comp; return(AX_BOUND_HELP_BOUND); } if (mibleaf == (MIBLEAF_T *)mibnode) return(AX_BOUND_HELP_NOBOUND); }/* If we have a target list skip all of the arcs before the desired node. If the desired nodes exists check it for a bounding node, if we have one add the current subid to the return object id */ap = mibnode->arcs;if (tcount) { for(; ap->nodep && (ap->id < *tlist); ap++) ; if (ap->nodep && (*tlist == ap->id)) { switch(find_bound_helper((MIBNODE_T *)ap->nodep, session_id, robj, num_comp + 1, tcount - 1, tlist + 1)) { case AX_BOUND_HELP_ERROR: return(AX_BOUND_HELP_ERROR); case AX_BOUND_HELP_BOUND: robj->component_list[num_comp] = ap->id; return(AX_BOUND_HELP_BOUND); } ap++; } }/* The target list didn't provide a boundary, try stepping through the rest of the arcs */for(; ap->nodep; ap++) { switch(find_bound_helper((MIBNODE_T *)ap->nodep, session_id, robj, num_comp + 1, 0, 0)) { case AX_BOUND_HELP_ERROR: return(AX_BOUND_HELP_ERROR); case AX_BOUND_HELP_BOUND: robj->component_list[num_comp] = ap->id; return(AX_BOUND_HELP_BOUND); } }/* no boundary was found */return(AX_BOUND_HELP_NOBOUND);}/****************************************************************************NAME: _snmp_find_next_boundPURPOSE: Find the boundary object id for the given vbp. The vbp must have the mib leaf information correctly set, probably via find_next_object. The boundary id will be inserted into the vb, if no boundary is found we put nothing into the vb.PARAMETERS: MIBNODE_T * root node to use VB_T * vb under discussion RETURNS: int 0 on success****************************************************************************/int _snmp_find_next_bound(MIBNODE_T *mibroot, VB_T *vbp){MIBNODE_T *mibnode = 0, *mibparent = 0;OBJ_ID_T objid;OIDC_T *clist, oldid;int num_comp;MIBARC_T *arcs = 0;num_comp = vbp->vb_obj_id.num_components - vbp->vb_ml.ml_remaining_objid.num_components;if (num_comp > 1) { objid.num_components = num_comp-1; objid.component_list = vbp->vb_obj_id.component_list; (void) Find_Node_From_Root(mibroot, &objid, &mibparent); } else if (num_comp == 1) { objid.num_components = num_comp-1; objid.component_list = vbp->vb_obj_id.component_list; mibparent = mibroot; }/* It would be nice to make sure that our parent is actually a MIBNODE_T and not a MIBLEAF_T. */if ((mibparent->node_type & NODE_TYPE) == LEAF_NODE) return(-1);if (num_comp) { for (arcs = mibparent->arcs; arcs->nodep; arcs++) { if (arcs->id == objid.component_list[num_comp-1]) { mibnode = (MIBNODE_T *) arcs->nodep; break; } } if (!mibnode) return(-1); } else { mibnode = mibroot; } if ((mibnode->node_type & NODE_TYPE) == INNER_NODE) { switch(find_bound_helper(mibnode, vbp->vb_ml.ml_leaf->session_id, &vbp->ax_search_end, num_comp, vbp->vb_ml.ml_remaining_objid.num_components, vbp->vb_ml.ml_remaining_objid.component_list)) { case AX_BOUND_HELP_ERROR: return(-1); case AX_BOUND_HELP_BOUND: if (num_comp) MEMCPY(vbp->ax_search_end.component_list, objid.component_list, num_comp * sizeof(OIDC_T)); return(0); case AX_BOUND_HELP_NOBOUND: break; } }if (num_comp == 0) return(0);for (oldid = arcs->id, arcs += 1; (arcs->nodep && (arcs->id == (oldid + 1))); arcs++, oldid++) { if ((((MIBNODE_T *)(arcs->nodep))->node_type & NODE_TYPE) == LEAF_NODE) { if (((MIBLEAF_T*)(arcs->nodep))->session_id != vbp->vb_ml.ml_leaf->session_id) break; else continue; } if ((((MIBNODE_T *)(arcs->nodep))->leaf == 0) || (((MIBNODE_T *)(arcs->nodep))->leaf->session_id != vbp->vb_ml.ml_leaf->session_id)) { break; } switch(find_bound_helper((MIBNODE_T *)arcs->nodep, vbp->vb_ml.ml_leaf->session_id, &vbp->ax_search_end, num_comp, 0, 0)) { case AX_BOUND_HELP_ERROR: return(-1); case AX_BOUND_HELP_BOUND: if (num_comp > 1) { MEMCPY(vbp->ax_search_end.component_list, objid.component_list, (num_comp-1) * sizeof(OIDC_T)); } vbp->ax_search_end.component_list[num_comp-1] = oldid + 1; return(0); } }if ((clist = (OIDC_T *)SNMP_memory_alloc(num_comp * sizeof(OIDC_T))) == 0) return(-1);if (num_comp > 1) MEMCPY(clist, objid.component_list, (num_comp - 1) * sizeof(OIDC_T));clist[num_comp-1] = oldid;while((++clist[num_comp - 1]) == 0) { num_comp--; if (num_comp == 0) { SNMP_memory_free(clist); return(0); } }vbp->ax_search_end.component_list = clist;vbp->ax_search_end.num_components = num_comp;return(0);}#endif /* #if INSTALL_ENVOY_AGENTX_MASTER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -