and added files
[bcm963xx.git] / userapps / opensource / net-snmp / agent / snmp_vars.c
1 /*
2  * snmp_vars.c - return a pointer to the named variable.
3  *
4  *
5  */
6 /***********************************************************
7         Copyright 1988, 1989, 1990 by Carnegie Mellon University
8         Copyright 1989  TGV, Incorporated
9
10                       All Rights Reserved
11
12 Permission to use, copy, modify, and distribute this software and its
13 documentation for any purpose and without fee is hereby granted,
14 provided that the above copyright notice appear in all copies and that
15 both that copyright notice and this permission notice appear in
16 supporting documentation, and that the name of CMU and TGV not be used
17 in advertising or publicity pertaining to distribution of the software
18 without specific, written prior permission.
19
20 CMU AND TGV DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
22 EVENT SHALL CMU OR TGV BE LIABLE FOR ANY SPECIAL, INDIRECT OR
23 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
24 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
25 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
26 PERFORMANCE OF THIS SOFTWARE.
27 ******************************************************************/
28 /*
29  * additions, fixes and enhancements for Linux by Erik Schoenfelder
30  * (schoenfr@ibr.cs.tu-bs.de) 1994/1995.
31  * Linux additions taken from CMU to UCD stack by Jennifer Bray of Origin
32  * (jbray@origin-at.co.uk) 1997
33  */
34
35 /*
36  * XXXWWW merge todo: incl/excl range changes in differences between
37  * 1.194 and 1.199 
38  */
39
40 #include <net-snmp/net-snmp-config.h>
41 #if HAVE_STRING_H
42 #include <string.h>
43 #endif
44 #if HAVE_STDLIB_H
45 #include <stdlib.h>
46 #endif
47 #include <sys/types.h>
48 #include <stdio.h>
49 #include <fcntl.h>
50
51 #if TIME_WITH_SYS_TIME
52 # ifdef WIN32
53 #  include <sys/timeb.h>
54 # else
55 #  include <sys/time.h>
56 # endif
57 # include <time.h>
58 #else
59 # if HAVE_SYS_TIME_H
60 #  include <sys/time.h>
61 # else
62 #  include <time.h>
63 # endif
64 #endif
65 #if HAVE_WINSOCK_H
66 # include <winsock.h>
67 #endif
68 #if HAVE_SYS_SOCKET_H
69 # include <sys/socket.h>
70 #endif
71 #if HAVE_SYS_STREAM_H
72 #include <sys/stream.h>
73 #endif
74 #if HAVE_SYS_SOCKETVAR_H
75 # include <sys/socketvar.h>
76 #endif
77 #if HAVE_NETINET_IN_H
78 #include <netinet/in.h>
79 #endif
80 #if HAVE_NETINET_IN_SYSTM_H
81 #include <netinet/in_systm.h>
82 #endif
83 #if HAVE_NETINET_IP_H
84 #include <netinet/ip.h>
85 #endif
86 #ifdef INET6
87 #if HAVE_NETINET_IP6_H
88 #include <netinet/ip6.h>
89 #endif
90 #endif
91 #if HAVE_SYS_QUEUE_H
92 #include <sys/queue.h>
93 #endif
94 #if HAVE_NET_ROUTE_H
95 #include <net/route.h>
96 #endif
97 #if HAVE_NETINET_IP_VAR_H
98 #include <netinet/ip_var.h>
99 #endif
100 #ifdef INET6
101 #if HAVE_NETINET6_IP6_VAR_H
102 #include <netinet6/ip6_var.h>
103 #endif
104 #endif
105 #if HAVE_NETINET_IN_PCB_H
106 #include <netinet/in_pcb.h>
107 #endif
108 #if HAVE_INET_MIB2_H
109 #include <inet/mib2.h>
110 #endif
111
112 #if HAVE_DMALLOC_H
113 #include <dmalloc.h>
114 #endif
115
116 #include <net-snmp/net-snmp-includes.h>
117 #include <net-snmp/agent/net-snmp-agent-includes.h>
118 #include "kernel.h"
119
120 #include "mibgroup/struct.h"
121 #include "snmpd.h"
122 #include "net-snmp/agent/all_helpers.h"
123 #include "mib_module_includes.h"
124 #include "net-snmp/library/container.h"
125
126 #ifndef  MIN
127 #define  MIN(a,b)                     (((a) < (b)) ? (a) : (b))
128 #endif
129
130 /*
131  * mib clients are passed a pointer to a oid buffer.  Some mib clients
132  * * (namely, those first noticed in mibII/vacm.c) modify this oid buffer
133  * * before they determine if they really need to send results back out
134  * * using it.  If the master agent determined that the client was not the
135  * * right one to talk with, it will use the same oid buffer to pass to the
136  * * rest of the clients, which may not longer be valid.  This should be
137  * * fixed in all clients rather than the master.  However, its not a
138  * * particularily easy bug to track down so this saves debugging time at
139  * * the expense of a few memcpy's.
140  */
141 #define MIB_CLIENTS_ARE_EVIL 1
142
143 extern netsnmp_subtree *subtrees;
144
145 /*
146  *      Each variable name is placed in the variable table, without the
147  * terminating substring that determines the instance of the variable.  When
148  * a string is found that is lexicographicly preceded by the input string,
149  * the function for that entry is called to find the method of access of the
150  * instance of the named variable.  If that variable is not found, NULL is
151  * returned, and the search through the table continues (it will probably
152  * stop at the next entry).  If it is found, the function returns a character
153  * pointer and a length or a function pointer.  The former is the address
154  * of the operand, the latter is a write routine for the variable.
155  *
156  * u_char *
157  * findVar(name, length, exact, var_len, write_method)
158  * oid      *name;          IN/OUT - input name requested, output name found
159  * int      length;         IN/OUT - number of sub-ids in the in and out oid's
160  * int      exact;          IN - TRUE if an exact match was requested.
161  * int      len;            OUT - length of variable or 0 if function returned.
162  * int      write_method;   OUT - pointer to function to set variable,
163  *                                otherwise 0
164  *
165  *     The writeVar function is returned to handle row addition or complex
166  * writes that require boundary checking or executing an action.
167  * This routine will be called three times for each varbind in the packet.
168  * The first time for each varbind, action is set to RESERVE1.  The type
169  * and value should be checked during this pass.  If any other variables
170  * in the MIB depend on this variable, this variable will be stored away
171  * (but *not* committed!) in a place where it can be found by a call to
172  * writeVar for a dependent variable, even in the same PDU.  During
173  * the second pass, action is set to RESERVE2.  If this variable is dependent
174  * on any other variables, it will check them now.  It must check to see
175  * if any non-committed values have been stored for variables in the same
176  * PDU that it depends on.  Sometimes resources will need to be reserved
177  * in the first two passes to guarantee that the operation can proceed
178  * during the third pass.  During the third pass, if there were no errors
179  * in the first two passes, writeVar is called for every varbind with action
180  * set to COMMIT.  It is now that the values should be written.  If there
181  * were errors during the first two passes, writeVar is called in the third
182  * pass once for each varbind, with the action set to FREE.  An opportunity
183  * is thus provided to free those resources reserved in the first two passes.
184  * 
185  * writeVar(action, var_val, var_val_type, var_val_len, statP, name, name_len)
186  * int      action;         IN - RESERVE1, RESERVE2, COMMIT, or FREE
187  * u_char   *var_val;       IN - input or output buffer space
188  * u_char   var_val_type;   IN - type of input buffer
189  * int      var_val_len;    IN - input and output buffer len
190  * u_char   *statP;         IN - pointer to local statistic
191  * oid      *name           IN - pointer to name requested
192  * int      name_len        IN - number of sub-ids in the name
193  */
194
195 long            long_return;
196 #ifndef ibm032
197 u_char          return_buf[258];
198 #else
199 u_char          return_buf[256];        /* nee 64 */
200 #endif
201
202 struct timeval  starttime;
203 netsnmp_session *callback_master_sess;
204 int             callback_master_num;
205
206 /*
207  * init_agent() returns non-zero on error 
208  */
209 int
210 init_agent(const char *app)
211 {
212     int             r = 0;
213
214     /*
215      * get current time (ie, the time the agent started) 
216      */
217     gettimeofday(&starttime, NULL);
218     starttime.tv_sec--;
219     starttime.tv_usec += 1000000L;
220
221     /*
222      * we handle alarm signals ourselves in the select loop 
223      */
224     netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
225                            NETSNMP_DS_LIB_ALARM_DONT_USE_SIG, 1);
226
227 #ifdef CAN_USE_NLIST
228     init_kmem("/dev/kmem");
229 #endif
230
231     setup_tree();
232 #ifndef BUILD_ILMI
233     init_agent_read_config(app);
234 #endif
235
236 #ifdef TESTING
237     auto_nlist_print_tree(-2, 0);
238 #endif
239
240 #ifndef WIN32
241         /*
242          * the pipe call creates fds that select chokes on, so
243          * disable callbacks on WIN32 until a fix can be found
244          */
245     /*
246      * always register a callback transport for internal use 
247      */
248 #ifdef BRCM_SNMP_SUPPORT
249     callback_master_sess = netsnmp_callback_open(0, handle_snmp_packet,
250                                                  netsnmp_agent_check_packet,
251                                                  netsnmp_agent_check_parse);
252 #esle
253     callback_master_sess = netsnmp_callback_open(0, handle_snmp_packet,
254                                                  NULL,NULL);
255 #endif
256     if (callback_master_sess)
257         callback_master_num = callback_master_sess->local_port;
258     else
259 #endif
260         callback_master_num = -1;
261
262 #ifdef BRCM_SNMP_SUPPORT
263     netsnmp_init_helpers();
264 #endif
265 #ifndef BUILD_ILMI
266     init_traps();
267 #endif
268
269 #ifdef BRCM_CONTAINER_SUPPORT
270     netsnmp_container_init_list();
271 #endif
272
273     /*
274      * initialize agentx subagent if necessary. 
275      */
276 #ifdef USING_AGENTX_SUBAGENT_MODULE
277     if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
278                                NETSNMP_DS_AGENT_ROLE) == SUB_AGENT) {
279         r = subagent_pre_init();
280         init_subagent();
281     }
282 #endif
283
284     /*
285      * Register configuration tokens from transport modules.  
286      */
287 #ifdef SNMP_TRANSPORT_UDP_DOMAIN
288     netsnmp_udp_agent_config_tokens_register();
289 #endif
290 #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN
291     netsnmp_udp6_agent_config_tokens_register();
292 #endif
293
294 #ifdef NETSNMP_EMBEDDED_PERL
295     init_perl();
296 #endif
297
298     return r;
299 }                               /* end init_agent() */
300
301 oid             nullOid[] = { 0, 0 };
302 int             nullOidLen = sizeof(nullOid);