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

📄 mib_structs.c

📁 《嵌入式网络系统设计-基于Atmel ARM7 系列》这个本书的光盘资料
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * @file * MIB tree access/construction functions. *//* * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * Author: Christiaan Simons <christiaan.simons@axon.tv> */#include "lwip/opt.h"#if LWIP_SNMP#include "lwip/snmp_structs.h"#include "lwip/mem.h"/** .iso.org.dod.internet address prefix, @see snmp_iso_*() */const s32_t prefix[4] = {1, 3, 6, 1};#define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN)/** node stack entry (old news?) */struct nse{  /** right child */  struct mib_node* r_ptr;  /** right child identifier */  s32_t r_id;  /** right child next level */  u8_t r_nl;};static u8_t node_stack_cnt = 0;static struct nse node_stack[NODE_STACK_SIZE];/** * Pushes nse struct onto stack. */static voidpush_node(struct nse* node){  LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE);  LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id));  if (node_stack_cnt < NODE_STACK_SIZE)  {    node_stack[node_stack_cnt] = *node;    node_stack_cnt++;  }}/** * Pops nse struct from stack. */static voidpop_node(struct nse* node){  if (node_stack_cnt > 0)  {    node_stack_cnt--;    *node = node_stack[node_stack_cnt];  }  LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id));}/** * Conversion from ifIndex to lwIP netif * @param ifindex is a s32_t object sub-identifier * @param netif points to returned netif struct pointer */voidsnmp_ifindextonetif(s32_t ifindex, struct netif **netif){  struct netif *nif = netif_list;  u16_t i, ifidx;  ifidx = ifindex - 1;  i = 0;  while ((nif != NULL) && (i < ifidx))  {    nif = nif->next;    i++;  }  *netif = nif;}/** * Conversion from lwIP netif to ifIndex * @param netif points to a netif struct * @param ifindex points to s32_t object sub-identifier */voidsnmp_netiftoifindex(struct netif *netif, s32_t *ifidx){  struct netif *nif = netif_list;  u16_t i;  i = 0;  while (nif != netif)  {    nif = nif->next;    i++;  }  *ifidx = i+1;}/** * Conversion from oid to lwIP ip_addr * @param ident points to s32_t ident[4] input * @param ip points to output struct */voidsnmp_oidtoip(s32_t *ident, struct ip_addr *ip){  u32_t ipa;  ipa = ident[0];  ipa <<= 8;  ipa |= ident[1];  ipa <<= 8;  ipa |= ident[2];  ipa <<= 8;  ipa |= ident[3];  ip->addr = ipa;}/** * Conversion from lwIP ip_addr to oid * @param ip points to input struct * @param ident points to s32_t ident[4] output */voidsnmp_iptooid(struct ip_addr *ip, s32_t *ident){  u32_t ipa;  ipa = ip->addr;  ident[0] = (ipa >> 24) & 0xff;  ident[1] = (ipa >> 16) & 0xff;  ident[2] = (ipa >> 8) & 0xff;  ident[3] = ipa & 0xff;}struct mib_list_node *snmp_mib_ln_alloc(s32_t id){  struct mib_list_node *ln;  ln = (struct mib_list_node *)mem_malloc(sizeof(struct mib_list_node));  if (ln != NULL)  {    ln->prev = NULL;    ln->next = NULL;    ln->objid = id;    ln->nptr = NULL;  }  return ln;}voidsnmp_mib_ln_free(struct mib_list_node *ln){  mem_free(ln);}struct mib_list_rootnode *snmp_mib_lrn_alloc(void){  struct mib_list_rootnode *lrn;  lrn = (struct mib_list_rootnode*)mem_malloc(sizeof(struct mib_list_rootnode));  if (lrn != NULL)  {    lrn->get_object_def = noleafs_get_object_def;    lrn->get_value = noleafs_get_value;    lrn->set_test = noleafs_set_test;    lrn->set_value = noleafs_set_value;    lrn->node_type = MIB_NODE_LR;    lrn->maxlength = 0;    lrn->head = NULL;    lrn->tail = NULL;    lrn->count = 0;  }  return lrn;}voidsnmp_mib_lrn_free(struct mib_list_rootnode *lrn){  mem_free(lrn);}/** * Inserts node in idx list in a sorted * (ascending order) fashion and * allocates the node if needed. * * @param rn points to the root node * @param objid is the object sub identifier * @param insn points to a pointer to the inserted node *   used for constructing the tree. * @return -1 if failed, 1 if inserted, 2 if present. */s8_tsnmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn){  struct mib_list_node *nn;  s8_t insert;  LWIP_ASSERT("rn != NULL",rn != NULL);  /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */  insert = 0;  if (rn->head == NULL)  {    /* empty list, add first node */    LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid));    nn = snmp_mib_ln_alloc(objid);    if (nn != NULL)    {      rn->head = nn;      rn->tail = nn;      *insn = nn;      insert = 1;    }    else    {      insert = -1;    }  }  else  {    struct mib_list_node *n;    /* at least one node is present */    n = rn->head;    while ((n != NULL) && (insert == 0))    {      if (n->objid == objid)      {        /* node is already there */        LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid));        *insn = n;        insert = 2;      }      else if (n->objid < objid)      {        if (n->next == NULL)        {          /* alloc and insert at the tail */          LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid));          nn = snmp_mib_ln_alloc(objid);          if (nn != NULL)          {            nn->next = NULL;            nn->prev = n;            n->next = nn;            rn->tail = nn;            *insn = nn;            insert = 1;          }          else          {            /* insertion failure */            insert = -1;          }        }        else        {          /* there's more to explore: traverse list */          LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n"));          n = n->next;        }      }      else      {        /* n->objid > objid */        /* alloc and insert between n->prev and n */        LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid));        nn = snmp_mib_ln_alloc(objid);        if (nn != NULL)        {          if (n->prev == NULL)          {            /* insert at the head */            nn->next = n;            nn->prev = NULL;            rn->head = nn;            n->prev = nn;          }          else          {            /* insert in the middle */            nn->next = n;            nn->prev = n->prev;            n->prev->next = nn;            n->prev = nn;          }          *insn = nn;          insert = 1;        }        else        {          /* insertion failure */          insert = -1;        }      }    }  }  if (insert == 1)  {    rn->count += 1;  }  LWIP_ASSERT("insert != 0",insert != 0);  return insert;}/** * Finds node in idx list and returns deletion mark. * * @param rn points to the root node * @param objid  is the object sub identifier * @param fn returns pointer to found node * @return 0 if not found, 1 if deletable, *   2 can't delete (2 or more children), 3 not a list_node */s8_tsnmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn){  s8_t fc;  struct mib_list_node *n;  LWIP_ASSERT("rn != NULL",rn != NULL);  n = rn->head;  while ((n != NULL) && (n->objid != objid))  {    n = n->next;  }  if (n == NULL)  {    fc = 0;  }  else if (n->nptr == NULL)  {    /* leaf, can delete node */    fc = 1;  }  else  {    struct mib_list_rootnode *rn;    if (n->nptr->node_type == MIB_NODE_LR)    {      rn = (struct mib_list_rootnode *)n->nptr;      if (rn->count > 1)      {        /* can't delete node */        fc = 2;      }      else      {        /* count <= 1, can delete node */        fc = 1;      }    }    else    {      /* other node type */      fc = 3;    }  }  *fn = n;  return fc;}/** * 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;

⌨️ 快捷键说明

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