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,                      &reg_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 + -
显示快捷键?