📄 ax_ma.c
字号:
the first time we check that the nodes we are to remove are in the reg list and generate an error if they aren't. the second time we update the mib tree as necessary PARAMETERS: ENVOY_AX_PKT_T * decoded packet to process OIDC_T pointer to component list of starting OID bits8_t index of component to range, or 0 bits8_t priority of this registration OIDC_T upper bound on ranged component, if any ENVOY_AX_CONTEXT_T * context structure, contains the mibrootRETURNS: bits16_t the error status for the response message 0 means no error, the error list is from the agentx spec.****************************************************************************/static bits16_t ax_ma_deregister_helper (int axpkt_num_comps, OIDC_T *axpkt_comp_list, bits8_t axpkt_range, bits8_t axpkt_priority, OIDC_T axpkt_bound, ENVOY_AX_CONTEXT_T *context){OIDC_T start_oid, end_oid, *comp_list;bits8_t range_id, priority;int num_comps;MIBLEAF_T *mleaf;OBJ_ID_T objid;ENVOY_AX_MA_REGLIST_T *thisptr, *regptr, *listptr;/* determine what information to use */num_comps = axpkt_num_comps;comp_list = axpkt_comp_list;range_id = axpkt_range;priority = axpkt_priority;if (range_id) { range_id--; start_oid = comp_list[range_id]; end_oid = axpkt_bound; }else { start_oid = comp_list[range_id]; end_oid = start_oid; }objid.component_list = comp_list;objid.num_components = num_comps;/* Go through the reg list and get the registration that matches this */for (thisptr = envoy_ax_registration_list; thisptr; thisptr = thisptr->next) { if ((thisptr->context_id == context->id) && (thisptr->priority == priority) && (oidcmp (thisptr->start_oid.num_components, thisptr->start_oid.component_list, objid.num_components, objid.component_list)) && (thisptr->range_id == axpkt_range)) { if (thisptr->range_id == 0) break; else if (thisptr->bound == axpkt_bound) break; } }/* Went through the list and found no match */if (thisptr == NULL) return(ENVOY_AX_UNKNOWN_REGISTRATION);/* Remove the registration from the registration list*/regptr = ax_ma_reglist_remove (thisptr->reg_index);if (regptr != thisptr) return (ENVOY_AX_PROCESSING_ERROR);/* Now update the mib tree as necessary */for(comp_list[range_id] = end_oid; comp_list[range_id] >= start_oid; (comp_list[range_id])--) { if ((listptr = ax_ma_get_registration_matchlist (&objid, context->id)) && (listptr->priority < priority)) { /* if the first one on the list has greater priority then no action taken, it is already the leaf in the MIB tree at this ID. if not then the one being removed had the greater priority, so it must be replaced in the MIB tree */ if (AX_Add_Leaf_From_Root(context->mibroot, &objid, listptr->mibleaf, &mleaf) != 1) break; } else if (!listptr) { /* There are no other registrations of any priority for this ID, so just remove the leaf being deregistered */ (void) AX_Remove_Leaf_From_Root(context->mibroot, &objid); } }Clean_Obj_ID (&(regptr->start_oid));if (regptr->mibleaf && ((--regptr->mibleaf->ref_count) == 0)) SNMP_memory_free (regptr->mibleaf);else return (ENVOY_AX_PROCESSING_ERROR);SNMP_memory_free (regptr);/* Note the sysUpTime value. */axRegTblLastChg = ENVOY_GET_SYSUPTIME(0);return(0);}/****************************************************************************NAME: ax_ma_deregisterPURPOSE: attempt to deregister the given node or range of nodes in the registration and mib trees. this routine just breaks the needed values out of the packet and calls the helper routine which actually does the work.PARAMETERS: ENVOY_AX_PKT_T * decoded packet to process ENVOY_AX_CONTEXT_T * context structure, contains the mibrootRETURNS: bits16_t the error status for the response message 0 means no error, the error list is from the agentx spec.****************************************************************************/static bits16_t ax_ma_deregister(ENVOY_AX_PKT_T *ax_pkt, ENVOY_AX_CONTEXT_T *context){return (ax_ma_deregister_helper (ax_pkt->data.reg_data.region.num_components, ax_pkt->data.reg_data.region.component_list, ax_pkt->data.reg_data.range, ax_pkt->data.reg_data.priority, ax_pkt->data.reg_data.bound, context));}/****************************************************************************NAME: ax_ma_registerPURPOSE: attempt to register the given node or range of nodes in the registration and mib trees. we make several loops through the range of nodes we are trying to add. the first one tests to see if this would be a duplicate registration either because there is something in the reg list, or because we are trying to replace a non-agentx node in the mib tree. if we pass those tests we then add the registration to the reg tree, adding the items into the mib tree as necessaryPARAMETERS: ENVOY_AX_PKT_T * the decoded packet to process MIBNODE_T * the root of the mib tree to useRETURNS: bits16_t the error status for the response message 0 means no error, the error list is from the agentx spec.****************************************************************************/static bits16_t ax_ma_register(ENVOY_AX_PKT_T *ax_pkt, ENVOY_AX_CONTEXT_T *context){OIDC_T start_oid, end_oid, *comp_list;bits8_t range_id, priority;int num_comps;MIBLEAF_T *nwleaf, *mleaf;OBJ_ID_T objid;ENVOY_AX_MA_REGLIST_T *rp, *listptr;ENVOY_AX_SESSION_T *tptr;/* determine what information to use */num_comps = ax_pkt->data.reg_data.region.num_components;comp_list = ax_pkt->data.reg_data.region.component_list;range_id = ax_pkt->data.reg_data.range;priority = ax_pkt->data.reg_data.priority;if (range_id) { range_id--; start_oid = comp_list[range_id]; end_oid = ax_pkt->data.reg_data.bound; }else { start_oid = comp_list[range_id]; end_oid = start_oid; }/* Check for duplicate registrations. We check the mib tree to see if any of the requested objects lie under a non-agentx leaf. If so we reject the leaf as we won't allow the leaves to be overwritten or have children. We also check the registration list for duplications */objid.component_list = comp_list;objid.num_components = num_comps;for(; comp_list[range_id] <= end_oid; (comp_list[range_id])++) { (void) Find_Leaf_From_Root(context->mibroot, &objid, &mleaf); if (((mleaf != 0) && (mleaf->getproc != (ASY_GETPROC_T *)ax_getproc)) || (ax_ma_find_matching_registration (&objid, priority, context->id, &listptr) == 0)) { agentxRegisterDuplicate++; return(ENVOY_AX_DUPLICATE_REGISTRATION); } }/* Reset the OID for later use */comp_list[range_id] = start_oid;/* Not a duplicate registration. Go ahead and allocate the new nodes needed */nwleaf = (MIBLEAF_T *)SNMP_memory_alloc(sizeof(MIBLEAF_T));if (nwleaf == 0) return (ENVOY_AX_PROCESSING_ERROR);nwleaf->node_type = LEAF_NODE | AGENTX_LEAF | REMOVABLE | REPLACEABLE;nwleaf->expected_tag = VT_EMPTY;nwleaf->access_type = READ_ACCESS | WRITE_ACCESS | CREATE_ACCESS;nwleaf->testproc = (ASY_TESTPROC_T *)ax_testproc;nwleaf->getproc = (ASY_GETPROC_T *)ax_getproc;nwleaf->setproc = (ASY_SETPROC_T *)ax_setproc;nwleaf->nextproc = (ASY_NEXTPROC_T *)ax_nextproc;nwleaf->user_cookie = 0;nwleaf->locator = 0;nwleaf->session_id = ax_pkt->session_id;nwleaf->ref_count = 1;nwleaf->timeout = ax_pkt->data.reg_data.timeout;rp = (ENVOY_AX_MA_REGLIST_T *)SNMP_memory_alloc(sizeof(ENVOY_AX_MA_REGLIST_T));if (rp == 0) { SNMP_memory_free(nwleaf); return (ENVOY_AX_PROCESSING_ERROR); }rp->reg_index = ax_registration_id++;if (ax_registration_id == 0) { SNMP_memory_free(nwleaf); SNMP_memory_free(rp); return (ENVOY_AX_PROCESSING_ERROR); }rp->session_id = ax_pkt->session_id; for (tptr = envoy_ax_session_list; tptr && (tptr->session_id < ax_pkt->session_id); tptr = tptr->next) ; /* empty for body */if (tptr && (tptr->session_id == ax_pkt->session_id)) rp->connection_id = tptr->connection_id;else return (ENVOY_AX_PROCESSING_ERROR);rp->range_id = ax_pkt->data.reg_data.range;rp->bound = ax_pkt->data.reg_data.bound;rp->flags = ax_pkt->flags;rp->mibleaf = nwleaf;rp->next = NULL;rp->context_id = context->id;rp->priority = priority;rp->match = NULL;clone_object_id (&objid, &rp->start_oid);/* * Now we try to link into the mib trees. If we have any errors * we clean up the current iteration and then call the * deregistration routine to clean up any previous iterations. */for(comp_list[range_id] = start_oid; comp_list[range_id] <= end_oid; (comp_list[range_id])++) { /* * The two cases where the mib tree should be modified are: * - listptr is null, meaning no other leaf at this ID, or * - The first registration on the list (thus currently top priority) * has a lower priority than the one being registered. */ if ((!listptr) || (listptr->priority > priority)) { if (AX_Add_Leaf_From_Root(context->mibroot, &objid, nwleaf, &mleaf) != 1) break; } }/* If we didn't finish all of the oids we had an error and need to cleanup. First check to see if we actually did anything yet. If we didn't we clean up the context if necessary and bail out. Otherwise we reset some of the information in the packet and call the deregistration routine *//* If no registrations succeeded return now */if (comp_list[range_id] == start_oid) { SNMP_memory_free(nwleaf); SNMP_memory_free(rp); return(ENVOY_AX_PROCESSING_ERROR); }/* If some succeeded but not all then deregister them and return */if (comp_list[range_id] <= end_oid) {/* reset some info and call the deregistration routine */ ax_pkt->data.reg_data.bound = comp_list[range_id]; comp_list[range_id] = start_oid; (void) ax_ma_deregister(ax_pkt, context); return(ENVOY_AX_PROCESSING_ERROR); } /* Otherwise add this to the registration list */ ax_ma_reglist_add (rp);/* Note the sysUpTime value. */axRegTblLastChg = ENVOY_GET_SYSUPTIME(0);return(0);}/****************************************************************************NAME: ax_ma_cleanup_registrationPURPOSE: Routine to cleanup any objects that have been registered by a sub agent when it decided to close the session.PARAMETERS: bits32_t id of the session to closeRETURNS: void****************************************************************************/static void ax_ma_cleanup_registration(bits32_t session_id){ENVOY_AX_MA_REGLIST_T *thisptr, *nextptr;/* Go through the reg list and get the registration that matches this */thisptr = envoy_ax_registration_list;while (thisptr) { nextptr = (thisptr)->next; /* Get the "next" pointer here because the deregister may change the list */ if (thisptr->session_id == session_id) { ax_ma_deregister_helper (thisptr->start_oid.num_components, thisptr->start_oid.component_list, thisptr->range_id, thisptr->priority, thisptr->bound, ax_context_index(thisptr->context_id)); } if (nextptr == NULL) break; thisptr = nextptr; }}/****************************************************************************NAME: ax_ma_cleanup_sessionPURPOSE: Cleanup all of the information associated with a sessionPARAMETERS: ENVOY_AX_SESSION_T session to cleanup bits8_t if 0 don't try to send a close message to the sub agents otherwise the error message to sendRETURNS: void****************************************************************************/static void ax_ma_cleanup_session(ENVOY_AX_SESSION_T *sp, bits8_t err_stat){ENVOY_AX_PKT_T query_pkt;if (err_stat) { /* send close message to sub agent */ envoy_ax_pkt_init(&query_pkt); query_pkt.version = ENVOY_AX_VERSION_1; query_pkt.type = ENVOY_AX_CLOSE; /* we don't give out a 0 */ if (ax_reqid == 0) ax_reqid++; query_pkt.packet_id = ax_reqid++; query_pkt.session_id = sp->session_id; query_pkt.flags = sp->flags & 0xFF; query_pkt.data.reason = err_stat; (void) sp->send(sp->cookie, &query_pkt, 0, envoy_ax_pkt_size(&query_pkt, 0)); }ax_ma_cleanup_registration(sp->session_id);ENVOY_AX_MA_AC_CLEAN(sp->session_id);ax_ma_cleanup_indexes(sp->session_id);ax_session_free(sp);}/****************************************************************************\NOMANUALNAME: envoy_ax_ma_cleanup_session_mthPURPOSE: Cleanup all of the information associated with a session This is an interlude to allow agentx method routines to remove a session.PARAMETERS: bits32_t session id bits8_t if 0 don't try to send a close message to the sub agents otherwise the error message to sendRETURNS: int 0 ok, session cleaned up, 1 no session to clean****************************************************************************/int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -