SNMP agent attached to SPI slave

Dependencies:   mbed

Committer:
lorcansmith
Date:
Mon Aug 13 15:07:40 2012 +0000
Revision:
0:2a53a4c3238c
v1.1 release includes ioAlarm traps

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lorcansmith 0:2a53a4c3238c 1 /**
lorcansmith 0:2a53a4c3238c 2 * @file
lorcansmith 0:2a53a4c3238c 3 * MIB tree access/construction functions.
lorcansmith 0:2a53a4c3238c 4 */
lorcansmith 0:2a53a4c3238c 5
lorcansmith 0:2a53a4c3238c 6 /*
lorcansmith 0:2a53a4c3238c 7 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
lorcansmith 0:2a53a4c3238c 8 * All rights reserved.
lorcansmith 0:2a53a4c3238c 9 *
lorcansmith 0:2a53a4c3238c 10 * Redistribution and use in source and binary forms, with or without modification,
lorcansmith 0:2a53a4c3238c 11 * are permitted provided that the following conditions are met:
lorcansmith 0:2a53a4c3238c 12 *
lorcansmith 0:2a53a4c3238c 13 * 1. Redistributions of source code must retain the above copyright notice,
lorcansmith 0:2a53a4c3238c 14 * this list of conditions and the following disclaimer.
lorcansmith 0:2a53a4c3238c 15 * 2. Redistributions in binary form must reproduce the above copyright notice,
lorcansmith 0:2a53a4c3238c 16 * this list of conditions and the following disclaimer in the documentation
lorcansmith 0:2a53a4c3238c 17 * and/or other materials provided with the distribution.
lorcansmith 0:2a53a4c3238c 18 * 3. The name of the author may not be used to endorse or promote products
lorcansmith 0:2a53a4c3238c 19 * derived from this software without specific prior written permission.
lorcansmith 0:2a53a4c3238c 20 *
lorcansmith 0:2a53a4c3238c 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
lorcansmith 0:2a53a4c3238c 22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
lorcansmith 0:2a53a4c3238c 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
lorcansmith 0:2a53a4c3238c 24 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
lorcansmith 0:2a53a4c3238c 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
lorcansmith 0:2a53a4c3238c 26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
lorcansmith 0:2a53a4c3238c 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
lorcansmith 0:2a53a4c3238c 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
lorcansmith 0:2a53a4c3238c 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
lorcansmith 0:2a53a4c3238c 30 * OF SUCH DAMAGE.
lorcansmith 0:2a53a4c3238c 31 *
lorcansmith 0:2a53a4c3238c 32 * Author: Christiaan Simons <christiaan.simons@axon.tv>
lorcansmith 0:2a53a4c3238c 33 */
lorcansmith 0:2a53a4c3238c 34
lorcansmith 0:2a53a4c3238c 35 #include "lwip/opt.h"
lorcansmith 0:2a53a4c3238c 36
lorcansmith 0:2a53a4c3238c 37 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
lorcansmith 0:2a53a4c3238c 38
lorcansmith 0:2a53a4c3238c 39 #include "lwip/snmp_structs.h"
lorcansmith 0:2a53a4c3238c 40 #include "lwip/memp.h"
lorcansmith 0:2a53a4c3238c 41 #include "lwip/netif.h"
lorcansmith 0:2a53a4c3238c 42
lorcansmith 0:2a53a4c3238c 43 /** .iso.org.dod.internet address prefix, @see snmp_iso_*() */
lorcansmith 0:2a53a4c3238c 44 const s32_t prefix[4] = {1, 3, 6, 1};
lorcansmith 0:2a53a4c3238c 45
lorcansmith 0:2a53a4c3238c 46 #define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN)
lorcansmith 0:2a53a4c3238c 47 /** node stack entry (old news?) */
lorcansmith 0:2a53a4c3238c 48 struct nse
lorcansmith 0:2a53a4c3238c 49 {
lorcansmith 0:2a53a4c3238c 50 /** right child */
lorcansmith 0:2a53a4c3238c 51 struct mib_node* r_ptr;
lorcansmith 0:2a53a4c3238c 52 /** right child identifier */
lorcansmith 0:2a53a4c3238c 53 s32_t r_id;
lorcansmith 0:2a53a4c3238c 54 /** right child next level */
lorcansmith 0:2a53a4c3238c 55 u8_t r_nl;
lorcansmith 0:2a53a4c3238c 56 };
lorcansmith 0:2a53a4c3238c 57 static u8_t node_stack_cnt;
lorcansmith 0:2a53a4c3238c 58 static struct nse node_stack[NODE_STACK_SIZE];
lorcansmith 0:2a53a4c3238c 59
lorcansmith 0:2a53a4c3238c 60 /**
lorcansmith 0:2a53a4c3238c 61 * Pushes nse struct onto stack.
lorcansmith 0:2a53a4c3238c 62 */
lorcansmith 0:2a53a4c3238c 63 static void
lorcansmith 0:2a53a4c3238c 64 push_node(struct nse* node)
lorcansmith 0:2a53a4c3238c 65 {
lorcansmith 0:2a53a4c3238c 66 LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE);
lorcansmith 0:2a53a4c3238c 67 LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id));
lorcansmith 0:2a53a4c3238c 68 if (node_stack_cnt < NODE_STACK_SIZE)
lorcansmith 0:2a53a4c3238c 69 {
lorcansmith 0:2a53a4c3238c 70 node_stack[node_stack_cnt] = *node;
lorcansmith 0:2a53a4c3238c 71 node_stack_cnt++;
lorcansmith 0:2a53a4c3238c 72 }
lorcansmith 0:2a53a4c3238c 73 }
lorcansmith 0:2a53a4c3238c 74
lorcansmith 0:2a53a4c3238c 75 /**
lorcansmith 0:2a53a4c3238c 76 * Pops nse struct from stack.
lorcansmith 0:2a53a4c3238c 77 */
lorcansmith 0:2a53a4c3238c 78 static void
lorcansmith 0:2a53a4c3238c 79 pop_node(struct nse* node)
lorcansmith 0:2a53a4c3238c 80 {
lorcansmith 0:2a53a4c3238c 81 if (node_stack_cnt > 0)
lorcansmith 0:2a53a4c3238c 82 {
lorcansmith 0:2a53a4c3238c 83 node_stack_cnt--;
lorcansmith 0:2a53a4c3238c 84 *node = node_stack[node_stack_cnt];
lorcansmith 0:2a53a4c3238c 85 }
lorcansmith 0:2a53a4c3238c 86 LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id));
lorcansmith 0:2a53a4c3238c 87 }
lorcansmith 0:2a53a4c3238c 88
lorcansmith 0:2a53a4c3238c 89 /**
lorcansmith 0:2a53a4c3238c 90 * Conversion from ifIndex to lwIP netif
lorcansmith 0:2a53a4c3238c 91 * @param ifindex is a s32_t object sub-identifier
lorcansmith 0:2a53a4c3238c 92 * @param netif points to returned netif struct pointer
lorcansmith 0:2a53a4c3238c 93 */
lorcansmith 0:2a53a4c3238c 94 void
lorcansmith 0:2a53a4c3238c 95 snmp_ifindextonetif(s32_t ifindex, struct netif **netif)
lorcansmith 0:2a53a4c3238c 96 {
lorcansmith 0:2a53a4c3238c 97 struct netif *nif = netif_list;
lorcansmith 0:2a53a4c3238c 98 s32_t i, ifidx;
lorcansmith 0:2a53a4c3238c 99
lorcansmith 0:2a53a4c3238c 100 ifidx = ifindex - 1;
lorcansmith 0:2a53a4c3238c 101 i = 0;
lorcansmith 0:2a53a4c3238c 102 while ((nif != NULL) && (i < ifidx))
lorcansmith 0:2a53a4c3238c 103 {
lorcansmith 0:2a53a4c3238c 104 nif = nif->next;
lorcansmith 0:2a53a4c3238c 105 i++;
lorcansmith 0:2a53a4c3238c 106 }
lorcansmith 0:2a53a4c3238c 107 *netif = nif;
lorcansmith 0:2a53a4c3238c 108 }
lorcansmith 0:2a53a4c3238c 109
lorcansmith 0:2a53a4c3238c 110 /**
lorcansmith 0:2a53a4c3238c 111 * Conversion from lwIP netif to ifIndex
lorcansmith 0:2a53a4c3238c 112 * @param netif points to a netif struct
lorcansmith 0:2a53a4c3238c 113 * @param ifidx points to s32_t object sub-identifier
lorcansmith 0:2a53a4c3238c 114 */
lorcansmith 0:2a53a4c3238c 115 void
lorcansmith 0:2a53a4c3238c 116 snmp_netiftoifindex(struct netif *netif, s32_t *ifidx)
lorcansmith 0:2a53a4c3238c 117 {
lorcansmith 0:2a53a4c3238c 118 struct netif *nif = netif_list;
lorcansmith 0:2a53a4c3238c 119 u16_t i;
lorcansmith 0:2a53a4c3238c 120
lorcansmith 0:2a53a4c3238c 121 i = 0;
lorcansmith 0:2a53a4c3238c 122 while ((nif != NULL) && (nif != netif))
lorcansmith 0:2a53a4c3238c 123 {
lorcansmith 0:2a53a4c3238c 124 nif = nif->next;
lorcansmith 0:2a53a4c3238c 125 i++;
lorcansmith 0:2a53a4c3238c 126 }
lorcansmith 0:2a53a4c3238c 127 *ifidx = i+1;
lorcansmith 0:2a53a4c3238c 128 }
lorcansmith 0:2a53a4c3238c 129
lorcansmith 0:2a53a4c3238c 130 /**
lorcansmith 0:2a53a4c3238c 131 * Conversion from oid to lwIP ip_addr
lorcansmith 0:2a53a4c3238c 132 * @param ident points to s32_t ident[4] input
lorcansmith 0:2a53a4c3238c 133 * @param ip points to output struct
lorcansmith 0:2a53a4c3238c 134 */
lorcansmith 0:2a53a4c3238c 135 void
lorcansmith 0:2a53a4c3238c 136 snmp_oidtoip(s32_t *ident, ip_addr_t *ip)
lorcansmith 0:2a53a4c3238c 137 {
lorcansmith 0:2a53a4c3238c 138 IP4_ADDR(ip, ident[0], ident[1], ident[2], ident[3]);
lorcansmith 0:2a53a4c3238c 139 }
lorcansmith 0:2a53a4c3238c 140
lorcansmith 0:2a53a4c3238c 141 /**
lorcansmith 0:2a53a4c3238c 142 * Conversion from lwIP ip_addr to oid
lorcansmith 0:2a53a4c3238c 143 * @param ip points to input struct
lorcansmith 0:2a53a4c3238c 144 * @param ident points to s32_t ident[4] output
lorcansmith 0:2a53a4c3238c 145 */
lorcansmith 0:2a53a4c3238c 146 void
lorcansmith 0:2a53a4c3238c 147 snmp_iptooid(ip_addr_t *ip, s32_t *ident)
lorcansmith 0:2a53a4c3238c 148 {
lorcansmith 0:2a53a4c3238c 149 ident[0] = ip4_addr1(ip);
lorcansmith 0:2a53a4c3238c 150 ident[1] = ip4_addr2(ip);
lorcansmith 0:2a53a4c3238c 151 ident[2] = ip4_addr3(ip);
lorcansmith 0:2a53a4c3238c 152 ident[3] = ip4_addr4(ip);
lorcansmith 0:2a53a4c3238c 153 }
lorcansmith 0:2a53a4c3238c 154
lorcansmith 0:2a53a4c3238c 155 struct mib_list_node *
lorcansmith 0:2a53a4c3238c 156 snmp_mib_ln_alloc(s32_t id)
lorcansmith 0:2a53a4c3238c 157 {
lorcansmith 0:2a53a4c3238c 158 struct mib_list_node *ln;
lorcansmith 0:2a53a4c3238c 159
lorcansmith 0:2a53a4c3238c 160 ln = (struct mib_list_node *)memp_malloc(MEMP_SNMP_NODE);
lorcansmith 0:2a53a4c3238c 161 if (ln != NULL)
lorcansmith 0:2a53a4c3238c 162 {
lorcansmith 0:2a53a4c3238c 163 ln->prev = NULL;
lorcansmith 0:2a53a4c3238c 164 ln->next = NULL;
lorcansmith 0:2a53a4c3238c 165 ln->objid = id;
lorcansmith 0:2a53a4c3238c 166 ln->nptr = NULL;
lorcansmith 0:2a53a4c3238c 167 }
lorcansmith 0:2a53a4c3238c 168 return ln;
lorcansmith 0:2a53a4c3238c 169 }
lorcansmith 0:2a53a4c3238c 170
lorcansmith 0:2a53a4c3238c 171 void
lorcansmith 0:2a53a4c3238c 172 snmp_mib_ln_free(struct mib_list_node *ln)
lorcansmith 0:2a53a4c3238c 173 {
lorcansmith 0:2a53a4c3238c 174 memp_free(MEMP_SNMP_NODE, ln);
lorcansmith 0:2a53a4c3238c 175 }
lorcansmith 0:2a53a4c3238c 176
lorcansmith 0:2a53a4c3238c 177 struct mib_list_rootnode *
lorcansmith 0:2a53a4c3238c 178 snmp_mib_lrn_alloc(void)
lorcansmith 0:2a53a4c3238c 179 {
lorcansmith 0:2a53a4c3238c 180 struct mib_list_rootnode *lrn;
lorcansmith 0:2a53a4c3238c 181
lorcansmith 0:2a53a4c3238c 182 lrn = (struct mib_list_rootnode*)memp_malloc(MEMP_SNMP_ROOTNODE);
lorcansmith 0:2a53a4c3238c 183 if (lrn != NULL)
lorcansmith 0:2a53a4c3238c 184 {
lorcansmith 0:2a53a4c3238c 185 lrn->get_object_def = noleafs_get_object_def;
lorcansmith 0:2a53a4c3238c 186 lrn->get_value = noleafs_get_value;
lorcansmith 0:2a53a4c3238c 187 lrn->set_test = noleafs_set_test;
lorcansmith 0:2a53a4c3238c 188 lrn->set_value = noleafs_set_value;
lorcansmith 0:2a53a4c3238c 189 lrn->node_type = MIB_NODE_LR;
lorcansmith 0:2a53a4c3238c 190 lrn->maxlength = 0;
lorcansmith 0:2a53a4c3238c 191 lrn->head = NULL;
lorcansmith 0:2a53a4c3238c 192 lrn->tail = NULL;
lorcansmith 0:2a53a4c3238c 193 lrn->count = 0;
lorcansmith 0:2a53a4c3238c 194 }
lorcansmith 0:2a53a4c3238c 195 return lrn;
lorcansmith 0:2a53a4c3238c 196 }
lorcansmith 0:2a53a4c3238c 197
lorcansmith 0:2a53a4c3238c 198 void
lorcansmith 0:2a53a4c3238c 199 snmp_mib_lrn_free(struct mib_list_rootnode *lrn)
lorcansmith 0:2a53a4c3238c 200 {
lorcansmith 0:2a53a4c3238c 201 memp_free(MEMP_SNMP_ROOTNODE, lrn);
lorcansmith 0:2a53a4c3238c 202 }
lorcansmith 0:2a53a4c3238c 203
lorcansmith 0:2a53a4c3238c 204 /**
lorcansmith 0:2a53a4c3238c 205 * Inserts node in idx list in a sorted
lorcansmith 0:2a53a4c3238c 206 * (ascending order) fashion and
lorcansmith 0:2a53a4c3238c 207 * allocates the node if needed.
lorcansmith 0:2a53a4c3238c 208 *
lorcansmith 0:2a53a4c3238c 209 * @param rn points to the root node
lorcansmith 0:2a53a4c3238c 210 * @param objid is the object sub identifier
lorcansmith 0:2a53a4c3238c 211 * @param insn points to a pointer to the inserted node
lorcansmith 0:2a53a4c3238c 212 * used for constructing the tree.
lorcansmith 0:2a53a4c3238c 213 * @return -1 if failed, 1 if inserted, 2 if present.
lorcansmith 0:2a53a4c3238c 214 */
lorcansmith 0:2a53a4c3238c 215 s8_t
lorcansmith 0:2a53a4c3238c 216 snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn)
lorcansmith 0:2a53a4c3238c 217 {
lorcansmith 0:2a53a4c3238c 218 struct mib_list_node *nn;
lorcansmith 0:2a53a4c3238c 219 s8_t insert;
lorcansmith 0:2a53a4c3238c 220
lorcansmith 0:2a53a4c3238c 221 LWIP_ASSERT("rn != NULL",rn != NULL);
lorcansmith 0:2a53a4c3238c 222
lorcansmith 0:2a53a4c3238c 223 /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */
lorcansmith 0:2a53a4c3238c 224 insert = 0;
lorcansmith 0:2a53a4c3238c 225 if (rn->head == NULL)
lorcansmith 0:2a53a4c3238c 226 {
lorcansmith 0:2a53a4c3238c 227 /* empty list, add first node */
lorcansmith 0:2a53a4c3238c 228 LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid));
lorcansmith 0:2a53a4c3238c 229 nn = snmp_mib_ln_alloc(objid);
lorcansmith 0:2a53a4c3238c 230 if (nn != NULL)
lorcansmith 0:2a53a4c3238c 231 {
lorcansmith 0:2a53a4c3238c 232 rn->head = nn;
lorcansmith 0:2a53a4c3238c 233 rn->tail = nn;
lorcansmith 0:2a53a4c3238c 234 *insn = nn;
lorcansmith 0:2a53a4c3238c 235 insert = 1;
lorcansmith 0:2a53a4c3238c 236 }
lorcansmith 0:2a53a4c3238c 237 else
lorcansmith 0:2a53a4c3238c 238 {
lorcansmith 0:2a53a4c3238c 239 insert = -1;
lorcansmith 0:2a53a4c3238c 240 }
lorcansmith 0:2a53a4c3238c 241 }
lorcansmith 0:2a53a4c3238c 242 else
lorcansmith 0:2a53a4c3238c 243 {
lorcansmith 0:2a53a4c3238c 244 struct mib_list_node *n;
lorcansmith 0:2a53a4c3238c 245 /* at least one node is present */
lorcansmith 0:2a53a4c3238c 246 n = rn->head;
lorcansmith 0:2a53a4c3238c 247 while ((n != NULL) && (insert == 0))
lorcansmith 0:2a53a4c3238c 248 {
lorcansmith 0:2a53a4c3238c 249 if (n->objid == objid)
lorcansmith 0:2a53a4c3238c 250 {
lorcansmith 0:2a53a4c3238c 251 /* node is already there */
lorcansmith 0:2a53a4c3238c 252 LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid));
lorcansmith 0:2a53a4c3238c 253 *insn = n;
lorcansmith 0:2a53a4c3238c 254 insert = 2;
lorcansmith 0:2a53a4c3238c 255 }
lorcansmith 0:2a53a4c3238c 256 else if (n->objid < objid)
lorcansmith 0:2a53a4c3238c 257 {
lorcansmith 0:2a53a4c3238c 258 if (n->next == NULL)
lorcansmith 0:2a53a4c3238c 259 {
lorcansmith 0:2a53a4c3238c 260 /* alloc and insert at the tail */
lorcansmith 0:2a53a4c3238c 261 LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid));
lorcansmith 0:2a53a4c3238c 262 nn = snmp_mib_ln_alloc(objid);
lorcansmith 0:2a53a4c3238c 263 if (nn != NULL)
lorcansmith 0:2a53a4c3238c 264 {
lorcansmith 0:2a53a4c3238c 265 nn->next = NULL;
lorcansmith 0:2a53a4c3238c 266 nn->prev = n;
lorcansmith 0:2a53a4c3238c 267 n->next = nn;
lorcansmith 0:2a53a4c3238c 268 rn->tail = nn;
lorcansmith 0:2a53a4c3238c 269 *insn = nn;
lorcansmith 0:2a53a4c3238c 270 insert = 1;
lorcansmith 0:2a53a4c3238c 271 }
lorcansmith 0:2a53a4c3238c 272 else
lorcansmith 0:2a53a4c3238c 273 {
lorcansmith 0:2a53a4c3238c 274 /* insertion failure */
lorcansmith 0:2a53a4c3238c 275 insert = -1;
lorcansmith 0:2a53a4c3238c 276 }
lorcansmith 0:2a53a4c3238c 277 }
lorcansmith 0:2a53a4c3238c 278 else
lorcansmith 0:2a53a4c3238c 279 {
lorcansmith 0:2a53a4c3238c 280 /* there's more to explore: traverse list */
lorcansmith 0:2a53a4c3238c 281 LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n"));
lorcansmith 0:2a53a4c3238c 282 n = n->next;
lorcansmith 0:2a53a4c3238c 283 }
lorcansmith 0:2a53a4c3238c 284 }
lorcansmith 0:2a53a4c3238c 285 else
lorcansmith 0:2a53a4c3238c 286 {
lorcansmith 0:2a53a4c3238c 287 /* n->objid > objid */
lorcansmith 0:2a53a4c3238c 288 /* alloc and insert between n->prev and n */
lorcansmith 0:2a53a4c3238c 289 LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid));
lorcansmith 0:2a53a4c3238c 290 nn = snmp_mib_ln_alloc(objid);
lorcansmith 0:2a53a4c3238c 291 if (nn != NULL)
lorcansmith 0:2a53a4c3238c 292 {
lorcansmith 0:2a53a4c3238c 293 if (n->prev == NULL)
lorcansmith 0:2a53a4c3238c 294 {
lorcansmith 0:2a53a4c3238c 295 /* insert at the head */
lorcansmith 0:2a53a4c3238c 296 nn->next = n;
lorcansmith 0:2a53a4c3238c 297 nn->prev = NULL;
lorcansmith 0:2a53a4c3238c 298 rn->head = nn;
lorcansmith 0:2a53a4c3238c 299 n->prev = nn;
lorcansmith 0:2a53a4c3238c 300 }
lorcansmith 0:2a53a4c3238c 301 else
lorcansmith 0:2a53a4c3238c 302 {
lorcansmith 0:2a53a4c3238c 303 /* insert in the middle */
lorcansmith 0:2a53a4c3238c 304 nn->next = n;
lorcansmith 0:2a53a4c3238c 305 nn->prev = n->prev;
lorcansmith 0:2a53a4c3238c 306 n->prev->next = nn;
lorcansmith 0:2a53a4c3238c 307 n->prev = nn;
lorcansmith 0:2a53a4c3238c 308 }
lorcansmith 0:2a53a4c3238c 309 *insn = nn;
lorcansmith 0:2a53a4c3238c 310 insert = 1;
lorcansmith 0:2a53a4c3238c 311 }
lorcansmith 0:2a53a4c3238c 312 else
lorcansmith 0:2a53a4c3238c 313 {
lorcansmith 0:2a53a4c3238c 314 /* insertion failure */
lorcansmith 0:2a53a4c3238c 315 insert = -1;
lorcansmith 0:2a53a4c3238c 316 }
lorcansmith 0:2a53a4c3238c 317 }
lorcansmith 0:2a53a4c3238c 318 }
lorcansmith 0:2a53a4c3238c 319 }
lorcansmith 0:2a53a4c3238c 320 if (insert == 1)
lorcansmith 0:2a53a4c3238c 321 {
lorcansmith 0:2a53a4c3238c 322 rn->count += 1;
lorcansmith 0:2a53a4c3238c 323 }
lorcansmith 0:2a53a4c3238c 324 LWIP_ASSERT("insert != 0",insert != 0);
lorcansmith 0:2a53a4c3238c 325 return insert;
lorcansmith 0:2a53a4c3238c 326 }
lorcansmith 0:2a53a4c3238c 327
lorcansmith 0:2a53a4c3238c 328 /**
lorcansmith 0:2a53a4c3238c 329 * Finds node in idx list and returns deletion mark.
lorcansmith 0:2a53a4c3238c 330 *
lorcansmith 0:2a53a4c3238c 331 * @param rn points to the root node
lorcansmith 0:2a53a4c3238c 332 * @param objid is the object sub identifier
lorcansmith 0:2a53a4c3238c 333 * @param fn returns pointer to found node
lorcansmith 0:2a53a4c3238c 334 * @return 0 if not found, 1 if deletable,
lorcansmith 0:2a53a4c3238c 335 * 2 can't delete (2 or more children), 3 not a list_node
lorcansmith 0:2a53a4c3238c 336 */
lorcansmith 0:2a53a4c3238c 337 s8_t
lorcansmith 0:2a53a4c3238c 338 snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn)
lorcansmith 0:2a53a4c3238c 339 {
lorcansmith 0:2a53a4c3238c 340 s8_t fc;
lorcansmith 0:2a53a4c3238c 341 struct mib_list_node *n;
lorcansmith 0:2a53a4c3238c 342
lorcansmith 0:2a53a4c3238c 343 LWIP_ASSERT("rn != NULL",rn != NULL);
lorcansmith 0:2a53a4c3238c 344 n = rn->head;
lorcansmith 0:2a53a4c3238c 345 while ((n != NULL) && (n->objid != objid))
lorcansmith 0:2a53a4c3238c 346 {
lorcansmith 0:2a53a4c3238c 347 n = n->next;
lorcansmith 0:2a53a4c3238c 348 }
lorcansmith 0:2a53a4c3238c 349 if (n == NULL)
lorcansmith 0:2a53a4c3238c 350 {
lorcansmith 0:2a53a4c3238c 351 fc = 0;
lorcansmith 0:2a53a4c3238c 352 }
lorcansmith 0:2a53a4c3238c 353 else if (n->nptr == NULL)
lorcansmith 0:2a53a4c3238c 354 {
lorcansmith 0:2a53a4c3238c 355 /* leaf, can delete node */
lorcansmith 0:2a53a4c3238c 356 fc = 1;
lorcansmith 0:2a53a4c3238c 357 }
lorcansmith 0:2a53a4c3238c 358 else
lorcansmith 0:2a53a4c3238c 359 {
lorcansmith 0:2a53a4c3238c 360 struct mib_list_rootnode *r;
lorcansmith 0:2a53a4c3238c 361
lorcansmith 0:2a53a4c3238c 362 if (n->nptr->node_type == MIB_NODE_LR)
lorcansmith 0:2a53a4c3238c 363 {
lorcansmith 0:2a53a4c3238c 364 r = (struct mib_list_rootnode *)n->nptr;
lorcansmith 0:2a53a4c3238c 365 if (r->count > 1)
lorcansmith 0:2a53a4c3238c 366 {
lorcansmith 0:2a53a4c3238c 367 /* can't delete node */
lorcansmith 0:2a53a4c3238c 368 fc = 2;
lorcansmith 0:2a53a4c3238c 369 }
lorcansmith 0:2a53a4c3238c 370 else
lorcansmith 0:2a53a4c3238c 371 {
lorcansmith 0:2a53a4c3238c 372 /* count <= 1, can delete node */
lorcansmith 0:2a53a4c3238c 373 fc = 1;
lorcansmith 0:2a53a4c3238c 374 }
lorcansmith 0:2a53a4c3238c 375 }
lorcansmith 0:2a53a4c3238c 376 else
lorcansmith 0:2a53a4c3238c 377 {
lorcansmith 0:2a53a4c3238c 378 /* other node type */
lorcansmith 0:2a53a4c3238c 379 fc = 3;
lorcansmith 0:2a53a4c3238c 380 }
lorcansmith 0:2a53a4c3238c 381 }
lorcansmith 0:2a53a4c3238c 382 *fn = n;
lorcansmith 0:2a53a4c3238c 383 return fc;
lorcansmith 0:2a53a4c3238c 384 }
lorcansmith 0:2a53a4c3238c 385
lorcansmith 0:2a53a4c3238c 386 /**
lorcansmith 0:2a53a4c3238c 387 * Removes node from idx list
lorcansmith 0:2a53a4c3238c 388 * if it has a single child left.
lorcansmith 0:2a53a4c3238c 389 *
lorcansmith 0:2a53a4c3238c 390 * @param rn points to the root node
lorcansmith 0:2a53a4c3238c 391 * @param n points to the node to delete
lorcansmith 0:2a53a4c3238c 392 * @return the nptr to be freed by caller
lorcansmith 0:2a53a4c3238c 393 */
lorcansmith 0:2a53a4c3238c 394 struct mib_list_rootnode *
lorcansmith 0:2a53a4c3238c 395 snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n)
lorcansmith 0:2a53a4c3238c 396 {
lorcansmith 0:2a53a4c3238c 397 struct mib_list_rootnode *next;
lorcansmith 0:2a53a4c3238c 398
lorcansmith 0:2a53a4c3238c 399 LWIP_ASSERT("rn != NULL",rn != NULL);
lorcansmith 0:2a53a4c3238c 400 LWIP_ASSERT("n != NULL",n != NULL);
lorcansmith 0:2a53a4c3238c 401
lorcansmith 0:2a53a4c3238c 402 /* caller must remove this sub-tree */
lorcansmith 0:2a53a4c3238c 403 next = (struct mib_list_rootnode*)(n->nptr);
lorcansmith 0:2a53a4c3238c 404 rn->count -= 1;
lorcansmith 0:2a53a4c3238c 405
lorcansmith 0:2a53a4c3238c 406 if (n == rn->head)
lorcansmith 0:2a53a4c3238c 407 {
lorcansmith 0:2a53a4c3238c 408 rn->head = n->next;
lorcansmith 0:2a53a4c3238c 409 if (n->next != NULL)
lorcansmith 0:2a53a4c3238c 410 {
lorcansmith 0:2a53a4c3238c 411 /* not last node, new list begin */
lorcansmith 0:2a53a4c3238c 412 n->next->prev = NULL;
lorcansmith 0:2a53a4c3238c 413 }
lorcansmith 0:2a53a4c3238c 414 }
lorcansmith 0:2a53a4c3238c 415 else if (n == rn->tail)
lorcansmith 0:2a53a4c3238c 416 {
lorcansmith 0:2a53a4c3238c 417 rn->tail = n->prev;
lorcansmith 0:2a53a4c3238c 418 if (n->prev != NULL)
lorcansmith 0:2a53a4c3238c 419 {
lorcansmith 0:2a53a4c3238c 420 /* not last node, new list end */
lorcansmith 0:2a53a4c3238c 421 n->prev->next = NULL;
lorcansmith 0:2a53a4c3238c 422 }
lorcansmith 0:2a53a4c3238c 423 }
lorcansmith 0:2a53a4c3238c 424 else
lorcansmith 0:2a53a4c3238c 425 {
lorcansmith 0:2a53a4c3238c 426 /* node must be in the middle */
lorcansmith 0:2a53a4c3238c 427 n->prev->next = n->next;
lorcansmith 0:2a53a4c3238c 428 n->next->prev = n->prev;
lorcansmith 0:2a53a4c3238c 429 }
lorcansmith 0:2a53a4c3238c 430 LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid));
lorcansmith 0:2a53a4c3238c 431 snmp_mib_ln_free(n);
lorcansmith 0:2a53a4c3238c 432 if (rn->count == 0)
lorcansmith 0:2a53a4c3238c 433 {
lorcansmith 0:2a53a4c3238c 434 rn->head = NULL;
lorcansmith 0:2a53a4c3238c 435 rn->tail = NULL;
lorcansmith 0:2a53a4c3238c 436 }
lorcansmith 0:2a53a4c3238c 437 return next;
lorcansmith 0:2a53a4c3238c 438 }
lorcansmith 0:2a53a4c3238c 439
lorcansmith 0:2a53a4c3238c 440
lorcansmith 0:2a53a4c3238c 441
lorcansmith 0:2a53a4c3238c 442 /**
lorcansmith 0:2a53a4c3238c 443 * Searches tree for the supplied (scalar?) object identifier.
lorcansmith 0:2a53a4c3238c 444 *
lorcansmith 0:2a53a4c3238c 445 * @param node points to the root of the tree ('.internet')
lorcansmith 0:2a53a4c3238c 446 * @param ident_len the length of the supplied object identifier
lorcansmith 0:2a53a4c3238c 447 * @param ident points to the array of sub identifiers
lorcansmith 0:2a53a4c3238c 448 * @param np points to the found object instance (return)
lorcansmith 0:2a53a4c3238c 449 * @return pointer to the requested parent (!) node if success, NULL otherwise
lorcansmith 0:2a53a4c3238c 450 */
lorcansmith 0:2a53a4c3238c 451 struct mib_node *
lorcansmith 0:2a53a4c3238c 452 snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np)
lorcansmith 0:2a53a4c3238c 453 {
lorcansmith 0:2a53a4c3238c 454 u8_t node_type, ext_level;
lorcansmith 0:2a53a4c3238c 455
lorcansmith 0:2a53a4c3238c 456 ext_level = 0;
lorcansmith 0:2a53a4c3238c 457 LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident));
lorcansmith 0:2a53a4c3238c 458 while (node != NULL)
lorcansmith 0:2a53a4c3238c 459 {
lorcansmith 0:2a53a4c3238c 460 node_type = node->node_type;
lorcansmith 0:2a53a4c3238c 461 //printf("snmp_search_tree: node_type = %d, ident_len %d\r\n", node_type, ident_len);
lorcansmith 0:2a53a4c3238c 462 if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
lorcansmith 0:2a53a4c3238c 463 {
lorcansmith 0:2a53a4c3238c 464 struct mib_array_node *an;
lorcansmith 0:2a53a4c3238c 465 u16_t i;
lorcansmith 0:2a53a4c3238c 466
lorcansmith 0:2a53a4c3238c 467 if (ident_len > 0)
lorcansmith 0:2a53a4c3238c 468 {
lorcansmith 0:2a53a4c3238c 469 /* array node (internal ROM or RAM, fixed length) */
lorcansmith 0:2a53a4c3238c 470 an = (struct mib_array_node *)node;
lorcansmith 0:2a53a4c3238c 471 i = 0;
lorcansmith 0:2a53a4c3238c 472 while ((i < an->maxlength) && (an->objid[i] != *ident))
lorcansmith 0:2a53a4c3238c 473 {
lorcansmith 0:2a53a4c3238c 474 i++;
lorcansmith 0:2a53a4c3238c 475 }
lorcansmith 0:2a53a4c3238c 476 if (i < an->maxlength)
lorcansmith 0:2a53a4c3238c 477 {
lorcansmith 0:2a53a4c3238c 478 /* found it, if available proceed to child, otherwise inspect leaf */
lorcansmith 0:2a53a4c3238c 479 LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident));
lorcansmith 0:2a53a4c3238c 480 //printf("\r\nsnmp_search_tree: an->objid[%d] %d *ident==%d\r\n",i,an->objid[i],*ident);
lorcansmith 0:2a53a4c3238c 481 if (an->nptr[i] == NULL)
lorcansmith 0:2a53a4c3238c 482 {
lorcansmith 0:2a53a4c3238c 483 /* a scalar leaf OR table,
lorcansmith 0:2a53a4c3238c 484 inspect remaining instance number / table index */
lorcansmith 0:2a53a4c3238c 485 np->ident_len = ident_len;
lorcansmith 0:2a53a4c3238c 486 np->ident = ident;
lorcansmith 0:2a53a4c3238c 487 //printf("snmp_search_tree: np->ident_len %d\r\n",np->ident_len);
lorcansmith 0:2a53a4c3238c 488 return (struct mib_node*)an;
lorcansmith 0:2a53a4c3238c 489 }
lorcansmith 0:2a53a4c3238c 490 else
lorcansmith 0:2a53a4c3238c 491 {
lorcansmith 0:2a53a4c3238c 492 /* follow next child pointer */
lorcansmith 0:2a53a4c3238c 493 ident++;
lorcansmith 0:2a53a4c3238c 494 ident_len--;
lorcansmith 0:2a53a4c3238c 495 node = an->nptr[i];
lorcansmith 0:2a53a4c3238c 496 //printf("snmp_search_tree: ident_len %d\r\n",ident_len);
lorcansmith 0:2a53a4c3238c 497 }
lorcansmith 0:2a53a4c3238c 498 }
lorcansmith 0:2a53a4c3238c 499 else
lorcansmith 0:2a53a4c3238c 500 {
lorcansmith 0:2a53a4c3238c 501 /* search failed, identifier mismatch (nosuchname) */
lorcansmith 0:2a53a4c3238c 502 LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident));
lorcansmith 0:2a53a4c3238c 503 return NULL;
lorcansmith 0:2a53a4c3238c 504 }
lorcansmith 0:2a53a4c3238c 505 }
lorcansmith 0:2a53a4c3238c 506 else
lorcansmith 0:2a53a4c3238c 507 {
lorcansmith 0:2a53a4c3238c 508 /* search failed, short object identifier (nosuchname) */
lorcansmith 0:2a53a4c3238c 509 LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n"));
lorcansmith 0:2a53a4c3238c 510 return NULL;
lorcansmith 0:2a53a4c3238c 511 }
lorcansmith 0:2a53a4c3238c 512 }
lorcansmith 0:2a53a4c3238c 513 else if(node_type == MIB_NODE_LR)
lorcansmith 0:2a53a4c3238c 514 {
lorcansmith 0:2a53a4c3238c 515 struct mib_list_rootnode *lrn;
lorcansmith 0:2a53a4c3238c 516 struct mib_list_node *ln;
lorcansmith 0:2a53a4c3238c 517
lorcansmith 0:2a53a4c3238c 518 if (ident_len > 0)
lorcansmith 0:2a53a4c3238c 519 {
lorcansmith 0:2a53a4c3238c 520 /* list root node (internal 'RAM', variable length) */
lorcansmith 0:2a53a4c3238c 521 lrn = (struct mib_list_rootnode *)node;
lorcansmith 0:2a53a4c3238c 522 ln = lrn->head;
lorcansmith 0:2a53a4c3238c 523 /* iterate over list, head to tail */
lorcansmith 0:2a53a4c3238c 524 while ((ln != NULL) && (ln->objid != *ident))
lorcansmith 0:2a53a4c3238c 525 {
lorcansmith 0:2a53a4c3238c 526 ln = ln->next;
lorcansmith 0:2a53a4c3238c 527 }
lorcansmith 0:2a53a4c3238c 528 if (ln != NULL)
lorcansmith 0:2a53a4c3238c 529 {
lorcansmith 0:2a53a4c3238c 530 /* found it, proceed to child */;
lorcansmith 0:2a53a4c3238c 531 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident));
lorcansmith 0:2a53a4c3238c 532 printf("\r\nsnmp_search_tree: ln->objid==%"S32_F" *ident==%"S32_F"\r\n",ln->objid,*ident);
lorcansmith 0:2a53a4c3238c 533 if (ln->nptr == NULL)
lorcansmith 0:2a53a4c3238c 534 {
lorcansmith 0:2a53a4c3238c 535 np->ident_len = ident_len;
lorcansmith 0:2a53a4c3238c 536 np->ident = ident;
lorcansmith 0:2a53a4c3238c 537 return (struct mib_node*)lrn;
lorcansmith 0:2a53a4c3238c 538 }
lorcansmith 0:2a53a4c3238c 539 else
lorcansmith 0:2a53a4c3238c 540 {
lorcansmith 0:2a53a4c3238c 541 /* follow next child pointer */
lorcansmith 0:2a53a4c3238c 542 ident_len--;
lorcansmith 0:2a53a4c3238c 543 ident++;
lorcansmith 0:2a53a4c3238c 544 node = ln->nptr;
lorcansmith 0:2a53a4c3238c 545 }
lorcansmith 0:2a53a4c3238c 546 }
lorcansmith 0:2a53a4c3238c 547 else
lorcansmith 0:2a53a4c3238c 548 {
lorcansmith 0:2a53a4c3238c 549 /* search failed */
lorcansmith 0:2a53a4c3238c 550 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident));
lorcansmith 0:2a53a4c3238c 551 return NULL;
lorcansmith 0:2a53a4c3238c 552 }
lorcansmith 0:2a53a4c3238c 553 }
lorcansmith 0:2a53a4c3238c 554 else
lorcansmith 0:2a53a4c3238c 555 {
lorcansmith 0:2a53a4c3238c 556 /* search failed, short object identifier (nosuchname) */
lorcansmith 0:2a53a4c3238c 557 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n"));
lorcansmith 0:2a53a4c3238c 558 return NULL;
lorcansmith 0:2a53a4c3238c 559 }
lorcansmith 0:2a53a4c3238c 560 }
lorcansmith 0:2a53a4c3238c 561 else if(node_type == MIB_NODE_EX)
lorcansmith 0:2a53a4c3238c 562 {
lorcansmith 0:2a53a4c3238c 563 struct mib_external_node *en;
lorcansmith 0:2a53a4c3238c 564 u16_t i, len;
lorcansmith 0:2a53a4c3238c 565
lorcansmith 0:2a53a4c3238c 566 if (ident_len > 0)
lorcansmith 0:2a53a4c3238c 567 {
lorcansmith 0:2a53a4c3238c 568 /* external node (addressing and access via functions) */
lorcansmith 0:2a53a4c3238c 569 en = (struct mib_external_node *)node;
lorcansmith 0:2a53a4c3238c 570
lorcansmith 0:2a53a4c3238c 571 i = 0;
lorcansmith 0:2a53a4c3238c 572 len = en->level_length(en->addr_inf,ext_level);
lorcansmith 0:2a53a4c3238c 573 while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0))
lorcansmith 0:2a53a4c3238c 574 {
lorcansmith 0:2a53a4c3238c 575 i++;
lorcansmith 0:2a53a4c3238c 576 }
lorcansmith 0:2a53a4c3238c 577 if (i < len)
lorcansmith 0:2a53a4c3238c 578 {
lorcansmith 0:2a53a4c3238c 579 s32_t debug_id;
lorcansmith 0:2a53a4c3238c 580
lorcansmith 0:2a53a4c3238c 581 en->get_objid(en->addr_inf,ext_level,i,&debug_id);
lorcansmith 0:2a53a4c3238c 582 LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident));
lorcansmith 0:2a53a4c3238c 583 if ((ext_level + 1) == en->tree_levels)
lorcansmith 0:2a53a4c3238c 584 {
lorcansmith 0:2a53a4c3238c 585 np->ident_len = ident_len;
lorcansmith 0:2a53a4c3238c 586 np->ident = ident;
lorcansmith 0:2a53a4c3238c 587 return (struct mib_node*)en;
lorcansmith 0:2a53a4c3238c 588 }
lorcansmith 0:2a53a4c3238c 589 else
lorcansmith 0:2a53a4c3238c 590 {
lorcansmith 0:2a53a4c3238c 591 /* found it, proceed to child */
lorcansmith 0:2a53a4c3238c 592 ident_len--;
lorcansmith 0:2a53a4c3238c 593 ident++;
lorcansmith 0:2a53a4c3238c 594 ext_level++;
lorcansmith 0:2a53a4c3238c 595 }
lorcansmith 0:2a53a4c3238c 596 }
lorcansmith 0:2a53a4c3238c 597 else
lorcansmith 0:2a53a4c3238c 598 {
lorcansmith 0:2a53a4c3238c 599 /* search failed */
lorcansmith 0:2a53a4c3238c 600 LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident));
lorcansmith 0:2a53a4c3238c 601 return NULL;
lorcansmith 0:2a53a4c3238c 602 }
lorcansmith 0:2a53a4c3238c 603 }
lorcansmith 0:2a53a4c3238c 604 else
lorcansmith 0:2a53a4c3238c 605 {
lorcansmith 0:2a53a4c3238c 606 /* search failed, short object identifier (nosuchname) */
lorcansmith 0:2a53a4c3238c 607 LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n"));
lorcansmith 0:2a53a4c3238c 608 printf("\r\nsnmp_search_tree: en search failed, short object identifier\r\n");
lorcansmith 0:2a53a4c3238c 609 return NULL;
lorcansmith 0:2a53a4c3238c 610 }
lorcansmith 0:2a53a4c3238c 611 }
lorcansmith 0:2a53a4c3238c 612 else if (node_type == MIB_NODE_SC)
lorcansmith 0:2a53a4c3238c 613 {
lorcansmith 0:2a53a4c3238c 614 mib_scalar_node *sn;
lorcansmith 0:2a53a4c3238c 615
lorcansmith 0:2a53a4c3238c 616 sn = (mib_scalar_node *)node;
lorcansmith 0:2a53a4c3238c 617 if ((ident_len == 1) && (*ident == 0))
lorcansmith 0:2a53a4c3238c 618 {
lorcansmith 0:2a53a4c3238c 619 np->ident_len = ident_len;
lorcansmith 0:2a53a4c3238c 620 np->ident = ident;
lorcansmith 0:2a53a4c3238c 621 printf("\r\nsnmp_search_tree: np->ident_len = %d\r\n", ident_len);
lorcansmith 0:2a53a4c3238c 622 return (struct mib_node*)sn;
lorcansmith 0:2a53a4c3238c 623 }
lorcansmith 0:2a53a4c3238c 624 else
lorcansmith 0:2a53a4c3238c 625 {
lorcansmith 0:2a53a4c3238c 626 /* search failed, short object identifier (nosuchname) */
lorcansmith 0:2a53a4c3238c 627 LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n"));
lorcansmith 0:2a53a4c3238c 628 return NULL;
lorcansmith 0:2a53a4c3238c 629 }
lorcansmith 0:2a53a4c3238c 630 }
lorcansmith 0:2a53a4c3238c 631 else
lorcansmith 0:2a53a4c3238c 632 {
lorcansmith 0:2a53a4c3238c 633 /* unknown node_type */
lorcansmith 0:2a53a4c3238c 634 LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type));
lorcansmith 0:2a53a4c3238c 635 return NULL;
lorcansmith 0:2a53a4c3238c 636 }
lorcansmith 0:2a53a4c3238c 637 }
lorcansmith 0:2a53a4c3238c 638 /* done, found nothing */
lorcansmith 0:2a53a4c3238c 639 LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node));
lorcansmith 0:2a53a4c3238c 640 return NULL;
lorcansmith 0:2a53a4c3238c 641 }
lorcansmith 0:2a53a4c3238c 642
lorcansmith 0:2a53a4c3238c 643 /**
lorcansmith 0:2a53a4c3238c 644 * Test table for presence of at least one table entry.
lorcansmith 0:2a53a4c3238c 645 */
lorcansmith 0:2a53a4c3238c 646 static u8_t
lorcansmith 0:2a53a4c3238c 647 empty_table(struct mib_node *node)
lorcansmith 0:2a53a4c3238c 648 {
lorcansmith 0:2a53a4c3238c 649 u8_t node_type;
lorcansmith 0:2a53a4c3238c 650 u8_t empty = 0;
lorcansmith 0:2a53a4c3238c 651
lorcansmith 0:2a53a4c3238c 652 if (node != NULL)
lorcansmith 0:2a53a4c3238c 653 {
lorcansmith 0:2a53a4c3238c 654 node_type = node->node_type;
lorcansmith 0:2a53a4c3238c 655 if (node_type == MIB_NODE_LR)
lorcansmith 0:2a53a4c3238c 656 {
lorcansmith 0:2a53a4c3238c 657 struct mib_list_rootnode *lrn;
lorcansmith 0:2a53a4c3238c 658 lrn = (struct mib_list_rootnode *)node;
lorcansmith 0:2a53a4c3238c 659 if ((lrn->count == 0) || (lrn->head == NULL))
lorcansmith 0:2a53a4c3238c 660 {
lorcansmith 0:2a53a4c3238c 661 empty = 1;
lorcansmith 0:2a53a4c3238c 662 }
lorcansmith 0:2a53a4c3238c 663 }
lorcansmith 0:2a53a4c3238c 664 else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
lorcansmith 0:2a53a4c3238c 665 {
lorcansmith 0:2a53a4c3238c 666 struct mib_array_node *an;
lorcansmith 0:2a53a4c3238c 667 an = (struct mib_array_node *)node;
lorcansmith 0:2a53a4c3238c 668 if ((an->maxlength == 0) || (an->nptr == NULL))
lorcansmith 0:2a53a4c3238c 669 {
lorcansmith 0:2a53a4c3238c 670 empty = 1;
lorcansmith 0:2a53a4c3238c 671 }
lorcansmith 0:2a53a4c3238c 672 }
lorcansmith 0:2a53a4c3238c 673 else if (node_type == MIB_NODE_EX)
lorcansmith 0:2a53a4c3238c 674 {
lorcansmith 0:2a53a4c3238c 675 struct mib_external_node *en;
lorcansmith 0:2a53a4c3238c 676 en = (struct mib_external_node *)node;
lorcansmith 0:2a53a4c3238c 677 if (en->tree_levels == 0)
lorcansmith 0:2a53a4c3238c 678 {
lorcansmith 0:2a53a4c3238c 679 empty = 1;
lorcansmith 0:2a53a4c3238c 680 }
lorcansmith 0:2a53a4c3238c 681 }
lorcansmith 0:2a53a4c3238c 682 }
lorcansmith 0:2a53a4c3238c 683 return empty;
lorcansmith 0:2a53a4c3238c 684 }
lorcansmith 0:2a53a4c3238c 685
lorcansmith 0:2a53a4c3238c 686 /**
lorcansmith 0:2a53a4c3238c 687 * Tree expansion.
lorcansmith 0:2a53a4c3238c 688 */
lorcansmith 0:2a53a4c3238c 689 struct mib_node *
lorcansmith 0:2a53a4c3238c 690 snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret)
lorcansmith 0:2a53a4c3238c 691 {
lorcansmith 0:2a53a4c3238c 692 u8_t node_type, ext_level, climb_tree;
lorcansmith 0:2a53a4c3238c 693
lorcansmith 0:2a53a4c3238c 694 ext_level = 0;
lorcansmith 0:2a53a4c3238c 695 /* reset node stack */
lorcansmith 0:2a53a4c3238c 696 node_stack_cnt = 0;
lorcansmith 0:2a53a4c3238c 697 while (node != NULL)
lorcansmith 0:2a53a4c3238c 698 {
lorcansmith 0:2a53a4c3238c 699 climb_tree = 0;
lorcansmith 0:2a53a4c3238c 700 node_type = node->node_type;
lorcansmith 0:2a53a4c3238c 701 if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
lorcansmith 0:2a53a4c3238c 702 {
lorcansmith 0:2a53a4c3238c 703 struct mib_array_node *an;
lorcansmith 0:2a53a4c3238c 704 u16_t i;
lorcansmith 0:2a53a4c3238c 705
lorcansmith 0:2a53a4c3238c 706 /* array node (internal ROM or RAM, fixed length) */
lorcansmith 0:2a53a4c3238c 707 an = (struct mib_array_node *)node;
lorcansmith 0:2a53a4c3238c 708 if (ident_len > 0)
lorcansmith 0:2a53a4c3238c 709 {
lorcansmith 0:2a53a4c3238c 710 i = 0;
lorcansmith 0:2a53a4c3238c 711 while ((i < an->maxlength) && (an->objid[i] < *ident))
lorcansmith 0:2a53a4c3238c 712 {
lorcansmith 0:2a53a4c3238c 713 i++;
lorcansmith 0:2a53a4c3238c 714 }
lorcansmith 0:2a53a4c3238c 715 printf("snmp_expand_tree: i %d, objid[i] %d\r\n", i, an->objid[i] );
lorcansmith 0:2a53a4c3238c 716 if (i < an->maxlength)
lorcansmith 0:2a53a4c3238c 717 {
lorcansmith 0:2a53a4c3238c 718 LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident));
lorcansmith 0:2a53a4c3238c 719 /* add identifier to oidret */
lorcansmith 0:2a53a4c3238c 720 oidret->id[oidret->len] = an->objid[i];
lorcansmith 0:2a53a4c3238c 721 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 722
lorcansmith 0:2a53a4c3238c 723 if (an->nptr[i] == NULL)
lorcansmith 0:2a53a4c3238c 724 {
lorcansmith 0:2a53a4c3238c 725 LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n"));
lorcansmith 0:2a53a4c3238c 726 /* leaf node (e.g. in a fixed size table) */
lorcansmith 0:2a53a4c3238c 727 if (an->objid[i] > *ident)
lorcansmith 0:2a53a4c3238c 728 {
lorcansmith 0:2a53a4c3238c 729 return (struct mib_node*)an;
lorcansmith 0:2a53a4c3238c 730 }
lorcansmith 0:2a53a4c3238c 731 else if ((i + 1) < an->maxlength)
lorcansmith 0:2a53a4c3238c 732 {
lorcansmith 0:2a53a4c3238c 733 /* an->objid[i] == *ident */
lorcansmith 0:2a53a4c3238c 734 (oidret->len)--;
lorcansmith 0:2a53a4c3238c 735 oidret->id[oidret->len] = an->objid[i + 1];
lorcansmith 0:2a53a4c3238c 736 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 737 return (struct mib_node*)an;
lorcansmith 0:2a53a4c3238c 738 }
lorcansmith 0:2a53a4c3238c 739 else
lorcansmith 0:2a53a4c3238c 740 {
lorcansmith 0:2a53a4c3238c 741 /* (i + 1) == an->maxlength */
lorcansmith 0:2a53a4c3238c 742 (oidret->len)--;
lorcansmith 0:2a53a4c3238c 743 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 744 }
lorcansmith 0:2a53a4c3238c 745 }
lorcansmith 0:2a53a4c3238c 746 else
lorcansmith 0:2a53a4c3238c 747 {
lorcansmith 0:2a53a4c3238c 748 u8_t j;
lorcansmith 0:2a53a4c3238c 749 struct nse cur_node;
lorcansmith 0:2a53a4c3238c 750
lorcansmith 0:2a53a4c3238c 751 LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
lorcansmith 0:2a53a4c3238c 752 /* non-leaf, store right child ptr and id */
lorcansmith 0:2a53a4c3238c 753 LWIP_ASSERT("i < 0xff", i < 0xff);
lorcansmith 0:2a53a4c3238c 754 j = (u8_t)i + 1;
lorcansmith 0:2a53a4c3238c 755 while ((j < an->maxlength) && (empty_table(an->nptr[j])))
lorcansmith 0:2a53a4c3238c 756 {
lorcansmith 0:2a53a4c3238c 757 j++;
lorcansmith 0:2a53a4c3238c 758 }
lorcansmith 0:2a53a4c3238c 759 if (j < an->maxlength)
lorcansmith 0:2a53a4c3238c 760 {
lorcansmith 0:2a53a4c3238c 761 cur_node.r_ptr = an->nptr[j];
lorcansmith 0:2a53a4c3238c 762 cur_node.r_id = an->objid[j];
lorcansmith 0:2a53a4c3238c 763 cur_node.r_nl = 0;
lorcansmith 0:2a53a4c3238c 764 }
lorcansmith 0:2a53a4c3238c 765 else
lorcansmith 0:2a53a4c3238c 766 {
lorcansmith 0:2a53a4c3238c 767 cur_node.r_ptr = NULL;
lorcansmith 0:2a53a4c3238c 768 }
lorcansmith 0:2a53a4c3238c 769 push_node(&cur_node);
lorcansmith 0:2a53a4c3238c 770 if (an->objid[i] == *ident)
lorcansmith 0:2a53a4c3238c 771 {
lorcansmith 0:2a53a4c3238c 772 ident_len--;
lorcansmith 0:2a53a4c3238c 773 ident++;
lorcansmith 0:2a53a4c3238c 774 }
lorcansmith 0:2a53a4c3238c 775 else
lorcansmith 0:2a53a4c3238c 776 {
lorcansmith 0:2a53a4c3238c 777 /* an->objid[i] < *ident */
lorcansmith 0:2a53a4c3238c 778 ident_len = 0;
lorcansmith 0:2a53a4c3238c 779 }
lorcansmith 0:2a53a4c3238c 780 /* follow next child pointer */
lorcansmith 0:2a53a4c3238c 781 node = an->nptr[i];
lorcansmith 0:2a53a4c3238c 782 }
lorcansmith 0:2a53a4c3238c 783 }
lorcansmith 0:2a53a4c3238c 784 else
lorcansmith 0:2a53a4c3238c 785 {
lorcansmith 0:2a53a4c3238c 786 /* i == an->maxlength */
lorcansmith 0:2a53a4c3238c 787 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 788 }
lorcansmith 0:2a53a4c3238c 789 }
lorcansmith 0:2a53a4c3238c 790 else
lorcansmith 0:2a53a4c3238c 791 {
lorcansmith 0:2a53a4c3238c 792 u8_t j;
lorcansmith 0:2a53a4c3238c 793 /* ident_len == 0, complete with leftmost '.thing' */
lorcansmith 0:2a53a4c3238c 794 j = 0;
lorcansmith 0:2a53a4c3238c 795 while ((j < an->maxlength) && empty_table(an->nptr[j]))
lorcansmith 0:2a53a4c3238c 796 {
lorcansmith 0:2a53a4c3238c 797 j++;
lorcansmith 0:2a53a4c3238c 798 }
lorcansmith 0:2a53a4c3238c 799 if (j < an->maxlength)
lorcansmith 0:2a53a4c3238c 800 {
lorcansmith 0:2a53a4c3238c 801 LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j]));
lorcansmith 0:2a53a4c3238c 802 oidret->id[oidret->len] = an->objid[j];
lorcansmith 0:2a53a4c3238c 803 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 804 if (an->nptr[j] == NULL)
lorcansmith 0:2a53a4c3238c 805 {
lorcansmith 0:2a53a4c3238c 806 /* leaf node */
lorcansmith 0:2a53a4c3238c 807 return (struct mib_node*)an;
lorcansmith 0:2a53a4c3238c 808 }
lorcansmith 0:2a53a4c3238c 809 else
lorcansmith 0:2a53a4c3238c 810 {
lorcansmith 0:2a53a4c3238c 811 /* no leaf, continue */
lorcansmith 0:2a53a4c3238c 812 node = an->nptr[j];
lorcansmith 0:2a53a4c3238c 813 }
lorcansmith 0:2a53a4c3238c 814 }
lorcansmith 0:2a53a4c3238c 815 else
lorcansmith 0:2a53a4c3238c 816 {
lorcansmith 0:2a53a4c3238c 817 /* j == an->maxlength */
lorcansmith 0:2a53a4c3238c 818 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 819 }
lorcansmith 0:2a53a4c3238c 820 }
lorcansmith 0:2a53a4c3238c 821 }
lorcansmith 0:2a53a4c3238c 822 else if(node_type == MIB_NODE_LR)
lorcansmith 0:2a53a4c3238c 823 {
lorcansmith 0:2a53a4c3238c 824 struct mib_list_rootnode *lrn;
lorcansmith 0:2a53a4c3238c 825 struct mib_list_node *ln;
lorcansmith 0:2a53a4c3238c 826
lorcansmith 0:2a53a4c3238c 827 /* list root node (internal 'RAM', variable length) */
lorcansmith 0:2a53a4c3238c 828 lrn = (struct mib_list_rootnode *)node;
lorcansmith 0:2a53a4c3238c 829 if (ident_len > 0)
lorcansmith 0:2a53a4c3238c 830 {
lorcansmith 0:2a53a4c3238c 831 ln = lrn->head;
lorcansmith 0:2a53a4c3238c 832 /* iterate over list, head to tail */
lorcansmith 0:2a53a4c3238c 833 while ((ln != NULL) && (ln->objid < *ident))
lorcansmith 0:2a53a4c3238c 834 {
lorcansmith 0:2a53a4c3238c 835 ln = ln->next;
lorcansmith 0:2a53a4c3238c 836 }
lorcansmith 0:2a53a4c3238c 837 if (ln != NULL)
lorcansmith 0:2a53a4c3238c 838 {
lorcansmith 0:2a53a4c3238c 839 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident));
lorcansmith 0:2a53a4c3238c 840 oidret->id[oidret->len] = ln->objid;
lorcansmith 0:2a53a4c3238c 841 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 842 if (ln->nptr == NULL)
lorcansmith 0:2a53a4c3238c 843 {
lorcansmith 0:2a53a4c3238c 844 /* leaf node */
lorcansmith 0:2a53a4c3238c 845 if (ln->objid > *ident)
lorcansmith 0:2a53a4c3238c 846 {
lorcansmith 0:2a53a4c3238c 847 return (struct mib_node*)lrn;
lorcansmith 0:2a53a4c3238c 848 }
lorcansmith 0:2a53a4c3238c 849 else if (ln->next != NULL)
lorcansmith 0:2a53a4c3238c 850 {
lorcansmith 0:2a53a4c3238c 851 /* ln->objid == *ident */
lorcansmith 0:2a53a4c3238c 852 (oidret->len)--;
lorcansmith 0:2a53a4c3238c 853 oidret->id[oidret->len] = ln->next->objid;
lorcansmith 0:2a53a4c3238c 854 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 855 return (struct mib_node*)lrn;
lorcansmith 0:2a53a4c3238c 856 }
lorcansmith 0:2a53a4c3238c 857 else
lorcansmith 0:2a53a4c3238c 858 {
lorcansmith 0:2a53a4c3238c 859 /* ln->next == NULL */
lorcansmith 0:2a53a4c3238c 860 (oidret->len)--;
lorcansmith 0:2a53a4c3238c 861 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 862 }
lorcansmith 0:2a53a4c3238c 863 }
lorcansmith 0:2a53a4c3238c 864 else
lorcansmith 0:2a53a4c3238c 865 {
lorcansmith 0:2a53a4c3238c 866 struct mib_list_node *jn;
lorcansmith 0:2a53a4c3238c 867 struct nse cur_node;
lorcansmith 0:2a53a4c3238c 868
lorcansmith 0:2a53a4c3238c 869 /* non-leaf, store right child ptr and id */
lorcansmith 0:2a53a4c3238c 870 jn = ln->next;
lorcansmith 0:2a53a4c3238c 871 while ((jn != NULL) && empty_table(jn->nptr))
lorcansmith 0:2a53a4c3238c 872 {
lorcansmith 0:2a53a4c3238c 873 jn = jn->next;
lorcansmith 0:2a53a4c3238c 874 }
lorcansmith 0:2a53a4c3238c 875 if (jn != NULL)
lorcansmith 0:2a53a4c3238c 876 {
lorcansmith 0:2a53a4c3238c 877 cur_node.r_ptr = jn->nptr;
lorcansmith 0:2a53a4c3238c 878 cur_node.r_id = jn->objid;
lorcansmith 0:2a53a4c3238c 879 cur_node.r_nl = 0;
lorcansmith 0:2a53a4c3238c 880 }
lorcansmith 0:2a53a4c3238c 881 else
lorcansmith 0:2a53a4c3238c 882 {
lorcansmith 0:2a53a4c3238c 883 cur_node.r_ptr = NULL;
lorcansmith 0:2a53a4c3238c 884 }
lorcansmith 0:2a53a4c3238c 885 push_node(&cur_node);
lorcansmith 0:2a53a4c3238c 886 if (ln->objid == *ident)
lorcansmith 0:2a53a4c3238c 887 {
lorcansmith 0:2a53a4c3238c 888 ident_len--;
lorcansmith 0:2a53a4c3238c 889 ident++;
lorcansmith 0:2a53a4c3238c 890 }
lorcansmith 0:2a53a4c3238c 891 else
lorcansmith 0:2a53a4c3238c 892 {
lorcansmith 0:2a53a4c3238c 893 /* ln->objid < *ident */
lorcansmith 0:2a53a4c3238c 894 ident_len = 0;
lorcansmith 0:2a53a4c3238c 895 }
lorcansmith 0:2a53a4c3238c 896 /* follow next child pointer */
lorcansmith 0:2a53a4c3238c 897 node = ln->nptr;
lorcansmith 0:2a53a4c3238c 898 }
lorcansmith 0:2a53a4c3238c 899
lorcansmith 0:2a53a4c3238c 900 }
lorcansmith 0:2a53a4c3238c 901 else
lorcansmith 0:2a53a4c3238c 902 {
lorcansmith 0:2a53a4c3238c 903 /* ln == NULL */
lorcansmith 0:2a53a4c3238c 904 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 905 }
lorcansmith 0:2a53a4c3238c 906 }
lorcansmith 0:2a53a4c3238c 907 else
lorcansmith 0:2a53a4c3238c 908 {
lorcansmith 0:2a53a4c3238c 909 struct mib_list_node *jn;
lorcansmith 0:2a53a4c3238c 910 /* ident_len == 0, complete with leftmost '.thing' */
lorcansmith 0:2a53a4c3238c 911 jn = lrn->head;
lorcansmith 0:2a53a4c3238c 912 while ((jn != NULL) && empty_table(jn->nptr))
lorcansmith 0:2a53a4c3238c 913 {
lorcansmith 0:2a53a4c3238c 914 jn = jn->next;
lorcansmith 0:2a53a4c3238c 915 }
lorcansmith 0:2a53a4c3238c 916 if (jn != NULL)
lorcansmith 0:2a53a4c3238c 917 {
lorcansmith 0:2a53a4c3238c 918 LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid));
lorcansmith 0:2a53a4c3238c 919 oidret->id[oidret->len] = jn->objid;
lorcansmith 0:2a53a4c3238c 920 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 921 if (jn->nptr == NULL)
lorcansmith 0:2a53a4c3238c 922 {
lorcansmith 0:2a53a4c3238c 923 /* leaf node */
lorcansmith 0:2a53a4c3238c 924 LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n"));
lorcansmith 0:2a53a4c3238c 925 return (struct mib_node*)lrn;
lorcansmith 0:2a53a4c3238c 926 }
lorcansmith 0:2a53a4c3238c 927 else
lorcansmith 0:2a53a4c3238c 928 {
lorcansmith 0:2a53a4c3238c 929 /* no leaf, continue */
lorcansmith 0:2a53a4c3238c 930 node = jn->nptr;
lorcansmith 0:2a53a4c3238c 931 }
lorcansmith 0:2a53a4c3238c 932 }
lorcansmith 0:2a53a4c3238c 933 else
lorcansmith 0:2a53a4c3238c 934 {
lorcansmith 0:2a53a4c3238c 935 /* jn == NULL */
lorcansmith 0:2a53a4c3238c 936 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 937 }
lorcansmith 0:2a53a4c3238c 938 }
lorcansmith 0:2a53a4c3238c 939 }
lorcansmith 0:2a53a4c3238c 940 else if(node_type == MIB_NODE_EX)
lorcansmith 0:2a53a4c3238c 941 {
lorcansmith 0:2a53a4c3238c 942 struct mib_external_node *en;
lorcansmith 0:2a53a4c3238c 943 s32_t ex_id;
lorcansmith 0:2a53a4c3238c 944
lorcansmith 0:2a53a4c3238c 945 /* external node (addressing and access via functions) */
lorcansmith 0:2a53a4c3238c 946 en = (struct mib_external_node *)node;
lorcansmith 0:2a53a4c3238c 947 if (ident_len > 0)
lorcansmith 0:2a53a4c3238c 948 {
lorcansmith 0:2a53a4c3238c 949 u16_t i, len;
lorcansmith 0:2a53a4c3238c 950
lorcansmith 0:2a53a4c3238c 951 i = 0;
lorcansmith 0:2a53a4c3238c 952 len = en->level_length(en->addr_inf,ext_level);
lorcansmith 0:2a53a4c3238c 953 while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0))
lorcansmith 0:2a53a4c3238c 954 {
lorcansmith 0:2a53a4c3238c 955 i++;
lorcansmith 0:2a53a4c3238c 956 }
lorcansmith 0:2a53a4c3238c 957 if (i < len)
lorcansmith 0:2a53a4c3238c 958 {
lorcansmith 0:2a53a4c3238c 959 /* add identifier to oidret */
lorcansmith 0:2a53a4c3238c 960 en->get_objid(en->addr_inf,ext_level,i,&ex_id);
lorcansmith 0:2a53a4c3238c 961 LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident));
lorcansmith 0:2a53a4c3238c 962 oidret->id[oidret->len] = ex_id;
lorcansmith 0:2a53a4c3238c 963 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 964
lorcansmith 0:2a53a4c3238c 965 if ((ext_level + 1) == en->tree_levels)
lorcansmith 0:2a53a4c3238c 966 {
lorcansmith 0:2a53a4c3238c 967 LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n"));
lorcansmith 0:2a53a4c3238c 968 /* leaf node */
lorcansmith 0:2a53a4c3238c 969 if (ex_id > *ident)
lorcansmith 0:2a53a4c3238c 970 {
lorcansmith 0:2a53a4c3238c 971 return (struct mib_node*)en;
lorcansmith 0:2a53a4c3238c 972 }
lorcansmith 0:2a53a4c3238c 973 else if ((i + 1) < len)
lorcansmith 0:2a53a4c3238c 974 {
lorcansmith 0:2a53a4c3238c 975 /* ex_id == *ident */
lorcansmith 0:2a53a4c3238c 976 en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id);
lorcansmith 0:2a53a4c3238c 977 (oidret->len)--;
lorcansmith 0:2a53a4c3238c 978 oidret->id[oidret->len] = ex_id;
lorcansmith 0:2a53a4c3238c 979 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 980 return (struct mib_node*)en;
lorcansmith 0:2a53a4c3238c 981 }
lorcansmith 0:2a53a4c3238c 982 else
lorcansmith 0:2a53a4c3238c 983 {
lorcansmith 0:2a53a4c3238c 984 /* (i + 1) == len */
lorcansmith 0:2a53a4c3238c 985 (oidret->len)--;
lorcansmith 0:2a53a4c3238c 986 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 987 }
lorcansmith 0:2a53a4c3238c 988 }
lorcansmith 0:2a53a4c3238c 989 else
lorcansmith 0:2a53a4c3238c 990 {
lorcansmith 0:2a53a4c3238c 991 u8_t j;
lorcansmith 0:2a53a4c3238c 992 struct nse cur_node;
lorcansmith 0:2a53a4c3238c 993
lorcansmith 0:2a53a4c3238c 994 LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
lorcansmith 0:2a53a4c3238c 995 /* non-leaf, store right child ptr and id */
lorcansmith 0:2a53a4c3238c 996 LWIP_ASSERT("i < 0xff", i < 0xff);
lorcansmith 0:2a53a4c3238c 997 j = (u8_t)i + 1;
lorcansmith 0:2a53a4c3238c 998 if (j < len)
lorcansmith 0:2a53a4c3238c 999 {
lorcansmith 0:2a53a4c3238c 1000 /* right node is the current external node */
lorcansmith 0:2a53a4c3238c 1001 cur_node.r_ptr = node;
lorcansmith 0:2a53a4c3238c 1002 en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id);
lorcansmith 0:2a53a4c3238c 1003 cur_node.r_nl = ext_level + 1;
lorcansmith 0:2a53a4c3238c 1004 }
lorcansmith 0:2a53a4c3238c 1005 else
lorcansmith 0:2a53a4c3238c 1006 {
lorcansmith 0:2a53a4c3238c 1007 cur_node.r_ptr = NULL;
lorcansmith 0:2a53a4c3238c 1008 }
lorcansmith 0:2a53a4c3238c 1009 push_node(&cur_node);
lorcansmith 0:2a53a4c3238c 1010 if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0)
lorcansmith 0:2a53a4c3238c 1011 {
lorcansmith 0:2a53a4c3238c 1012 ident_len--;
lorcansmith 0:2a53a4c3238c 1013 ident++;
lorcansmith 0:2a53a4c3238c 1014 }
lorcansmith 0:2a53a4c3238c 1015 else
lorcansmith 0:2a53a4c3238c 1016 {
lorcansmith 0:2a53a4c3238c 1017 /* external id < *ident */
lorcansmith 0:2a53a4c3238c 1018 ident_len = 0;
lorcansmith 0:2a53a4c3238c 1019 }
lorcansmith 0:2a53a4c3238c 1020 /* proceed to child */
lorcansmith 0:2a53a4c3238c 1021 ext_level++;
lorcansmith 0:2a53a4c3238c 1022 }
lorcansmith 0:2a53a4c3238c 1023 }
lorcansmith 0:2a53a4c3238c 1024 else
lorcansmith 0:2a53a4c3238c 1025 {
lorcansmith 0:2a53a4c3238c 1026 /* i == len (en->level_len()) */
lorcansmith 0:2a53a4c3238c 1027 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 1028 }
lorcansmith 0:2a53a4c3238c 1029 }
lorcansmith 0:2a53a4c3238c 1030 else
lorcansmith 0:2a53a4c3238c 1031 {
lorcansmith 0:2a53a4c3238c 1032 /* ident_len == 0, complete with leftmost '.thing' */
lorcansmith 0:2a53a4c3238c 1033 en->get_objid(en->addr_inf,ext_level,0,&ex_id);
lorcansmith 0:2a53a4c3238c 1034 LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id));
lorcansmith 0:2a53a4c3238c 1035 oidret->id[oidret->len] = ex_id;
lorcansmith 0:2a53a4c3238c 1036 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 1037 if ((ext_level + 1) == en->tree_levels)
lorcansmith 0:2a53a4c3238c 1038 {
lorcansmith 0:2a53a4c3238c 1039 /* leaf node */
lorcansmith 0:2a53a4c3238c 1040 LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n"));
lorcansmith 0:2a53a4c3238c 1041 return (struct mib_node*)en;
lorcansmith 0:2a53a4c3238c 1042 }
lorcansmith 0:2a53a4c3238c 1043 else
lorcansmith 0:2a53a4c3238c 1044 {
lorcansmith 0:2a53a4c3238c 1045 /* no leaf, proceed to child */
lorcansmith 0:2a53a4c3238c 1046 ext_level++;
lorcansmith 0:2a53a4c3238c 1047 }
lorcansmith 0:2a53a4c3238c 1048 }
lorcansmith 0:2a53a4c3238c 1049 }
lorcansmith 0:2a53a4c3238c 1050 else if(node_type == MIB_NODE_SC)
lorcansmith 0:2a53a4c3238c 1051 {
lorcansmith 0:2a53a4c3238c 1052 mib_scalar_node *sn;
lorcansmith 0:2a53a4c3238c 1053
lorcansmith 0:2a53a4c3238c 1054 /* scalar node */
lorcansmith 0:2a53a4c3238c 1055 sn = (mib_scalar_node *)node;
lorcansmith 0:2a53a4c3238c 1056 if (ident_len > 0)
lorcansmith 0:2a53a4c3238c 1057 {
lorcansmith 0:2a53a4c3238c 1058 /* at .0 */
lorcansmith 0:2a53a4c3238c 1059 climb_tree = 1;
lorcansmith 0:2a53a4c3238c 1060 }
lorcansmith 0:2a53a4c3238c 1061 else
lorcansmith 0:2a53a4c3238c 1062 {
lorcansmith 0:2a53a4c3238c 1063 /* ident_len == 0, complete object identifier */
lorcansmith 0:2a53a4c3238c 1064 oidret->id[oidret->len] = 0;
lorcansmith 0:2a53a4c3238c 1065 (oidret->len)++;
lorcansmith 0:2a53a4c3238c 1066 /* leaf node */
lorcansmith 0:2a53a4c3238c 1067 LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n"));
lorcansmith 0:2a53a4c3238c 1068 return (struct mib_node*)sn;
lorcansmith 0:2a53a4c3238c 1069 }
lorcansmith 0:2a53a4c3238c 1070 }
lorcansmith 0:2a53a4c3238c 1071 else
lorcansmith 0:2a53a4c3238c 1072 {
lorcansmith 0:2a53a4c3238c 1073 /* unknown/unhandled node_type */
lorcansmith 0:2a53a4c3238c 1074 LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type));
lorcansmith 0:2a53a4c3238c 1075 return NULL;
lorcansmith 0:2a53a4c3238c 1076 }
lorcansmith 0:2a53a4c3238c 1077
lorcansmith 0:2a53a4c3238c 1078 if (climb_tree)
lorcansmith 0:2a53a4c3238c 1079 {
lorcansmith 0:2a53a4c3238c 1080 struct nse child;
lorcansmith 0:2a53a4c3238c 1081
lorcansmith 0:2a53a4c3238c 1082 /* find right child ptr */
lorcansmith 0:2a53a4c3238c 1083 child.r_ptr = NULL;
lorcansmith 0:2a53a4c3238c 1084 child.r_id = 0;
lorcansmith 0:2a53a4c3238c 1085 child.r_nl = 0;
lorcansmith 0:2a53a4c3238c 1086 while ((node_stack_cnt > 0) && (child.r_ptr == NULL))
lorcansmith 0:2a53a4c3238c 1087 {
lorcansmith 0:2a53a4c3238c 1088 pop_node(&child);
lorcansmith 0:2a53a4c3238c 1089 /* trim returned oid */
lorcansmith 0:2a53a4c3238c 1090 (oidret->len)--;
lorcansmith 0:2a53a4c3238c 1091 }
lorcansmith 0:2a53a4c3238c 1092 if (child.r_ptr != NULL)
lorcansmith 0:2a53a4c3238c 1093 {
lorcansmith 0:2a53a4c3238c 1094 /* incoming ident is useless beyond this point */
lorcansmith 0:2a53a4c3238c 1095 ident_len = 0;
lorcansmith 0:2a53a4c3238c 1096 oidret->id[oidret->len] = child.r_id;
lorcansmith 0:2a53a4c3238c 1097 oidret->len++;
lorcansmith 0:2a53a4c3238c 1098 node = child.r_ptr;
lorcansmith 0:2a53a4c3238c 1099 ext_level = child.r_nl;
lorcansmith 0:2a53a4c3238c 1100 }
lorcansmith 0:2a53a4c3238c 1101 else
lorcansmith 0:2a53a4c3238c 1102 {
lorcansmith 0:2a53a4c3238c 1103 /* tree ends here ... */
lorcansmith 0:2a53a4c3238c 1104 LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n"));
lorcansmith 0:2a53a4c3238c 1105 return NULL;
lorcansmith 0:2a53a4c3238c 1106 }
lorcansmith 0:2a53a4c3238c 1107 }
lorcansmith 0:2a53a4c3238c 1108 }
lorcansmith 0:2a53a4c3238c 1109 /* done, found nothing */
lorcansmith 0:2a53a4c3238c 1110 LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node));
lorcansmith 0:2a53a4c3238c 1111 return NULL;
lorcansmith 0:2a53a4c3238c 1112 }
lorcansmith 0:2a53a4c3238c 1113
lorcansmith 0:2a53a4c3238c 1114 /**
lorcansmith 0:2a53a4c3238c 1115 * Test object identifier for the iso.org.dod.internet prefix.
lorcansmith 0:2a53a4c3238c 1116 *
lorcansmith 0:2a53a4c3238c 1117 * @param ident_len the length of the supplied object identifier
lorcansmith 0:2a53a4c3238c 1118 * @param ident points to the array of sub identifiers
lorcansmith 0:2a53a4c3238c 1119 * @return 1 if it matches, 0 otherwise
lorcansmith 0:2a53a4c3238c 1120 */
lorcansmith 0:2a53a4c3238c 1121 u8_t
lorcansmith 0:2a53a4c3238c 1122 snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident)
lorcansmith 0:2a53a4c3238c 1123 {
lorcansmith 0:2a53a4c3238c 1124 if ((ident_len > 3) &&
lorcansmith 0:2a53a4c3238c 1125 (ident[0] == 1) && (ident[1] == 3) &&
lorcansmith 0:2a53a4c3238c 1126 (ident[2] == 6) && (ident[3] == 1))
lorcansmith 0:2a53a4c3238c 1127 {
lorcansmith 0:2a53a4c3238c 1128 return 1;
lorcansmith 0:2a53a4c3238c 1129 }
lorcansmith 0:2a53a4c3238c 1130 else
lorcansmith 0:2a53a4c3238c 1131 {
lorcansmith 0:2a53a4c3238c 1132 return 0;
lorcansmith 0:2a53a4c3238c 1133 }
lorcansmith 0:2a53a4c3238c 1134 }
lorcansmith 0:2a53a4c3238c 1135
lorcansmith 0:2a53a4c3238c 1136 /**
lorcansmith 0:2a53a4c3238c 1137 * Expands object identifier to the iso.org.dod.internet
lorcansmith 0:2a53a4c3238c 1138 * prefix for use in getnext operation.
lorcansmith 0:2a53a4c3238c 1139 *
lorcansmith 0:2a53a4c3238c 1140 * @param ident_len the length of the supplied object identifier
lorcansmith 0:2a53a4c3238c 1141 * @param ident points to the array of sub identifiers
lorcansmith 0:2a53a4c3238c 1142 * @param oidret points to returned expanded object identifier
lorcansmith 0:2a53a4c3238c 1143 * @return 1 if it matches, 0 otherwise
lorcansmith 0:2a53a4c3238c 1144 *
lorcansmith 0:2a53a4c3238c 1145 * @note ident_len 0 is allowed, expanding to the first known object id!!
lorcansmith 0:2a53a4c3238c 1146 */
lorcansmith 0:2a53a4c3238c 1147 u8_t
lorcansmith 0:2a53a4c3238c 1148 snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret)
lorcansmith 0:2a53a4c3238c 1149 {
lorcansmith 0:2a53a4c3238c 1150 const s32_t *prefix_ptr;
lorcansmith 0:2a53a4c3238c 1151 s32_t *ret_ptr;
lorcansmith 0:2a53a4c3238c 1152 u8_t i;
lorcansmith 0:2a53a4c3238c 1153
lorcansmith 0:2a53a4c3238c 1154 i = 0;
lorcansmith 0:2a53a4c3238c 1155 prefix_ptr = &prefix[0];
lorcansmith 0:2a53a4c3238c 1156 ret_ptr = &oidret->id[0];
lorcansmith 0:2a53a4c3238c 1157 ident_len = ((ident_len < 4)?ident_len:4);
lorcansmith 0:2a53a4c3238c 1158 while ((i < ident_len) && ((*ident) <= (*prefix_ptr)))
lorcansmith 0:2a53a4c3238c 1159 {
lorcansmith 0:2a53a4c3238c 1160 *ret_ptr++ = *prefix_ptr++;
lorcansmith 0:2a53a4c3238c 1161 ident++;
lorcansmith 0:2a53a4c3238c 1162 i++;
lorcansmith 0:2a53a4c3238c 1163 }
lorcansmith 0:2a53a4c3238c 1164 if (i == ident_len)
lorcansmith 0:2a53a4c3238c 1165 {
lorcansmith 0:2a53a4c3238c 1166 /* match, complete missing bits */
lorcansmith 0:2a53a4c3238c 1167 while (i < 4)
lorcansmith 0:2a53a4c3238c 1168 {
lorcansmith 0:2a53a4c3238c 1169 *ret_ptr++ = *prefix_ptr++;
lorcansmith 0:2a53a4c3238c 1170 i++;
lorcansmith 0:2a53a4c3238c 1171 }
lorcansmith 0:2a53a4c3238c 1172 oidret->len = i;
lorcansmith 0:2a53a4c3238c 1173 printf("\r\nsnmp_iso_prefix_expand ok\r\n");
lorcansmith 0:2a53a4c3238c 1174 return 1;
lorcansmith 0:2a53a4c3238c 1175 }
lorcansmith 0:2a53a4c3238c 1176 else
lorcansmith 0:2a53a4c3238c 1177 {
lorcansmith 0:2a53a4c3238c 1178 /* i != ident_len */
lorcansmith 0:2a53a4c3238c 1179 return 0;
lorcansmith 0:2a53a4c3238c 1180 }
lorcansmith 0:2a53a4c3238c 1181 }
lorcansmith 0:2a53a4c3238c 1182
lorcansmith 0:2a53a4c3238c 1183 #endif /* LWIP_SNMP */