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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [snmp/] [agent/] [current/] [src/] [snmp_vars.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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