Embedded WebSockets Experiment

Dependencies:   mbed MD5

Committer:
nandgate
Date:
Tue Jul 26 05:30:53 2011 +0000
Revision:
0:6dee052a3fa4

        

Who changed what in which revision?

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