📄 mibutils.c
字号:
* Specify where to look for the node.* \i <**npp>* Point to a leaf node.* \ie** RETURNS: This routine returns one of three codes.* \ml* \m -* If all components of the object ID have been consumed, it returns 0 and sets * <npp> to a pointer to the node.* \m -* If a leaf node was encountered before all of the components were consumed, it * returns 1 and sets <npp> to a pointer to the node.* \m -* If an object identifier component does not match any of the choices at an * inner node, it returns 2 and sets <npp> to 0.* \me** ERRNO: N/A** SEE ALSO: Add_Node_From_Root(), Remove_Node_From_Root()*/sbits32_t Find_Node_From_Root(MIBNODE_T *root, OBJ_ID_T *objp, MIBNODE_T **npp){MIBNODE_T *np;MIBARC_T *ap;OIDC_T *compp; /* Current object id component of interest */int comp_num; /* Index of current object id component *//* find the proper root of the tree */if (root) np = root;else np = &(ENVOY_MIB_ROOT_NODE);for(comp_num = objp->num_components, compp = objp->component_list; ((np->node_type & NODE_TYPE) == INNER_NODE) && (comp_num > 0); comp_num--, compp++) { for(ap = np->arcs; (MIBNODE_T *)(ap->nodep) != 0; ap++) { if (ap->id == *compp) break; } /* If we fall through the arcs, then we have failed in the search */ if ((MIBNODE_T *)(ap->nodep) == 0) { *npp = 0; return (2); } /* we found a matching arc so we step down to the next level of the tree */ np = (MIBNODE_T *)(ap->nodep); }/* We have a node, set up to return it to the caller, then check if we have consumed all the identifiers. If we haven't we return 1 otherwise return 0 */*npp = np;if (comp_num > 0) return(1);else return(0);}/********************************************************************************* Add_Node_From_Root - add node to the specified MIB tree at the specified point* SYNOPSIS** \cs* int Add_Node_From_Root* (* MIBNODE_T * root, * OBJ_ID_T * objp, * MIBNODE_T * anode,* MIBNODE_T ** rnode* )* \ce** DESCRIPTION** This routine adds a node to a MIB tree at the specified point. Use this * routine when you are writing an SNMP agent or server rather than in SNMP * managers or clients. This routine also creates any missing branches to * connect the new node. If there is an error any new branches are freed.** \&NOTE: It is up to the calling routine to free <rnode>.** PARAMETERS* \is* \i <*root>* Specify the MIB tree root. To specify the default MIB tree, set this value to * 0.* \i <*objp>* Specify where to add the new node.* \i <*anode>* Specify the node to add. When you build a node, pay particular attention to * the <node_type> field. The flags in this field specify the type of the node * and how to handle the node. You can use these options to make the node * removable and replaceable or mark the node and any arcs or cookies that it * points to as dynamic. Once you install a node, you can not change its flags * to make it replaceable or removable.* \i <**rnode>* Specify a replaceable node. If a replaceable node already exists at that * point in the tree, this routine unlinks it and returns a pointer to it in * <rnode>.* \ie** RETURNS: If successful, this routine returns 0. If a general error occurs, * for example, a memory allocation failure, it returns 1. If it is unable to * attach the node because the MIB contains a leaf, it returns 2. If there is an * unreachable node at the specified location, it returns 3. If a replaceable * node exists but it is different type, for example, an inner node rather than * a leaf node, it returns 4. If the object ID was invalid, it returns 5.** ERRNO: N/A** SEE ALSO: Find_Node_From_Root(), Remove_Node_From_Root()*/int Add_Node_From_Root(MIBNODE_T *root, OBJ_ID_T *objp, MIBNODE_T *anode, MIBNODE_T **rnode){MIBNODE_T *np, *newnode;MIBARC_T *ap = 0, *newarc, *savearc;OIDC_T *compp; /* Current object id component of interest */int comp_num; /* Index of current object id component */int num_arcs; /* number of arcs, for allocating more space *//* Make sure the objid is acceptable */if (objp->num_components < 1) return(5);/* Set the replaced node to be 0 in case we don't have a node to return */*rnode = 0;/* find the proper root of the tree */if (root) np = root;else np = &(ENVOY_MIB_ROOT_NODE);/* find the last matching node in the given object id */for(comp_num = objp->num_components, compp = objp->component_list; ((np->node_type & NODE_TYPE) == INNER_NODE) && (comp_num > 0); comp_num--, compp++, np = (MIBNODE_T *)(ap->nodep)) { for(ap = np->arcs; (MIBNODE_T *)(ap->nodep) != 0; ap++) { if (ap->id == *compp) break; } /* If we are out of arcs we use the current node else we had a matching arc and we continue to the next level */ if ((MIBNODE_T *)(ap->nodep) == 0) break; }/* Take care of the simple cases first, if we are out of sub ids we are at the point where we would add the new node, so we do some tests to make sure we don't destroy a leaf or overwrite something that can't be overwritten or overwrite a leaf with an inner node or vice versa. If none of the tests fail we simply change the pointer in the arc list to point to the new node. */if (comp_num == 0) { if ((np->node_type & NODE_TYPE) == LEAF_NODE) { if ((((MIBLEAF_T *)np)->node_type & REPLACEABLE) == 0) return(3); if ((anode->node_type & NODE_TYPE) != LEAF_NODE) return(4); *rnode = np; ap->nodep = (MIBARC_T *)anode; return(0); } else { if ((np->node_type & REPLACEABLE) == 0) return(3); if ((anode->node_type & NODE_TYPE) != INNER_NODE) return(4); *rnode = np; ap->nodep = (MIBARC_T *)anode; return(0); } }/* If we are here we have more sub ids left. We check that the last node we matched isn't a leaf node (we need an inner node to hook the subtree we are about to create onto) and then we start building the subtree. */if ((np->node_type & NODE_TYPE) == LEAF_NODE) return(2);/* We work from the leaf back to the current tree, allocate the arc space fill it in (including the terminator), allocate the next level node, connect the arcs to it and repeat */for (newnode = anode; comp_num > 1; comp_num--) { newarc = (MIBARC_T *)SNMP_memory_alloc(sizeof(MIBARC_T) * 2); if (newarc == 0) { /* free any memory allocated for this branch */ branch_free(newnode, anode); return(1); } newarc[0].id = compp[comp_num - 1]; newarc[0].nodep = (MIBARC_T *)newnode; newarc[1].id = 0; newarc[1].nodep = 0; if ((newnode = (MIBNODE_T *)SNMP_memory_alloc(sizeof(MIBNODE_T))) == 0) { /* free any memory allocated for this branch */ newnode = (MIBNODE_T *)(newarc->nodep); SNMP_memory_free(newarc); branch_free(newnode, anode); return(1); } MEMSET(newnode, 0, sizeof(MIBNODE_T)); newnode->node_type = INNER_NODE | NODE_DYNAMIC | ARC_DYNAMIC | SYSTEM_OWNED; newnode->arcs = newarc; }/* num_arcs is the number of arcs in the current list */for(num_arcs = 1, ap = np->arcs; (MIBNODE_T *)(ap->nodep) != 0; ap++) num_arcs++;/* add one to num_arcs for the new arc we are adding */newarc = (MIBARC_T *)SNMP_memory_alloc((unsigned int) (sizeof(MIBARC_T) * (num_arcs + 1)));if (newarc == 0) { /* free the branch */ branch_free(newnode, anode); return(1); }/* copy all arcs less then the new arc, then add the new arc *//* then copy all the arcs after the new arc, there will always be at least one, the terminator */savearc = newarc;for(ap = np->arcs; (ap->id < *compp) && ((MIBNODE_T *)(ap->nodep) != 0); ap++, newarc++, num_arcs--) MEMCPY(newarc, ap, sizeof(MIBARC_T));newarc->id = *compp;newarc->nodep = (MIBARC_T *)newnode;newarc++;MEMCPY(newarc, ap, sizeof(MIBARC_T) * num_arcs);/* now clean up, if necessary free the old arc list then tag the node so that the new arc list will be freed when released */ap = np->arcs;np->arcs = savearc;if (np->node_type & ARC_DYNAMIC) SNMP_memory_free(ap);np->node_type |= ARC_DYNAMIC;return 0;}/********************************************************************************* Remove_Node_From_Root - remove a node from the MIB tree* SYNOPSIS** \cs* MIBNODE_T * Remove_Node_From_Root* ( * MIBNODE_T * root * OBJ_ID_T * objp * )* \ce** DESCRIPTION** This routine removes a node from the MIB tree and any branches that exist * only to connect that node to the tree. Use this routine when you are writing * an SNMP agent or server rather than in SNMP managers or clients.** \&NOTE: The caller must free any allocated space associated with the node.** PARAMETERS* \is* \i <*root>* Specify the MIB tree root. To specify the default MIB tree, set this value to * 0.* \i <*objp>* Specify where to look for the node.* \ie** RETURNS: If successful, this routine returns the MIB node being removed. If * it does not find a node, it returns 0.** ERRNO: N/A** SEE ALSO: Add_Node_From_Root()*/MIBNODE_T * Remove_Node_From_Root(MIBNODE_T *root, OBJ_ID_T *objp){MIBNODE_T *np, *bnode;MIBARC_T *ap;OIDC_T barc, *compp; /* Current object id component of interest */int comp_num; /* Index of current object id component */if (objp->num_components < 1) return(0);/* find the proper root of the tree */if (root) np = root;else np = &(ENVOY_MIB_ROOT_NODE);bnode = np;/* find the last matching node in the given object id */for(comp_num = objp->num_components, compp = objp->component_list, barc = *compp; ((np->node_type & NODE_TYPE) == INNER_NODE) && (comp_num > 0); comp_num--, compp++, np = (MIBNODE_T *)(ap->nodep)) { /* If we have multiple branches descending from this node or this node isn't owned by the system we update the branch node pointer (which will control what gets removed along with the specified node). */ ap = np->arcs; if (((np->node_type & SYSTEM_OWNED) == 0) || ((MIBNODE_T *)(ap[1].nodep) != 0)) { bnode = np; barc = *compp; } /* step through the arcs (ap is already pointing to the beginning of the arcs) looking for the current subid. If we hit a null node pointer we have run out of arcs and the node we were looking for doesn't exist so we return a 0 for an error */ for(; ; ap++) { if (ap->id == *compp) break; if ((MIBNODE_T *)(ap->nodep) == 0) return(0); }#if INSTALL_ENVOY_AGENTX_MASTER DYNCFG_IFCFGVBL_BEGIN(agentx_master_component) /* if agentx is installed we want to set the branch pointer in front of inner nodes that also have direct pointers to leaves but that aren't the node to remove. This will allow us to keep those leaves by moving them into the arc list in place of the node */ if (((MIBNODE_T *)ap->nodep)->leaf && (comp_num != 1)) { bnode = np; barc = *compp; } DYNCFG_IFCFGVBL_END(agentx_master_component)#endif }/* np should point to the node we want to remove, bnode points to the last node before the branch that should be removed from the tree and barc is the id of the branch coming out of bnode's arc list that connects to np *//* first some tests, we see if we used all of the subids and if the node is removeable */if ((comp_num != 0) || ((np->node_type & REMOVABLE) == 0)) return(0);/* Now we unlink the branch from the tree *//* Find the arc to remove then either copy all the arcs above it down by one arc structure or if agentx is installed we might need to move a leaf pointer from the first node in the branch to the arc list in its place. In either case save a pointer to the branch to be removed. */for(ap = bnode->arcs; ap->id != barc; ap++) ;bnode = (MIBNODE_T *)ap->nodep;#if INSTALL_ENVOY_AGENTX_MASTERDYNCFG_IFCFGVBL_BEGIN(agentx_master_component)if ((bnode != np) && (bnode->leaf)) { ap->nodep = (MIBARC_T *)bnode->leaf; branch_free(bnode, np); return(np); }DYNCFG_IFCFGVBL_END(agentx_master_component)#endiffor(; ((MIBNODE_T *)(ap->nodep) != 0); ap++) MEMCPY(ap, (ap + 1), sizeof(MIBARC_T));/* Free the branch */branch_free(bnode, np);/* return the node */return(np);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -