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

📄 mib_structs.c

📁 基于STM32F107的UDP服务器程序
💻 C
📖 第 1 页 / 共 3 页
字号:

/**
 * Removes node from idx list
 * if it has a single child left.
 *
 * @param rn points to the root node
 * @param n points to the node to delete
 * @return the nptr to be freed by caller
 */
struct mib_list_rootnode *
snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n)
{
  struct mib_list_rootnode *next;

  LWIP_ASSERT("rn != NULL",rn != NULL);
  LWIP_ASSERT("n != NULL",n != NULL);

  /* caller must remove this sub-tree */
  next = (struct mib_list_rootnode*)(n->nptr);
  rn->count -= 1;

  if (n == rn->head)
  {
    rn->head = n->next;
    if (n->next != NULL)
    {
      /* not last node, new list begin */
      n->next->prev = NULL;
    }
  }
  else if (n == rn->tail)
  {
    rn->tail = n->prev;
    if (n->prev != NULL)
    {
      /* not last node, new list end */
      n->prev->next = NULL;
    }
  }
  else
  {
    /* node must be in the middle */
    n->prev->next = n->next;
    n->next->prev = n->prev;
  }
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid));
  snmp_mib_ln_free(n);
  if (rn->count == 0)
  {
    rn->head = NULL;
    rn->tail = NULL;
  }
  return next;
}



/**
 * Searches tree for the supplied (scalar?) object identifier.
 *
 * @param node points to the root of the tree ('.internet')
 * @param ident_len the length of the supplied object identifier
 * @param ident points to the array of sub identifiers
 * @param np points to the found object instance (rerurn)
 * @return pointer to the requested parent (!) node if success, NULL otherwise
 */
struct mib_node *
snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np)
{
  u8_t node_type, ext_level;

  ext_level = 0;
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident));
  while (node != NULL)
  {
    node_type = node->node_type;
    if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
    {
      struct mib_array_node *an;
      u16_t i;

      if (ident_len > 0)
      {
        /* array node (internal ROM or RAM, fixed length) */
        an = (struct mib_array_node *)node;
        i = 0;
        while ((i < an->maxlength) && (an->objid[i] != *ident))
        {
          i++;
        }
        if (i < an->maxlength)
        {
          /* found it, if available proceed to child, otherwise inspect leaf */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident));
          if (an->nptr[i] == NULL)
          {
            /* a scalar leaf OR table,
               inspect remaining instance number / table index */
            np->ident_len = ident_len;
            np->ident = ident;
            return (struct mib_node*)an;
          }
          else
          {
            /* follow next child pointer */
            ident++;
            ident_len--;
            node = an->nptr[i];
          }
        }
        else
        {
          /* search failed, identifier mismatch (nosuchname) */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident));
          return NULL;
        }
      }
      else
      {
        /* search failed, short object identifier (nosuchname) */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n"));
        return NULL;
      }
    }
    else if(node_type == MIB_NODE_LR)
    {
      struct mib_list_rootnode *lrn;
      struct mib_list_node *ln;

      if (ident_len > 0)
      {
        /* list root node (internal 'RAM', variable length) */
        lrn = (struct mib_list_rootnode *)node;
        ln = lrn->head;
        /* iterate over list, head to tail */
        while ((ln != NULL) && (ln->objid != *ident))
        {
          ln = ln->next;
        }
        if (ln != NULL)
        {
          /* found it, proceed to child */;
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident));
          if (ln->nptr == NULL)
          {
            np->ident_len = ident_len;
            np->ident = ident;
            return (struct mib_node*)lrn;
          }
          else
          {
            /* follow next child pointer */
            ident_len--;
            ident++;
            node = ln->nptr;
          }
        }
        else
        {
          /* search failed */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident));
          return NULL;
        }
      }
      else
      {
        /* search failed, short object identifier (nosuchname) */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n"));
        return NULL;
      }
    }
    else if(node_type == MIB_NODE_EX)
    {
      struct mib_external_node *en;
      u16_t i, len;

      if (ident_len > 0)
      {
        /* external node (addressing and access via functions) */
        en = (struct mib_external_node *)node;

        i = 0;
        len = en->level_length(en->addr_inf,ext_level);
        while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0))
        {
          i++;
        }
        if (i < len)
        {
          s32_t debug_id;

          en->get_objid(en->addr_inf,ext_level,i,&debug_id);
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident));
          if ((ext_level + 1) == en->tree_levels)
          {
            np->ident_len = ident_len;
            np->ident = ident;
            return (struct mib_node*)en;
          }
          else
          {
            /* found it, proceed to child */
            ident_len--;
            ident++;
            ext_level++;
          }
        }
        else
        {
          /* search failed */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident));
          return NULL;
        }
      }
      else
      {
        /* search failed, short object identifier (nosuchname) */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n"));
        return NULL;
      }
    }
    else if (node_type == MIB_NODE_SC)
    {
      mib_scalar_node *sn;

      sn = (mib_scalar_node *)node;
      if ((ident_len == 1) && (*ident == 0))
      {
        np->ident_len = ident_len;
        np->ident = ident;
        return (struct mib_node*)sn;
      }
      else
      {
        /* search failed, short object identifier (nosuchname) */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n"));
        return NULL;
      }
    }
    else
    {
      /* unknown node_type */
      LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type));
      return NULL;
    }
  }
  /* done, found nothing */
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node));
  return NULL;
}

/**
 * Test table for presence of at least one table entry.
 */
static u8_t
empty_table(struct mib_node *node)
{
  u8_t node_type;
  u8_t empty = 0;

  if (node != NULL)
  {
    node_type = node->node_type;
    if (node_type == MIB_NODE_LR)
    {
      struct mib_list_rootnode *lrn;
      lrn = (struct mib_list_rootnode *)node;
      if ((lrn->count == 0) || (lrn->head == NULL))
      {
        empty = 1;
      }
    }
    else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
    {
      struct mib_array_node *an;
      an = (struct mib_array_node *)node;
      if ((an->maxlength == 0) || (an->nptr == NULL))
      {
        empty = 1;
      }
    }
    else if (node_type == MIB_NODE_EX)
    {
      struct mib_external_node *en;
      en = (struct mib_external_node *)node;
      if (en->tree_levels == 0)
      {
        empty = 1;
      }
    }
  }
  return empty;
}

/**
 * Tree expansion.
 */
struct mib_node *
snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret)
{
  u8_t node_type, ext_level, climb_tree;

  ext_level = 0;
  /* reset node stack */
  node_stack_cnt = 0;
  while (node != NULL)
  {
    climb_tree = 0;
    node_type = node->node_type;
    if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
    {
      struct mib_array_node *an;
      u16_t i;

      /* array node (internal ROM or RAM, fixed length) */
      an = (struct mib_array_node *)node;
      if (ident_len > 0)
      {
        i = 0;
        while ((i < an->maxlength) && (an->objid[i] < *ident))
        {
          i++;
        }
        if (i < an->maxlength)
        {
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident));
          /* add identifier to oidret */
          oidret->id[oidret->len] = an->objid[i];
          (oidret->len)++;

          if (an->nptr[i] == NULL)
          {
            LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n"));
            /* leaf node (e.g. in a fixed size table) */
            if (an->objid[i] > *ident)
            {
              return (struct mib_node*)an;
            }
            else if ((i + 1) < an->maxlength)
            {
              /* an->objid[i] == *ident */
              (oidret->len)--;
              oidret->id[oidret->len] = an->objid[i + 1];
              (oidret->len)++;
              return (struct mib_node*)an;
            }
            else
            {
              /* (i + 1) == an->maxlength */
              (oidret->len)--;
              climb_tree = 1;
            }
          }
          else
          {
            u8_t j;
            struct nse cur_node;

            LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
            /* non-leaf, store right child ptr and id */
            j = i + 1;
            while ((j < an->maxlength) && (empty_table(an->nptr[j])))
            {
              j++;
            }
            if (j < an->maxlength)
            {
              cur_node.r_ptr = an->nptr[j];
              cur_node.r_id = an->objid[j];
              cur_node.r_nl = 0;
            }
            else
            {
              cur_node.r_ptr = NULL;
            }
            push_node(&cur_node);
            if (an->objid[i] == *ident)
            {
              ident_len--;
              ident++;
            }
            else
            {
              /* an->objid[i] < *ident */
              ident_len = 0;
            }
            /* follow next child pointer */
            node = an->nptr[i];
          }
        }
        else
        {
          /* i == an->maxlength */
          climb_tree = 1;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -