MIB-2 object values near to completion, just committing for keeping the flame alive.

This commit is contained in:
christiaans
2006-08-11 14:16:36 +00:00
parent d0b81d3b20
commit 8559f3e583
7 changed files with 1872 additions and 261 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -221,4 +221,26 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
return NULL;
}
/**
* Test object identifier for the iso.org.dod.internet prefix.
*
* @param ident_len the length of the supplied object identifier
* @param ident points to the array of sub identifiers
* @return 1 if it matches, 0 otherwise
*/
u8_t
snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident)
{
if ((ident_len > 3) &&
(ident[0] == 1) && (ident[1] == 3) &&
(ident[2] == 6) && (ident[3] == 1))
{
return 1;
}
else
{
return 0;
}
}
#endif /* LWIP_SNMP */

View File

@@ -46,7 +46,6 @@
#include "lwip/snmp.h"
#include "lwip/snmp_asn1.h"
#include "lwip/snmp_msg.h"
#include "lwip/snmp_structs.h"
#if LWIP_SNMP
@@ -74,9 +73,7 @@ static void snmp_varbind_list_free(struct snmp_varbind_root *root);
static void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb);
static struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root);
/** @todo: move this to header */
extern const struct mib_array_node internet;
extern const struct mib_array_node sys_tem; /* test only */
/**
* Starts SNMP Agent.
@@ -106,11 +103,81 @@ snmp_init(void)
}
/**
*
* called for each variable binding (also for the fist one)
*/
void
snmp_msg_event(void)
snmp_msg_event(struct snmp_msg_pstat *msg_ps)
{
struct mib_node *mn;
struct obj_def object_def;
if (msg_ps->state == SNMP_MSG_DEMUX)
{
if (msg_ps->vb_idx == 0)
{
msg_ps->vb_ptr = msg_ps->invb.head;
}
else
{
msg_ps->vb_ptr = msg_ps->vb_ptr->next;
msg_ps->vb_idx += 1;
}
if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
{
/** test object identifier for .iso.org.dod.internet prefix */
if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident))
{
mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
msg_ps->vb_ptr->ident + 4, &object_def);
}
else
{
mn = NULL;
}
if (mn != NULL)
{
if (mn->node_type == MIB_NODE_EX)
{
/* external object */
msg_ps->state = SNMP_MSG_EXTERNAL;
}
else
{
/* internal object */
msg_ps->state = SNMP_MSG_INTERNAL;
}
}
else
{
/* mn == NULL, noSuchName */
msg_ps->error_status = SNMP_ES_NOSUCHNAME;
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);
msg_ps->state = SNMP_MSG_EMPTY;
}
}
else if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ)
{
}
else if (msg_ps->rt == SNMP_ASN1_PDU_SET_REQ)
{
}
else
{
/** @todo not a request, return generror?? */
}
}
else if (msg_ps->state == SNMP_MSG_INTERNAL)
{
}
else if (msg_ps->state == SNMP_MSG_EXTERNAL)
{
}
}
/* lwIP UDP receive callback function */
@@ -156,6 +223,8 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
msg_ps->sp = port;
/* demultiplex variable bindings */
msg_ps->state = SNMP_MSG_DEMUX;
/* first variable binding from list to inspect */
msg_ps->vb_idx = 0;
/* read UDP payload length from UDP header */
payload_len = ntohs(udphdr->len) - UDP_HLEN;
@@ -171,7 +240,7 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
/* Builds a list of variable bindings. Copy the varbinds from the pbuf
chain to glue them when these are divided over two or more pbuf's. */
err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps);
if (err_ret == ERR_OK)
if ((err_ret == ERR_OK) && (msg_ps->invb.count > 0))
{
struct mib_node *mn;
struct obj_def object_def;
@@ -183,14 +252,18 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
{
/** @todo check if count > 0 and if we got .iso.dod.internet and iterate from vb 0 .. count-1 */
mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->invb.head->ident_len - 2 /* trim iso.dod.internet */,
msg_ps->invb.head->ident + 2, &object_def);
/** test object identifier for .iso.org.dod.internet prefix */
if (snmp_iso_prefix_tst(msg_ps->invb.head->ident_len, msg_ps->invb.head->ident))
{
mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->invb.head->ident_len - 4,
msg_ps->invb.head->ident + 4, &object_def);
}
else
{
mn = NULL;
}
if (mn != NULL)
{
LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv mn=%p sys_tem=%p node_typ=%"U16_F,
(void*)mn,(void*)&sys_tem,(u16_t)mn->node_type));
if (msg_ps->invb.head->value != NULL)
{
LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv free value before vb recycle"));
@@ -201,7 +274,7 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
msg_ps->invb.head->value = mem_malloc(object_def.v_len);
if (msg_ps->invb.head->value != NULL)
{
mn->get_value(object_def.id_inst_len, object_def.id_inst_ptr, object_def.v_len, msg_ps->invb.head->value);
mn->get_value(&object_def, object_def.v_len, msg_ps->invb.head->value);
}
else
{
@@ -213,8 +286,7 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
{
/* mn == NULL, noSuchName */
msg_ps->error_status = SNMP_ES_NOSUCHNAME;
/** @todo current varbind index */
msg_ps->error_index = 1;
msg_ps->error_index = 1 + msg_ps->vb_idx;
msg_ps->outvb.head = NULL;
msg_ps->outvb.tail = NULL;
msg_ps->outvb.count = 0;
@@ -232,6 +304,10 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
msg_ps->error_index = 0;
}
/* when more variable bindings left msg_ps->state = SNMP_MSG_DEMUX */
/* when completed transaction */
err_ret = snmp_send_response(msg_ps);
if (err_ret == ERR_MEM)
{
@@ -247,13 +323,21 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
/* free varbinds (if available) */
snmp_varbind_list_free(&msg_ps->invb);
msg_ps->state = SNMP_MSG_EMPTY;
}
else
{
/* varbind-list decode failed! */
/* varbind-list decode failed, or varbind list empty (silly cmd for agent) */
pbuf_free(p);
/** @todo should we return SNMP_ES_GENERROR here ? */
LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed"));
msg_ps->error_status = SNMP_ES_GENERROR;
msg_ps->error_index = 0;
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);
}
}
else
@@ -306,14 +390,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
snmp_inc_snmpinasnparseerrs();
return ERR_ARG;
}
if (type & SNMP_ASN1_CONSTR)
{
ofs += (1 + len_octets);
}
else
{
ofs += (1 + len_octets + len);
}
ofs += (1 + len_octets);
snmp_asn1_dec_type(p, ofs, &type);
derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
@@ -335,14 +412,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
snmp_inc_snmpinbadversions();
return ERR_ARG;
}
if (type & SNMP_ASN1_CONSTR)
{
ofs += (1 + len_octets);
}
else
{
ofs += (1 + len_octets + len);
}
ofs += (1 + len_octets + len);
snmp_asn1_dec_type(p, ofs, &type);
derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)))
@@ -369,14 +439,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
/** @todo: send authentication failure trap, if we have a trap destination */
return ERR_ARG;
}
if (type & SNMP_ASN1_CONSTR)
{
ofs += (1 + len_octets);
}
else
{
ofs += (1 + len_octets + len);
}
ofs += (1 + len_octets + len);
snmp_asn1_dec_type(p, ofs, &type);
derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
if (derr != ERR_OK)
@@ -422,14 +485,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
return ERR_ARG;
}
m_stat->rt = type & 0x1F;
if (type & SNMP_ASN1_CONSTR)
{
ofs += (1 + len_octets);
}
else
{
ofs += (1 + len_octets + len);
}
ofs += (1 + len_octets);
snmp_asn1_dec_type(p, ofs, &type);
derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
@@ -445,14 +501,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
snmp_inc_snmpinasnparseerrs();
return ERR_ARG;
}
if (type & SNMP_ASN1_CONSTR)
{
ofs += (1 + len_octets);
}
else
{
ofs += (1 + len_octets + len);
}
ofs += (1 + len_octets + len);
snmp_asn1_dec_type(p, ofs, &type);
derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
@@ -488,14 +537,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
snmp_inc_snmpingenerrs();
break;
}
if (type & SNMP_ASN1_CONSTR)
{
ofs += (1 + len_octets);
}
else
{
ofs += (1 + len_octets + len);
}
ofs += (1 + len_octets + len);
snmp_asn1_dec_type(p, ofs, &type);
derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
@@ -505,14 +547,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
return ERR_ARG;
}
/* skip 'error-index', usually 0 for incoming requests */
if (type & SNMP_ASN1_CONSTR)
{
ofs += (1 + len_octets);
}
else
{
ofs += (1 + len_octets + len);
}
ofs += (1 + len_octets + len);
*ofs_ret = ofs;
return ERR_OK;
}