]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/blob - src/core/snmp/mib_structs.c
0d2dfd8e6e3c5b2354fd6405c853c7759839db7b
[pes-rpp/rpp-lwip.git] / src / core / snmp / mib_structs.c
1 /**
2  * @file
3  * [EXPERIMENTAL] Generic 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 #include "lwip/snmp_structs.h"
37
38 #if LWIP_SNMP
39
40 /**
41  * Searches tree for the supplied (scalar?) object identifier.
42  *
43  * @param node points to the root of the tree ('.internet')
44  * @param ident_len the length of the supplied object identifier
45  * @param ident points to the array of sub identifiers
46  * @param object_def points to the object definition to return
47  * @return pointer to the requested parent (!) node if success, NULL otherwise
48  */
49 struct mib_node *
50 snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj_def *object_def)
51 {
52   u8_t node_type;
53
54   LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F,(void*)node,*ident));
55   while (node != NULL)
56   {
57     node_type = node->node_type;
58     if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
59     {
60       struct mib_array_node *an;
61       u16_t i;
62
63       /* array node (internal ROM or RAM, fixed length) */
64       an = (struct mib_array_node *)node;
65       i = 0;
66       while ((i < an->maxlength) && (an->objid[i] != *ident))
67       {
68         i++;
69       }
70       if (i < an->maxlength)
71       {
72         if (ident_len > 0)
73         { 
74           /* found it, if available proceed to child, otherwise inspect leaf */
75           LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F,i,an->objid[i],*ident));
76           if (an->nptr[i] == NULL)
77           {
78             /* a scalar leaf OR table,
79                inspect remaining instance number / table index */
80             /* retrieve object definition with get_object_def() 
81                is it scalar, or a valid table item, or non-existent? */
82             an->get_object_def(ident_len, ident, object_def);
83             if (object_def->instance != MIB_OBJECT_NONE)
84             {
85               /** @todo return something more usefull ?? */
86               return (struct mib_node*)an;
87             }
88             else
89             {
90               /* search failed, object id points to unknown object (nosuchname) */
91               LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, object not in this MIB"));
92               return NULL;
93             }
94           }
95           else
96           {
97             /* follow next child pointer */
98             ident++;
99             ident_len--;
100             node = an->nptr[i];
101           }
102         }
103         else
104         {
105           /* search failed, short object identifier (nosuchname) */
106           LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
107           return NULL;
108         }
109       }
110       else
111       {
112         /* search failed, identifier mismatch (nosuchname) */
113         LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
114         return NULL;
115       }
116     }
117     else if(node_type == MIB_NODE_LR)
118     {
119       struct mib_list_rootnode *lrn;
120       struct mib_list_node *ln;
121
122       /* list root node (internal 'RAM', variable length) */
123       lrn = (struct mib_list_rootnode *)node;
124       ln = lrn->head;
125       /* iterate over list, head to tail */
126       while ((ln != NULL) && (ln->objid != *ident))
127       {
128         ln = ln->next;
129       }
130       if (ln != NULL)
131       {
132         if (ident_len > 0)
133         { 
134           /* found it, proceed to child */;
135           LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F,ln->objid,*ident));
136           if (ln->nptr == NULL)
137           {
138             lrn->get_object_def(ident_len, ident, object_def);
139             if (object_def->instance != MIB_OBJECT_NONE)
140             {
141               /** @todo return something more usefull ?? */
142               return (struct mib_node*)lrn;
143             }
144             else
145             {
146               /* search failed, object id points to unknown object (nosuchname) */
147               LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, object not in this MIB"));
148               return NULL;
149             }
150           }
151           else
152           {
153             /* follow next child pointer */
154             ident_len--;
155             ident++;
156             node = ln->nptr;
157           }
158         }
159         else
160         {
161           /* search failed, short object identifier (nosuchname) */
162           LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
163           return NULL;
164         }
165       }
166       else
167       {
168         /* search failed */
169         LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
170         return NULL;
171       }
172     }
173     else if(node_type == MIB_NODE_EX)
174     {
175       struct mib_external_node *en;
176       u16_t i;
177
178       /* external node (addressing and access via functions) */
179       en = (struct mib_external_node *)node;
180       i = 0;
181       while ((i < en->count) && en->ident_cmp(i,*ident))
182       {
183         i++;
184       }
185       if (i < en->count)
186       {
187         if (ident_len > 0)
188         { 
189           if (en->get_nptr(i) == NULL)
190           {
191 /** @todo, this object is elsewhere, we can only start the request,
192      but can't return something usefull yet.*/
193             en->req_object_def(ident_len, ident);
194             return (struct mib_node*)en;
195           }
196           else
197           {
198             /* found it, proceed to child */
199             ident_len--;
200             ident++;
201             node = (struct mib_node*)en->get_nptr(i);
202           }
203         }
204         else
205         {
206           /* search failed, short object identifier (nosuchname) */
207           LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, short object identifier"));
208           return NULL;
209         }
210       }
211       else
212       {
213         /* search failed */
214         LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed *ident==%"S32_F,*ident));
215         return NULL;
216       }
217     }
218   }
219   /* done, found nothing */
220   LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p",(void*)node));
221   return NULL;
222 }
223
224 #endif /* LWIP_SNMP */