agent_registry.c
来自「eCos操作系统源码」· C语言 代码 · 共 1,474 行 · 第 1/3 页
C
1,474 行
{ return register_mib_priority( moduleName, var, varsize, numvars, mibloc, mibloclen, DEFAULT_MIB_PRIORITY );}voidunload_subtree( struct subtree *sub, struct subtree *prev){ struct subtree *ptr; if ( prev != NULL ) { /* non-leading entries are easy */ prev->children = sub->children; return; } /* otherwise, we need to amend our neighbours as well */ if ( sub->children == NULL) { /* just remove this node completely */ for (ptr = sub->prev ; ptr ; ptr=ptr->children ) ptr->next = sub->next; for (ptr = sub->next ; ptr ; ptr=ptr->children ) ptr->prev = sub->prev; return; } else { for (ptr = sub->prev ; ptr ; ptr=ptr->children ) ptr->next = sub->children; for (ptr = sub->next ; ptr ; ptr=ptr->children ) ptr->prev = sub->children; return; }}intunregister_mib_range( oid *name, size_t len, int priority, int range_subid, oid range_ubound){ struct subtree *list, *myptr; struct subtree *prev, *child; /* loop through children */ struct register_parameters reg_parms; list = find_subtree( name, len, subtrees ); if ( list == NULL ) return MIB_NO_SUCH_REGISTRATION; for ( child=list, prev=NULL; child != NULL; prev=child, child=child->children ) { if (( snmp_oid_compare( child->name, child->namelen, name, len) == 0 ) && ( child->priority == priority )) break; /* found it */ } if ( child == NULL ) return MIB_NO_SUCH_REGISTRATION; unload_subtree( child, prev ); myptr = child; /* remember this for later */ /* * Now handle any occurances in the following subtrees, * as a result of splitting this range. Due to the * nature of the way such splits work, the first * subtree 'slice' that doesn't refer to the given * name marks the end of the original region. * * This should also serve to register ranges. */ for ( list = myptr->next ; list != NULL ; list=list->next ) { for ( child=list, prev=NULL; child != NULL; prev=child, child=child->children ) { if (( snmp_oid_compare( child->name, child->namelen, name, len) == 0 ) && ( child->priority == priority )) { unload_subtree( child, prev ); free_subtree( child ); break; } } if ( child == NULL ) /* Didn't find the given name */ break; } free_subtree( myptr ); reg_parms.name = name; reg_parms.namelen = len; reg_parms.priority = priority; reg_parms.range_subid = range_subid; reg_parms.range_ubound = range_ubound; snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREGISTER_OID, ®_parms); return MIB_UNREGISTERED_OK;}intunregister_mib_priority(oid *name, size_t len, int priority){ return unregister_mib_range( name, len, priority, 0, 0 );}intunregister_mib(oid *name, size_t len){ return unregister_mib_priority( name, len, DEFAULT_MIB_PRIORITY );}voidunregister_mibs_by_session (struct snmp_session *ss){ struct subtree *list, *list2; struct subtree *child, *prev, *next_child; for( list = subtrees; list != NULL; list = list2) { list2 = list->next; for ( child=list, prev=NULL; child != NULL; child=next_child ) { next_child = child->children; if (( (ss->flags & SNMP_FLAGS_SUBSESSION) && child->session == ss ) || (!(ss->flags & SNMP_FLAGS_SUBSESSION) && child->session->subsession == ss )) { unload_subtree( child, prev ); free_subtree( child ); } else prev = child; } }}struct subtree *free_subtree(struct subtree *st){ struct subtree *ret = NULL; if ((snmp_oid_compare(st->name, st->namelen, st->start, st->start_len) == 0) && (st->variables != NULL)) free(st->variables); if (st->next != NULL) ret = st->next; free(st); return ret;}/* in_a_view: determines if a given snmp_pdu is allowed to see a given name/namelen OID pointer name IN - name of var, OUT - name matched nameLen IN -number of sub-ids in name, OUT - subid-is in matched name pi IN - relevant auth info re PDU cvp IN - relevant auth info re mib module*/intin_a_view(oid *name, /* IN - name of var, OUT - name matched */ size_t *namelen, /* IN -number of sub-ids in name*/ struct snmp_pdu *pdu, /* IN - relevant auth info re PDU */ int type) /* IN - variable type being checked */{ struct view_parameters view_parms; view_parms.pdu = pdu; view_parms.name = name; if (namelen) view_parms.namelen = *namelen; else view_parms.namelen = 0; view_parms.errorcode = 0; if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW) return 0; /* Enable bypassing of view-based access control */ /* check for v1 and counter64s, since snmpv1 doesn't support it */ if (pdu->version == SNMP_VERSION_1 && type == ASN_COUNTER64) return 5; switch (pdu->version) { case SNMP_VERSION_1: case SNMP_VERSION_2c:#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT case SNMP_VERSION_3:#endif snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK, &view_parms); return view_parms.errorcode; } return 1;}/* in_a_view: determines if a given snmp_pdu is ever going to be allowed to do anynthing or if it's not going to ever be authenticated. */intcheck_access(struct snmp_pdu *pdu) /* IN - pdu being checked */{ struct view_parameters view_parms; view_parms.pdu = pdu; view_parms.name = 0; view_parms.namelen = 0; view_parms.errorcode = 0; if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW) return 0; /* Enable bypassing of view-based access control */ switch (pdu->version) { case SNMP_VERSION_1: case SNMP_VERSION_2c:#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT case SNMP_VERSION_3:#endif snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK_INITIAL, &view_parms); return view_parms.errorcode; } return 1;}/* lexicographical compare two object identifiers. * Returns -1 if name1 < name2, * 0 if name1 = name2, or name1 matches name2 for length of name2 * 1 if name1 > name2 * * Note: snmp_oid_compare checks len2 before last return. */intcompare_tree(const oid *in_name1, size_t len1, const oid *in_name2, size_t len2){ register int len, res; register const oid * name1 = in_name1; register const oid * name2 = in_name2; /* len = minimum of len1 and len2 */ if (len1 < len2) len = len1; else len = len2; /* find first non-matching OID */ while(len-- > 0){ res = *(name1++) - *(name2++); if (res < 0) return -1; if (res > 0) return 1; } /* both OIDs equal up to length of shorter OID */ if (len1 < len2) return -1; /* name1 matches name2 for length of name2, or they are equal */ return 0;}struct subtree *find_subtree_previous(oid *name, size_t len, struct subtree *subtree){ struct subtree *myptr, *previous = NULL; if ( subtree ) myptr = subtree; else myptr = subtrees; /* look through everything */ for( ; myptr != NULL; previous = myptr, myptr = myptr->next) { if (snmp_oid_compare(name, len, myptr->start, myptr->start_len) < 0) return previous; } return previous;}struct subtree *find_subtree_next(oid *name, size_t len, struct subtree *subtree){ struct subtree *myptr = NULL; myptr = find_subtree_previous(name, len, subtree); if ( myptr != NULL ) { myptr = myptr->next; while ( myptr && (myptr->variables == NULL || myptr->variables_len == 0) ) myptr = myptr->next; return myptr; } else if (subtree && snmp_oid_compare(name, len, subtree->start, subtree->start_len) < 0) return subtree; else return NULL;}struct subtree *find_subtree(oid *name, size_t len, struct subtree *subtree){ struct subtree *myptr; myptr = find_subtree_previous(name, len, subtree); if (myptr && snmp_oid_compare(name, len, myptr->end, myptr->end_len) < 0) return myptr; return NULL;}struct snmp_session *get_session_for_oid( oid *name, size_t len){ struct subtree *myptr; myptr = find_subtree_previous(name, len, subtrees); while ( myptr && myptr->variables == NULL ) myptr = myptr->next; if ( myptr == NULL ) return NULL; else return myptr->session;}static struct subtree root_subtrees[] = { { { 0 }, 1 }, /* ccitt */ { { 1 }, 1 }, /* iso */ { { 2 }, 1 } /* joint-ccitt-iso */};void setup_tree (void){#ifdef USING_AGENTX_SUBAGENT_MODULE int role; role = ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE); ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);#endif register_mib("", NULL, 0, 0, root_subtrees[0].name, root_subtrees[0].namelen); register_mib("", NULL, 0, 0, root_subtrees[1].name, root_subtrees[1].namelen); register_mib("", NULL, 0, 0, root_subtrees[2].name, root_subtrees[2].namelen); /* Support for 'static' subtrees (subtrees_old) has now been dropped */ /* No longer necessary to sort the mib tree - this is inherent in the construction of the subtree structure */#ifdef USING_AGENTX_SUBAGENT_MODULE ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, role);#endif} /* * Initial support for index allocation */extern struct snmp_session *main_session;char *register_string_index( oid *name, size_t name_len, char *cp ){ struct variable_list varbind, *res; memset( &varbind, 0, sizeof(struct variable_list)); varbind.type = ASN_OCTET_STR; snmp_set_var_objid( &varbind, name, name_len ); if ( cp != ANY_STRING_INDEX ) { snmp_set_var_value( &varbind, (u_char *)cp, strlen(cp) ); res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session ); } else res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session ); if ( res == NULL ) return NULL; else return (char *)res->val.string;}intregister_int_index( oid *name, size_t name_len, int val ){ struct variable_list varbind, *res; memset( &varbind, 0, sizeof(struct variable_list)); varbind.type = ASN_INTEGER; snmp_set_var_objid( &varbind, name, name_len ); varbind.val.string = varbind.buf; if ( val != ANY_INTEGER_INDEX ) { varbind.val_len = sizeof(long); *varbind.val.integer = val; res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session ); } else res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session ); if ( res == NULL ) return -1; else return *res->val.integer;}struct variable_list *register_oid_index( oid *name, size_t name_len, oid *value, size_t value_len ){ struct variable_list varbind; memset( &varbind, 0, sizeof(struct variable_list)); varbind.type = ASN_OBJECT_ID; snmp_set_var_objid( &varbind, name, name_len ); if ( value != ANY_OID_INDEX ) { snmp_set_var_value( &varbind, (u_char*)value, value_len*sizeof(oid) ); return( register_index( &varbind, ALLOCATE_THIS_INDEX, main_session )); } else return( register_index( &varbind, ALLOCATE_ANY_INDEX, main_session ));}struct variable_list*register_index(struct variable_list *varbind, int flags, struct snmp_session *ss ){ struct snmp_index *new_index, *idxptr, *idxptr2; struct snmp_index *prev_oid_ptr, *prev_idx_ptr; int res, res2, i;#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING) if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT ) return( agentx_register_index( ss, varbind, flags ));#endif /* Look for the requested OID entry */ prev_oid_ptr = NULL; prev_idx_ptr = NULL; res = 1; res2 = 1; for( idxptr = snmp_index_head ; idxptr != NULL; prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) { if ((res = snmp_oid_compare(varbind->name, varbind->name_length, idxptr->varbind.name, idxptr->varbind.name_length)) <= 0 ) break; } /* Found the OID - now look at the registered indices */ if ( res == 0 && idxptr ) { if ( varbind->type != idxptr->varbind.type ) return NULL; /* wrong type */ /* * If we've been asked for an arbitrary new value, * then find the end of the list. * If we've been asked for any arbitrary value, * then look for an unused entry, and use that. * If there aren't any, continue as for new. * Otherwise, locate the given value in the (sorted) * list of already allocated values */ if ( flags & ALLOCATE_ANY_INDEX ) { for(idxptr2 = idxptr ; idxptr2 != NULL; prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) { if ( flags == ALLOCATE_ANY_INDEX && idxptr2->session == NULL ) { idxptr2->session = ss ; return &idxptr2->varbind; } } } else { for(idxptr2 = idxptr ; idxptr2 != NULL; prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) { switch ( varbind->type ) { case ASN_INTEGER: res2 = (*varbind->val.integer - *idxptr2->varbind.val.integer); break; case ASN_OCTET_STR: i = SNMP_MIN(varbind->val_len, idxptr2->varbind.val_len); res2 = memcmp(varbind->val.string, idxptr2->varbind.val.string, i); break; case ASN_OBJECT_ID: res2 = snmp_oid_compare(varbind->val.objid, varbind->val_len/sizeof(oid), idxptr2->varbind.val.objid, idxptr2->varbind.val_len/sizeof(oid)); break; default: return NULL; /* wrong type */ } if ( res2 <= 0 ) break; } if ( res2 == 0 ) return NULL; /* duplicate value */ } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?