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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      ./agent/current/src/snmpd.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
 * snmpd.c - rrespond to SNMP queries from management stations
93
 *
94
 */
95
/***********************************************************
96
        Copyright 1988, 1989 by Carnegie Mellon University
97
 
98
                      All Rights Reserved
99
 
100
Permission to use, copy, modify, and distribute this software and its
101
documentation for any purpose and without fee is hereby granted,
102
provided that the above copyright notice appear in all copies and that
103
both that copyright notice and this permission notice appear in
104
supporting documentation, and that the name of CMU not be
105
used in advertising or publicity pertaining to distribution of the
106
software without specific, written prior permission.
107
 
108
CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
109
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
110
CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
111
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
112
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
113
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
114
SOFTWARE.
115
******************************************************************/
116
#include <config.h>
117
 
118
#include <stdio.h>
119
#include <errno.h>
120
#if HAVE_STRING_H
121
#include <string.h>
122
#else
123
#include <strings.h>
124
#endif
125
#if HAVE_STDLIB_H
126
#include <stdlib.h>
127
#endif
128
#if HAVE_UNISTD_H
129
#include <unistd.h>
130
#endif
131
#include <sys/types.h>
132
#if HAVE_NETINET_IN_H
133
#include <netinet/in.h>
134
#endif
135
#if HAVE_ARPA_INET_H
136
#include <arpa/inet.h>
137
#endif
138
#if TIME_WITH_SYS_TIME
139
# ifdef WIN32
140
#  include <sys/timeb.h>
141
# else
142
#  include <sys/time.h>
143
# endif
144
# include <time.h>
145
#else
146
# if HAVE_SYS_TIME_H
147
#  include <sys/time.h>
148
# else
149
#  include <time.h>
150
# endif
151
#endif
152
#if HAVE_SYS_SELECT_H
153
#include <sys/select.h>
154
#endif
155
#if HAVE_SYS_SOCKET_H
156
#include <sys/socket.h>
157
#elif HAVE_WINSOCK_H
158
#include <winsock.h>
159
#endif
160
#if HAVE_NET_IF_H
161
#include <net/if.h>
162
#endif
163
#if HAVE_INET_MIB2_H
164
#include <inet/mib2.h>
165
#endif
166
#if HAVE_SYS_IOCTL_H
167
#include <sys/ioctl.h>
168
#endif
169
#if HAVE_SYS_FILE_H
170
#include <sys/file.h>
171
#endif
172
#if HAVE_FCNTL_H
173
#include <fcntl.h>
174
#endif
175
#if HAVE_SYS_WAIT_H
176
#include <sys/wait.h>
177
#endif
178
#include <signal.h>
179
#ifdef HAVE_SYS_PARAM_H
180
#include <sys/param.h>
181
#endif
182
 
183
#ifndef FD_SET
184
typedef long    fd_mask;
185
#define NFDBITS (sizeof(fd_mask) * NBBY)        /* bits per mask */
186
#define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
187
#define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
188
#define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
189
#define FD_ZERO(p)      memset((p), 0, sizeof(*(p)))
190
#endif
191
 
192
#if HAVE_DMALLOC_H
193
#include <dmalloc.h>
194
#endif
195
 
196
#include "asn1.h"
197
#include "snmp_api.h"
198
#include "snmp_impl.h"
199
#include "system.h"
200
#include "read_config.h"
201
#include "snmp.h"
202
#include "mib.h"
203
#include "m2m.h"
204
#include "snmp_vars.h"
205
#include "agent_read_config.h"
206
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
207
#include "snmpv3.h"
208
#endif
209
#include "callback.h"
210
#include "snmp_alarm.h"
211
#include "default_store.h"
212
#include "mib_module_config.h"
213
 
214
#include "snmp_client.h"
215
#include "snmpd.h"
216
#include "var_struct.h"
217
#include "mibgroup/struct.h"
218
#include "mibgroup/util_funcs.h"
219
#include "snmp_debug.h"
220
#include "mib_modules.h"
221
 
222
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
223
#include "snmpusm.h"
224
#endif
225
#include "tools.h"
226
#include "lcd_time.h"
227
 
228
#include "transform_oids.h"
229
 
230
#include "snmp_agent.h"
231
#include "agent_trap.h"
232
#include "ds_agent.h"
233
#include "agent_read_config.h"
234
#include "snmp_logging.h"
235
 
236
#include "version.h"
237
 
238
#include "mib_module_includes.h"
239
 
240
/*
241
 * Globals.
242
 */
243
#ifdef USE_LIBWRAP
244
#include <tcpd.h>
245
 
246
int allow_severity       = LOG_INFO;
247
int deny_severity        = LOG_WARNING;
248
#endif  /* USE_LIBWRAP */
249
 
250
#define TIMETICK         500000L
251
#define ONE_SEC         1000000L
252
 
253
static int      log_addresses    = 0;
254
int             snmp_dump_packet;
255
static int      running          = 1;
256
static int      reconfig         = 0;
257
 
258
struct addrCache {
259
    in_addr_t   addr;
260
    int         status;
261
#define UNUSED  0
262
#define USED    1
263
#define OLD     2
264
};
265
 
266
#define ADDRCACHE 10
267
 
268
static struct addrCache addrCache[ADDRCACHE];
269
static int              lastAddrAge = 0;
270
 
271
extern char **argvrestartp;
272
extern char  *argvrestart;
273
extern char  *argvrestartname;
274
 
275
#define NUM_SOCKETS     32
276
 
277
#ifdef USING_SMUX_MODULE
278
static int sdlist[NUM_SOCKETS], sdlen = 0;
279
int smux_listen_sd;
280
#endif /* USING_SMUX_MODULE */
281
 
282
/*
283
 * Prototypes.
284
 */
285
int snmp_read_packet (int);
286
int snmp_input (int, struct snmp_session *, int, struct snmp_pdu *, void *);
287
int main (int, char **);
288
static void SnmpTrapNodeDown (void);
289
static int receive(void);
290
int snmp_check_packet(struct snmp_session*, snmp_ipaddr);
291
int snmp_check_parse(struct snmp_session*, struct snmp_pdu*, int);
292
 
293
#if !defined(__ECOS)
294
static void usage(char *prog)
295
{
296
        printf("\nUsage:  %s [-h] [-v] [-f] [-a] [-d] [-V] [-P PIDFILE] [-q] [-D] [-p NUM] [-L] [-l LOGFILE] [-r]",prog);
297
#if HAVE_UNISTD_H
298
        printf(" [-u uid] [-g gid]");
299
#endif
300
        printf("\n");
301
        printf("\n\tVersion:  %s\n",VersionInfo);
302
        printf("\tAuthor:   Wes Hardaker\n");
303
        printf("\tEmail:    ucd-snmp-coders@ucd-snmp.ucdavis.edu\n");
304
        printf("\n-h\t\tThis usage message.\n");
305
        printf("-H\t\tDisplay configuration file directives understood.\n");
306
        printf("-v\t\tVersion information.\n");
307
        printf("-f\t\tDon't fork from the shell.\n");
308
        printf("-a\t\tLog addresses.\n");
309
        printf("-d\t\tDump sent and received UDP SNMP packets\n");
310
        printf("-V\t\tVerbose display\n");
311
        printf("-P PIDFILE\tUse PIDFILE to store process id\n");
312
        printf("-q\t\tPrint information in a more parsable format (quick-print)\n");
313
        printf("-D\t\tTurn on debugging output\n");
314
        printf("-p NUM\t\tRun on port NUM instead of the default:  161\n");
315
        printf("-x SOCKADDR\tBind AgentX to this address\n");
316
        printf("-c CONFFILE\tRead CONFFILE as a configuration file.\n");
317
        printf("-C\t\tDon't read the default configuration files.\n");
318
        printf("-L\t\tPrint warnings/messages to stdout/err\n");
319
        printf("-s\t\tLog warnings/messages to syslog\n");
320
        printf("-A\t\tAppend to the logfile rather than truncating it.\n");
321
        printf("-r Don't exit if root only accessible files can't be opened\n");
322
        printf("-l LOGFILE\tPrint warnings/messages to LOGFILE\n");
323
        printf("\t\t(By default LOGFILE=%s)\n",
324
#ifdef LOGFILE
325
                        LOGFILE
326
#else
327
                        "none"
328
#endif
329
              );
330
#if HAVE_UNISTD_H
331
        printf("-g \t\tChange to this gid after opening port\n");
332
        printf("-u \t\tChange to this uid after opening port\n");
333
#endif
334
        printf("\n");
335
        exit(1);
336
}
337
#endif // !defined(__ECOS)
338
 
339
        RETSIGTYPE
340
SnmpdShutDown(int a)
341
{
342
        running = 0;
343
}
344
 
345
#ifdef SIGHUP
346
        RETSIGTYPE
347
SnmpdReconfig(int a)
348
{
349
        reconfig = 1;
350
        signal(SIGHUP, SnmpdReconfig);
351
}
352
#endif
353
 
354
#ifdef SIGUSR1
355
extern void dump_registry( void );
356
        RETSIGTYPE
357
SnmpdDump(int a)
358
{
359
        dump_registry();
360
        signal(SIGUSR1, SnmpdDump);
361
}
362
#endif
363
 
364
 
365
        static void
366
SnmpTrapNodeDown(void)
367
{
368
    send_easy_trap (SNMP_TRAP_ENTERPRISESPECIFIC, 2);
369
    /* XXX  2 - Node Down #define it as NODE_DOWN_TRAP */
370
}
371
 
372
/*******************************************************************-o-******
373
 * main
374
 *
375
 * Parameters:
376
 *       argc
377
 *      *argv[]
378
 *
379
 * Returns:
380
 *      0        Always succeeds.  (?)
381
 *
382
 *
383
 * Setup and start the agent daemon.
384
 *
385
 * Also successfully EXITs with zero for some options.
386
 */
387
#if !defined(__ECOS)
388
 
389
        int
390
main(int argc, char *argv[])
391
{
392
        int             arg, i;
393
        int             ret;
394
        u_short         dest_port = SNMP_PORT;
395
        int             dont_fork = 0;
396
        char            logfile[SNMP_MAXBUF_SMALL];
397
        char           *cptr, **argvptr;
398
        char           *pid_file = NULL;
399
#if HAVE_GETPID
400
        FILE           *PID;
401
#endif
402
        int             dont_zero_log = 0;
403
        int             stderr_log=0, syslog_log=0;
404
        int             uid=0, gid=0;
405
 
406
        logfile[0]               = 0;
407
 
408
#ifdef LOGFILE
409
        strcpy(logfile, LOGFILE);
410
#endif
411
 
412
 
413
        /*
414
         * usage: snmpd
415
         */
416
        for (arg = 1; arg < argc; arg++)
417
          {
418
            if (argv[arg][0] == '-') {
419
              switch (argv[arg][1]) {
420
 
421
                case 'c':
422
                  if (++arg == argc)
423
                    usage(argv[0]);
424
                  ds_set_string(DS_LIBRARY_ID, DS_LIB_OPTIONALCONFIG,
425
                                 argv[arg]);
426
                  break;
427
 
428
                case 'C':
429
                    ds_set_boolean(DS_LIBRARY_ID, DS_LIB_DONT_READ_CONFIGS, 1);
430
                    break;
431
 
432
                case 'd':
433
                    snmp_set_dump_packet(++snmp_dump_packet);
434
                    ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE, 1);
435
                    break;
436
 
437
                case 'q':
438
                    snmp_set_quick_print(1);
439
                    break;
440
 
441
                case 'T':
442
                    if (argv[arg][2] != '\0')
443
                        cptr = &argv[arg][2];
444
                    else if (++arg>argc) {
445
                        fprintf(stderr,"Need UDP or TCP after -T flag.\n");
446
                        usage(argv[0]);
447
                        exit(1);
448
                    } else {
449
                        cptr = argv[arg];
450
                    }
451
                    if (strcasecmp(cptr,"TCP") == 0) {
452
                        ds_set_int(DS_APPLICATION_ID, DS_AGENT_FLAGS,
453
                                   ds_get_int(DS_APPLICATION_ID, DS_AGENT_FLAGS)
454
                                   | SNMP_FLAGS_STREAM_SOCKET);
455
                    } else if (strcasecmp(cptr,"UDP") == 0) {
456
                        /* default, do nothing */
457
                    } else {
458
                        fprintf(stderr,
459
                                "Unknown transport \"%s\" after -T flag.\n",
460
                                cptr);
461
                        usage(argv[0]);
462
                        exit(1);
463
                    }
464
                    break;
465
 
466
                case 'D':
467
                    debug_register_tokens(&argv[arg][2]);
468
                    snmp_set_do_debugging(1);
469
                    break;
470
 
471
                case 'p':
472
                  if (++arg == argc)
473
                    usage(argv[0]);
474
                  dest_port = atoi(argv[arg]);
475
                  if (dest_port <= 0)
476
                    usage(argv[0]);
477
                  break;
478
 
479
                case 'x':
480
                  if (++arg == argc)
481
                    usage(argv[0]);
482
                  ds_set_string(DS_APPLICATION_ID, DS_AGENT_X_SOCKET, argv[arg]);
483
                  break;
484
 
485
                case 'r':
486
                    ds_set_boolean(DS_APPLICATION_ID,
487
                                      DS_AGENT_NO_ROOT_ACCESS, 1);
488
                    break;
489
 
490
                case 'P':
491
                  if (++arg == argc)
492
                    usage(argv[0]);
493
                  pid_file = argv[arg];
494
 
495
                case 'a':
496
                      log_addresses++;
497
                  break;
498
 
499
                case 'V':
500
                  ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE, 1);
501
                  break;
502
 
503
                case 'f':
504
                  dont_fork = 1;
505
                  break;
506
 
507
                case 'l':
508
                  if (++arg == argc)
509
                    usage(argv[0]);
510
                  strcpy(logfile, argv[arg]);
511
                  break;
512
 
513
                case 'L':
514
                    stderr_log=1;
515
                    break;
516
 
517
                case 's':
518
                    syslog_log=1;
519
                    break;
520
 
521
                case 'A':
522
                    dont_zero_log = 1;
523
                    break;
524
#if HAVE_UNISTD_H
525
                case 'u':
526
                  if (++arg == argc) usage(argv[0]);
527
                  uid = atoi(argv[arg]);
528
                  break;
529
                case 'g':
530
                  if (++arg == argc) usage(argv[0]);
531
                  gid = atoi(argv[arg]);
532
                  break;
533
#endif
534
                case 'h':
535
                  usage(argv[0]);
536
                  break;
537
                case 'H':
538
                  init_agent("snmpd");   /* register our .conf handlers */
539
                  init_mib_modules();
540
                  init_snmp("snmpd");
541
                  fprintf(stderr, "Configuration directives understood:\n");
542
                  read_config_print_usage("  ");
543
                  exit(0);
544
                case 'v':
545
                  printf("\nUCD-snmp version:  %s\n",VersionInfo);
546
                  printf("Author:            Wes Hardaker\n");
547
                  printf("Email:             ucd-snmp-coders@ucd-snmp.ucdavis.edu\n\n");
548
                  exit (0);
549
                case '-':
550
                  switch(argv[arg][2]){
551
                    case 'v':
552
                      printf("\nUCD-snmp version:  %s\n",VersionInfo);
553
                      printf("Author:            Wes Hardaker\n");
554
                      printf("Email:             ucd-snmp-coders@ucd-snmp.ucdavis.edu\n\n");
555
                      exit (0);
556
                    case 'h':
557
                      usage(argv[0]);
558
                      exit(0);
559
                  }
560
 
561
                default:
562
                  printf("invalid option: %s\n", argv[arg]);
563
                  usage(argv[0]);
564
                  break;
565
              }
566
              continue;
567
            }
568
        }  /* end-for */
569
 
570
        /*
571
         * Initialize a argv set to the current for restarting the agent.
572
         */
573
        argvrestartp = (char **) malloc((argc + 2) * sizeof(char *));
574
        argvptr = argvrestartp;
575
        for (i = 0, ret = 1; i < argc; i++) {
576
                ret += strlen(argv[i]) + 1;
577
        }
578
        argvrestart = (char *) malloc(ret);
579
        argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
580
        strcpy(argvrestartname, argv[0]);
581
        if ( strstr(argvrestartname, "agentxd") != NULL)
582
          ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, SUB_AGENT);
583
        else
584
          ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);
585
        for (cptr = argvrestart, i = 0; i < argc; i++) {
586
                strcpy(cptr, argv[i]);
587
                *(argvptr++) = cptr;
588
                cptr += strlen(argv[i]) + 1;
589
        }
590
        *cptr = 0;
591
        *argvptr = NULL;
592
 
593
 
594
        /*
595
         * Open the logfile if necessary.
596
         */
597
 
598
        /* Should open logfile and/or syslog based on arguments */
599
        if (logfile[0])
600
                snmp_enable_filelog(logfile, dont_zero_log);
601
        if (syslog_log)
602
                snmp_enable_syslog();
603
#ifdef BUFSIZ
604
        setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
605
#endif
606
    /*
607
     * Initialize the world.  Detach from the shell.
608
     * Create initial user.
609
     */
610
#if HAVE_FORK
611
    if (!dont_fork && fork() != 0) {
612
      exit(0);
613
    }
614
#endif
615
 
616
#if HAVE_GETPID
617
    if (pid_file != NULL) {
618
      if ((PID = fopen(pid_file, "w")) == NULL) {
619
        snmp_log_perror("fopen");
620
        if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
621
          exit(1);
622
      }
623
      else {
624
        fprintf(PID, "%d\n", (int)getpid());
625
        fclose(PID);
626
      }
627
    }
628
#endif
629
 
630
#else /* __ECOS environment: */
631
void snmpd( void *initfunc( void ) ) {
632
    int             ret;
633
    u_short         dest_port = SNMP_PORT;
634
#define stderr_log 1
635
#endif
636
 
637
    // ---------
638
    // En-bloc reinitialization of statics.
639
    running = 1;
640
    // ---------
641
 
642
    SOCK_STARTUP;
643
    init_agent("snmpd");                /* do what we need to do first. */
644
    init_mib_modules();
645
 
646
 
647
    /* start library */
648
    init_snmp("snmpd");
649
 
650
    ret = init_master_agent( dest_port,
651
                       snmp_check_packet,
652
                       snmp_check_parse );
653
        if( ret != 0 )
654
                Exit(1); /* Exit logs exit val for us */
655
 
656
#ifdef SIGTERM
657
    signal(SIGTERM, SnmpdShutDown);
658
#endif
659
#ifdef SIGINT
660
    signal(SIGINT, SnmpdShutDown);
661
#endif
662
#ifdef SIGHUP
663
    signal(SIGHUP, SnmpdReconfig);
664
#endif
665
#ifdef SIGUSR1
666
    signal(SIGUSR1, SnmpdDump);
667
#endif
668
 
669
    /* send coldstart trap via snmptrap(1) if possible */
670
    send_easy_trap (0, 0);
671
 
672
#if HAVE_UNISTD_H
673
        if (gid) {
674
                DEBUGMSGTL(("snmpd", "Changing gid to %d.\n", gid));
675
                if (setgid(gid)==-1) {
676
                        snmp_log_perror("setgid failed");
677
                        if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
678
                          exit(1);
679
                }
680
        }
681
        if (uid) {
682
                DEBUGMSGTL(("snmpd", "Changing uid to %d.\n", uid));
683
                if(setuid(uid)==-1) {
684
                        snmp_log_perror("setuid failed");
685
                        if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
686
                          exit(1);
687
                }
688
        }
689
#endif
690
 
691
        /* honor selection of standard error output */
692
        if (!stderr_log)
693
                snmp_disable_stderrlog();
694
 
695
        /* we're up, log our version number */
696
        snmp_log(LOG_INFO, "UCD-SNMP version %s\n", VersionInfo);
697
 
698
        memset(addrCache, 0, sizeof(addrCache));
699
 
700
        /*
701
         * Call initialization function if necessary
702
         */
703
        DEBUGMSGTL(("snmpd", "Calling initfunc().\n"));
704
        if ( initfunc )
705
            (initfunc)();
706
 
707
        /*
708
         * Forever monitor the dest_port for incoming PDUs.
709
         */
710
        DEBUGMSGTL(("snmpd", "We're up.  Starting to process data.\n"));
711
        receive();
712
#include "mib_module_shutdown.h"
713
        DEBUGMSGTL(("snmpd", "sending shutdown trap\n"));
714
        SnmpTrapNodeDown();
715
        DEBUGMSGTL(("snmpd", "Bye...\n"));
716
        snmp_shutdown("snmpd");
717
 
718
}  /* End main() -- snmpd */
719
 
720
/*******************************************************************-o-******
721
 * receive
722
 *
723
 * Parameters:
724
 *
725
 * Returns:
726
 *      0        On success.
727
 *      -1      System error.
728
 *
729
 * Infinite while-loop which monitors incoming messges for the agent.
730
 * Invoke the established message handlers for incoming messages on a per
731
 * port basis.  Handle timeouts.
732
 */
733
        static int
734
receive(void)
735
{
736
    int numfds;
737
    fd_set fdset;
738
    struct timeval      timeout, *tvp = &timeout;
739
    struct timeval      sched,   *svp = &sched,
740
                        now,     *nvp = &now;
741
    int count, block;
742
#ifdef  USING_SMUX_MODULE
743
    int i, sd;
744
#endif  /* USING_SMUX_MODULE */
745
 
746
 
747
    /*
748
     * Set the 'sched'uled timeout to the current time + one TIMETICK.
749
     */
750
    gettimeofday(nvp, (struct timezone *) NULL);
751
    svp->tv_usec = nvp->tv_usec + TIMETICK;
752
    svp->tv_sec = nvp->tv_sec;
753
 
754
    while (svp->tv_usec >= ONE_SEC){
755
        svp->tv_usec -= ONE_SEC;
756
        svp->tv_sec++;
757
    }
758
 
759
    /*
760
     * Loop-forever: execute message handlers for sockets with data,
761
     * reset the 'sched'uler.
762
     */
763
    while (running) {
764
        if (reconfig) {
765
          reconfig = 0;
766
          snmp_log(LOG_INFO, "Reconfiguring daemon\n");
767
          update_config();
768
        }
769
        tvp =  &timeout;
770
        tvp->tv_sec = 0;
771
        tvp->tv_usec = TIMETICK;
772
 
773
        numfds = 0;
774
        FD_ZERO(&fdset);
775
        block = 0;
776
        snmp_select_info(&numfds, &fdset, tvp, &block);
777
        if (block == 1)
778
            tvp = NULL; /* block without timeout */
779
 
780
#ifdef  USING_SMUX_MODULE
781
                if (smux_listen_sd >= 0) {
782
                        FD_SET(smux_listen_sd, &fdset);
783
                        numfds = smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;
784
                        for (i = 0; i < sdlen; i++) {
785
                                FD_SET(sdlist[i], &fdset);
786
                                numfds = sdlist[i] >= numfds ? sdlist[i] + 1 : numfds;
787
                        }
788
                }
789
#endif  /* USING_SMUX_MODULE */
790
 
791
        count = select(numfds, &fdset, 0, 0, tvp);
792
 
793
        if (count > 0){
794
            snmp_read(&fdset);
795
        } else switch(count){
796
            case 0:
797
                snmp_timeout();
798
                break;
799
            case -1:
800
                if (errno == EINTR){
801
                    continue;
802
                } else {
803
                    snmp_log_perror("select");
804
                }
805
                return -1;
806
            default:
807
                snmp_log(LOG_ERR, "select returned %d\n", count);
808
                return -1;
809
        }  /* endif -- count>0 */
810
 
811
#ifdef  USING_SMUX_MODULE
812
                /* handle the SMUX sd's */
813
                if (smux_listen_sd >= 0) {
814
                        for (i = 0; i < sdlen; i++) {
815
                                if (FD_ISSET(sdlist[i], &fdset)) {
816
                                        if (smux_process(sdlist[i]) < 0) {
817
                                                for (; i < (sdlen - 1); i++) {
818
                                                        sdlist[i] = sdlist[i+1];
819
                                                }
820
                                                sdlen--;
821
                                        }
822
                                }
823
                        }
824
                        /* new connection */
825
                        if (FD_ISSET(smux_listen_sd, &fdset)) {
826
                                if ((sd = smux_accept(smux_listen_sd)) >= 0) {
827
                                        sdlist[sdlen++] = sd;
828
                                }
829
                        }
830
                }
831
#endif  /* USING_SMUX_MODULE */
832
 
833
 
834
 
835
        /*
836
         * If the time 'now' is greater than the 'sched'uled time, then:
837
         *
838
         *    Check alarm and event timers.
839
         *    Reset the 'sched'uled time to current time + one TIMETICK.
840
         *    Age the cache network addresses (from whom messges have
841
         *        been received).
842
         */
843
        gettimeofday(nvp, (struct timezone *) NULL);
844
 
845
        if (nvp->tv_sec > svp->tv_sec
846
                || (nvp->tv_sec == svp->tv_sec && nvp->tv_usec > svp->tv_usec)){
847
            svp->tv_usec = nvp->tv_usec + TIMETICK;
848
            svp->tv_sec = nvp->tv_sec;
849
 
850
            while (svp->tv_usec >= ONE_SEC){
851
                svp->tv_usec -= ONE_SEC;
852
                svp->tv_sec++;
853
            }
854
            if (log_addresses && lastAddrAge++ > 600){
855
 
856
                lastAddrAge = 0;
857
                for(count = 0; count < ADDRCACHE; count++){
858
                    if (addrCache[count].status == OLD)
859
                        addrCache[count].status = UNUSED;
860
                    if (addrCache[count].status == USED)
861
                        addrCache[count].status = OLD;
862
                }
863
            }
864
        }  /* endif -- now>sched */
865
 
866
        /* run requested alarms */
867
        run_alarms();
868
 
869
    }  /* endwhile */
870
 
871
    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
872
    return 0;
873
 
874
}  /* end receive() */
875
 
876
 
877
 
878
 
879
/*******************************************************************-o-******
880
 * snmp_check_packet
881
 *
882
 * Parameters:
883
 *      session, from
884
 *
885
 * Returns:
886
 *      1       On success.
887
 *      0        On error.
888
 *
889
 * Handler for all incoming messages (a.k.a. packets) for the agent.  If using
890
 * the libwrap utility, log the connection and deny/allow the access. Print
891
 * output when appropriate, and increment the incoming counter.
892
 *
893
 */
894
int
895
snmp_check_packet(struct snmp_session *session,
896
  snmp_ipaddr from)
897
{
898
    struct sockaddr_in *fromIp = (struct sockaddr_in *)&from;
899
 
900
#ifdef USE_LIBWRAP
901
    const char *addr_string;
902
    /*
903
     * Log the message and/or dump the message.
904
     * Optionally cache the network address of the sender.
905
     */
906
    addr_string = inet_ntoa(fromIp->sin_addr);
907
 
908
    if(!addr_string) {
909
      addr_string = STRING_UNKNOWN;
910
    }
911
    if(hosts_ctl("snmpd", addr_string, addr_string, STRING_UNKNOWN)) {
912
      snmp_log(allow_severity, "Connection from %s\n", addr_string);
913
    } else {
914
      snmp_log(deny_severity, "Connection from %s REFUSED\n", addr_string);
915
      return(0);
916
    }
917
#endif  /* USE_LIBWRAP */
918
 
919
    snmp_increment_statistic(STAT_SNMPINPKTS);
920
 
921
    if (log_addresses || ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE)){
922
        int count;
923
 
924
        for(count = 0; count < ADDRCACHE; count++){
925
            if (addrCache[count].status > UNUSED /* used or old */
926
                && fromIp->sin_addr.s_addr == addrCache[count].addr)
927
                break;
928
        }
929
 
930
        if (count >= ADDRCACHE ||
931
            ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE)){
932
            snmp_log(LOG_INFO, "Received SNMP packet(s) from %s\n",
933
                        inet_ntoa(fromIp->sin_addr));
934
            for(count = 0; count < ADDRCACHE; count++){
935
                if (addrCache[count].status == UNUSED){
936
                    addrCache[count].addr = fromIp->sin_addr.s_addr;
937
                    addrCache[count].status = USED;
938
                    break;
939
                }
940
            }
941
        } else {
942
            addrCache[count].status = USED;
943
        }
944
    }
945
 
946
    return ( 1 );
947
}
948
 
949
 
950
int
951
snmp_check_parse( struct snmp_session *session,
952
    struct snmp_pdu     *pdu,
953
    int    result)
954
{
955
    if ( result == 0 ) {
956
        if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE) &&
957
             snmp_get_do_logging() ) {
958
             char c_oid [SPRINT_MAX_LEN];
959
             struct variable_list *var_ptr;
960
 
961
            switch (pdu->command) {
962
            case SNMP_MSG_GET:
963
                snmp_log(LOG_DEBUG, "  GET message\n"); break;
964
            case SNMP_MSG_GETNEXT:
965
                snmp_log(LOG_DEBUG, "  GETNEXT message\n"); break;
966
            case SNMP_MSG_RESPONSE:
967
                snmp_log(LOG_DEBUG, "  RESPONSE message\n"); break;
968
            case SNMP_MSG_SET:
969
                snmp_log(LOG_DEBUG, "  SET message\n"); break;
970
            case SNMP_MSG_TRAP:
971
                snmp_log(LOG_DEBUG, "  TRAP message\n"); break;
972
            case SNMP_MSG_GETBULK:
973
                snmp_log(LOG_DEBUG, "  GETBULK message, non-rep=%d, max_rep=%d\n",
974
                        pdu->errstat, pdu->errindex); break;
975
            case SNMP_MSG_INFORM:
976
                snmp_log(LOG_DEBUG, "  INFORM message\n"); break;
977
            case SNMP_MSG_TRAP2:
978
                snmp_log(LOG_DEBUG, "  TRAP2 message\n"); break;
979
            case SNMP_MSG_REPORT:
980
                snmp_log(LOG_DEBUG, "  REPORT message\n"); break;
981
            }
982
 
983
            for ( var_ptr = pdu->variables ;
984
                var_ptr != NULL ; var_ptr=var_ptr->next_variable )
985
            {
986
                sprint_objid (c_oid, var_ptr->name, var_ptr->name_length);
987
                snmp_log(LOG_DEBUG, "    -- %s\n", c_oid);
988
            }
989
        }
990
        return 1;
991
    }
992
    return 0; /* XXX: does it matter what the return value is? */
993
}
994
 
995
/*******************************************************************-o-******
996
 * snmp_input
997
 *
998
 * Parameters:
999
 *       op
1000
 *      *session
1001
 *       requid
1002
 *      *pdu
1003
 *      *magic
1004
 *
1005
 * Returns:
1006
 *      1               On success      -OR-
1007
 *      Passes through  Return from alarmGetResponse() when
1008
 *                        USING_V2PARTY_ALARM_MODULE is defined.
1009
 *
1010
 * Call-back function to manage responses to traps (informs) and alarms.
1011
 * Not used by the agent to process other Response PDUs.
1012
 */
1013
int
1014
snmp_input(int op,
1015
           struct snmp_session *session,
1016
           int reqid,
1017
           struct snmp_pdu *pdu,
1018
           void *magic)
1019
{
1020
    struct get_req_state *state = (struct get_req_state *)magic;
1021
 
1022
    if (op == RECEIVED_MESSAGE) {
1023
        if (pdu->command == SNMP_MSG_GET) {
1024
            if (state->type == EVENT_GET_REQ) {
1025
                /* this is just the ack to our inform pdu */
1026
                return 1;
1027
            }
1028
        }
1029
    }
1030
    else if (op == TIMED_OUT) {
1031
        if (state->type == ALARM_GET_REQ) {
1032
                /* Need a mechanism to replace obsolete SNMPv2p alarm */
1033
        }
1034
    }
1035
    return 1;
1036
 
1037
}  /* end snmp_input() */

powered by: WebSVN 2.1.0

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