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