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

View File

@ -50,6 +50,20 @@ Running the agent
The following function calls must be made in your program to
actually get the SNMP agent running.
Before starting the agent you should supply pointers
to non-volatile memory for sysContact, sysLocation,
and snmpEnableAuthenTraps. You can do this by calling
snmp_set_syscontact()
snmp_set_syslocation()
snmp_set_snmpenableauthentraps()
Additionally you may want to set
snmp_set_sysdescr()
snmp_set_sysobjid() (if you have a private MIB)
snmp_set_sysname()
In the lwIP initialisation sequence call snmp_init() just after
the call to udp_init().
@ -57,14 +71,6 @@ Exactly every 10 msec the SNMP uptime timestamp must be updated with
snmp_inc_sysuptime(). You should call this from a timer interrupt
or a timer signal handler depending on your runtime environment.
You _must_ create the following support functions for non-volatile storage
since lwIP does not have notion of files or other non-volatile memories.
void snmp_store_syscontact(u8_t* ocstr, u8_t ocstrlen);
void snmp_store_sysname(u8_t* ocstr, u8_t ocstrlen);
void snmp_store_syslocation(u8_t* ocstr, u8_t ocstrlen);
Private MIBs
============

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;
}

View File

@ -49,19 +49,14 @@ struct snmp_obj_id
};
/* system */
void snmp_set_sysdesr(u8_t* str, u8_t strlen);
void snmp_set_sysdesr(u8_t* str, u8_t* strlen);
void snmp_set_sysobjid(struct snmp_obj_id *oid);
void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid);
void snmp_inc_sysuptime(void);
void snmp_get_sysuptime(u32_t *value);
void snmp_set_syscontact(u8_t *ocstr, u8_t ocstrlen);
void snmp_set_sysname(u8_t *ocstr, u8_t ocstrlen);
void snmp_set_syslocation(u8_t *ocstr, u8_t ocstrlen);
/** externally supplied system functions
@see lwip/doc/snmp_agent.txt */
void snmp_store_syscontact(u8_t* ocstr, u8_t ocstrlen);
void snmp_store_sysname(u8_t* ocstr, u8_t ocstrlen);
void snmp_store_syslocation(u8_t* ocstr, u8_t ocstrlen);
void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen);
void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen);
void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen);
/* network interface */
void snmp_add_ifinoctets(struct netif *ni, u32_t value);
@ -75,13 +70,22 @@ void snmp_inc_ifoutdiscards(struct netif *ni);
/* IP */
void snmp_inc_ipinreceives(void);
void snmp_inc_ipindelivers(void);
void snmp_inc_ipindiscards(void);
void snmp_inc_ipoutdiscards(void);
void snmp_inc_ipoutrequests(void);
void snmp_inc_ipunknownprotos(void);
void snmp_inc_ipnoroutes(void);
void snmp_inc_ipinhdrerrors(void);
void snmp_inc_ipinaddrerrors(void);
void snmp_inc_ipforwdatagrams(void);
void snmp_inc_ipinunknownprotos(void);
void snmp_inc_ipindiscards(void);
void snmp_inc_ipindelivers(void);
void snmp_inc_ipoutrequests(void);
void snmp_inc_ipoutdiscards(void);
void snmp_inc_ipoutnoroutes(void);
void snmp_inc_ipreasmreqds(void);
void snmp_inc_ipreasmoks(void);
void snmp_inc_ipreasmfails(void);
void snmp_inc_ipfragoks(void);
void snmp_inc_ipfragfails(void);
void snmp_inc_ipfragcreates(void);
void snmp_inc_iproutingdiscards(void);
/* ICMP */
void snmp_inc_icmpinmsgs(void);
@ -158,15 +162,18 @@ void snmp_inc_snmpoutsetrequests(void);
void snmp_inc_snmpoutgetresponses(void);
void snmp_inc_snmpouttraps(void);
void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
void snmp_set_snmpenableauthentraps(u8_t *value);
/* LWIP_SNMP support not available */
/* define everything to be empty */
#else
/* system */
#define snmp_set_sysdesr(str, strlen)
#define snmp_get_sysobjid_ptr(oid)
#define snmp_inc_sysuptime()
#define snmp_get_sysuptime(value)
#define snmp_get_sysobjid_ptr(oid)
/* network interface */
#define snmp_add_ifinoctets(ni,value)
@ -180,13 +187,22 @@ void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
/* IP */
#define snmp_inc_ipinreceives()
#define snmp_inc_ipindelivers()
#define snmp_inc_ipindiscards()
#define snmp_inc_ipoutdiscards()
#define snmp_inc_ipoutrequests()
#define snmp_inc_ipunknownprotos()
#define snmp_inc_ipnoroutes()
#define snmp_inc_ipinhdrerrors()
#define snmp_inc_ipinaddrerrors()
#define snmp_inc_ipforwdatagrams()
#define snmp_inc_ipinunknownprotos()
#define snmp_inc_ipindiscards()
#define snmp_inc_ipindelivers()
#define snmp_inc_ipoutrequests()
#define snmp_inc_ipoutdiscards()
#define snmp_inc_ipoutnoroutes()
#define snmp_inc_ipreasmreqds()
#define snmp_inc_ipreasmoks()
#define snmp_inc_ipreasmfails()
#define snmp_inc_ipfragoks()
#define snmp_inc_ipfragfails()
#define snmp_inc_ipfragcreates()
#define snmp_inc_iproutingdiscards()
/* ICMP */
#define snmp_inc_icmpinmsgs()
@ -262,6 +278,7 @@ void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
#define snmp_inc_snmpoutgetresponses()
#define snmp_inc_snmpouttraps()
#define snmp_get_snmpgrpid_ptr(oid)
#define snmp_set_snmpenableauthentraps(value)
#endif

View File

@ -208,8 +208,12 @@ struct snmp_msg_pstat
u8_t community[SNMP_COMMUNITY_STR_LEN + 1];
/* community string length (exclusive zero term) */
u8_t com_strlen;
/* one out of MSG_EMPTY, MSG_DEMUX, MSG_MGMT, MSG_PRIVATE */
/* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL */
u8_t state;
/* index into input variable binding list */
u8_t vb_idx;
/* ptr into input variable binding list */
struct snmp_varbind *vb_ptr;
/* list of variable bindings from input */
struct snmp_varbind_root invb;
/* list of variable bindings to output */
@ -260,7 +264,8 @@ extern struct snmp_msg_trap trap_msg;
/** Agent setup, start listening to port 161. */
void snmp_init(void);
/** Handles internal/external events. */
void snmp_msg_event(struct snmp_msg_pstat *msg_ps);
err_t snmp_send_response(struct snmp_msg_pstat *m_stat);
err_t snmp_send_trap(struct ip_addr *dst, s8_t generic_trap, s32_t specific_trap);

View File

@ -70,6 +70,8 @@ struct obj_def
u8_t id_inst_len;
/* instance part of supplied object identifier */
s32_t *id_inst_ptr;
/* optional value address hint */
void *addr;
};
/** MIB const array node */
@ -88,7 +90,7 @@ struct mib_node
void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
/** returns object value for the given object identifier,
@note the caller must allocate at least len bytes for the value */
void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
void (*get_value)(struct obj_def *od, u16_t len, void *value);
/** @todo set_value() */
/** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */
const u8_t node_type;
@ -102,7 +104,7 @@ struct mib_array_node
{
/* inherited "base class" */
const void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
const void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
const void (*get_value)(struct obj_def *od, u16_t len, void *value);
const u8_t node_type;
const u16_t maxlength;
@ -117,7 +119,7 @@ struct mib_ram_array_node
{
/* inherited "base class" */
void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
void (*get_value)(struct obj_def *od, u16_t len, void *value);
u8_t node_type;
u16_t maxlength;
@ -140,7 +142,7 @@ struct mib_list_rootnode
{
/* inherited "base class" */
void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
void (*get_value)(struct obj_def *od, u16_t len, void *value);
u8_t node_type;
u16_t maxlength;
@ -157,13 +159,13 @@ struct mib_external_node
{
/* inherited "base class" */
void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
void (*get_value)(struct obj_def *od, u16_t len, void *value);
u8_t node_type;
u16_t maxlength;
/* aditional struct members */
void (*req_object_def)(u8_t ident_len, s32_t *ident);
void (*getreq_value)(u8_t ident_len, s32_t *ident);
void (*getreq_value)(struct obj_def *od);
/** compares object sub identifier with externally available id
return zero when equal, nonzero when unequal */
@ -174,6 +176,10 @@ struct mib_external_node
u16_t count;
};
/** export MIB tree from mib2.c */
extern const struct mib_array_node internet;
struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj_def *object_def);
u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident);
#endif