From 1485edf8e19ee63830e815129b9503fe3e276b51 Mon Sep 17 00:00:00 2001 From: christiaans Date: Tue, 29 Aug 2006 11:28:28 +0000 Subject: [PATCH] Added index tree node structs and functions, e.g. to be used for ARP table indexes. --- src/core/snmp/mib2.c | 227 +++++++++++++++----- src/core/snmp/mib_structs.c | 354 +++++++++++++++++++++++++++++++- src/include/lwip/snmp.h | 7 + src/include/lwip/snmp_structs.h | 35 ++++ src/netif/etharp.c | 6 + 5 files changed, 574 insertions(+), 55 deletions(-) diff --git a/src/core/snmp/mib2.c b/src/core/snmp/mib2.c index 4171e0cc..eb07f2fb 100644 --- a/src/core/snmp/mib2.c +++ b/src/core/snmp/mib2.c @@ -1,6 +1,9 @@ /** * @file - * [EXPERIMENTAL] Management Information Base II (RFC1213) objects and functions + * [EXPERIMENTAL] Management Information Base II (RFC1213) objects and functions. + * + * @note the object identifiers for this MIB-2 and private MIB tree + * must be kept in sorted ascending order. This to ensure correct getnext operation. */ /* @@ -516,7 +519,8 @@ static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default; static const struct snmp_obj_id ifspecific = {2, {0, 0}}; /** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */ static const struct snmp_obj_id iprouteinfo = {2, {0, 0}}; -/** mib-2.snmp.snmpEnableAuthenTraps 1 = enabled 2 = disabled */ + +static struct idx_root_node arptree_root = {NULL, NULL, 0}; /* mib-2.system counter(s) */ static u32_t sysuptime = 0; @@ -778,6 +782,106 @@ void snmp_inc_ifoutdiscards(struct netif *ni) (ni->ifoutdiscards)++; } +/** + * Inserts ARP table indexes (.xIfIndex.xNetAddress) + * into arp table index tree. + */ +void snmp_insert_arpidx_tree(struct netif *ni, struct ip_addr *ip) +{ + struct idx_root_node *at_rn; + struct idx_node *at_node; + struct ip_addr hip; + s32_t arpidx[5]; + u8_t level; + + LWIP_ASSERT("ni != NULL", ni != NULL); + snmp_netiftoifindex(ni, &arpidx[0]); + hip.addr = ntohl(ip->addr); + snmp_iptooid(&hip, &arpidx[1]); + + level = 0; + at_rn = &arptree_root; + while (level < 5) + { + at_node = NULL; + snmp_idx_node_insert(at_rn, arpidx[level], &at_node); + if ((level != 4) && (at_node != NULL)) + { + if (at_node->nptr == NULL) + { + at_rn = snmp_idx_root_node_alloc(); + at_node->nptr = at_rn; + } + else + { + at_rn = at_node->nptr; + } + } + level++; + } +} + +/** + * Removes ARP table indexes (.xIfIndex.xNetAddress) + * from arp table index tree. + */ +void snmp_delete_arpidx_tree(struct netif *ni, struct ip_addr *ip) +{ + struct idx_node *at_n, *del_n[5]; + struct idx_root_node *at_rn, *next, *del_rn[5]; + struct ip_addr hip; + s32_t arpidx[5]; + u8_t fc, level, del_cnt; + + snmp_netiftoifindex(ni, &arpidx[0]); + hip.addr = ntohl(ip->addr); + snmp_iptooid(&hip, &arpidx[1]); + + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + at_rn = &arptree_root; + while ((level < 5) && (at_rn != NULL)) + { + fc = snmp_idx_node_find(at_rn, arpidx[level], &at_n); + if (fc == 0) + { + /* arpidx[level] does not exist */ + del_cnt = 0; + at_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = at_rn; + del_n[del_cnt] = at_n; + del_cnt++; + at_rn = at_n->nptr; + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + at_rn = at_n->nptr; + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + at_rn = del_rn[del_cnt]; + at_n = del_n[del_cnt]; + + next = snmp_idx_node_delete(at_rn, at_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_idx_root_node_free(next); + } + } +} + void snmp_inc_ipinreceives(void) { ipinreceives++; @@ -1688,13 +1792,7 @@ atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) netif = netif->next; i++; } - ip.addr = ident[2]; - ip.addr <<= 8; - ip.addr |= ident[3]; - ip.addr <<= 8; - ip.addr |= ident[4]; - ip.addr <<= 8; - ip.addr |= ident[5]; + snmp_oidtoip(&ident[2], &ip); ip.addr = htonl(ip.addr); if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) @@ -1996,13 +2094,7 @@ ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) struct ip_addr ip; struct netif *netif = netif_list; - ip.addr = ident[1]; - ip.addr <<= 8; - ip.addr |= ident[2]; - ip.addr <<= 8; - ip.addr |= ident[3]; - ip.addr <<= 8; - ip.addr |= ident[4]; + snmp_oidtoip(&ident[1], &ip); ip.addr = htonl(ip.addr); while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr)) @@ -2140,13 +2232,7 @@ ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) struct ip_addr dest; struct netif *netif; - dest.addr = ident[1]; - dest.addr <<= 8; - dest.addr |= ident[2]; - dest.addr <<= 8; - dest.addr |= ident[3]; - dest.addr <<= 8; - dest.addr |= ident[4]; + snmp_oidtoip(&ident[1], &dest); dest.addr = htonl(dest.addr); if (dest.addr == 0) @@ -2236,13 +2322,8 @@ ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value) netif = od->addr; ident = od->id_inst_ptr; - dest.addr = ident[1]; - dest.addr <<= 8; - dest.addr |= ident[2]; - dest.addr <<= 8; - dest.addr |= ident[3]; - dest.addr <<= 8; - dest.addr |= ident[4]; + + snmp_oidtoip(&ident[1], &dest); dest.addr = htonl(dest.addr); id = ident[0]; @@ -2392,13 +2473,7 @@ ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) netif = netif->next; i++; } - ip.addr = ident[2]; - ip.addr <<= 8; - ip.addr |= ident[3]; - ip.addr <<= 8; - ip.addr |= ident[4]; - ip.addr <<= 8; - ip.addr |= ident[5]; + snmp_oidtoip(&ident[2], &ip); ip.addr = htonl(ip.addr); if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) @@ -2679,15 +2754,17 @@ tcp_get_value(struct obj_def *od, u16_t len, void *value) *sint_ptr = 4; break; case 2: /* tcpRtoMin */ - /* @todo need value */ - *sint_ptr = 0; + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 1000; break; case 3: /* tcpRtoMax */ - /* @todo need value */ - *sint_ptr = 0; + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 60000; break; case 4: /* tcpMaxConn */ - *sint_ptr = MEMP_NUM_TCP_PCB_LISTEN; + *sint_ptr = MEMP_NUM_TCP_PCB; break; case 5: /* tcpActiveOpens */ *uint_ptr = tcpactiveopens; @@ -2738,6 +2815,60 @@ tcp_get_value(struct obj_def *od, u16_t len, void *value) static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) { + if (ident_len == 11) + { + u8_t id; + struct ip_addr lip, rip; + u16_t lport, rport; + + snmp_oidtoip(&ident[1], &lip); + lip.addr = htonl(lip.addr); + lport = ident[5]; + snmp_oidtoip(&ident[6], &rip); + rip.addr = htonl(rip.addr); + rport = ident[10]; + + /* @todo find matching PCB */ + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0",(u16_t)id)); + + switch (id) + { + case 1: /* tcpConnState */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* tcpConnLocalAddress */ + case 4: /* tcpConnRemAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 3: /* tcpConnLocalPort */ + case 5: /* tcpConnRemPort */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object")); + od->instance = MIB_OBJECT_NONE; + } } static void @@ -2801,13 +2932,7 @@ udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) struct ip_addr ip; u16_t port; - ip.addr = ident[1]; - ip.addr <<= 8; - ip.addr |= ident[2]; - ip.addr <<= 8; - ip.addr |= ident[3]; - ip.addr <<= 8; - ip.addr |= ident[4]; + snmp_oidtoip(&ident[1], &ip); ip.addr = htonl(ip.addr); port = ident[5]; @@ -2830,13 +2955,13 @@ udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) { case 1: /* udpLocalAddress */ od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; + od->access = MIB_OBJECT_READ_ONLY; od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); od->v_len = 4; break; case 2: /* udpLocalPort */ od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; + od->access = MIB_OBJECT_READ_ONLY; od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); od->v_len = sizeof(s32_t); break; diff --git a/src/core/snmp/mib_structs.c b/src/core/snmp/mib_structs.c index f06f49b3..b480f93e 100644 --- a/src/core/snmp/mib_structs.c +++ b/src/core/snmp/mib_structs.c @@ -1,6 +1,6 @@ /** * @file - * [EXPERIMENTAL] Generic MIB tree access/construction functions. + * [EXPERIMENTAL] MIB tree access/construction functions. */ /* @@ -36,6 +36,7 @@ #if LWIP_SNMP #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}; @@ -52,6 +53,9 @@ struct nse static u8_t node_stack_cnt = 0; static struct nse node_stack[NODE_STACK_SIZE]; +/** + * Pushes nse struct onto stack. + */ static void push_node(struct nse* node) { @@ -63,6 +67,9 @@ push_node(struct nse* node) } } +/** + * Pops nse struct from stack. + */ static void pop_node(struct nse* node) { @@ -73,6 +80,345 @@ pop_node(struct nse* node) } } +/** + * 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 ifindex 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) +{ + ip->addr = ident[0]; + ip->addr <<= 8; + ip->addr |= ident[1]; + ip->addr <<= 8; + ip->addr |= ident[2]; + ip->addr <<= 8; + ip->addr |= ident[3]; +} + +/** + * 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) +{ + u8_t trnc; + + trnc = ip->addr >> 24; + ident[0] = trnc & 0xff; + trnc = ip->addr >> 16; + ident[1] = trnc & 0xff; + trnc = ip->addr >> 8; + ident[2] = trnc & 0xff; + trnc = ip->addr; + ident[3] = trnc & 0xff; +} + +struct idx_node * +snmp_idx_node_alloc(s32_t id) +{ + struct idx_node *in; + + in = (struct idx_node*)mem_malloc(sizeof(struct idx_node)); + if (in != NULL) + { + in->next = NULL; + in->prev = NULL; + in->objid = id; + in->nptr = NULL; + } + return in; +} + +void +snmp_idx_node_free(struct idx_node *in) +{ + mem_free(in); +} + +struct idx_root_node * +snmp_idx_root_node_alloc(void) +{ + struct idx_root_node *irn; + + irn = (struct idx_root_node*)mem_malloc(sizeof(struct idx_root_node)); + if (irn != NULL) + { + irn->head = NULL; + irn->tail = NULL; + irn->count = 0; + } + return irn; +} + +void +snmp_idx_root_node_free(struct idx_root_node *irn) +{ + mem_free(irn); +} + +/** + * 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 success. + */ +s8_t +snmp_idx_node_insert(struct idx_root_node *rn, s32_t objid, struct idx_node **insn) +{ + struct idx_node *nn; + s8_t insert; + + LWIP_ASSERT("rn != NULL",rn != NULL); + + /* -1 = malloc failure, 0 = not inserted, 1 = inserted (or 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_idx_node_alloc(objid); + if (nn != NULL) + { + rn->head = nn; + rn->tail = nn; + *insn = nn; + insert = 1; + } + else + { + insert = -1; + } + } + else + { + struct idx_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 = 1; + } + 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_idx_node_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_idx_node_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) + */ +s8_t +snmp_idx_node_find(struct idx_root_node *rn, s32_t objid, struct idx_node **fn) +{ + s8_t fc; + struct idx_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 if (n->nptr->count > 1) + { + /* can't delete node */ + fc = 2; + } + else + { + /* count <= 1, can delete node */ + fc = 1; + } + *fn = n; + return fc; +} + +/** + * 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 idx_root_node * +snmp_idx_node_delete(struct idx_root_node *rn, struct idx_node *n) +{ + struct idx_root_node *next; + + LWIP_ASSERT("rn != NULL",rn != NULL); + LWIP_ASSERT("n != NULL",n != NULL); + + /* caller must remove this sub-tree */ + next = 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_idx_node_free(n); + + return next; +} + /** * Searches tree for the supplied (scalar?) object identifier. * @@ -307,7 +653,7 @@ snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snm if (an->nptr[i] == NULL) { - /* leaf node, /* + /* leaf node, if scalar: if ident_len == 1 add '.0', nextThing.0 otherwise */ if (ident_len == 1) { @@ -344,7 +690,7 @@ snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snm { cur_node.r_ptr = NULL; } - LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand, push_node() node=%p id=%"S32_F,cur_node.r_ptr,cur_node.r_id)); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand, push_node() node=%p id=%"S32_F,(void*)cur_node.r_ptr,cur_node.r_id)); push_node(&cur_node); /* follow next child pointer */ ident_len--; @@ -367,7 +713,7 @@ snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snm while ((node_stack_cnt > 0) && (child.r_ptr == NULL)) { pop_node(&child); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand, pop_node() node=%p id=%"S32_F, child.r_ptr, child.r_id)); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand, pop_node() node=%p id=%"S32_F,(void *)child.r_ptr, child.r_id)); /* trim returned oid */ (oidret->len)--; } diff --git a/src/include/lwip/snmp.h b/src/include/lwip/snmp.h index b4c1fd97..cbc2b2ee 100644 --- a/src/include/lwip/snmp.h +++ b/src/include/lwip/snmp.h @@ -58,6 +58,10 @@ 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); +/* ARP */ +void snmp_insert_arpidx_tree(struct netif *ni, struct ip_addr *ip); +void snmp_delete_arpidx_tree(struct netif *ni, struct ip_addr *ip); + /* network interface */ void snmp_add_ifinoctets(struct netif *ni, u32_t value); void snmp_inc_ifinucastpkts(struct netif *ni); @@ -173,6 +177,9 @@ void snmp_set_snmpenableauthentraps(u8_t *value); #define snmp_inc_sysuptime() #define snmp_get_sysuptime(value) +/* ARP */ +#define snmp_insert_arpidx_tree(ni,ip) +#define snmp_delete_arpidx_tree(ni,ip) /* network interface */ #define snmp_add_ifinoctets(ni,value) diff --git a/src/include/lwip/snmp_structs.h b/src/include/lwip/snmp_structs.h index de5ca8c1..27271f05 100644 --- a/src/include/lwip/snmp_structs.h +++ b/src/include/lwip/snmp_structs.h @@ -186,6 +186,41 @@ extern const struct mib_array_node internet; void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); void noleafs_get_value(struct obj_def *od, u16_t len, void *value); +/** forward decl */ +struct idx_root_node; +/** "index" tree node */ +struct idx_node +{ + struct idx_node* next; + struct idx_node* prev; + /* child id */ + s32_t objid; + /* tree child pointer */ + struct idx_root_node *nptr; +}; +/** "index" tree root node */ +struct idx_root_node +{ + struct idx_node *head; + struct idx_node *tail; + u16_t count; +}; + +void snmp_oidtoip(s32_t *ident, struct ip_addr *ip); +void snmp_iptooid(struct ip_addr *ip, s32_t *ident); +void snmp_ifindextonetif(s32_t ifindex, struct netif **netif); +void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx); + +struct idx_node* snmp_idx_node_alloc(s32_t id); +void snmp_idx_node_free(struct idx_node *in); +struct idx_root_node* snmp_idx_root_node_alloc(void); +void snmp_idx_root_node_free(struct idx_root_node *irn); + + +s8_t snmp_idx_node_insert(struct idx_root_node *rn, s32_t objid, struct idx_node **insn); +s8_t snmp_idx_node_find(struct idx_root_node *rn, s32_t objid, struct idx_node **fn); +struct idx_root_node *snmp_idx_node_delete(struct idx_root_node *rn, struct idx_node *n); + struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj_def *object_def); struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident); diff --git a/src/netif/etharp.c b/src/netif/etharp.c index 70bffb9c..0788be79 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -49,6 +49,7 @@ #include "netif/etharp.h" #include "lwip/ip.h" #include "lwip/stats.h" +#include "lwip/snmp.h" /* ARP needs to inform DHCP of any ARP replies? */ #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) @@ -150,6 +151,8 @@ etharp_tmr(void) (arp_table[i].ctime >= ARP_MAXAGE)) { LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %"U16_F".\n", (u16_t)i)); arp_table[i].state = ETHARP_STATE_EXPIRED; + /* remove from SNMP ARP index tree */ + snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); /* pending entry? */ } else if (arp_table[i].state == ETHARP_STATE_PENDING) { /* entry unresolved/pending for too long? */ @@ -383,6 +386,9 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e /* record network interface */ arp_table[i].netif = netif; + /* insert in SNMP ARP index tree */ + snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); + LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); /* update address */ k = netif->hwaddr_len;