📄 mib_structs.c
字号:
/**
* @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 /* don't build if not configured for use in lwipopts.h */
#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;
static struct nse node_stack[NODE_STACK_SIZE];
/**
* Pushes nse struct onto stack.
*/
static void
push_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 void
pop_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
*/
void
snmp_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 ifidx points to s32_t object sub-identifier
*/
void
snmp_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
*/
void
snmp_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
*/
void
snmp_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;
}
void
snmp_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;
}
void
snmp_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_t
snmp_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_t
snmp_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 *r;
if (n->nptr->node_type == MIB_NODE_LR)
{
r = (struct mib_list_rootnode *)n->nptr;
if (r->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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -