⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agent_registry.c

📁 嵌入式操作系统ECOS的网络开发包
💻 C
📖 第 1 页 / 共 3 页
字号:
{
  return register_mib_priority( moduleName, var, varsize, numvars,
				mibloc, mibloclen, DEFAULT_MIB_PRIORITY );
}


void
unload_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;
    }
}

int
unregister_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;
}

int
unregister_mib_priority(oid *name, size_t len, int priority)
{
  return unregister_mib_range( name, len, priority, 0, 0 );
}

int
unregister_mib(oid *name,
	       size_t len)
{
  return unregister_mib_priority( name, len, DEFAULT_MIB_PRIORITY );
}

void
unregister_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
*/

int
in_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. */
int
check_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.
 */
int
compare_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;
}

int
register_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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -