OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [snmp/] [agent/] [v2_0/] [src/] [snmp_vars.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ./agent/current/src/snmp_vars.c
4
//
5
//
6
//==========================================================================
7
//####ECOSGPLCOPYRIGHTBEGIN####
8
// -------------------------------------------
9
// This file is part of eCos, the Embedded Configurable Operating System.
10
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
11
//
12
// eCos is free software; you can redistribute it and/or modify it under
13
// the terms of the GNU General Public License as published by the Free
14
// Software Foundation; either version 2 or (at your option) any later version.
15
//
16
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19
// for more details.
20
//
21
// You should have received a copy of the GNU General Public License along
22
// with eCos; if not, write to the Free Software Foundation, Inc.,
23
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24
//
25
// As a special exception, if other files instantiate templates or use macros
26
// or inline functions from this file, or you compile this file and link it
27
// with other works to produce a work based on this file, this file does not
28
// by itself cause the resulting work to be covered by the GNU General Public
29
// License. However the source code for this file must still be made available
30
// in accordance with section (3) of the GNU General Public License.
31
//
32
// This exception does not invalidate any other reasons why a work based on
33
// this file might be covered by the GNU General Public License.
34
//
35
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36
// at http://sources.redhat.com/ecos/ecos-license/
37
// -------------------------------------------
38
//####ECOSGPLCOPYRIGHTEND####
39
//####UCDSNMPCOPYRIGHTBEGIN####
40
//
41
// -------------------------------------------
42
//
43
// Portions of this software may have been derived from the UCD-SNMP
44
// project,  <http://ucd-snmp.ucdavis.edu/>  from the University of
45
// California at Davis, which was originally based on the Carnegie Mellon
46
// University SNMP implementation.  Portions of this software are therefore
47
// covered by the appropriate copyright disclaimers included herein.
48
//
49
// The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
50
// -------------------------------------------
51
//
52
//####UCDSNMPCOPYRIGHTEND####
53
//==========================================================================
54
//#####DESCRIPTIONBEGIN####
55
//
56
// Author(s):    hmt
57
// Contributors: hmt
58
// Date:         2000-05-30
59
// Purpose:      Port of UCD-SNMP distribution to eCos.
60
// Description:  
61
//              
62
//
63
//####DESCRIPTIONEND####
64
//
65
//==========================================================================
66
/********************************************************************
67
       Copyright 1989, 1991, 1992 by Carnegie Mellon University
68
 
69
                          Derivative Work -
70
Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
71
 
72
                         All Rights Reserved
73
 
74
Permission to use, copy, modify and distribute this software and its
75
documentation for any purpose and without fee is hereby granted,
76
provided that the above copyright notice appears in all copies and
77
that both that copyright notice and this permission notice appear in
78
supporting documentation, and that the name of CMU and The Regents of
79
the University of California not be used in advertising or publicity
80
pertaining to distribution of the software without specific written
81
permission.
82
 
83
CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
84
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
85
WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL CMU OR
86
THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
87
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
88
FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
89
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
90
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
91
*********************************************************************/
92
/*
93
 * snmp_vars.c - return a pointer to the named variable.
94
 *
95
 *
96
 */
97
/***********************************************************
98
        Copyright 1988, 1989, 1990 by Carnegie Mellon University
99
        Copyright 1989  TGV, Incorporated
100
 
101
                      All Rights Reserved
102
 
103
Permission to use, copy, modify, and distribute this software and its
104
documentation for any purpose and without fee is hereby granted,
105
provided that the above copyright notice appear in all copies and that
106
both that copyright notice and this permission notice appear in
107
supporting documentation, and that the name of CMU and TGV not be used
108
in advertising or publicity pertaining to distribution of the software
109
without specific, written prior permission.
110
 
111
CMU AND TGV DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
112
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
113
EVENT SHALL CMU OR TGV BE LIABLE FOR ANY SPECIAL, INDIRECT OR
114
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
115
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
116
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
117
PERFORMANCE OF THIS SOFTWARE.
118
******************************************************************/
119
/*
120
 * additions, fixes and enhancements for Linux by Erik Schoenfelder
121
 * (schoenfr@ibr.cs.tu-bs.de) 1994/1995.
122
 * Linux additions taken from CMU to UCD stack by Jennifer Bray of Origin
123
 * (jbray@origin-at.co.uk) 1997
124
 */
125
 
126
 
127
#include <config.h>
128
#if HAVE_STRING_H
129
#include <string.h>
130
#endif
131
#if HAVE_STDLIB_H
132
#include <stdlib.h>
133
#endif
134
#include <sys/types.h>
135
#include <stdio.h>
136
#if HAVE_FCNTL_H
137
#include <fcntl.h>
138
#endif
139
 
140
#if TIME_WITH_SYS_TIME
141
# ifdef WIN32
142
#  include <sys/timeb.h>
143
# else
144
#  include <sys/time.h>
145
# endif
146
# include <time.h>
147
#else
148
# if HAVE_SYS_TIME_H
149
#  include <sys/time.h>
150
# else
151
#  include <time.h>
152
# endif
153
#endif
154
#if HAVE_SYS_SOCKET_H
155
#include <sys/socket.h>
156
#elif HAVE_WINSOCK_H
157
#include <winsock.h>
158
#endif
159
#if HAVE_NETINET_IN_H
160
#include <netinet/in.h>
161
#endif
162
#if HAVE_NETINET_IN_SYSTM_H
163
#include <netinet/in_systm.h>
164
#endif
165
#if HAVE_NETINET_IP_H
166
#include <netinet/ip.h>
167
#endif
168
#ifdef INET6
169
#if HAVE_NETINET_IP6_H
170
#include <netinet/ip6.h>
171
#endif
172
#endif
173
#if HAVE_SYS_QUEUE_H
174
#include <sys/queue.h>
175
#endif
176
#if HAVE_SYS_STREAM_H
177
#include <sys/stream.h>
178
#endif
179
#if HAVE_NET_ROUTE_H
180
#include <net/route.h>
181
#endif
182
#if HAVE_NETINET_IP_VAR_H
183
#include <netinet/ip_var.h>
184
#endif
185
#ifdef INET6
186
#if HAVE_NETINET6_IP6_VAR_H
187
#include <netinet6/ip6_var.h>
188
#endif
189
#endif
190
#if HAVE_NETINET_IN_PCB_H
191
#include <netinet/in_pcb.h>
192
#endif
193
#if HAVE_INET_MIB2_H
194
#include <inet/mib2.h>
195
#endif
196
 
197
#if HAVE_DMALLOC_H
198
#include <dmalloc.h>
199
#endif
200
 
201
#include "mibincl.h"
202
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
203
#include "snmpv3.h"
204
#include "snmpusm.h"
205
#endif
206
#include "system.h"
207
#include "kernel.h"
208
#include "snmp_vars.h"
209
#include "default_store.h"
210
#include "ds_agent.h"
211
 
212
#include "mibgroup/struct.h"
213
#include "read_config.h"
214
#include "snmp_vars.h"
215
#include "agent_read_config.h"
216
#include "agent_registry.h"
217
#include "transform_oids.h"
218
#include "callback.h"
219
#include "snmp_alarm.h"
220
#include "snmpd.h"
221
#include "mib_module_includes.h"
222
 
223
#ifndef  MIN
224
#define  MIN(a,b)                     (((a) < (b)) ? (a) : (b)) 
225
#endif
226
 
227
/* mib clients are passed a pointer to a oid buffer.  Some mib clients
228
 * (namely, those first noticed in mibII/vacm.c) modify this oid buffer
229
 * before they determine if they really need to send results back out
230
 * using it.  If the master agent determined that the client was not the
231
 * right one to talk with, it will use the same oid buffer to pass to the
232
 * rest of the clients, which may not longer be valid.  This should be
233
 * fixed in all clients rather than the master.  However, its not a
234
 * particularily easy bug to track down so this saves debugging time at
235
 * the expense of a few memcpy's.
236
 */
237
#define MIB_CLIENTS_ARE_EVIL 1
238
 
239
extern struct subtree *subtrees;
240
int subtree_size;
241
int subtree_malloc_size;
242
 
243
/*
244
 *      Each variable name is placed in the variable table, without the
245
 * terminating substring that determines the instance of the variable.  When
246
 * a string is found that is lexicographicly preceded by the input string,
247
 * the function for that entry is called to find the method of access of the
248
 * instance of the named variable.  If that variable is not found, NULL is
249
 * returned, and the search through the table continues (it will probably
250
 * stop at the next entry).  If it is found, the function returns a character
251
 * pointer and a length or a function pointer.  The former is the address
252
 * of the operand, the latter is a write routine for the variable.
253
 *
254
 * u_char *
255
 * findVar(name, length, exact, var_len, write_method)
256
 * oid      *name;          IN/OUT - input name requested, output name found
257
 * int      length;         IN/OUT - number of sub-ids in the in and out oid's
258
 * int      exact;          IN - TRUE if an exact match was requested.
259
 * int      len;            OUT - length of variable or 0 if function returned.
260
 * int      write_method;   OUT - pointer to function to set variable,
261
 *                                otherwise 0
262
 *
263
 *     The writeVar function is returned to handle row addition or complex
264
 * writes that require boundary checking or executing an action.
265
 * This routine will be called three times for each varbind in the packet.
266
 * The first time for each varbind, action is set to RESERVE1.  The type
267
 * and value should be checked during this pass.  If any other variables
268
 * in the MIB depend on this variable, this variable will be stored away
269
 * (but *not* committed!) in a place where it can be found by a call to
270
 * writeVar for a dependent variable, even in the same PDU.  During
271
 * the second pass, action is set to RESERVE2.  If this variable is dependent
272
 * on any other variables, it will check them now.  It must check to see
273
 * if any non-committed values have been stored for variables in the same
274
 * PDU that it depends on.  Sometimes resources will need to be reserved
275
 * in the first two passes to guarantee that the operation can proceed
276
 * during the third pass.  During the third pass, if there were no errors
277
 * in the first two passes, writeVar is called for every varbind with action
278
 * set to COMMIT.  It is now that the values should be written.  If there
279
 * were errors during the first two passes, writeVar is called in the third
280
 * pass once for each varbind, with the action set to FREE.  An opportunity
281
 * is thus provided to free those resources reserved in the first two passes.
282
 *
283
 * writeVar(action, var_val, var_val_type, var_val_len, statP, name, name_len)
284
 * int      action;         IN - RESERVE1, RESERVE2, COMMIT, or FREE
285
 * u_char   *var_val;       IN - input or output buffer space
286
 * u_char   var_val_type;   IN - type of input buffer
287
 * int      var_val_len;    IN - input and output buffer len
288
 * u_char   *statP;         IN - pointer to local statistic
289
 * oid      *name           IN - pointer to name requested
290
 * int      name_len        IN - number of sub-ids in the name
291
 */
292
 
293
long            long_return;
294
#ifndef ibm032
295
u_char          return_buf[258];
296
#else
297
u_char          return_buf[256]; /* nee 64 */
298
#endif
299
 
300
struct timeval  starttime;
301
 
302
void
303
init_agent (const char *app)
304
{
305
  /* get current time (ie, the time the agent started) */
306
  gettimeofday(&starttime, NULL);
307
  starttime.tv_sec--;
308
  starttime.tv_usec += 1000000L;
309
 
310
  /* we handle alarm signals ourselves in the select loop */
311
  ds_set_boolean(DS_LIBRARY_ID, DS_LIB_ALARM_DONT_USE_SIG, 1);
312
 
313
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
314
  usm_set_reportErrorOnUnknownID(1);
315
#endif
316
 
317
#ifdef CAN_USE_NLIST
318
  init_kmem("/dev/kmem");
319
#endif
320
 
321
  setup_tree();
322
 
323
  init_agent_read_config(app);
324
 
325
#ifdef TESTING
326
  auto_nlist_print_tree(-2, 0);
327
#endif
328
 
329
  /* initialize agentx subagent if necessary. */
330
#ifdef USING_AGENTX_SUBAGENT_MODULE
331
  if(ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT)
332
      subagent_pre_init();
333
#endif
334
 
335
}  /* end init_agent() */
336
 
337
 
338
 
339
oid nullOid[] = {0,0};
340
int nullOidLen = sizeof(nullOid)/sizeof(oid);
341
 
342
/*
343
 * getStatPtr - return a pointer to the named variable, as well as it's
344
 * type, length, and access control list.
345
 * Now uses 'search_subtree' (recursively) and 'search_subtree_vars'
346
 * to do most of the work
347
 *
348
 * If an exact match for the variable name exists, it is returned.  If not,
349
 * and exact is false, the next variable lexicographically after the
350
 * requested one is returned.
351
 *
352
 * If no appropriate variable can be found, NULL is returned.
353
 */
354
static  int             found;
355
 
356
static u_char *
357
search_subtree_vars(struct subtree *tp,
358
                    oid *name,    /* IN - name of var, OUT - name matched */
359
                    size_t *namelen, /* IN -number of sub-ids in name,
360
                                     OUT - subid-is in matched name */
361
                    u_char *type, /* OUT - type of matched variable */
362
                    size_t *len,  /* OUT - length of matched variable */
363
                    u_short *acl, /* OUT - access control list */
364
                    int exact,    /* IN - TRUE if exact match wanted */
365
                    WriteMethod **write_method,
366
                    struct snmp_pdu *pdu, /* IN - relevant auth info re PDU */
367
                    int *noSuchObject)
368
{
369
    register struct variable *vp;
370
    struct variable     compat_var, *cvp = &compat_var;
371
    register int        x;
372
    u_char              *access = NULL;
373
    int                 result;
374
    oid                 *suffix;
375
    size_t              suffixlen;
376
#if MIB_CLIENTS_ARE_EVIL
377
    oid                 save[MAX_OID_LEN];
378
    size_t              savelen = 0;
379
#endif
380
 
381
            if ( tp->variables == NULL )
382
                return NULL;
383
 
384
            result = compare_tree(name, *namelen, tp->name, tp->namelen);
385
            suffixlen = *namelen - tp->namelen;
386
            suffix = name + tp->namelen;
387
            /* the following is part of the setup for the compatability
388
               structure below that has been moved out of the main loop.
389
             */
390
            memcpy(cvp->name, tp->name, tp->namelen * sizeof(oid));
391
 
392
            *noSuchObject = TRUE;       /* In case of null variables_len */
393
            for(x = 0, vp = tp->variables; x < tp->variables_len;
394
                vp =(struct variable *)((char *)vp +tp->variables_width), x++){
395
                /* if exact and ALWAYS
396
                   if next  and result >= 0 */
397
                /* and if vp->namelen != 0   -- Wes */
398
                if (vp->namelen && (exact || result >= 0)){
399
                    result = compare_tree(suffix, suffixlen, vp->name,
400
                                     vp->namelen);
401
                }
402
                /* if exact and result == 0
403
                   if next  and result <= 0 */
404
                /* or if vp->namelen == 0    -- Wes */
405
                if ((!exact && (result <= 0)) || (exact && (result == 0)) ||
406
                  vp->namelen == 0) {
407
                    /* builds an old (long) style variable structure to retain
408
                       compatability with var_* functions written previously.
409
                     */
410
                  if (vp->namelen)
411
                    memcpy((cvp->name + tp->namelen),
412
                          vp->name, vp->namelen * sizeof(oid));
413
                    cvp->namelen = tp->namelen + vp->namelen;
414
                    cvp->type = vp->type;
415
                    cvp->magic = vp->magic;
416
                    cvp->acl = vp->acl;
417
                    cvp->findVar = vp->findVar;
418
                    *write_method = NULL;
419
#if MIB_CLIENTS_ARE_EVIL
420
                    memcpy(save, name, *namelen*sizeof(oid));
421
                    savelen = *namelen;
422
#endif
423
                    DEBUGMSGTL(("snmp_vars", "Trying variable: "));
424
                    DEBUGMSGOID(("snmp_vars", cvp->name, cvp->namelen));
425
                    DEBUGMSG(("snmp_vars"," ...\n"));
426
 
427
                gaga:
428
                    access = (*(vp->findVar))(cvp, name, namelen, exact,
429
                                                  len, write_method);
430
                    DEBUGMSGTL(("snmp_vars", "Returned %s\n",
431
                                (access==NULL) ? "(null)" : "something" ));
432
 
433
                        /*
434
                         * Check that the answer is acceptable.
435
                         *  i.e. lies within the current subtree chunk
436
                         *
437
                         * It might be worth saving this answer just in
438
                         *  case it turns out to be valid, but for now
439
                         *  we'll simply discard it.
440
                         */
441
                    if ( access && snmp_oid_compare(name, *namelen,
442
                                                    tp->end, tp->end_len) > 0) {
443
                        memcpy(name, tp->end, tp->end_len);
444
                        access = 0;
445
                    }
446
#if MIB_CLIENTS_ARE_EVIL
447
                    if (access == NULL) {
448
                      if (snmp_oid_compare(name, *namelen, save, savelen) != 0) {
449
                        DEBUGMSGTL(("snmp_vars", "evil_client: "));
450
                        DEBUGMSGOID(("snmp_vars", save, savelen));
451
                        DEBUGMSG(("snmp_vars"," =>"));
452
                        DEBUGMSGOID(("snmp_vars", name, *namelen));
453
                        DEBUGMSG(("snmp_vars","\n"));
454
                        memcpy(name, save, savelen*sizeof(oid));
455
                        *namelen = savelen;
456
                      }
457
                    }
458
#endif
459
                    if (*write_method)
460
                        *acl = cvp->acl;
461
                    /* check for permission to view this part of the OID tree */
462
                    if ((access != NULL || (*write_method != NULL && exact)) &&
463
                        in_a_view(name, namelen, pdu, cvp->type)) {
464
                        if ( access && !exact ) {
465
                                /*
466
                                 * We've got an answer, but shouldn't use it.
467
                                 * But we *might* be able to use a later
468
                                 *  instance of the same object, so we can't
469
                                 *  legitimately move on to the next variable
470
                                 *  in the variable structure just yet.
471
                                 * Let's try re-calling the findVar routine
472
                                 *  with the returned name, and see whether
473
                                 *  the next answer is acceptable
474
                                 */
475
                           *write_method = NULL;
476
                           goto gaga;
477
                        }
478
                        access = NULL;
479
                        *write_method = NULL;
480
                    } else if (exact){
481
                        found = TRUE;
482
                    }
483
                    if (access != NULL || (*write_method != NULL && exact))
484
                        break;
485
                }
486
                /* if exact and result <= 0 */
487
                if (exact && (result  <= 0)){
488
                    *type = cvp->type;
489
                    *acl = cvp->acl;
490
                    if (found)
491
                      *noSuchObject = FALSE;
492
                    else
493
                      *noSuchObject = TRUE;
494
                    return NULL;
495
                }
496
            }
497
            if (access != NULL || (exact && *write_method != NULL)) {
498
                *type = cvp->type;
499
                *acl = cvp->acl;
500
                return access;
501
            }
502
            return NULL;
503
}
504
 
505
u_char *
506
getStatPtr(
507
    oid         *name,      /* IN - name of var, OUT - name matched */
508
    size_t      *namelen,   /* IN -number of sub-ids in name,
509
                               OUT - subid-is in matched name */
510
    u_char      *type,      /* OUT - type of matched variable */
511
    size_t      *len,       /* OUT - length of matched variable */
512
    u_short     *acl,       /* OUT - access control list */
513
    int         exact,      /* IN - TRUE if exact match wanted */
514
    WriteMethod **write_method,
515
    struct snmp_pdu *pdu,   /* IN - relevant auth info re PDU */
516
    int         *noSuchObject)
517
{
518
    struct subtree      *tp;
519
    oid                 save[MAX_OID_LEN];
520
    size_t              savelen = 0;
521
    u_char              result_type;
522
    u_short             result_acl;
523
    u_char              *search_return=NULL;
524
 
525
    found = FALSE;
526
 
527
    if (!exact){
528
        memcpy(save, name, *namelen * sizeof(oid));
529
        savelen = *namelen;
530
    }
531
    *write_method = NULL;
532
 
533
    DEBUGMSGTL(("snmp_vars", "Looking for: "));
534
    DEBUGMSGOID(("snmp_vars", name, *namelen));
535
    DEBUGMSG(("snmp_vars"," ...\n"));
536
 
537
    tp = find_subtree(name, *namelen, NULL);
538
 
539
    while ( search_return == NULL && tp != NULL ) {
540
        DEBUGMSGTL(("snmp_vars", "Trying tree: "));
541
        DEBUGMSGOID(("snmp_vars", tp->name, tp->namelen));
542
        DEBUGMSG(("snmp_vars"," ...\n"));
543
        search_return = search_subtree_vars( tp, name, namelen, &result_type,
544
                                        len, &result_acl, exact, write_method,
545
                                        pdu, noSuchObject);
546
        if ( search_return != NULL || exact )
547
            break;
548
        tp = tp->next;
549
    }
550
    if ( tp == NULL ) {
551
        if (!search_return && !exact){
552
            memcpy(name, save, savelen * sizeof(oid));
553
            *namelen = savelen;
554
        }
555
        if (found)
556
            *noSuchObject = FALSE;
557
        else
558
            *noSuchObject = TRUE;
559
        return NULL;
560
    }
561
    *type = result_type;
562
    *acl =  result_acl;
563
    return search_return;
564
}
565
 

powered by: WebSVN 2.1.0

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