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/] [agent_registry.c] - Blame information for rev 307

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ./agent/current/src/agent_registry.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
 * agent_registry.c
94
 *
95
 * Maintain a registry of MIB subtrees, together
96
 *   with related information regarding mibmodule, sessions, etc
97
 */
98
 
99
#define IN_SNMP_VARS_C
100
 
101
#include <config.h>
102
#if HAVE_STRING_H
103
#include <string.h>
104
#endif
105
#if HAVE_STDLIB_H
106
#include <stdlib.h>
107
#endif
108
#include <sys/types.h>
109
#include <stdio.h>
110
#if HAVE_FCNTL_H
111
#include <fcntl.h>
112
#endif
113
#if HAVE_WINSOCK_H
114
#include <winsock.h>
115
#endif
116
#if TIME_WITH_SYS_TIME
117
# ifdef WIN32
118
#  include <sys/timeb.h>
119
# else
120
#  include <sys/time.h>
121
# endif
122
# include <time.h>
123
#else
124
# if HAVE_SYS_TIME_H
125
#  include <sys/time.h>
126
# else
127
#  include <time.h>
128
# endif
129
#endif
130
 
131
#if HAVE_DMALLOC_H
132
#include <dmalloc.h>
133
#endif
134
 
135
#include "mibincl.h"
136
#include "snmp_client.h"
137
#include "default_store.h"
138
#include "ds_agent.h"
139
#include "callback.h"
140
#include "agent_callbacks.h"
141
#include "agent_registry.h"
142
#include "snmp_alarm.h"
143
 
144
#include "snmpd.h"
145
#include "mibgroup/struct.h"
146
#include "mib_module_includes.h"
147
 
148
#ifdef USING_AGENTX_SUBAGENT_MODULE
149
#include "agentx/subagent.h"
150
#include "agentx/client.h"
151
#endif
152
 
153
 
154
struct snmp_index {
155
    struct variable_list        varbind;        /* or pointer to var_list ? */
156
    struct snmp_session         *session;       /* NULL implies unused  ? */
157
    struct snmp_index           *next_oid;
158
    struct snmp_index           *prev_oid;
159
    struct snmp_index           *next_idx;
160
} *snmp_index_head = NULL;
161
struct subtree *subtrees;
162
 
163
int tree_compare(const struct subtree *ap, const struct subtree *bp)
164
{
165
  return snmp_oid_compare(ap->name,ap->namelen,bp->name,bp->namelen);
166
}
167
 
168
 
169
 
170
        /*
171
         *  Split the subtree into two at the specified point,
172
         *    returning the new (second) subtree
173
         */
174
struct subtree *
175
split_subtree(struct subtree *current, oid name[], int name_len )
176
{
177
    struct subtree *new_sub, *ptr;
178
    int i;
179
    char *cp;
180
 
181
    if ( snmp_oid_compare(name, name_len,
182
                          current->end, current->end_len) > 0 )
183
        return NULL;    /* Split comes after the end of this subtree */
184
 
185
    new_sub = (struct subtree *)malloc(sizeof(struct subtree));
186
    if ( new_sub == NULL )
187
        return NULL;
188
    memcpy(new_sub, current, sizeof(struct subtree));
189
 
190
        /* Set up the point of division */
191
    memcpy(current->end,   name, name_len*sizeof(oid));
192
    memcpy(new_sub->start, name, name_len*sizeof(oid));
193
    current->end_len   = name_len;
194
    new_sub->start_len = name_len;
195
 
196
        /*
197
         * Split the variables between the two new subtrees
198
         */
199
    i = current->variables_len;
200
    current->variables_len = 0;
201
 
202
    for ( ; i > 0 ; i-- ) {
203
                /* Note that the variable "name" field omits
204
                   the prefix common to the whole registration,
205
                   hence the strange comparison here */
206
        if ( snmp_oid_compare( new_sub->variables[0].name,
207
                               new_sub->variables[0].namelen,
208
                               name     + current->namelen,
209
                               name_len - current->namelen ) >= 0 )
210
            break;      /* All following variables belong to the second subtree */
211
 
212
        current->variables_len++;
213
        new_sub->variables_len--;
214
        cp = (char *)new_sub->variables;
215
        new_sub->variables = (struct variable *)(cp + new_sub->variables_width);
216
    }
217
 
218
        /* Delegated trees should retain their variables regardless */
219
    if ( current->variables_len > 0 &&
220
                IS_DELEGATED((u_char)current->variables[0].type)) {
221
        new_sub->variables_len = 1;
222
        new_sub->variables     = current->variables;
223
    }
224
 
225
        /* Propogate this split down through any children */
226
    if ( current->children )
227
        new_sub->children = split_subtree(current->children, name, name_len);
228
 
229
        /* Retain the correct linking of the list */
230
    for ( ptr = current ; ptr != NULL ; ptr=ptr->children )
231
          ptr->next = new_sub;
232
    for ( ptr = new_sub ; ptr != NULL ; ptr=ptr->children )
233
          ptr->prev = current;
234
    for ( ptr = new_sub->next ; ptr != NULL ; ptr=ptr->children )
235
          ptr->prev = new_sub;
236
 
237
    return new_sub;
238
}
239
 
240
int
241
load_subtree( struct subtree *new_sub )
242
{
243
    struct subtree *tree1, *tree2, *new2;
244
    struct subtree *prev, *next;
245
    int res;
246
 
247
    if ( new_sub == NULL )
248
        return MIB_REGISTERED_OK;       /* Degenerate case */
249
 
250
                /*
251
                 * Find the subtree that contains the start of
252
                 *  the new subtree (if any)...
253
                 */
254
    tree1 = find_subtree( new_sub->start, new_sub->start_len, NULL );
255
                /*
256
                 * ...and the subtree that follows the new one
257
                 *      (NULL implies this is the final region covered)
258
                 */
259
    if ( tree1 == NULL )
260
        tree2 = find_subtree_next( new_sub->start, new_sub->start_len, NULL );
261
    else
262
        tree2 = tree1->next;
263
 
264
 
265
        /*
266
         * Handle new subtrees that start in virgin territory.
267
         */
268
    if ( tree1 == NULL ) {
269
        new2 = NULL;
270
                /* Is there any overlap with later subtrees ? */
271
        if ( tree2 && snmp_oid_compare( new_sub->end, new_sub->end_len,
272
                                        tree2->start, tree2->start_len ) > 0 )
273
            new2 = split_subtree( new_sub, tree2->start, tree2->start_len );
274
 
275
                /*
276
                 * Link the new subtree (less any overlapping region)
277
                 *  with the list of existing registrations
278
                 */
279
        if ( tree2 ) {
280
            new_sub->prev = tree2->prev;
281
            tree2->prev       = new_sub;
282
        }
283
        else
284
            new_sub->prev = find_subtree_previous( new_sub->start, new_sub->start_len, NULL );
285
 
286
        if ( new_sub->prev )
287
            new_sub->prev->next = new_sub;
288
        else
289
            subtrees = new_sub;
290
 
291
        new_sub->next     = tree2;
292
 
293
                /*
294
                 * If there was any overlap,
295
                 *  recurse to merge in the overlapping region
296
                 *  (including anything that may follow the overlap)
297
                 */
298
        if ( new2 )
299
            return load_subtree( new2 );
300
    }
301
 
302
    else {
303
        /*
304
         *  If the new subtree starts *within* an existing registration
305
         *    (rather than at the same point as it), then split the
306
         *    existing subtree at this point.
307
         */
308
        if ( snmp_oid_compare( new_sub->start, new_sub->start_len,
309
                               tree1->start,   tree1->start_len) != 0 )
310
            tree1 = split_subtree( tree1, new_sub->start, new_sub->start_len);
311
            if ( tree1 == NULL )
312
                return MIB_REGISTRATION_FAILED;
313
 
314
        /*  Now consider the end of this existing subtree:
315
         *      If it matches the new subtree precisely,
316
         *        simply merge the new one into the list of children
317
         *      If it includes the whole of the new subtree,
318
         *        split it at the appropriate point, and merge again
319
         *
320
         *      If the new subtree extends beyond this existing region,
321
         *        split it, and recurse to merge the two parts.
322
         */
323
 
324
         switch ( snmp_oid_compare( new_sub->end, new_sub->end_len,
325
                                    tree1->end,   tree1->end_len))  {
326
 
327
                case -1:        /* Existing subtree contains new one */
328
                        (void) split_subtree( tree1,
329
                                        new_sub->end, new_sub->end_len);
330
                        /* Fall Through */
331
 
332
                case  0: /* The two trees match precisely */
333
                        /*
334
                         * Note: This is the only point where the original
335
                         *       registration OID ("name") is used
336
                         */
337
                        prev = NULL;
338
                        next = tree1;
339
                        while ( next && next->namelen > new_sub->namelen ) {
340
                                prev = next;
341
                                next = next->children;
342
                        }
343
                        while ( next && next->namelen == new_sub->namelen &&
344
                                        next->priority < new_sub->priority ) {
345
                                prev = next;
346
                                next = next->children;
347
                        }
348
                        if ( next &&    next->namelen  == new_sub->namelen &&
349
                                        next->priority == new_sub->priority )
350
                           return MIB_DUPLICATE_REGISTRATION;
351
 
352
                        if ( prev ) {
353
                            new_sub->children = next;
354
                            prev->children    = new_sub;
355
                            new_sub->prev = prev->prev;
356
                            new_sub->next = prev->next;
357
                        }
358
                        else {
359
                            new_sub->children = next;
360
                            new_sub->prev = next->prev;
361
                            new_sub->next = next->next;
362
 
363
                            for ( next = new_sub->next ;
364
                                  next != NULL ;
365
                                  next = next->children )
366
                                        next->prev = new_sub;
367
 
368
                            for ( prev = new_sub->prev ;
369
                                  prev != NULL ;
370
                                  prev = prev->children )
371
                                        prev->next = new_sub;
372
                        }
373
                        break;
374
 
375
                case  1:        /* New subtree contains the existing one */
376
                        new2 = split_subtree( new_sub,
377
                                        tree1->end, tree1->end_len);
378
                        res = load_subtree( new_sub );
379
                        if ( res != MIB_REGISTERED_OK )
380
                            return res;
381
                        return load_subtree( new2 );
382
 
383
         }
384
 
385
    }
386
    return 0;
387
}
388
 
389
 
390
int
391
register_mib_range(const char *moduleName,
392
             struct variable *var,
393
             size_t varsize,
394
             size_t numvars,
395
             oid *mibloc,
396
             size_t mibloclen,
397
             int priority,
398
             int range_subid,
399
             oid range_ubound,
400
             struct snmp_session *ss)
401
{
402
  struct subtree *subtree, *sub2;
403
  int res, i;
404
  struct register_parameters reg_parms;
405
 
406
  subtree = (struct subtree *) malloc(sizeof(struct subtree));
407
  if ( subtree == NULL )
408
    return MIB_REGISTRATION_FAILED;
409
  memset(subtree, 0, sizeof(struct subtree));
410
 
411
  DEBUGMSGTL(("register_mib", "registering \"%s\" at ", moduleName));
412
  DEBUGMSGOID(("register_mib", mibloc, mibloclen));
413
  DEBUGMSG(("register_mib","\n"));
414
 
415
        /*
416
         * Create the new subtree node being registered
417
         */
418
  memcpy(subtree->name, mibloc, mibloclen*sizeof(oid));
419
  subtree->namelen = (u_char) mibloclen;
420
  memcpy(subtree->start, mibloc, mibloclen*sizeof(oid));
421
  subtree->start_len = (u_char) mibloclen;
422
  memcpy(subtree->end, mibloc, mibloclen*sizeof(oid));
423
  subtree->end[ mibloclen-1 ]++;        /* XXX - or use 'variables' info ? */
424
  subtree->end_len = (u_char) mibloclen;
425
  memcpy(subtree->label, moduleName, strlen(moduleName)+1);
426
  if ( var ) {
427
    subtree->variables = (struct variable *) malloc(varsize*numvars);
428
    memcpy(subtree->variables, var, numvars*varsize);
429
    subtree->variables_len = numvars;
430
    subtree->variables_width = varsize;
431
  }
432
  subtree->priority = priority;
433
  subtree->session = ss;
434
  res = load_subtree(subtree);
435
 
436
        /*
437
         * If registering a range,
438
         *   use the first subtree as a template
439
         *   for the rest of the range
440
         */
441
  if (( res == MIB_REGISTERED_OK ) && ( range_subid != 0 )) {
442
    for ( i = mibloc[range_subid-1] +1 ; i < (int)range_ubound ; i++ ) {
443
        sub2 = (struct subtree *) malloc(sizeof(struct subtree));
444
        if ( sub2 == NULL ) {
445
            unregister_mib_range( mibloc, mibloclen, priority,
446
                                  range_subid, range_ubound);
447
            return MIB_REGISTRATION_FAILED;
448
        }
449
        memcpy( sub2, subtree, sizeof(struct subtree));
450
        sub2->start[range_subid-1] = i;
451
        sub2->end[  range_subid-1] = i;         /* XXX - ???? */
452
        res = load_subtree(sub2);
453
        if ( res != MIB_REGISTERED_OK ) {
454
            unregister_mib_range( mibloc, mibloclen, priority,
455
                                  range_subid, range_ubound);
456
            return MIB_REGISTRATION_FAILED;
457
        }
458
    }
459
  }
460
 
461
 
462
  reg_parms.name = mibloc;
463
  reg_parms.namelen = mibloclen;
464
  reg_parms.priority = priority;
465
  reg_parms.range_subid  = range_subid;
466
  reg_parms.range_ubound = range_ubound;
467
  snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_REGISTER_OID,
468
                      &reg_parms);
469
 
470
  return res;
471
}
472
 
473
int
474
register_mib_priority(const char *moduleName,
475
             struct variable *var,
476
             size_t varsize,
477
             size_t numvars,
478
             oid *mibloc,
479
             size_t mibloclen,
480
             int priority)
481
{
482
  return register_mib_range( moduleName, var, varsize, numvars,
483
                                mibloc, mibloclen, priority, 0, 0, NULL );
484
}
485
 
486
int
487
register_mib(const char *moduleName,
488
             struct variable *var,
489
             size_t varsize,
490
             size_t numvars,
491
             oid *mibloc,
492
             size_t mibloclen)
493
{
494
  return register_mib_priority( moduleName, var, varsize, numvars,
495
                                mibloc, mibloclen, DEFAULT_MIB_PRIORITY );
496
}
497
 
498
 
499
void
500
unload_subtree( struct subtree *sub, struct subtree *prev)
501
{
502
    struct subtree *ptr;
503
 
504
    if ( prev != NULL ) {       /* non-leading entries are easy */
505
        prev->children = sub->children;
506
        return;
507
    }
508
                        /* otherwise, we need to amend our neighbours as well */
509
 
510
    if ( sub->children == NULL) {       /* just remove this node completely */
511
        for (ptr = sub->prev ; ptr ; ptr=ptr->children )
512
            ptr->next = sub->next;
513
        for (ptr = sub->next ; ptr ; ptr=ptr->children )
514
            ptr->prev = sub->prev;
515
        return;
516
    }
517
    else {
518
        for (ptr = sub->prev ; ptr ; ptr=ptr->children )
519
            ptr->next = sub->children;
520
        for (ptr = sub->next ; ptr ; ptr=ptr->children )
521
            ptr->prev = sub->children;
522
        return;
523
    }
524
}
525
 
526
int
527
unregister_mib_range( oid *name, size_t len, int priority,
528
                        int range_subid, oid range_ubound)
529
{
530
  struct subtree *list, *myptr;
531
  struct subtree *prev, *child;             /* loop through children */
532
  struct register_parameters reg_parms;
533
 
534
  list = find_subtree( name, len, subtrees );
535
  if ( list == NULL )
536
        return MIB_NO_SUCH_REGISTRATION;
537
 
538
  for ( child=list, prev=NULL;  child != NULL;
539
                                prev=child, child=child->children ) {
540
      if (( snmp_oid_compare( child->name, child->namelen, name, len) == 0 )
541
          && ( child->priority == priority ))
542
                break;  /* found it */
543
  }
544
  if ( child == NULL )
545
        return MIB_NO_SUCH_REGISTRATION;
546
 
547
  unload_subtree( child, prev );
548
  myptr = child;        /* remember this for later */
549
 
550
                /*
551
                 *  Now handle any occurances in the following subtrees,
552
                 *      as a result of splitting this range.  Due to the
553
                 *      nature of the way such splits work, the first
554
                 *      subtree 'slice' that doesn't refer to the given
555
                 *      name marks the end of the original region.
556
                 *
557
                 *  This should also serve to register ranges.
558
                 */
559
 
560
  for ( list = myptr->next ; list != NULL ; list=list->next ) {
561
        for ( child=list, prev=NULL;  child != NULL;
562
                                      prev=child, child=child->children ) {
563
            if (( snmp_oid_compare( child->name, child->namelen,
564
                                                        name, len) == 0 )
565
                && ( child->priority == priority )) {
566
 
567
                    unload_subtree( child, prev );
568
                    free_subtree( child );
569
                    break;
570
            }
571
        }
572
        if ( child == NULL )    /* Didn't find the given name */
573
            break;
574
  }
575
  free_subtree( myptr );
576
 
577
  reg_parms.name = name;
578
  reg_parms.namelen = len;
579
  reg_parms.priority = priority;
580
  reg_parms.range_subid  = range_subid;
581
  reg_parms.range_ubound = range_ubound;
582
  snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREGISTER_OID,
583
                      &reg_parms);
584
 
585
  return MIB_UNREGISTERED_OK;
586
}
587
 
588
int
589
unregister_mib_priority(oid *name, size_t len, int priority)
590
{
591
  return unregister_mib_range( name, len, priority, 0, 0 );
592
}
593
 
594
int
595
unregister_mib(oid *name,
596
               size_t len)
597
{
598
  return unregister_mib_priority( name, len, DEFAULT_MIB_PRIORITY );
599
}
600
 
601
void
602
unregister_mibs_by_session (struct snmp_session *ss)
603
{
604
  struct subtree *list, *list2;
605
  struct subtree *child, *prev, *next_child;
606
 
607
  for( list = subtrees; list != NULL; list = list2) {
608
    list2 = list->next;
609
    for ( child=list, prev=NULL;  child != NULL; child=next_child ) {
610
 
611
      next_child = child->children;
612
      if (( (ss->flags & SNMP_FLAGS_SUBSESSION) && child->session == ss ) ||
613
          (!(ss->flags & SNMP_FLAGS_SUBSESSION) &&
614
                                      child->session->subsession == ss )) {
615
              unload_subtree( child, prev );
616
              free_subtree( child );
617
      }
618
      else
619
          prev = child;
620
    }
621
  }
622
}
623
 
624
 
625
struct subtree *
626
free_subtree(struct subtree *st)
627
{
628
  struct subtree *ret = NULL;
629
  if ((snmp_oid_compare(st->name, st->namelen, st->start, st->start_len) == 0)
630
       && (st->variables != NULL))
631
    free(st->variables);
632
  if (st->next != NULL)
633
    ret = st->next;
634
  free(st);
635
  return ret;
636
}
637
 
638
/* in_a_view: determines if a given snmp_pdu is allowed to see a
639
   given name/namelen OID pointer
640
   name         IN - name of var, OUT - name matched
641
   nameLen      IN -number of sub-ids in name, OUT - subid-is in matched name
642
   pi           IN - relevant auth info re PDU
643
   cvp          IN - relevant auth info re mib module
644
*/
645
 
646
int
647
in_a_view(oid             *name,      /* IN - name of var, OUT - name matched */
648
          size_t          *namelen,   /* IN -number of sub-ids in name*/
649
          struct snmp_pdu *pdu,       /* IN - relevant auth info re PDU */
650
          int              type)      /* IN - variable type being checked */
651
{
652
 
653
  struct view_parameters view_parms;
654
  view_parms.pdu = pdu;
655
  view_parms.name = name;
656
  if (namelen)
657
      view_parms.namelen = *namelen;
658
  else
659
      view_parms.namelen = 0;
660
  view_parms.errorcode = 0;
661
 
662
  if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW)
663
    return 0;            /* Enable bypassing of view-based access control */
664
 
665
  /* check for v1 and counter64s, since snmpv1 doesn't support it */
666
  if (pdu->version == SNMP_VERSION_1 && type == ASN_COUNTER64)
667
    return 5;
668
  switch (pdu->version) {
669
  case SNMP_VERSION_1:
670
  case SNMP_VERSION_2c:
671
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
672
  case SNMP_VERSION_3:
673
#endif
674
    snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK,
675
                        &view_parms);
676
    return view_parms.errorcode;
677
  }
678
  return 1;
679
}
680
 
681
/* in_a_view: determines if a given snmp_pdu is ever going to be allowed to do
682
   anynthing or if it's not going to ever be authenticated. */
683
int
684
check_access(struct snmp_pdu *pdu)      /* IN - pdu being checked */
685
{
686
  struct view_parameters view_parms;
687
  view_parms.pdu = pdu;
688
  view_parms.name = 0;
689
  view_parms.namelen = 0;
690
  view_parms.errorcode = 0;
691
 
692
  if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW)
693
    return 0;            /* Enable bypassing of view-based access control */
694
 
695
  switch (pdu->version) {
696
  case SNMP_VERSION_1:
697
  case SNMP_VERSION_2c:
698
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
699
  case SNMP_VERSION_3:
700
#endif
701
    snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
702
                        SNMPD_CALLBACK_ACM_CHECK_INITIAL,
703
                        &view_parms);
704
    return view_parms.errorcode;
705
  }
706
  return 1;
707
}
708
 
709
/* lexicographical compare two object identifiers.
710
 * Returns -1 if name1 < name2,
711
 *          0 if name1 = name2, or name1 matches name2 for length of name2
712
 *          1 if name1 > name2
713
 *
714
 * Note: snmp_oid_compare checks len2 before last return.
715
 */
716
int
717
compare_tree(const oid *in_name1,
718
             size_t len1,
719
             const oid *in_name2,
720
             size_t len2)
721
{
722
    register int len, res;
723
    register const oid * name1 = in_name1;
724
    register const oid * name2 = in_name2;
725
 
726
    /* len = minimum of len1 and len2 */
727
    if (len1 < len2)
728
        len = len1;
729
    else
730
        len = len2;
731
    /* find first non-matching OID */
732
    while(len-- > 0){
733
        res = *(name1++) - *(name2++);
734
        if (res < 0)
735
            return -1;
736
        if (res > 0)
737
            return 1;
738
    }
739
    /* both OIDs equal up to length of shorter OID */
740
    if (len1 < len2)
741
        return -1;
742
 
743
    /* name1 matches name2 for length of name2, or they are equal */
744
    return 0;
745
}
746
 
747
struct subtree *find_subtree_previous(oid *name,
748
                             size_t len,
749
                             struct subtree *subtree)
750
{
751
  struct subtree *myptr, *previous = NULL;
752
 
753
  if ( subtree )
754
        myptr = subtree;
755
  else
756
        myptr = subtrees;       /* look through everything */
757
 
758
  for( ; myptr != NULL; previous = myptr, myptr = myptr->next) {
759
    if (snmp_oid_compare(name, len, myptr->start, myptr->start_len) < 0)
760
      return previous;
761
  }
762
  return previous;
763
}
764
 
765
struct subtree *find_subtree_next(oid *name,
766
                                  size_t len,
767
                                  struct subtree *subtree)
768
{
769
  struct subtree *myptr = NULL;
770
 
771
  myptr = find_subtree_previous(name, len, subtree);
772
  if ( myptr != NULL ) {
773
     myptr = myptr->next;
774
     while ( myptr && (myptr->variables == NULL || myptr->variables_len == 0) )
775
         myptr = myptr->next;
776
     return myptr;
777
  }
778
  else if (subtree && snmp_oid_compare(name, len, subtree->start, subtree->start_len) < 0)
779
     return subtree;
780
  else
781
     return NULL;
782
}
783
 
784
struct subtree *find_subtree(oid *name,
785
                             size_t len,
786
                             struct subtree *subtree)
787
{
788
  struct subtree *myptr;
789
 
790
  myptr = find_subtree_previous(name, len, subtree);
791
  if (myptr && snmp_oid_compare(name, len, myptr->end, myptr->end_len) < 0)
792
        return myptr;
793
 
794
  return NULL;
795
}
796
 
797
struct snmp_session *get_session_for_oid( oid *name, size_t len)
798
{
799
   struct subtree *myptr;
800
 
801
   myptr = find_subtree_previous(name, len, subtrees);
802
   while ( myptr && myptr->variables == NULL )
803
        myptr = myptr->next;
804
 
805
   if ( myptr == NULL )
806
        return NULL;
807
   else
808
        return myptr->session;
809
}
810
 
811
 
812
 
813
static struct subtree root_subtrees[] = {
814
   { { 0 }, 1 }, /* ccitt */
815
   { { 1 }, 1 },        /*  iso  */
816
   { { 2 }, 1 }         /* joint-ccitt-iso */
817
};
818
 
819
 
820
void setup_tree (void)
821
{
822
#ifdef USING_AGENTX_SUBAGENT_MODULE
823
  int role;
824
 
825
  role = ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE);
826
  ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);
827
#endif
828
 
829
  register_mib("", NULL, 0, 0,
830
        root_subtrees[0].name,  root_subtrees[0].namelen);
831
  register_mib("", NULL, 0, 0,
832
        root_subtrees[1].name,  root_subtrees[1].namelen);
833
  register_mib("", NULL, 0, 0,
834
        root_subtrees[2].name,  root_subtrees[2].namelen);
835
 
836
  /* Support for 'static' subtrees (subtrees_old) has now been dropped */
837
 
838
  /* No longer necessary to sort the mib tree - this is inherent in
839
     the construction of the subtree structure */
840
 
841
#ifdef USING_AGENTX_SUBAGENT_MODULE
842
  ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, role);
843
#endif
844
}
845
 
846
        /*
847
         * Initial support for index allocation
848
         */
849
extern struct snmp_session *main_session;
850
 
851
char *
852
register_string_index( oid *name, size_t name_len, char *cp )
853
{
854
    struct variable_list varbind, *res;
855
 
856
    memset( &varbind, 0, sizeof(struct variable_list));
857
    varbind.type = ASN_OCTET_STR;
858
    snmp_set_var_objid( &varbind, name, name_len );
859
    if ( cp != ANY_STRING_INDEX ) {
860
        snmp_set_var_value( &varbind, (u_char *)cp, strlen(cp) );
861
        res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session );
862
    }
863
    else
864
        res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session );
865
 
866
    if ( res == NULL )
867
        return NULL;
868
    else
869
        return (char *)res->val.string;
870
}
871
 
872
int
873
register_int_index( oid *name, size_t name_len, int val )
874
{
875
    struct variable_list varbind, *res;
876
 
877
    memset( &varbind, 0, sizeof(struct variable_list));
878
    varbind.type = ASN_INTEGER;
879
    snmp_set_var_objid( &varbind, name, name_len );
880
    varbind.val.string = varbind.buf;
881
    if ( val != ANY_INTEGER_INDEX ) {
882
        varbind.val_len = sizeof(long);
883
        *varbind.val.integer = val;
884
        res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session );
885
    }
886
    else
887
        res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session );
888
 
889
    if ( res == NULL )
890
        return -1;
891
    else
892
        return *res->val.integer;
893
}
894
 
895
struct variable_list *
896
register_oid_index( oid *name, size_t name_len,
897
                    oid *value, size_t value_len )
898
{
899
    struct variable_list varbind;
900
 
901
    memset( &varbind, 0, sizeof(struct variable_list));
902
    varbind.type = ASN_OBJECT_ID;
903
    snmp_set_var_objid( &varbind, name, name_len );
904
    if ( value != ANY_OID_INDEX ) {
905
        snmp_set_var_value( &varbind, (u_char*)value, value_len*sizeof(oid) );
906
        return( register_index( &varbind, ALLOCATE_THIS_INDEX, main_session ));
907
    }
908
    else
909
        return( register_index( &varbind, ALLOCATE_ANY_INDEX, main_session ));
910
}
911
 
912
struct variable_list*
913
register_index(struct variable_list *varbind, int flags, struct snmp_session *ss )
914
{
915
    struct snmp_index *new_index, *idxptr, *idxptr2;
916
    struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
917
    int res, res2, i;
918
 
919
#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
920
    if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
921
        return( agentx_register_index( ss, varbind, flags ));
922
#endif
923
                /* Look for the requested OID entry */
924
    prev_oid_ptr = NULL;
925
    prev_idx_ptr = NULL;
926
    res  = 1;
927
    res2 = 1;
928
    for( idxptr = snmp_index_head ; idxptr != NULL;
929
                         prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
930
        if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
931
                                        idxptr->varbind.name,
932
                                        idxptr->varbind.name_length)) <= 0 )
933
                break;
934
    }
935
 
936
                /*  Found the OID - now look at the registered indices */
937
    if ( res == 0 && idxptr ) {
938
        if ( varbind->type != idxptr->varbind.type )
939
            return NULL;                /* wrong type */
940
 
941
                        /*
942
                         * If we've been asked for an arbitrary new value,
943
                         *      then find the end of the list.
944
                         * If we've been asked for any arbitrary value,
945
                         *      then look for an unused entry, and use that.
946
                         *      If there aren't any, continue as for new.
947
                         * Otherwise, locate the given value in the (sorted)
948
                         *      list of already allocated values
949
                         */
950
        if ( flags & ALLOCATE_ANY_INDEX ) {
951
            for(idxptr2 = idxptr ; idxptr2 != NULL;
952
                 prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
953
                if ( flags == ALLOCATE_ANY_INDEX && idxptr2->session == NULL ) {
954
                    idxptr2->session = ss ;
955
                    return &idxptr2->varbind;
956
                }
957
            }
958
        }
959
        else {
960
            for(idxptr2 = idxptr ; idxptr2 != NULL;
961
                 prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
962
                switch ( varbind->type ) {
963
                    case ASN_INTEGER:
964
                        res2 = (*varbind->val.integer - *idxptr2->varbind.val.integer);
965
                        break;
966
                    case ASN_OCTET_STR:
967
                        i = SNMP_MIN(varbind->val_len, idxptr2->varbind.val_len);
968
                        res2 = memcmp(varbind->val.string, idxptr2->varbind.val.string, i);
969
                        break;
970
                    case ASN_OBJECT_ID:
971
                        res2 = snmp_oid_compare(varbind->val.objid, varbind->val_len/sizeof(oid),
972
                                        idxptr2->varbind.val.objid,
973
                                        idxptr2->varbind.val_len/sizeof(oid));
974
                        break;
975
                    default:
976
                        return NULL;            /* wrong type */
977
                }
978
                if ( res2 <= 0 )
979
                    break;
980
            }
981
            if ( res2 == 0 )
982
                return NULL;                    /* duplicate value */
983
        }
984
    }
985
 
986
                /*
987
                 * OK - we've now located where the new entry needs to
988
                 *      be fitted into the index registry tree
989
                 * To recap:
990
                 *      'prev_oid_ptr' points to the head of the OID index
991
                 *          list prior to this one.  If this is null, then
992
                 *          it means that this is the first OID in the list.
993
                 *      'idxptr' points either to the head of this OID list,
994
                 *          or the next OID (if this is a new OID request)
995
                 *          These can be distinguished by the value of 'res'.
996
                 *
997
                 *      'prev_idx_ptr' points to the index entry that sorts
998
                 *          immediately prior to the requested value (if any).
999
                 *          If an arbitrary value is required, then this will
1000
                 *          point to the last allocated index.
1001
                 *          If this pointer is null, then either this is a new
1002
                 *          OID request, or the requested value is the first
1003
                 *          in the list.
1004
                 *      'idxptr2' points to the next sorted index (if any)
1005
                 *          but is not actually needed any more.
1006
                 *
1007
                 *  Clear?  Good!
1008
                 *      I hope you've been paying attention.
1009
                 *          There'll be a test later :-)
1010
                 */
1011
 
1012
                /*
1013
                 *      We proceed by creating the new entry
1014
                 *         (by copying the entry provided)
1015
                 */
1016
        new_index = (struct snmp_index *)malloc( sizeof( struct snmp_index ));
1017
        if (new_index == NULL)
1018
            return NULL;
1019
        if (snmp_clone_var( varbind, &new_index->varbind ) != 0 ) {
1020
            free( new_index );
1021
            return NULL;
1022
        }
1023
        new_index->session = ss;
1024
 
1025
        if ( varbind->type == ASN_OCTET_STR && flags == ALLOCATE_THIS_INDEX )
1026
            new_index->varbind.val.string[new_index->varbind.val_len] = 0;
1027
 
1028
                /*
1029
                 * If we've been given a value, then we can use that, but
1030
                 *    otherwise, we need to create a new value for this entry.
1031
                 * Note that ANY_INDEX and NEW_INDEX are both covered by this
1032
                 *   test (since NEW_INDEX & ANY_INDEX = ANY_INDEX, remember?)
1033
                 */
1034
        if ( flags & ALLOCATE_ANY_INDEX ) {
1035
            if ( prev_idx_ptr ) {
1036
                if ( snmp_clone_var( &prev_idx_ptr->varbind, &new_index->varbind ) != 0 ) {
1037
                    free( new_index );
1038
                    return NULL;
1039
                }
1040
            }
1041
            else
1042
                new_index->varbind.val.string = new_index->varbind.buf;
1043
 
1044
            switch ( varbind->type ) {
1045
                case ASN_INTEGER:
1046
                    if ( prev_idx_ptr ) {
1047
                        (*new_index->varbind.val.integer)++;
1048
                    }
1049
                    else
1050
                        *(new_index->varbind.val.integer) = 1;
1051
                    new_index->varbind.val_len = sizeof(long);
1052
                    break;
1053
                case ASN_OCTET_STR:
1054
                    if ( prev_idx_ptr ) {
1055
                        i =  new_index->varbind.val_len-1;
1056
                        while ( new_index->varbind.buf[ i ] == 'z' ) {
1057
                            new_index->varbind.buf[ i ] = 'a';
1058
                            i--;
1059
                            if ( i < 0 ) {
1060
                                i =  new_index->varbind.val_len;
1061
                                new_index->varbind.buf[ i ] = 'a';
1062
                                new_index->varbind.buf[ i+1 ] = 0;
1063
                            }
1064
                        }
1065
                        new_index->varbind.buf[ i ]++;
1066
                    }
1067
                    else
1068
                        strcpy((char *)new_index->varbind.buf, "aaaa");
1069
                    new_index->varbind.val_len = strlen((char *)new_index->varbind.buf);
1070
                    break;
1071
                case ASN_OBJECT_ID:
1072
                    if ( prev_idx_ptr ) {
1073
                        i =  prev_idx_ptr->varbind.val_len/sizeof(oid) -1;
1074
                        while ( new_index->varbind.val.objid[ i ] == 255 ) {
1075
                            new_index->varbind.val.objid[ i ] = 1;
1076
                            i--;
1077
                            if ( i == 0 && new_index->varbind.val.objid[0] == 2 ) {
1078
                                new_index->varbind.val.objid[ 0 ] = 1;
1079
                                i =  new_index->varbind.val_len/sizeof(oid);
1080
                                new_index->varbind.val.objid[ i ] = 0;
1081
                                new_index->varbind.val_len += sizeof(oid);
1082
                            }
1083
                        }
1084
                        new_index->varbind.val.objid[ i ]++;
1085
                    }
1086
                    else {
1087
                        /* If the requested OID name is small enough,
1088
                         *   append another OID (1) and use this as the
1089
                         *   default starting value for new indexes.
1090
                         */
1091
                        if ( (varbind->name_length+1) * sizeof(oid) <= 40 ) {
1092
                            for ( i = 0 ; i < (int)varbind->name_length ; i++ )
1093
                                new_index->varbind.val.objid[i] = varbind->name[i];
1094
                            new_index->varbind.val.objid[varbind->name_length] = 1;
1095
                            new_index->varbind.val_len =
1096
                                        (varbind->name_length+1) * sizeof(oid);
1097
                        }
1098
                        else {
1099
                            /* Otherwise use '.1.1.1.1...' */
1100
                            i = 40/sizeof(oid);
1101
                            if ( i > 4 )
1102
                                i = 4;
1103
                            new_index->varbind.val_len = i * (sizeof(oid));
1104
                            for (i-- ; i>=0 ; i-- )
1105
                                new_index->varbind.val.objid[i] = 1;
1106
                        }
1107
                    }
1108
                    break;
1109
                default:
1110
                    free( new_index );
1111
                    return NULL;        /* Index type not supported */
1112
            }
1113
        }
1114
 
1115
                /*
1116
                 * Right - we've set up the new entry.
1117
                 * All that remains is to link it into the tree.
1118
                 * There are a number of possible cases here,
1119
                 *   so watch carefully.
1120
                 */
1121
        if ( prev_idx_ptr ) {
1122
            new_index->next_idx = prev_idx_ptr->next_idx;
1123
            new_index->next_oid = prev_idx_ptr->next_oid;
1124
            prev_idx_ptr->next_idx = new_index;
1125
        }
1126
        else {
1127
            if ( res == 0 && idxptr ) {
1128
                new_index->next_idx = idxptr;
1129
                new_index->next_oid = idxptr->next_oid;
1130
            }
1131
            else {
1132
                new_index->next_idx = NULL;
1133
                new_index->next_oid = idxptr;
1134
            }
1135
 
1136
            if ( prev_oid_ptr ) {
1137
                while ( prev_oid_ptr ) {
1138
                    prev_oid_ptr->next_oid = new_index;
1139
                    prev_oid_ptr = prev_oid_ptr->next_idx;
1140
                }
1141
            }
1142
            else
1143
                snmp_index_head = new_index;
1144
        }
1145
    return &new_index->varbind;
1146
}
1147
 
1148
        /*
1149
         * Release an allocated index,
1150
         *   to allow it to be used elsewhere
1151
         */
1152
int
1153
release_index(struct variable_list *varbind)
1154
{
1155
    return( unregister_index( varbind, TRUE, NULL ));
1156
}
1157
 
1158
        /*
1159
         * Completely remove an allocated index,
1160
         *   due to errors in the registration process.
1161
         */
1162
int
1163
remove_index(struct variable_list *varbind, struct snmp_session *ss)
1164
{
1165
    return( unregister_index( varbind, FALSE, ss ));
1166
}
1167
 
1168
void
1169
unregister_index_by_session(struct snmp_session *ss)
1170
{
1171
    struct snmp_index *idxptr, *idxptr2;
1172
    for(idxptr = snmp_index_head ; idxptr != NULL; idxptr = idxptr->next_oid)
1173
        for(idxptr2 = idxptr ; idxptr2 != NULL; idxptr2 = idxptr2->next_idx)
1174
            if ( idxptr2->session == ss )
1175
                idxptr2->session = NULL;
1176
}
1177
 
1178
 
1179
int
1180
unregister_index(struct variable_list *varbind, int remember, struct snmp_session *ss)
1181
{
1182
    struct snmp_index *idxptr, *idxptr2;
1183
    struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
1184
    int res, res2, i;
1185
 
1186
#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
1187
    if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
1188
        return( agentx_unregister_index( ss, varbind ));
1189
#endif
1190
                /* Look for the requested OID entry */
1191
    prev_oid_ptr = NULL;
1192
    prev_idx_ptr = NULL;
1193
    res  = 1;
1194
    res2 = 1;
1195
    for( idxptr = snmp_index_head ; idxptr != NULL;
1196
                         prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
1197
        if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
1198
                                        idxptr->varbind.name,
1199
                                        idxptr->varbind.name_length)) <= 0 )
1200
                break;
1201
    }
1202
 
1203
    if ( res != 0 )
1204
        return INDEX_ERR_NOT_ALLOCATED;
1205
    if ( varbind->type != idxptr->varbind.type )
1206
        return INDEX_ERR_WRONG_TYPE;
1207
 
1208
    for(idxptr2 = idxptr ; idxptr2 != NULL;
1209
                prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
1210
        i = SNMP_MIN(varbind->val_len, idxptr2->varbind.val_len);
1211
        res2 = memcmp(varbind->val.string, idxptr2->varbind.val.string, i);
1212
        if ( res2 <= 0 )
1213
            break;
1214
    }
1215
    if ( res2 != 0 )
1216
        return INDEX_ERR_NOT_ALLOCATED;
1217
    if ( ss != idxptr2->session )
1218
        return INDEX_ERR_WRONG_SESSION;
1219
 
1220
                /*
1221
                 *  If this is a "normal" index unregistration,
1222
                 *      mark the index entry as unused, but leave
1223
                 *      it in situ.  This allows differentiation
1224
                 *      between ANY_INDEX and NEW_INDEX
1225
                 */
1226
    if ( remember ) {
1227
        idxptr2->session = NULL;        /* Unused index */
1228
        return SNMP_ERR_NOERROR;
1229
    }
1230
                /*
1231
                 *  If this is a failed attempt to register a
1232
                 *      number of indexes, the successful ones
1233
                 *      must be removed completely.
1234
                 */
1235
    if ( prev_idx_ptr ) {
1236
        prev_idx_ptr->next_idx = idxptr2->next_idx;
1237
    }
1238
    else if ( prev_oid_ptr ) {
1239
        if ( idxptr2->next_idx )        /* Use p_idx_ptr as a temp variable */
1240
            prev_idx_ptr = idxptr2->next_idx;
1241
        else
1242
            prev_idx_ptr = idxptr2->next_oid;
1243
        while ( prev_oid_ptr ) {
1244
            prev_oid_ptr->next_oid = prev_idx_ptr;
1245
            prev_oid_ptr = prev_oid_ptr->next_idx;
1246
        }
1247
    }
1248
    else {
1249
        if ( idxptr2->next_idx )
1250
            snmp_index_head = idxptr2->next_idx;
1251
        else
1252
            snmp_index_head = idxptr2->next_oid;
1253
    }
1254
    snmp_free_var( (struct variable_list *)idxptr2 );
1255
    return SNMP_ERR_NOERROR;
1256
}
1257
 
1258
 
1259
void dump_registry( void )
1260
{
1261
    struct subtree *myptr, *myptr2;
1262
    struct snmp_index *idxptr, *idxptr2;
1263
    char start_oid[SPRINT_MAX_LEN];
1264
    char end_oid[SPRINT_MAX_LEN];
1265
 
1266
    for( myptr = subtrees ; myptr != NULL; myptr = myptr->next) {
1267
        sprint_objid(start_oid, myptr->start, myptr->start_len);
1268
        sprint_objid(end_oid, myptr->end, myptr->end_len);
1269
        printf("%c %s - %s %c\n",
1270
                ( myptr->variables ? ' ' : '(' ),
1271
                  start_oid, end_oid,
1272
                ( myptr->variables ? ' ' : ')' ));
1273
        for( myptr2 = myptr ; myptr2 != NULL; myptr2 = myptr2->children) {
1274
            if ( myptr2->label && myptr2->label[0] )
1275
                printf("\t%s\n", myptr2->label);
1276
        }
1277
    }
1278
 
1279
    if ( snmp_index_head )
1280
        printf("\nIndex Allocations:\n");
1281
    for( idxptr = snmp_index_head ; idxptr != NULL; idxptr = idxptr->next_oid) {
1282
        sprint_objid(start_oid, idxptr->varbind.name, idxptr->varbind.name_length);
1283
        printf("%s indexes:\n", start_oid);
1284
        for( idxptr2 = idxptr ; idxptr2 != NULL; idxptr2 = idxptr2->next_idx) {
1285
            switch( idxptr2->varbind.type ) {
1286
                case ASN_INTEGER:
1287
                    printf("    %c %ld %c\n",
1288
                        ( idxptr2->session ? ' ' : '(' ),
1289
                          *idxptr2->varbind.val.integer,
1290
                        ( idxptr2->session ? ' ' : ')' ));
1291
                    break;
1292
                case ASN_OCTET_STR:
1293
                    printf("    %c %s %c\n",
1294
                        ( idxptr2->session ? ' ' : '(' ),
1295
                          idxptr2->varbind.val.string,
1296
                        ( idxptr2->session ? ' ' : ')' ));
1297
                    break;
1298
                case ASN_OBJECT_ID:
1299
                    sprint_objid(end_oid, idxptr2->varbind.val.objid,
1300
                                idxptr2->varbind.val_len/sizeof(oid));
1301
                    printf("    %c %s %c\n",
1302
                        ( idxptr2->session ? ' ' : '(' ),
1303
                          end_oid,
1304
                        ( idxptr2->session ? ' ' : ')' ));
1305
                    break;
1306
                default:
1307
                    printf("unsupported type (%d)\n",
1308
                                idxptr2->varbind.type);
1309
            }
1310
        }
1311
    }
1312
}
1313
 
1314
#ifdef TESTING
1315
struct variable_list varbind;
1316
struct snmp_session main_sess, *main_session=&main_sess;
1317
 
1318
void
1319
test_string_register( int n, char *cp )
1320
{
1321
    varbind.name[4] = n;
1322
    if (register_string_index(varbind.name, varbind.name_length, cp) == NULL)
1323
        printf("allocating %s failed\n", cp);
1324
}
1325
 
1326
void
1327
test_int_register( int n, int val )
1328
{
1329
    varbind.name[4] = n;
1330
    if (register_int_index( varbind.name, varbind.name_length, val ) == -1 )
1331
        printf("allocating %d/%d failed\n", n, val);
1332
}
1333
 
1334
void
1335
test_oid_register( int n, int subid )
1336
{
1337
    struct variable_list *res;
1338
 
1339
    varbind.name[4] = n;
1340
    if ( subid != -1 ) {
1341
        varbind.val.objid[5] = subid;
1342
        res = register_oid_index(varbind.name, varbind.name_length,
1343
                    varbind.val.objid,
1344
                    varbind.val_len/sizeof(oid) );
1345
    }
1346
    else
1347
        res = register_oid_index(varbind.name, varbind.name_length, NULL, 0);
1348
 
1349
    if (res == NULL )
1350
        printf("allocating %d/%d failed\n", n, subid);
1351
}
1352
 
1353
void
1354
main( int argc, char argv[] )
1355
{
1356
    oid name[] = { 1, 2, 3, 4, 0 };
1357
    int i;
1358
 
1359
    memset( &varbind, 0, sizeof(struct variable_list));
1360
    snmp_set_var_objid( &varbind, name, 5 );
1361
    varbind.type = ASN_OCTET_STR;
1362
                /*
1363
                 * Test index structure linking:
1364
                 *      a) sorted by OID
1365
                 */
1366
    test_string_register( 20, "empty OID" );
1367
    test_string_register( 10, "first OID" );
1368
    test_string_register( 40, "last OID" );
1369
    test_string_register( 30, "middle OID" );
1370
 
1371
                /*
1372
                 *      b) sorted by index value
1373
                 */
1374
    test_string_register( 25, "eee: empty IDX" );
1375
    test_string_register( 25, "aaa: first IDX" );
1376
    test_string_register( 25, "zzz: last IDX" );
1377
    test_string_register( 25, "mmm: middle IDX" );
1378
    printf("This next one should fail....\n");
1379
    test_string_register( 25, "eee: empty IDX" );       /* duplicate */
1380
    printf("done\n");
1381
 
1382
                /*
1383
                 *      c) test initial index linking
1384
                 */
1385
    test_string_register( 5, "eee: empty initial IDX" );
1386
    test_string_register( 5, "aaa: replace initial IDX" );
1387
 
1388
                /*
1389
                 *      Did it all work?
1390
                 */
1391
    dump_registry();
1392
    unregister_index_by_session( main_session );
1393
                /*
1394
                 *  Now test index allocation
1395
                 *      a) integer values
1396
                 */
1397
    test_int_register( 110, -1 );       /* empty */
1398
    test_int_register( 110, -1 );       /* append */
1399
    test_int_register( 110, 10 );       /* append exact */
1400
    printf("This next one should fail....\n");
1401
    test_int_register( 110, 10 );       /* exact duplicate */
1402
    printf("done\n");
1403
    test_int_register( 110, -1 );       /* append */
1404
    test_int_register( 110,  5 );       /* insert exact */
1405
 
1406
                /*
1407
                 *      b) string values
1408
                 */
1409
    test_string_register( 120, NULL );          /* empty */
1410
    test_string_register( 120, NULL );          /* append */
1411
    test_string_register( 120, "aaaz" );
1412
    test_string_register( 120, NULL );          /* minor rollover */
1413
    test_string_register( 120, "zzzz" );
1414
    test_string_register( 120, NULL );          /* major rollover */
1415
 
1416
                /*
1417
                 *      c) OID values
1418
                 */
1419
 
1420
    test_oid_register( 130, -1 );       /* empty */
1421
    test_oid_register( 130, -1 );       /* append */
1422
 
1423
    varbind.val_len = varbind.name_length*sizeof(oid);
1424
    memcpy( varbind.buf, varbind.name, varbind.val_len);
1425
    varbind.val.objid = (oid*) varbind.buf;
1426
    varbind.val_len += sizeof(oid);
1427
 
1428
    test_oid_register( 130, 255 );      /* append exact */
1429
    test_oid_register( 130, -1 );       /* minor rollover */
1430
    test_oid_register( 130, 100 );      /* insert exact */
1431
    printf("This next one should fail....\n");
1432
    test_oid_register( 130, 100 );      /* exact duplicate */
1433
    printf("done\n");
1434
 
1435
    varbind.val.objid = (oid*)varbind.buf;
1436
    for ( i=0; i<6; i++ )
1437
        varbind.val.objid[i]=255;
1438
    varbind.val.objid[0]=1;
1439
    test_oid_register( 130, 255 );      /* set up rollover  */
1440
    test_oid_register( 130, -1 );       /* medium rollover */
1441
 
1442
    for ( i=0; i<6; i++ )
1443
        varbind.val.objid[i]=255;
1444
    varbind.val.objid[0]=2;
1445
    test_oid_register( 130, 255 );      /* set up rollover  */
1446
    test_oid_register( 130, -1 );       /* major rollover */
1447
 
1448
                /*
1449
                 *      Did it all work?
1450
                 */
1451
    dump_registry();
1452
 
1453
                /*
1454
                 *      Test the various "invalid" requests
1455
                 *      (unsupported types, mis-matched types, etc)
1456
                 */
1457
    printf("The rest of these should fail....\n");
1458
    test_oid_register( 110, -1 );
1459
    test_oid_register( 110, 100 );
1460
    test_oid_register( 120, -1 );
1461
    test_oid_register( 120, 100 );
1462
    test_string_register( 110, NULL );
1463
    test_string_register( 110, "aaaa" );
1464
    test_string_register( 130, NULL );
1465
    test_string_register( 130, "aaaa" );
1466
    test_int_register( 120, -1 );
1467
    test_int_register( 120,  1 );
1468
    test_int_register( 130, -1 );
1469
    test_int_register( 130,  1 );
1470
    printf("done - this dump should be the same as before\n");
1471
    dump_registry();
1472
}
1473
#endif

powered by: WebSVN 2.1.0

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