Some quick code to use UDP-only (no TCP) with mBed. Echos received packets and sends packets when a button is pressed
mib_structs.c
00001 /** 00002 * @file 00003 * MIB tree access/construction functions. 00004 */ 00005 00006 /* 00007 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. 00008 * All rights reserved. 00009 * 00010 * Redistribution and use in source and binary forms, with or without modification, 00011 * are permitted provided that the following conditions are met: 00012 * 00013 * 1. Redistributions of source code must retain the above copyright notice, 00014 * this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright notice, 00016 * this list of conditions and the following disclaimer in the documentation 00017 * and/or other materials provided with the distribution. 00018 * 3. The name of the author may not be used to endorse or promote products 00019 * derived from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00022 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00024 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00026 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00029 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00030 * OF SUCH DAMAGE. 00031 * 00032 * Author: Christiaan Simons <christiaan.simons@axon.tv> 00033 */ 00034 00035 #include "lwip/opt.h" 00036 00037 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ 00038 00039 #include "lwip/snmp_structs.h" 00040 #include "lwip/mem.h" 00041 00042 /** .iso.org.dod.internet address prefix, @see snmp_iso_*() */ 00043 const s32_t prefix[4] = {1, 3, 6, 1}; 00044 00045 #define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN) 00046 /** node stack entry (old news?) */ 00047 struct nse 00048 { 00049 /** right child */ 00050 struct mib_node* r_ptr; 00051 /** right child identifier */ 00052 s32_t r_id; 00053 /** right child next level */ 00054 u8_t r_nl; 00055 }; 00056 static u8_t node_stack_cnt; 00057 static struct nse node_stack[NODE_STACK_SIZE]; 00058 00059 /** 00060 * Pushes nse struct onto stack. 00061 */ 00062 static void 00063 push_node(struct nse* node) 00064 { 00065 LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE); 00066 LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id)); 00067 if (node_stack_cnt < NODE_STACK_SIZE) 00068 { 00069 node_stack[node_stack_cnt] = *node; 00070 node_stack_cnt++; 00071 } 00072 } 00073 00074 /** 00075 * Pops nse struct from stack. 00076 */ 00077 static void 00078 pop_node(struct nse* node) 00079 { 00080 if (node_stack_cnt > 0) 00081 { 00082 node_stack_cnt--; 00083 *node = node_stack[node_stack_cnt]; 00084 } 00085 LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id)); 00086 } 00087 00088 /** 00089 * Conversion from ifIndex to lwIP netif 00090 * @param ifindex is a s32_t object sub-identifier 00091 * @param netif points to returned netif struct pointer 00092 */ 00093 void 00094 snmp_ifindextonetif(s32_t ifindex, struct netif **netif) 00095 { 00096 struct netif *nif = netif_list; 00097 u16_t i, ifidx; 00098 00099 ifidx = ifindex - 1; 00100 i = 0; 00101 while ((nif != NULL) && (i < ifidx)) 00102 { 00103 nif = nif->next; 00104 i++; 00105 } 00106 *netif = nif; 00107 } 00108 00109 /** 00110 * Conversion from lwIP netif to ifIndex 00111 * @param netif points to a netif struct 00112 * @param ifidx points to s32_t object sub-identifier 00113 */ 00114 void 00115 snmp_netiftoifindex(struct netif *netif, s32_t *ifidx) 00116 { 00117 struct netif *nif = netif_list; 00118 u16_t i; 00119 00120 i = 0; 00121 while (nif != netif) 00122 { 00123 nif = nif->next; 00124 i++; 00125 } 00126 *ifidx = i+1; 00127 } 00128 00129 /** 00130 * Conversion from oid to lwIP ip_addr 00131 * @param ident points to s32_t ident[4] input 00132 * @param ip points to output struct 00133 */ 00134 void 00135 snmp_oidtoip(s32_t *ident, struct ip_addr *ip) 00136 { 00137 u32_t ipa; 00138 00139 ipa = ident[0]; 00140 ipa <<= 8; 00141 ipa |= ident[1]; 00142 ipa <<= 8; 00143 ipa |= ident[2]; 00144 ipa <<= 8; 00145 ipa |= ident[3]; 00146 ip->addr = ipa; 00147 } 00148 00149 /** 00150 * Conversion from lwIP ip_addr to oid 00151 * @param ip points to input struct 00152 * @param ident points to s32_t ident[4] output 00153 */ 00154 void 00155 snmp_iptooid(struct ip_addr *ip, s32_t *ident) 00156 { 00157 u32_t ipa; 00158 00159 ipa = ip->addr; 00160 ident[0] = (ipa >> 24) & 0xff; 00161 ident[1] = (ipa >> 16) & 0xff; 00162 ident[2] = (ipa >> 8) & 0xff; 00163 ident[3] = ipa & 0xff; 00164 } 00165 00166 struct mib_list_node * 00167 snmp_mib_ln_alloc(s32_t id) 00168 { 00169 struct mib_list_node *ln; 00170 00171 ln = (struct mib_list_node *)mem_malloc(sizeof(struct mib_list_node)); 00172 if (ln != NULL) 00173 { 00174 ln->prev = NULL; 00175 ln->next = NULL; 00176 ln->objid = id; 00177 ln->nptr = NULL; 00178 } 00179 return ln; 00180 } 00181 00182 void 00183 snmp_mib_ln_free(struct mib_list_node *ln) 00184 { 00185 mem_free(ln); 00186 } 00187 00188 struct mib_list_rootnode * 00189 snmp_mib_lrn_alloc(void) 00190 { 00191 struct mib_list_rootnode *lrn; 00192 00193 lrn = (struct mib_list_rootnode*)mem_malloc(sizeof(struct mib_list_rootnode)); 00194 if (lrn != NULL) 00195 { 00196 lrn->get_object_def = noleafs_get_object_def; 00197 lrn->get_value = noleafs_get_value; 00198 lrn->set_test = noleafs_set_test; 00199 lrn->set_value = noleafs_set_value; 00200 lrn->node_type = MIB_NODE_LR; 00201 lrn->maxlength = 0; 00202 lrn->head = NULL; 00203 lrn->tail = NULL; 00204 lrn->count = 0; 00205 } 00206 return lrn; 00207 } 00208 00209 void 00210 snmp_mib_lrn_free(struct mib_list_rootnode *lrn) 00211 { 00212 mem_free(lrn); 00213 } 00214 00215 /** 00216 * Inserts node in idx list in a sorted 00217 * (ascending order) fashion and 00218 * allocates the node if needed. 00219 * 00220 * @param rn points to the root node 00221 * @param objid is the object sub identifier 00222 * @param insn points to a pointer to the inserted node 00223 * used for constructing the tree. 00224 * @return -1 if failed, 1 if inserted, 2 if present. 00225 */ 00226 s8_t 00227 snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn) 00228 { 00229 struct mib_list_node *nn; 00230 s8_t insert; 00231 00232 LWIP_ASSERT("rn != NULL",rn != NULL); 00233 00234 /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */ 00235 insert = 0; 00236 if (rn->head == NULL) 00237 { 00238 /* empty list, add first node */ 00239 LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid)); 00240 nn = snmp_mib_ln_alloc(objid); 00241 if (nn != NULL) 00242 { 00243 rn->head = nn; 00244 rn->tail = nn; 00245 *insn = nn; 00246 insert = 1; 00247 } 00248 else 00249 { 00250 insert = -1; 00251 } 00252 } 00253 else 00254 { 00255 struct mib_list_node *n; 00256 /* at least one node is present */ 00257 n = rn->head; 00258 while ((n != NULL) && (insert == 0)) 00259 { 00260 if (n->objid == objid) 00261 { 00262 /* node is already there */ 00263 LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid)); 00264 *insn = n; 00265 insert = 2; 00266 } 00267 else if (n->objid < objid) 00268 { 00269 if (n->next == NULL) 00270 { 00271 /* alloc and insert at the tail */ 00272 LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid)); 00273 nn = snmp_mib_ln_alloc(objid); 00274 if (nn != NULL) 00275 { 00276 nn->next = NULL; 00277 nn->prev = n; 00278 n->next = nn; 00279 rn->tail = nn; 00280 *insn = nn; 00281 insert = 1; 00282 } 00283 else 00284 { 00285 /* insertion failure */ 00286 insert = -1; 00287 } 00288 } 00289 else 00290 { 00291 /* there's more to explore: traverse list */ 00292 LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n")); 00293 n = n->next; 00294 } 00295 } 00296 else 00297 { 00298 /* n->objid > objid */ 00299 /* alloc and insert between n->prev and n */ 00300 LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid)); 00301 nn = snmp_mib_ln_alloc(objid); 00302 if (nn != NULL) 00303 { 00304 if (n->prev == NULL) 00305 { 00306 /* insert at the head */ 00307 nn->next = n; 00308 nn->prev = NULL; 00309 rn->head = nn; 00310 n->prev = nn; 00311 } 00312 else 00313 { 00314 /* insert in the middle */ 00315 nn->next = n; 00316 nn->prev = n->prev; 00317 n->prev->next = nn; 00318 n->prev = nn; 00319 } 00320 *insn = nn; 00321 insert = 1; 00322 } 00323 else 00324 { 00325 /* insertion failure */ 00326 insert = -1; 00327 } 00328 } 00329 } 00330 } 00331 if (insert == 1) 00332 { 00333 rn->count += 1; 00334 } 00335 LWIP_ASSERT("insert != 0",insert != 0); 00336 return insert; 00337 } 00338 00339 /** 00340 * Finds node in idx list and returns deletion mark. 00341 * 00342 * @param rn points to the root node 00343 * @param objid is the object sub identifier 00344 * @param fn returns pointer to found node 00345 * @return 0 if not found, 1 if deletable, 00346 * 2 can't delete (2 or more children), 3 not a list_node 00347 */ 00348 s8_t 00349 snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn) 00350 { 00351 s8_t fc; 00352 struct mib_list_node *n; 00353 00354 LWIP_ASSERT("rn != NULL",rn != NULL); 00355 n = rn->head; 00356 while ((n != NULL) && (n->objid != objid)) 00357 { 00358 n = n->next; 00359 } 00360 if (n == NULL) 00361 { 00362 fc = 0; 00363 } 00364 else if (n->nptr == NULL) 00365 { 00366 /* leaf, can delete node */ 00367 fc = 1; 00368 } 00369 else 00370 { 00371 struct mib_list_rootnode *r; 00372 00373 if (n->nptr->node_type == MIB_NODE_LR) 00374 { 00375 r = (struct mib_list_rootnode *)n->nptr; 00376 if (r->count > 1) 00377 { 00378 /* can't delete node */ 00379 fc = 2; 00380 } 00381 else 00382 { 00383 /* count <= 1, can delete node */ 00384 fc = 1; 00385 } 00386 } 00387 else 00388 { 00389 /* other node type */ 00390 fc = 3; 00391 } 00392 } 00393 *fn = n; 00394 return fc; 00395 } 00396 00397 /** 00398 * Removes node from idx list 00399 * if it has a single child left. 00400 * 00401 * @param rn points to the root node 00402 * @param n points to the node to delete 00403 * @return the nptr to be freed by caller 00404 */ 00405 struct mib_list_rootnode * 00406 snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n) 00407 { 00408 struct mib_list_rootnode *next; 00409 00410 LWIP_ASSERT("rn != NULL",rn != NULL); 00411 LWIP_ASSERT("n != NULL",n != NULL); 00412 00413 /* caller must remove this sub-tree */ 00414 next = (struct mib_list_rootnode*)(n->nptr); 00415 rn->count -= 1; 00416 00417 if (n == rn->head) 00418 { 00419 rn->head = n->next; 00420 if (n->next != NULL) 00421 { 00422 /* not last node, new list begin */ 00423 n->next->prev = NULL; 00424 } 00425 } 00426 else if (n == rn->tail) 00427 { 00428 rn->tail = n->prev; 00429 if (n->prev != NULL) 00430 { 00431 /* not last node, new list end */ 00432 n->prev->next = NULL; 00433 } 00434 } 00435 else 00436 { 00437 /* node must be in the middle */ 00438 n->prev->next = n->next; 00439 n->next->prev = n->prev; 00440 } 00441 LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid)); 00442 snmp_mib_ln_free(n); 00443 if (rn->count == 0) 00444 { 00445 rn->head = NULL; 00446 rn->tail = NULL; 00447 } 00448 return next; 00449 } 00450 00451 00452 00453 /** 00454 * Searches tree for the supplied (scalar?) object identifier. 00455 * 00456 * @param node points to the root of the tree ('.internet') 00457 * @param ident_len the length of the supplied object identifier 00458 * @param ident points to the array of sub identifiers 00459 * @param np points to the found object instance (rerurn) 00460 * @return pointer to the requested parent (!) node if success, NULL otherwise 00461 */ 00462 struct mib_node * 00463 snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np) 00464 { 00465 u8_t node_type, ext_level; 00466 00467 ext_level = 0; 00468 LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident)); 00469 while (node != NULL) 00470 { 00471 node_type = node->node_type; 00472 if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) 00473 { 00474 struct mib_array_node *an; 00475 u16_t i; 00476 00477 if (ident_len > 0) 00478 { 00479 /* array node (internal ROM or RAM, fixed length) */ 00480 an = (struct mib_array_node *)node; 00481 i = 0; 00482 while ((i < an->maxlength) && (an->objid[i] != *ident)) 00483 { 00484 i++; 00485 } 00486 if (i < an->maxlength) 00487 { 00488 /* found it, if available proceed to child, otherwise inspect leaf */ 00489 LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); 00490 if (an->nptr[i] == NULL) 00491 { 00492 /* a scalar leaf OR table, 00493 inspect remaining instance number / table index */ 00494 np->ident_len = ident_len; 00495 np->ident = ident; 00496 return (struct mib_node*)an; 00497 } 00498 else 00499 { 00500 /* follow next child pointer */ 00501 ident++; 00502 ident_len--; 00503 node = an->nptr[i]; 00504 } 00505 } 00506 else 00507 { 00508 /* search failed, identifier mismatch (nosuchname) */ 00509 LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident)); 00510 return NULL; 00511 } 00512 } 00513 else 00514 { 00515 /* search failed, short object identifier (nosuchname) */ 00516 LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n")); 00517 return NULL; 00518 } 00519 } 00520 else if(node_type == MIB_NODE_LR) 00521 { 00522 struct mib_list_rootnode *lrn; 00523 struct mib_list_node *ln; 00524 00525 if (ident_len > 0) 00526 { 00527 /* list root node (internal 'RAM', variable length) */ 00528 lrn = (struct mib_list_rootnode *)node; 00529 ln = lrn->head; 00530 /* iterate over list, head to tail */ 00531 while ((ln != NULL) && (ln->objid != *ident)) 00532 { 00533 ln = ln->next; 00534 } 00535 if (ln != NULL) 00536 { 00537 /* found it, proceed to child */; 00538 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); 00539 if (ln->nptr == NULL) 00540 { 00541 np->ident_len = ident_len; 00542 np->ident = ident; 00543 return (struct mib_node*)lrn; 00544 } 00545 else 00546 { 00547 /* follow next child pointer */ 00548 ident_len--; 00549 ident++; 00550 node = ln->nptr; 00551 } 00552 } 00553 else 00554 { 00555 /* search failed */ 00556 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident)); 00557 return NULL; 00558 } 00559 } 00560 else 00561 { 00562 /* search failed, short object identifier (nosuchname) */ 00563 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n")); 00564 return NULL; 00565 } 00566 } 00567 else if(node_type == MIB_NODE_EX) 00568 { 00569 struct mib_external_node *en; 00570 u16_t i, len; 00571 00572 if (ident_len > 0) 00573 { 00574 /* external node (addressing and access via functions) */ 00575 en = (struct mib_external_node *)node; 00576 00577 i = 0; 00578 len = en->level_length(en->addr_inf,ext_level); 00579 while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0)) 00580 { 00581 i++; 00582 } 00583 if (i < len) 00584 { 00585 s32_t debug_id; 00586 00587 en->get_objid(en->addr_inf,ext_level,i,&debug_id); 00588 LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident)); 00589 if ((ext_level + 1) == en->tree_levels) 00590 { 00591 np->ident_len = ident_len; 00592 np->ident = ident; 00593 return (struct mib_node*)en; 00594 } 00595 else 00596 { 00597 /* found it, proceed to child */ 00598 ident_len--; 00599 ident++; 00600 ext_level++; 00601 } 00602 } 00603 else 00604 { 00605 /* search failed */ 00606 LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident)); 00607 return NULL; 00608 } 00609 } 00610 else 00611 { 00612 /* search failed, short object identifier (nosuchname) */ 00613 LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n")); 00614 return NULL; 00615 } 00616 } 00617 else if (node_type == MIB_NODE_SC) 00618 { 00619 mib_scalar_node *sn; 00620 00621 sn = (mib_scalar_node *)node; 00622 if ((ident_len == 1) && (*ident == 0)) 00623 { 00624 np->ident_len = ident_len; 00625 np->ident = ident; 00626 return (struct mib_node*)sn; 00627 } 00628 else 00629 { 00630 /* search failed, short object identifier (nosuchname) */ 00631 LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n")); 00632 return NULL; 00633 } 00634 } 00635 else 00636 { 00637 /* unknown node_type */ 00638 LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type)); 00639 return NULL; 00640 } 00641 } 00642 /* done, found nothing */ 00643 LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node)); 00644 return NULL; 00645 } 00646 00647 /** 00648 * Test table for presence of at least one table entry. 00649 */ 00650 static u8_t 00651 empty_table(struct mib_node *node) 00652 { 00653 u8_t node_type; 00654 u8_t empty = 0; 00655 00656 if (node != NULL) 00657 { 00658 node_type = node->node_type; 00659 if (node_type == MIB_NODE_LR) 00660 { 00661 struct mib_list_rootnode *lrn; 00662 lrn = (struct mib_list_rootnode *)node; 00663 if ((lrn->count == 0) || (lrn->head == NULL)) 00664 { 00665 empty = 1; 00666 } 00667 } 00668 else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) 00669 { 00670 struct mib_array_node *an; 00671 an = (struct mib_array_node *)node; 00672 if ((an->maxlength == 0) || (an->nptr == NULL)) 00673 { 00674 empty = 1; 00675 } 00676 } 00677 else if (node_type == MIB_NODE_EX) 00678 { 00679 struct mib_external_node *en; 00680 en = (struct mib_external_node *)node; 00681 if (en->tree_levels == 0) 00682 { 00683 empty = 1; 00684 } 00685 } 00686 } 00687 return empty; 00688 } 00689 00690 /** 00691 * Tree expansion. 00692 */ 00693 struct mib_node * 00694 snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) 00695 { 00696 u8_t node_type, ext_level, climb_tree; 00697 00698 ext_level = 0; 00699 /* reset node stack */ 00700 node_stack_cnt = 0; 00701 while (node != NULL) 00702 { 00703 climb_tree = 0; 00704 node_type = node->node_type; 00705 if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) 00706 { 00707 struct mib_array_node *an; 00708 u16_t i; 00709 00710 /* array node (internal ROM or RAM, fixed length) */ 00711 an = (struct mib_array_node *)node; 00712 if (ident_len > 0) 00713 { 00714 i = 0; 00715 while ((i < an->maxlength) && (an->objid[i] < *ident)) 00716 { 00717 i++; 00718 } 00719 if (i < an->maxlength) 00720 { 00721 LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); 00722 /* add identifier to oidret */ 00723 oidret->id[oidret->len] = an->objid[i]; 00724 (oidret->len)++; 00725 00726 if (an->nptr[i] == NULL) 00727 { 00728 LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); 00729 /* leaf node (e.g. in a fixed size table) */ 00730 if (an->objid[i] > *ident) 00731 { 00732 return (struct mib_node*)an; 00733 } 00734 else if ((i + 1) < an->maxlength) 00735 { 00736 /* an->objid[i] == *ident */ 00737 (oidret->len)--; 00738 oidret->id[oidret->len] = an->objid[i + 1]; 00739 (oidret->len)++; 00740 return (struct mib_node*)an; 00741 } 00742 else 00743 { 00744 /* (i + 1) == an->maxlength */ 00745 (oidret->len)--; 00746 climb_tree = 1; 00747 } 00748 } 00749 else 00750 { 00751 u8_t j; 00752 struct nse cur_node; 00753 00754 LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); 00755 /* non-leaf, store right child ptr and id */ 00756 j = i + 1; 00757 while ((j < an->maxlength) && (empty_table(an->nptr[j]))) 00758 { 00759 j++; 00760 } 00761 if (j < an->maxlength) 00762 { 00763 cur_node.r_ptr = an->nptr[j]; 00764 cur_node.r_id = an->objid[j]; 00765 cur_node.r_nl = 0; 00766 } 00767 else 00768 { 00769 cur_node.r_ptr = NULL; 00770 } 00771 push_node(&cur_node); 00772 if (an->objid[i] == *ident) 00773 { 00774 ident_len--; 00775 ident++; 00776 } 00777 else 00778 { 00779 /* an->objid[i] < *ident */ 00780 ident_len = 0; 00781 } 00782 /* follow next child pointer */ 00783 node = an->nptr[i]; 00784 } 00785 } 00786 else 00787 { 00788 /* i == an->maxlength */ 00789 climb_tree = 1; 00790 } 00791 } 00792 else 00793 { 00794 u8_t j; 00795 /* ident_len == 0, complete with leftmost '.thing' */ 00796 j = 0; 00797 while ((j < an->maxlength) && empty_table(an->nptr[j])) 00798 { 00799 j++; 00800 } 00801 if (j < an->maxlength) 00802 { 00803 LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j])); 00804 oidret->id[oidret->len] = an->objid[j]; 00805 (oidret->len)++; 00806 if (an->nptr[j] == NULL) 00807 { 00808 /* leaf node */ 00809 return (struct mib_node*)an; 00810 } 00811 else 00812 { 00813 /* no leaf, continue */ 00814 node = an->nptr[j]; 00815 } 00816 } 00817 else 00818 { 00819 /* j == an->maxlength */ 00820 climb_tree = 1; 00821 } 00822 } 00823 } 00824 else if(node_type == MIB_NODE_LR) 00825 { 00826 struct mib_list_rootnode *lrn; 00827 struct mib_list_node *ln; 00828 00829 /* list root node (internal 'RAM', variable length) */ 00830 lrn = (struct mib_list_rootnode *)node; 00831 if (ident_len > 0) 00832 { 00833 ln = lrn->head; 00834 /* iterate over list, head to tail */ 00835 while ((ln != NULL) && (ln->objid < *ident)) 00836 { 00837 ln = ln->next; 00838 } 00839 if (ln != NULL) 00840 { 00841 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); 00842 oidret->id[oidret->len] = ln->objid; 00843 (oidret->len)++; 00844 if (ln->nptr == NULL) 00845 { 00846 /* leaf node */ 00847 if (ln->objid > *ident) 00848 { 00849 return (struct mib_node*)lrn; 00850 } 00851 else if (ln->next != NULL) 00852 { 00853 /* ln->objid == *ident */ 00854 (oidret->len)--; 00855 oidret->id[oidret->len] = ln->next->objid; 00856 (oidret->len)++; 00857 return (struct mib_node*)lrn; 00858 } 00859 else 00860 { 00861 /* ln->next == NULL */ 00862 (oidret->len)--; 00863 climb_tree = 1; 00864 } 00865 } 00866 else 00867 { 00868 struct mib_list_node *jn; 00869 struct nse cur_node; 00870 00871 /* non-leaf, store right child ptr and id */ 00872 jn = ln->next; 00873 while ((jn != NULL) && empty_table(jn->nptr)) 00874 { 00875 jn = jn->next; 00876 } 00877 if (jn != NULL) 00878 { 00879 cur_node.r_ptr = jn->nptr; 00880 cur_node.r_id = jn->objid; 00881 cur_node.r_nl = 0; 00882 } 00883 else 00884 { 00885 cur_node.r_ptr = NULL; 00886 } 00887 push_node(&cur_node); 00888 if (ln->objid == *ident) 00889 { 00890 ident_len--; 00891 ident++; 00892 } 00893 else 00894 { 00895 /* ln->objid < *ident */ 00896 ident_len = 0; 00897 } 00898 /* follow next child pointer */ 00899 node = ln->nptr; 00900 } 00901 00902 } 00903 else 00904 { 00905 /* ln == NULL */ 00906 climb_tree = 1; 00907 } 00908 } 00909 else 00910 { 00911 struct mib_list_node *jn; 00912 /* ident_len == 0, complete with leftmost '.thing' */ 00913 jn = lrn->head; 00914 while ((jn != NULL) && empty_table(jn->nptr)) 00915 { 00916 jn = jn->next; 00917 } 00918 if (jn != NULL) 00919 { 00920 LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid)); 00921 oidret->id[oidret->len] = jn->objid; 00922 (oidret->len)++; 00923 if (jn->nptr == NULL) 00924 { 00925 /* leaf node */ 00926 LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n")); 00927 return (struct mib_node*)lrn; 00928 } 00929 else 00930 { 00931 /* no leaf, continue */ 00932 node = jn->nptr; 00933 } 00934 } 00935 else 00936 { 00937 /* jn == NULL */ 00938 climb_tree = 1; 00939 } 00940 } 00941 } 00942 else if(node_type == MIB_NODE_EX) 00943 { 00944 struct mib_external_node *en; 00945 s32_t ex_id; 00946 00947 /* external node (addressing and access via functions) */ 00948 en = (struct mib_external_node *)node; 00949 if (ident_len > 0) 00950 { 00951 u16_t i, len; 00952 00953 i = 0; 00954 len = en->level_length(en->addr_inf,ext_level); 00955 while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0)) 00956 { 00957 i++; 00958 } 00959 if (i < len) 00960 { 00961 /* add identifier to oidret */ 00962 en->get_objid(en->addr_inf,ext_level,i,&ex_id); 00963 LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident)); 00964 oidret->id[oidret->len] = ex_id; 00965 (oidret->len)++; 00966 00967 if ((ext_level + 1) == en->tree_levels) 00968 { 00969 LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); 00970 /* leaf node */ 00971 if (ex_id > *ident) 00972 { 00973 return (struct mib_node*)en; 00974 } 00975 else if ((i + 1) < len) 00976 { 00977 /* ex_id == *ident */ 00978 en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id); 00979 (oidret->len)--; 00980 oidret->id[oidret->len] = ex_id; 00981 (oidret->len)++; 00982 return (struct mib_node*)en; 00983 } 00984 else 00985 { 00986 /* (i + 1) == len */ 00987 (oidret->len)--; 00988 climb_tree = 1; 00989 } 00990 } 00991 else 00992 { 00993 u8_t j; 00994 struct nse cur_node; 00995 00996 LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); 00997 /* non-leaf, store right child ptr and id */ 00998 j = i + 1; 00999 if (j < len) 01000 { 01001 /* right node is the current external node */ 01002 cur_node.r_ptr = node; 01003 en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id); 01004 cur_node.r_nl = ext_level + 1; 01005 } 01006 else 01007 { 01008 cur_node.r_ptr = NULL; 01009 } 01010 push_node(&cur_node); 01011 if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0) 01012 { 01013 ident_len--; 01014 ident++; 01015 } 01016 else 01017 { 01018 /* external id < *ident */ 01019 ident_len = 0; 01020 } 01021 /* proceed to child */ 01022 ext_level++; 01023 } 01024 } 01025 else 01026 { 01027 /* i == len (en->level_len()) */ 01028 climb_tree = 1; 01029 } 01030 } 01031 else 01032 { 01033 /* ident_len == 0, complete with leftmost '.thing' */ 01034 en->get_objid(en->addr_inf,ext_level,0,&ex_id); 01035 LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id)); 01036 oidret->id[oidret->len] = ex_id; 01037 (oidret->len)++; 01038 if ((ext_level + 1) == en->tree_levels) 01039 { 01040 /* leaf node */ 01041 LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n")); 01042 return (struct mib_node*)en; 01043 } 01044 else 01045 { 01046 /* no leaf, proceed to child */ 01047 ext_level++; 01048 } 01049 } 01050 } 01051 else if(node_type == MIB_NODE_SC) 01052 { 01053 mib_scalar_node *sn; 01054 01055 /* scalar node */ 01056 sn = (mib_scalar_node *)node; 01057 if (ident_len > 0) 01058 { 01059 /* at .0 */ 01060 climb_tree = 1; 01061 } 01062 else 01063 { 01064 /* ident_len == 0, complete object identifier */ 01065 oidret->id[oidret->len] = 0; 01066 (oidret->len)++; 01067 /* leaf node */ 01068 LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n")); 01069 return (struct mib_node*)sn; 01070 } 01071 } 01072 else 01073 { 01074 /* unknown/unhandled node_type */ 01075 LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type)); 01076 return NULL; 01077 } 01078 01079 if (climb_tree) 01080 { 01081 struct nse child; 01082 01083 /* find right child ptr */ 01084 child.r_ptr = NULL; 01085 child.r_id = 0; 01086 child.r_nl = 0; 01087 while ((node_stack_cnt > 0) && (child.r_ptr == NULL)) 01088 { 01089 pop_node(&child); 01090 /* trim returned oid */ 01091 (oidret->len)--; 01092 } 01093 if (child.r_ptr != NULL) 01094 { 01095 /* incoming ident is useless beyond this point */ 01096 ident_len = 0; 01097 oidret->id[oidret->len] = child.r_id; 01098 oidret->len++; 01099 node = child.r_ptr; 01100 ext_level = child.r_nl; 01101 } 01102 else 01103 { 01104 /* tree ends here ... */ 01105 LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n")); 01106 return NULL; 01107 } 01108 } 01109 } 01110 /* done, found nothing */ 01111 LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node)); 01112 return NULL; 01113 } 01114 01115 /** 01116 * Test object identifier for the iso.org.dod.internet prefix. 01117 * 01118 * @param ident_len the length of the supplied object identifier 01119 * @param ident points to the array of sub identifiers 01120 * @return 1 if it matches, 0 otherwise 01121 */ 01122 u8_t 01123 snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident) 01124 { 01125 if ((ident_len > 3) && 01126 (ident[0] == 1) && (ident[1] == 3) && 01127 (ident[2] == 6) && (ident[3] == 1)) 01128 { 01129 return 1; 01130 } 01131 else 01132 { 01133 return 0; 01134 } 01135 } 01136 01137 /** 01138 * Expands object identifier to the iso.org.dod.internet 01139 * prefix for use in getnext operation. 01140 * 01141 * @param ident_len the length of the supplied object identifier 01142 * @param ident points to the array of sub identifiers 01143 * @param oidret points to returned expanded object identifier 01144 * @return 1 if it matches, 0 otherwise 01145 * 01146 * @note ident_len 0 is allowed, expanding to the first known object id!! 01147 */ 01148 u8_t 01149 snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) 01150 { 01151 const s32_t *prefix_ptr; 01152 s32_t *ret_ptr; 01153 u8_t i; 01154 01155 i = 0; 01156 prefix_ptr = &prefix[0]; 01157 ret_ptr = &oidret->id[0]; 01158 ident_len = ((ident_len < 4)?ident_len:4); 01159 while ((i < ident_len) && ((*ident) <= (*prefix_ptr))) 01160 { 01161 *ret_ptr++ = *prefix_ptr++; 01162 ident++; 01163 i++; 01164 } 01165 if (i == ident_len) 01166 { 01167 /* match, complete missing bits */ 01168 while (i < 4) 01169 { 01170 *ret_ptr++ = *prefix_ptr++; 01171 i++; 01172 } 01173 oidret->len = i; 01174 return 1; 01175 } 01176 else 01177 { 01178 /* i != ident_len */ 01179 return 0; 01180 } 01181 } 01182 01183 #endif /* LWIP_SNMP */
Generated on Tue Jul 12 2022 19:17:23 by 1.7.2