OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [lwIP/] [core/] [snmp/] [mib_structs.c] - Blame information for rev 606

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.