mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-04-16 08:43:17 +00:00
Started with getnext and ensure zero length identifiers are accepted.
This commit is contained in:
parent
4b5c14470a
commit
7d1728f05a
@ -32,11 +32,41 @@
|
|||||||
* Author: Christiaan Simons <christiaan.simons@axon.tv>
|
* Author: Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
|
||||||
#include "lwip/snmp_structs.h"
|
#include "lwip/snmp_structs.h"
|
||||||
|
|
||||||
#if LWIP_SNMP
|
#if LWIP_SNMP
|
||||||
|
|
||||||
|
/** .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)
|
||||||
|
static u8_t node_stack_cnt = 0;
|
||||||
|
static struct mib_node* node_stack[NODE_STACK_SIZE];
|
||||||
|
|
||||||
|
static void
|
||||||
|
push_node(struct mib_node* node)
|
||||||
|
{
|
||||||
|
if (node_stack_cnt < NODE_STACK_SIZE)
|
||||||
|
{
|
||||||
|
node_stack[node_stack_cnt] = node;
|
||||||
|
node_stack_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mib_node*
|
||||||
|
pop_node(void)
|
||||||
|
{
|
||||||
|
if (node_stack_cnt > 0)
|
||||||
|
{
|
||||||
|
node_stack_cnt--;
|
||||||
|
return node_stack[node_stack_cnt];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches tree for the supplied (scalar?) object identifier.
|
* Searches tree for the supplied (scalar?) object identifier.
|
||||||
*
|
*
|
||||||
@ -60,6 +90,8 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
struct mib_array_node *an;
|
struct mib_array_node *an;
|
||||||
u16_t i;
|
u16_t i;
|
||||||
|
|
||||||
|
if (ident_len > 0)
|
||||||
|
{
|
||||||
/* array node (internal ROM or RAM, fixed length) */
|
/* array node (internal ROM or RAM, fixed length) */
|
||||||
an = (struct mib_array_node *)node;
|
an = (struct mib_array_node *)node;
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -68,8 +100,6 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i < an->maxlength)
|
if (i < an->maxlength)
|
||||||
{
|
|
||||||
if (ident_len > 0)
|
|
||||||
{
|
{
|
||||||
/* found it, if available proceed to child, otherwise inspect leaf */
|
/* found it, if available proceed to child, otherwise inspect leaf */
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F,i,an->objid[i],*ident));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F,i,an->objid[i],*ident));
|
||||||
@ -102,15 +132,15 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* search failed, short object identifier (nosuchname) */
|
/* search failed, identifier mismatch (nosuchname) */
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* search failed, identifier mismatch (nosuchname) */
|
/* search failed, short object identifier (nosuchname) */
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,6 +149,8 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
struct mib_list_rootnode *lrn;
|
struct mib_list_rootnode *lrn;
|
||||||
struct mib_list_node *ln;
|
struct mib_list_node *ln;
|
||||||
|
|
||||||
|
if (ident_len > 0)
|
||||||
|
{
|
||||||
/* list root node (internal 'RAM', variable length) */
|
/* list root node (internal 'RAM', variable length) */
|
||||||
lrn = (struct mib_list_rootnode *)node;
|
lrn = (struct mib_list_rootnode *)node;
|
||||||
ln = lrn->head;
|
ln = lrn->head;
|
||||||
@ -128,8 +160,6 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
ln = ln->next;
|
ln = ln->next;
|
||||||
}
|
}
|
||||||
if (ln != NULL)
|
if (ln != NULL)
|
||||||
{
|
|
||||||
if (ident_len > 0)
|
|
||||||
{
|
{
|
||||||
/* found it, proceed to child */;
|
/* found it, proceed to child */;
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F,ln->objid,*ident));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F,ln->objid,*ident));
|
||||||
@ -158,15 +188,15 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* search failed, short object identifier (nosuchname) */
|
/* search failed */
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* search failed */
|
/* search failed, short object identifier (nosuchname) */
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,6 +205,8 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
struct mib_external_node *en;
|
struct mib_external_node *en;
|
||||||
u16_t i;
|
u16_t i;
|
||||||
|
|
||||||
|
if (ident_len > 0)
|
||||||
|
{
|
||||||
/* external node (addressing and access via functions) */
|
/* external node (addressing and access via functions) */
|
||||||
en = (struct mib_external_node *)node;
|
en = (struct mib_external_node *)node;
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -183,8 +215,6 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i < en->count)
|
if (i < en->count)
|
||||||
{
|
|
||||||
if (ident_len > 0)
|
|
||||||
{
|
{
|
||||||
if (en->get_nptr(i) == NULL)
|
if (en->get_nptr(i) == NULL)
|
||||||
{
|
{
|
||||||
@ -202,6 +232,13 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* search failed */
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* search failed, short object identifier (nosuchname) */
|
/* search failed, short object identifier (nosuchname) */
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
|
||||||
@ -210,11 +247,111 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* search failed */
|
/* unknown node_type */
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type "U16_F" unkown",(u16_t)node_type));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* done, found nothing */
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p",(void*)node));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/* reset stack */
|
||||||
|
node_stack_cnt = 0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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,i,an->objid[i],*ident));
|
||||||
|
|
||||||
|
/* add identifier to oidret */
|
||||||
|
oidret->id[oidret->len] = an->objid[i];
|
||||||
|
(oidret->len)++;
|
||||||
|
|
||||||
|
if (an->nptr[i] == NULL)
|
||||||
|
{
|
||||||
|
/* leaf node */
|
||||||
|
/*
|
||||||
|
if scalar: add '.0'
|
||||||
|
@todo if tabular: if not empty add first index, nextThing otherwise
|
||||||
|
*/
|
||||||
|
oidret->id[oidret->len] = 0;
|
||||||
|
(oidret->len)++;
|
||||||
|
return (struct mib_node*)an;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* follow next child pointer */
|
||||||
|
ident_len--;
|
||||||
|
ident++;
|
||||||
|
node = an->nptr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* @todo return to parent */
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* short object identifier, complete it */
|
||||||
|
|
||||||
|
/* add leftmost '.Thing' */
|
||||||
|
oidret->id[oidret->len] = an->objid[0];
|
||||||
|
(oidret->len)++;
|
||||||
|
|
||||||
|
if (an->nptr[0] == NULL)
|
||||||
|
{
|
||||||
|
/* leaf node */
|
||||||
|
/*
|
||||||
|
if scalar: add '.0'
|
||||||
|
@todo if tabular: if not empty add first index, nextThing otherwise
|
||||||
|
*/
|
||||||
|
oidret->id[oidret->len] = 0;
|
||||||
|
(oidret->len)++;
|
||||||
|
return (struct mib_node*)an;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no leaf, continue */
|
||||||
|
node = an->nptr[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* unknown/unhandled node_type */
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type "U16_F" unkown",(u16_t)node_type));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* done, found nothing */
|
/* done, found nothing */
|
||||||
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p",(void*)node));
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p",(void*)node));
|
||||||
@ -243,4 +380,51 @@ snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expands object identifier to the iso.org.dod.internet
|
||||||
|
* prefix for use in getnext operation.
|
||||||
|
*
|
||||||
|
* @param ident_len the length of the supplied object identifier
|
||||||
|
* @param ident points to the array of sub identifiers
|
||||||
|
* @param oidret points to returned expanded object identifier
|
||||||
|
* @return 1 if it matches, 0 otherwise
|
||||||
|
*
|
||||||
|
* @note ident_len 0 is allowed, expanding to the first known object id!!
|
||||||
|
*/
|
||||||
|
u8_t
|
||||||
|
snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret)
|
||||||
|
{
|
||||||
|
const s32_t *prefix_ptr;
|
||||||
|
s32_t *ret_ptr;
|
||||||
|
u8_t i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
prefix_ptr = &prefix[0];
|
||||||
|
ret_ptr = &oidret->id[0];
|
||||||
|
ident_len = ((ident_len < 4)?ident_len:4);
|
||||||
|
while ((i < ident_len) && ((*ident) <= (*prefix_ptr)))
|
||||||
|
{
|
||||||
|
*ret_ptr++ = *prefix_ptr++;
|
||||||
|
ident++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i == ident_len)
|
||||||
|
{
|
||||||
|
/* match, complete missing bits */
|
||||||
|
while (i < 4)
|
||||||
|
{
|
||||||
|
*ret_ptr++ = *prefix_ptr++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
oidret->len = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* i != ident_len */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* LWIP_SNMP */
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@
|
|||||||
|
|
||||||
#if LWIP_SNMP
|
#if LWIP_SNMP
|
||||||
|
|
||||||
#define LWIP_SNMP_DBG_LOOPBACK_TST 0
|
|
||||||
#define SNMP_CONCURRENT_REQUESTS 2
|
#define SNMP_CONCURRENT_REQUESTS 2
|
||||||
|
|
||||||
/* public (non-static) constants */
|
/* public (non-static) constants */
|
||||||
@ -102,6 +101,7 @@ snmp_init(void)
|
|||||||
trap_msg.pcb = snmp1_pcb;
|
trap_msg.pcb = snmp1_pcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* called for each variable binding (also for the fist one)
|
* called for each variable binding (also for the fist one)
|
||||||
*/
|
*/
|
||||||
@ -150,13 +150,10 @@ snmp_msg_event(struct snmp_msg_pstat *msg_ps)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* mn == NULL, noSuchName */
|
/* mn == NULL, noSuchName */
|
||||||
|
snmp_varbind_list_free(&msg_ps->outvb);
|
||||||
|
msg_ps->outvb = msg_ps->invb;
|
||||||
msg_ps->error_status = SNMP_ES_NOSUCHNAME;
|
msg_ps->error_status = SNMP_ES_NOSUCHNAME;
|
||||||
msg_ps->error_index = 1 + msg_ps->vb_idx;
|
msg_ps->error_index = 1 + msg_ps->vb_idx;
|
||||||
msg_ps->outvb.head = NULL;
|
|
||||||
msg_ps->outvb.tail = NULL;
|
|
||||||
msg_ps->outvb.count = 0;
|
|
||||||
msg_ps->outvb.seqlen = 0;
|
|
||||||
msg_ps->outvb.seqlenlen = 1;
|
|
||||||
snmp_send_response(msg_ps);
|
snmp_send_response(msg_ps);
|
||||||
msg_ps->state = SNMP_MSG_EMPTY;
|
msg_ps->state = SNMP_MSG_EMPTY;
|
||||||
}
|
}
|
||||||
@ -179,6 +176,7 @@ snmp_msg_event(struct snmp_msg_pstat *msg_ps)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* lwIP UDP receive callback function */
|
/* lwIP UDP receive callback function */
|
||||||
static void
|
static void
|
||||||
@ -264,34 +262,99 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
|
|||||||
}
|
}
|
||||||
if (mn != NULL)
|
if (mn != NULL)
|
||||||
{
|
{
|
||||||
if (msg_ps->invb.head->value != NULL)
|
struct snmp_varbind *vb;
|
||||||
|
|
||||||
|
/* allocate output varbind */
|
||||||
|
vb = (struct snmp_varbind *)mem_malloc(sizeof(struct snmp_varbind));
|
||||||
|
if (vb != NULL)
|
||||||
{
|
{
|
||||||
LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv free value before vb recycle"));
|
vb->next = NULL;
|
||||||
mem_free(msg_ps->invb.head->value);
|
vb->prev = NULL;
|
||||||
}
|
|
||||||
msg_ps->invb.head->value_type = object_def.asn_type;
|
/* move name from invb to outvb */
|
||||||
msg_ps->invb.head->value_len = object_def.v_len;
|
vb->ident = msg_ps->invb.head->ident;
|
||||||
msg_ps->invb.head->value = mem_malloc(object_def.v_len);
|
vb->ident_len = msg_ps->invb.head->ident_len;
|
||||||
if (msg_ps->invb.head->value != NULL)
|
/* ensure this memory is refereced once only */
|
||||||
|
msg_ps->invb.head->ident = NULL;
|
||||||
|
msg_ps->invb.head->ident_len = 0;
|
||||||
|
|
||||||
|
vb->value_type = object_def.asn_type;
|
||||||
|
vb->value_len = object_def.v_len;
|
||||||
|
vb->value = mem_malloc(object_def.v_len);
|
||||||
|
if (vb->value != NULL)
|
||||||
{
|
{
|
||||||
mn->get_value(&object_def, object_def.v_len, msg_ps->invb.head->value);
|
mn->get_value(&object_def, object_def.v_len, vb->value);
|
||||||
|
snmp_varbind_tail_add(&msg_ps->outvb, vb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate variable space"));
|
LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate variable space"));
|
||||||
}
|
}
|
||||||
msg_ps->outvb = msg_ps->invb;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* mn == NULL, noSuchName */
|
/* mn == NULL, noSuchName */
|
||||||
|
/* @todo move used names back from outvb to invb */
|
||||||
|
snmp_varbind_list_free(&msg_ps->outvb);
|
||||||
|
msg_ps->outvb = msg_ps->invb;
|
||||||
|
msg_ps->error_status = SNMP_ES_NOSUCHNAME;
|
||||||
|
msg_ps->error_index = 1 + msg_ps->vb_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ)
|
||||||
|
{
|
||||||
|
struct snmp_obj_id oid;
|
||||||
|
|
||||||
|
if (snmp_iso_prefix_expand(msg_ps->invb.head->ident_len, msg_ps->invb.head->ident, &oid))
|
||||||
|
{
|
||||||
|
/** @todo expand tree and complete oid */
|
||||||
|
#if 1
|
||||||
|
if (msg_ps->invb.head->ident_len > 3)
|
||||||
|
{
|
||||||
|
/* can offset ident_len and ident */
|
||||||
|
mn = snmp_expand_tree((struct mib_node*)&internet,
|
||||||
|
msg_ps->invb.head->ident_len - 4,
|
||||||
|
msg_ps->invb.head->ident + 4, &oid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* can't offset ident_len -4, ident + 4 */
|
||||||
|
mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
mn = (struct mib_node*)&internet;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mn = NULL;
|
||||||
|
}
|
||||||
|
if (mn != NULL)
|
||||||
|
{
|
||||||
|
struct snmp_varbind *vb;
|
||||||
|
|
||||||
|
vb = snmp_varbind_alloc(&oid, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL), 0);
|
||||||
|
if (vb != NULL)
|
||||||
|
{
|
||||||
|
snmp_varbind_tail_add(&msg_ps->outvb, vb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* mn == NULL, noSuchName */
|
||||||
|
snmp_varbind_list_free(&msg_ps->outvb);
|
||||||
|
msg_ps->outvb = msg_ps->invb;
|
||||||
msg_ps->error_status = SNMP_ES_NOSUCHNAME;
|
msg_ps->error_status = SNMP_ES_NOSUCHNAME;
|
||||||
msg_ps->error_index = 1 + msg_ps->vb_idx;
|
msg_ps->error_index = 1 + msg_ps->vb_idx;
|
||||||
msg_ps->outvb.head = NULL;
|
|
||||||
msg_ps->outvb.tail = NULL;
|
|
||||||
msg_ps->outvb.count = 0;
|
|
||||||
msg_ps->outvb.seqlen = 0;
|
|
||||||
msg_ps->outvb.seqlenlen = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -322,8 +385,8 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
|
|||||||
}
|
}
|
||||||
/* free varbinds (if available) */
|
/* free varbinds (if available) */
|
||||||
snmp_varbind_list_free(&msg_ps->invb);
|
snmp_varbind_list_free(&msg_ps->invb);
|
||||||
|
snmp_varbind_list_free(&msg_ps->outvb);
|
||||||
msg_ps->state = SNMP_MSG_EMPTY;
|
msg_ps->state = SNMP_MSG_EMPTY;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -770,6 +833,8 @@ snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
|
|||||||
vb->prev = NULL;
|
vb->prev = NULL;
|
||||||
i = oid->len;
|
i = oid->len;
|
||||||
vb->ident_len = i;
|
vb->ident_len = i;
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
/* allocate array of s32_t for our object identifier */
|
/* allocate array of s32_t for our object identifier */
|
||||||
vb->ident = (s32_t*)mem_malloc(sizeof(s32_t) * i);
|
vb->ident = (s32_t*)mem_malloc(sizeof(s32_t) * i);
|
||||||
if (vb->ident == NULL)
|
if (vb->ident == NULL)
|
||||||
@ -782,6 +847,12 @@ snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
|
|||||||
i--;
|
i--;
|
||||||
vb->ident[i] = oid->id[i];
|
vb->ident[i] = oid->id[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* i == 0, pass zero length object identifier */
|
||||||
|
vb->ident = NULL;
|
||||||
|
}
|
||||||
vb->value_type = type;
|
vb->value_type = type;
|
||||||
vb->value_len = len;
|
vb->value_len = len;
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
@ -789,8 +860,11 @@ snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
|
|||||||
/* allocate raw bytes for our object value */
|
/* allocate raw bytes for our object value */
|
||||||
vb->value = mem_malloc(len);
|
vb->value = mem_malloc(len);
|
||||||
if (vb->value == NULL)
|
if (vb->value == NULL)
|
||||||
|
{
|
||||||
|
if (vb->ident != NULL)
|
||||||
{
|
{
|
||||||
mem_free(vb->ident);
|
mem_free(vb->ident);
|
||||||
|
}
|
||||||
mem_free(vb);
|
mem_free(vb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -821,15 +895,18 @@ snmp_varbind_free(struct snmp_varbind *vb)
|
|||||||
static void
|
static void
|
||||||
snmp_varbind_list_free(struct snmp_varbind_root *root)
|
snmp_varbind_list_free(struct snmp_varbind_root *root)
|
||||||
{
|
{
|
||||||
struct snmp_varbind *vb;
|
struct snmp_varbind *vb, *prev;
|
||||||
|
|
||||||
vb = root->tail;
|
vb = root->tail;
|
||||||
while ( vb != NULL )
|
while ( vb != NULL )
|
||||||
{
|
{
|
||||||
|
prev = vb->prev;
|
||||||
snmp_varbind_free(vb);
|
snmp_varbind_free(vb);
|
||||||
vb = vb->prev;
|
vb = prev;
|
||||||
}
|
}
|
||||||
root->count = 0;
|
root->count = 0;
|
||||||
|
root->head = NULL;
|
||||||
|
root->tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user