📄 mib_structs.c
字号:
/**
* 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 + -