📄 mib_next.c
字号:
/* * Copyright 2000-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. *//* * Copyright 1988-1997 Epilogue Technology Corporation. * Copyright 1998 Integrated Systems, Inc. * All rights reserved. *//* * $Log: mib_next.c,v $ * Revision 1.4 2003/01/15 14:05:05 josh * directory structure shifting * * Revision 1.3 2001/11/06 21:50:47 josh * second (and hopefully final) pass of new path hacking * * Revision 1.2 2001/11/06 21:20:15 josh * revised new path hacking * * Revision 1.1.1.1 2001/11/05 17:47:43 tneale * Tornado shuffle * * Revision 9.6.4.1 2001/08/07 21:53:32 meister * reworked to use dynamic component configuration macros, to allow * separate vxworks agentx components * * Revision 9.6 2001/04/11 20:12:02 josh * merging changes from the kingfisher branch back onto * the trunk * * Revision 9.5 2001/01/19 22:22:22 paul * Update copyright. * * Revision 9.4.2.2 2001/03/12 22:08:19 tneale * Updated copyright * * Revision 9.4.2.1 2000/10/13 21:17:36 josh * function prototypes and static declarations to eliminate warnings * from the Tornado compiler * * Revision 9.4 2000/03/17 00:19:08 meister * Update copyright message * * Revision 9.3 2000/02/29 21:39:18 sar * Handle short registrations (a single subid) better in find_next_bound. * Previously we could use an uninitialized pointer and try to copy a zero * length string. * * Revision 9.2 1999/09/15 16:20:01 josh * adding a break to a switch statement to make a compiler happy * * Revision 9.1 1999/03/15 17:04:28 josh * make tree walking agentx subagents more efficient * * Revision 9.0 1998/10/16 22:11:41 sar * Update version stamp to match release * * Revision 8.4 1998/06/22 03:34:27 sar * Cast some things to unsigned ints to try and keep compilers happy * * Revision 8.3 1998/06/05 18:53:14 sra * "#include <foo.h>" => "#include <envoy/h/foo.h>". * * Revision 8.2 1998/05/24 04:47:14 sar * Change the ifdef code to depend on DYNAMIC_VIEWS instead of RFC1445_VIEWS. * also modified the view_check call to use view_family_check this means * the routine that called the mib routines must also have set up the * view family. * * Revision 8.1 1998/02/25 04:52:02 sra * Update copyrights. * * Revision 8.0 1997/11/18 00:56:52 sar * Updated revision to 8.0 * * Revision 1.2 1997/10/22 03:10:22 sar * Modified the installation options for agentx and the older sub agent scheme * * Also moved the allocation of the locks into envoy_init (env_init.c), * so they can be initialized if necessary. * * Revision 1.1 1997/10/16 00:35:06 sar * Result of the break up of the mibutils.c file. These were broken * out to allow for better granularity and smaller size for customers * that weren't using all of the functions in mibutils.c * *//* [clearcase]modification history-------------------01b,18apr05,job update copyright notices01a,24nov03,job update copyright information*//* moved the routines for find next object here from mibutils.c (where the revision log lives) to allow for better granularity of code. */#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/common/dyncfg.h>DYNCFG_VBL_DECLARE_EXTERN(agentx_master_component)DYNCFG_EXTERN_FUNCPTR8(_snmp_find_next_helper_ax, int, MIBNODE_T *, int, OIDC_T*, OBJ_ID_T *, int, VB_T *, SNMP_PKT_T *, int)DYNCFG_EXTERN_FUNCPTR2(_snmp_find_next_bound, int, MIBNODE_T *, VB_T *)extern int _snmp_find_next_helper_ax(MIBNODE_T *, int, OIDC_T *, OBJ_ID_T *,int, VB_T *vbp, SNMP_PKT_T *, int);extern int_snmp_find_next_bound(MIBNODE_T *, VB_T *);int _snmp_leaf_check(SNMP_PKT_T *pktp, VB_T *vbp, MIBLEAF_T *lp, OBJ_ID_T *robj, int rcount, int check_flag){/* An inactive leaf is the same as the leaf not existing, if the inactive flag is set return an error indicating no leaf found */if (lp->node_type & LEAF_INACTIVE) return(VIEW_EXCLUDED);/* We also skip objects that don't allow read access */if (((lp->access_type) & READ_ACCESS) == 0) return(VIEW_EXCLUDED);/* If we have v1 installed and don't have use_v2_types installed then we may have objects that have types that shouldn't be used in a v1 setting. We need to test for that case (v1 && !v2_types) and skip any objects that have v2 types if this is a v1 packet */#if (INSTALL_ENVOY_SNMP_VERSION_1 && !(INSTALL_ENVOY_SNMP_USE_V2_TYPES)) if ((pktp->snmp_version == SNMP_VERSION_1) && (lp->expected_tag == VT_COUNTER64)) return(VIEW_EXCLUDED);#endif#if (INSTALL_ENVOY_MAIN_AGENT)if (check_flag) { /* Check if the variable is within the given view of the MIB. The customer chooses which view mechanism to use at compile time. */#if (INSTALL_ENVOY_SNMP_DYNAMIC_VIEWS) return(SNMP_View_Family_Check(pktp, robj->component_list, rcount, VIEW_CHECK_IND));#else /* (INSTALL_ENVOY_SNMP_DYNAMIC_VIEWS) */ if ((lp->view_mask & pktp->mib_view) == 0) return (VIEW_EXCLUDED);#endif /* (INSTALL_ENVOY_SNMP_DYNAMIC_VIEWS) */ }#endif /* INSTALL_ENVOY_MAIN_AGENT */return(VIEW_INCLUDED);}/* return codes: -1 error, 0 leaf found, 1 no leaf found */static int find_next_helper(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 + MAX_OID_COUNT > robj->num_components) { OIDC_T *nlist; nlist = (OIDC_T *)SNMP_memory_alloc((unsigned int) ((robj->num_components + 4) * sizeof(OIDC_T))); if (nlist == 0) return(-1); 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; } if ((np->node_type & NODE_TYPE) == INNER_NODE) { MIBARC_T *ap = np->arcs; /* if agentx is installed we see if we have an interior leaf. if we do we send it to an agentx specific routine to figure out if the leaf is within our view and if there are any other leaves in that leave's subtree */#if INSTALL_ENVOY_AGENTX_MASTER DYNCFG_IFCFGVBL_BEGIN(agentx_master_component) if (np->leaf) { eret = DYNCFG_FUNCALL(_snmp_find_next_helper_ax) (np, tcount, tlist, robj, rcount, vbp, pktp, check_flag); if (eret == 3) return(0); else return(eret); } DYNCFG_IFCFGVBL_END(agentx_master_component)#endif /* INSTALL_ENVOY_AGENTX_MASTER */ /* if we have a target object id then we need to skip any arcs that come "before" the target. If one matches the target we need to check if it has a "next" at a lower level If there isn't a target or for the arcs "after" the target we need to check if any of those provide a usable next */ if (tcount > 0) { for(; ap->nodep && (ap->id < *tlist); ap++) ; if (ap->nodep && (ap->id == *tlist)) { vbp->vb_ml.ml_last_match = ap->id; robj->component_list[rcount] = ap->id; eret = find_next_helper((MIBNODE_T *)ap->nodep, tcount - 1, tlist + 1, robj, rcount + 1, vbp, pktp, check_flag); if (eret <= 0) return (eret); ap++; } } /* If we have no target object id at this level, then */ /* we need to scan the available arcs, from the lowest */ /* to the highest, to see if any of them can provide */ /* a usable "next". */#if INSTALL_ENVOY_AGENTX_MASTER DYNCFG_IFCFGVBL_BEGIN(agentx_master_component) /* 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; DYNCFG_IFCFGVBL_END(agentx_master_component)#endif /* INSTALL_ENVOY_AGENTX_MASTER */ for(; ap->nodep; ap++) { robj->component_list[rcount] = ap->id; vbp->vb_ml.ml_last_match = ap->id; eret = find_next_helper((MIBNODE_T *)(ap->nodep), 0, 0, robj, rcount + 1, vbp, pktp, check_flag); if (eret <= 0) return (eret); } return(1); }else { /* node_type != INNER_NODE, i.e. it must be of type LEAF_NODE */ /* 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. */ /* 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(1); 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(0); }/*NOTREACHED*/}/****************************************************************************NAME: find_next_objectPURPOSE: Given an object identifier, find the "next" SNMP object using SNMP's notion of lexicographic ordering of object identifiers. The "next" object may be a leaf node of the MIB tree or an object within a tabular structure. In the latter case, located object id will pass through the leaf node representing the table. We install an object id and some mib leaf info into the given var bind. The returned object id, unless null, will be a valid id for the next routine named in the leaf node for the object.PARAMETERS: VB_T * The vb structure to store the results, we put the result object id, and some mib leaf info into it. OBJ_ID_T * The target oid to start with. SNMP_PKT_T * The received packet int Do the view check (1) or not (0)RETURNS: int > 0 for success, 0 if nothing found, -1 for internal failure. On success, the object identifier referenced by the vbp will contain the resulting object id.Note that the for the bulk of find_next_object and find_next helper weuse the num_components field in the result objid as the amount of spacewe have allocated in the componet_list field. Rcount is the actual numberof components.****************************************************************************/int find_next_object(VB_T *vbp, OBJ_ID_T *targetp, SNMP_PKT_T *pktp, int check_flag){OBJ_ID_T *resultp;MIBNODE_T *np;int eret;/* Set result to point to the objid in the vbp (where we want the result) */resultp = &(vbp->vb_obj_id);resultp->num_components = max(targetp->num_components, 16 + MAX_OID_COUNT);resultp->component_list = (OIDC_T *)SNMP_memory_alloc((unsigned int) (resultp->num_components * sizeof(OIDC_T)));if (resultp->component_list == 0) return(-1);if (pktp->mib_root) np = pktp->mib_root;else np = &(ENVOY_MIB_ROOT_NODE);eret = find_next_helper(np, targetp->num_components, targetp->component_list, resultp, 0, vbp, pktp, check_flag);if (eret) { Clean_Obj_ID(resultp); if (eret > 0) return(0); else return(-1); }#if INSTALL_ENVOY_AGENTX_MASTERDYNCFG_IFCFGVBL_BEGIN(agentx_master_component)/* if agentx is installed and this is an agentx leaf we need to find the boundary oid. We also need to update the reference counter */if (vbp->vb_ml.ml_node->node_type & AGENTX_LEAF) { if (DYNCFG_FUNCALL(_snmp_find_next_bound) (np, vbp) || (vbp->vb_ml.ml_leaf->ref_count == AX_MAX_REF_COUNT)) { Clean_Obj_ID(resultp); return(-1); } vbp->vb_ml.ml_leaf->ref_count++; }DYNCFG_IFCFGVBL_END(agentx_master_component)#endif /* INSTALL_ENVOY_AGENTX_MASTER */return (resultp->num_components);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -