00001
00002
00003
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <net-snmp/net-snmp-config.h>
00039
00040 #if HAVE_IO_H
00041 #include <io.h>
00042 #endif
00043 #include <stdio.h>
00044 #include <errno.h>
00045 #if HAVE_STRING_H
00046 #include <string.h>
00047 #else
00048 #include <strings.h>
00049 #endif
00050 #if HAVE_STDLIB_H
00051 #include <stdlib.h>
00052 #endif
00053 #if HAVE_UNISTD_H
00054 #include <unistd.h>
00055 #endif
00056 #include <sys/types.h>
00057 #if HAVE_NETINET_IN_H
00058 #include <netinet/in.h>
00059 #endif
00060 #if HAVE_ARPA_INET_H
00061 #include <arpa/inet.h>
00062 #endif
00063 #if TIME_WITH_SYS_TIME
00064 # ifdef WIN32
00065 # include <sys/timeb.h>
00066 # else
00067 # include <sys/time.h>
00068 # endif
00069 # include <time.h>
00070 #else
00071 # if HAVE_SYS_TIME_H
00072 # include <sys/time.h>
00073 # else
00074 # include <time.h>
00075 # endif
00076 #endif
00077 #if HAVE_SYS_SELECT_H
00078 #include <sys/select.h>
00079 #endif
00080 #if HAVE_SYS_SOCKET_H
00081 #include <sys/socket.h>
00082 #elif HAVE_WINSOCK_H
00083 #include <winsock.h>
00084 #endif
00085 #if HAVE_NET_IF_H
00086 #include <net/if.h>
00087 #endif
00088 #if HAVE_INET_MIB2_H
00089 #include <inet/mib2.h>
00090 #endif
00091 #if HAVE_SYS_IOCTL_H
00092 #include <sys/ioctl.h>
00093 #endif
00094 #if HAVE_SYS_FILE_H
00095 #include <sys/file.h>
00096 #endif
00097 #ifdef HAVE_FCNTL_H
00098 #include <fcntl.h>
00099 #endif
00100 #if HAVE_SYS_WAIT_H
00101 #include <sys/wait.h>
00102 #endif
00103 #include <signal.h>
00104 #ifdef HAVE_SYS_PARAM_H
00105 #include <sys/param.h>
00106 #endif
00107 #if HAVE_PROCESS_H
00108 #include <process.h>
00109 #endif
00110 #if HAVE_LIMITS_H
00111 #include <limits.h>
00112 #endif
00113 #if HAVE_PWD_H
00114 #include <pwd.h>
00115 #endif
00116 #if HAVE_GRP_H
00117 #include <grp.h>
00118 #endif
00119
00120 #ifndef PATH_MAX
00121 # ifdef _POSIX_PATH_MAX
00122 # define PATH_MAX _POSIX_PATH_MAX
00123 # else
00124 # define PATH_MAX 255
00125 # endif
00126 #endif
00127
00128 #ifndef FD_SET
00129 typedef long fd_mask;
00130 #define NFDBITS (sizeof(fd_mask) * NBBY)
00131 #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
00132 #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
00133 #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
00134 #define FD_ZERO(p) memset((p), 0, sizeof(*(p)))
00135 #endif
00136
00137 #include <net-snmp/net-snmp-includes.h>
00138 #include <net-snmp/agent/net-snmp-agent-includes.h>
00139
00140 #include <net-snmp/library/fd_event_manager.h>
00141
00142 #include "m2m.h"
00143 #include <net-snmp/agent/mib_module_config.h>
00144
00145 #include "snmpd.h"
00146 #include "mibgroup/struct.h"
00147 #include <net-snmp/agent/mib_modules.h>
00148
00149 #include "mibgroup/util_funcs.h"
00150
00151 #include <net-snmp/agent/agent_trap.h>
00152
00153 #include <net-snmp/agent/table.h>
00154 #include <net-snmp/agent/table_iterator.h>
00155 #include "mib_module_includes.h"
00156
00157
00158
00159
00160 #ifdef WIN32
00161 #include <windows.h>
00162 #include <tchar.h>
00163 #include <net-snmp/library/winservice.h>
00164
00165 #define WIN32SERVICE
00166
00167 #endif
00168
00169
00170
00171
00172 #ifdef NETSNMP_USE_LIBWRAP
00173 #include <tcpd.h>
00174 #endif
00175
00176 #define TIMETICK 500000L
00177
00178 int snmp_dump_packet;
00179 int reconfig = 0;
00180 int Facility = LOG_DAEMON;
00181
00182 #ifdef WIN32SERVICE
00183
00184
00185
00186 #define AGENT_RUNNING 1
00187 #define AGENT_STOPPED 0
00188 int agent_status = AGENT_STOPPED;
00189
00190 LPTSTR app_name_long = _T("Net-SNMP Agent");
00191 #endif
00192
00193 const char *app_name = "snmpd";
00194
00195 extern int netsnmp_running;
00196 extern char **argvrestartp;
00197 extern char *argvrestart;
00198 extern char *argvrestartname;
00199
00200 #ifdef USING_SMUX_MODULE
00201 #include <mibgroup/smux/smux.h>
00202 #endif
00203
00204
00205
00206
00207 int snmp_read_packet(int);
00208 int snmp_input(int, netsnmp_session *, int, netsnmp_pdu *,
00209 void *);
00210 static void usage(char *);
00211 static void SnmpTrapNodeDown(void);
00212 static int receive(void);
00213 #ifdef WIN32SERVICE
00214 void StopSnmpAgent(void);
00215 int SnmpDaemonMain(int argc, TCHAR * argv[]);
00216 int __cdecl _tmain(int argc, TCHAR * argv[]);
00217 #else
00218 int main(int, char **);
00219 #endif
00220
00221
00222
00223
00224 #ifndef LOG_CONS
00225 #define LOG_CONS 0
00226 #endif
00227 #ifndef LOG_PID
00228 #define LOG_PID 0
00229 #endif
00230 #ifndef LOG_LOCAL0
00231 #define LOG_LOCAL0 0
00232 #endif
00233 #ifndef LOG_LOCAL1
00234 #define LOG_LOCAL1 0
00235 #endif
00236 #ifndef LOG_LOCAL2
00237 #define LOG_LOCAL2 0
00238 #endif
00239 #ifndef LOG_LOCAL3
00240 #define LOG_LOCAL3 0
00241 #endif
00242 #ifndef LOG_LOCAL4
00243 #define LOG_LOCAL4 0
00244 #endif
00245 #ifndef LOG_LOCAL5
00246 #define LOG_LOCAL5 0
00247 #endif
00248 #ifndef LOG_LOCAL6
00249 #define LOG_LOCAL6 0
00250 #endif
00251 #ifndef LOG_LOCAL7
00252 #define LOG_LOCAL7 0
00253 #endif
00254 #ifndef LOG_DAEMON
00255 #define LOG_DAEMON 0
00256 #endif
00257
00258
00259 static void
00260 usage(char *prog)
00261 {
00262 #ifdef WIN32SERVICE
00263 printf("\nUsage: %s [-register] [-quiet] [OPTIONS] [LISTENING ADDRESSES]",
00264 prog);
00265 printf("\n %s [-unregister] [-quiet]", prog);
00266 #else
00267 printf("\nUsage: %s [OPTIONS] [LISTENING ADDRESSES]", prog);
00268 #endif
00269 printf("\n");
00270 printf("\n\tVersion: %s\n", netsnmp_get_version());
00271 printf("\tWeb: http://www.net-snmp.org/\n");
00272 printf("\tEmail: net-snmp-coders@lists.sourceforge.net\n");
00273 printf("\n -a\t\t\tlog addresses\n");
00274 printf(" -A\t\t\tappend to the logfile rather than truncating it\n");
00275 printf(" -c FILE[,...]\t\tread FILE(s) as configuration file(s)\n");
00276 printf(" -C\t\t\tdo not read the default configuration files\n");
00277 printf(" -d\t\t\tdump sent and received SNMP packets\n");
00278 printf(" -D TOKEN[,...]\tturn on debugging output for the given TOKEN(s)\n"
00279 "\t\t\t (try ALL for extremely verbose output)\n");
00280 printf(" -f\t\t\tdo not fork from the shell\n");
00281 #if HAVE_UNISTD_H
00282 printf(" -g GID\t\tchange to this numeric gid after opening\n"
00283 "\t\t\t transport endpoints\n");
00284 #endif
00285 printf(" -h, --help\t\tdisplay this usage message\n");
00286 printf(" -H\t\t\tdisplay configuration file directives understood\n");
00287 printf(" -I [-]INITLIST\tlist of mib modules to initialize (or not)\n");
00288 printf("\t\t\t (run snmpd with -Dmib_init for a list)\n");
00289 printf(" -L <LOGOPTS>\t\ttoggle options controlling where to log to\n");
00290 snmp_log_options_usage("\t", stdout);
00291 printf(" -m MIBLIST\t\tuse MIBLIST instead of the default MIB list\n");
00292 printf(" -M DIRLIST\t\tuse DIRLIST as the list of locations\n\t\t\t to look for MIBs\n");
00293 printf(" -p FILE\t\tstore process id in FILE\n");
00294 printf(" -q\t\t\tprint information in a more parsable format\n");
00295 printf(" -r\t\t\tdo not exit if files only accessible to root\n"
00296 "\t\t\t cannot be opened\n");
00297 #ifdef WIN32SERVICE
00298 printf(" -register\t\tregister as a Windows service\n");
00299 printf(" \t\t\t (followed by -quiet to prevent message popups)\n");
00300 printf(" \t\t\t (followed by the startup parameter list)\n");
00301 printf(" \t\t\t Note that some parameters are not relevant when running as a service\n");
00302 #endif
00303 #if HAVE_UNISTD_H
00304 printf(" -u UID\t\tchange to this uid (numeric or textual) after\n"
00305 "\t\t\t opening transport endpoints\n");
00306 #endif
00307 #ifdef WIN32SERVICE
00308 printf(" -unregister\t\tunregister as a Windows service\n");
00309 printf(" \t\t\t (followed -quiet to prevent message popups)\n");
00310 #endif
00311 printf(" -v, --version\t\tdisplay version information\n");
00312 printf(" -V\t\t\tverbose display\n");
00313 #if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
00314 printf(" -x ADDRESS\t\tuse ADDRESS as AgentX address\n");
00315 #endif
00316 #ifdef USING_AGENTX_SUBAGENT_MODULE
00317 printf(" -X\t\t\trun as an AgentX subagent rather than as an\n"
00318 "\t\t\t SNMP master agent\n");
00319 #endif
00320
00321 printf("\nDeprecated options:\n");
00322 printf(" -l FILE\t\tuse -Lf <FILE> instead\n");
00323 printf(" -P\t\t\tuse -p instead\n");
00324 printf(" -s\t\t\tuse -Lsd instead\n");
00325 printf(" -S d|i|0-7\t\tuse -Ls <facility> instead\n");
00326
00327 printf("\n");
00328 exit(1);
00329 }
00330
00331 static void
00332 version(void)
00333 {
00334 printf("\nNET-SNMP version: %s\n", netsnmp_get_version());
00335 printf("Web: http://www.net-snmp.org/\n");
00336 printf("Email: net-snmp-coders@lists.sourceforge.net\n\n");
00337 exit(0);
00338 }
00339
00340 RETSIGTYPE
00341 SnmpdShutDown(int a)
00342 {
00343 #ifdef WIN32SERVICE
00344 extern netsnmp_session *main_session;
00345 #endif
00346 netsnmp_running = 0;
00347 #ifdef WIN32SERVICE
00348
00349
00350
00351
00352
00353 snmp_close(main_session);
00354 #endif
00355 }
00356
00357 #ifdef SIGHUP
00358 RETSIGTYPE
00359 SnmpdReconfig(int a)
00360 {
00361 reconfig = 1;
00362 signal(SIGHUP, SnmpdReconfig);
00363 }
00364 #endif
00365
00366 #ifdef SIGUSR1
00367 extern void dump_registry(void);
00368 RETSIGTYPE
00369 SnmpdDump(int a)
00370 {
00371 dump_registry();
00372 signal(SIGUSR1, SnmpdDump);
00373 }
00374 #endif
00375
00376 RETSIGTYPE
00377 SnmpdCatchRandomSignal(int a)
00378 {
00379
00380 snmp_disable_log();
00381 snmp_enable_syslog();
00382 snmp_log(LOG_ERR, "Exiting on signal %d\n", a);
00383 snmp_disable_syslog();
00384 exit(1);
00385 }
00386
00387 static void
00388 SnmpTrapNodeDown(void)
00389 {
00390 send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 2);
00391
00392
00393
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 int
00413 #ifdef WIN32SERVICE
00414 SnmpDaemonMain(int argc, TCHAR * argv[])
00415 #else
00416 main(int argc, char *argv[])
00417 #endif
00418 {
00419 char options[128] = "aAc:CdD::fhHI:l:L:m:M:n:p:P:qrsS:UvV-:Y:";
00420 int arg, i, ret;
00421 int dont_fork = 0, do_help = 0;
00422 int log_set = 0;
00423 int uid = 0, gid = 0;
00424 int agent_mode = -1;
00425 char *cptr, **argvptr;
00426 char *pid_file = NULL;
00427 char option_compatability[] = "-Le";
00428 #if HAVE_GETPID
00429 int fd;
00430 FILE *PID;
00431 #endif
00432
00433 #ifndef WIN32
00434
00435
00436
00437
00438 for (i = getdtablesize() - 1; i > 2; --i) {
00439 (void) close(i);
00440 }
00441 #endif
00442
00443
00444
00445
00446
00447 #ifdef SIGTERM
00448 DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n"));
00449 signal(SIGTERM, SnmpdShutDown);
00450 #endif
00451 #ifdef SIGINT
00452 DEBUGMSGTL(("signal", "registering SIGINT signal handler\n"));
00453 signal(SIGINT, SnmpdShutDown);
00454 #endif
00455 #ifdef SIGHUP
00456 signal(SIGHUP, SIG_IGN);
00457 #endif
00458 #ifdef SIGUSR1
00459 DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n"));
00460 signal(SIGUSR1, SnmpdDump);
00461 #endif
00462 #ifdef SIGPIPE
00463 DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n"));
00464 signal(SIGPIPE, SIG_IGN);
00465 #endif
00466 #ifdef SIGXFSZ
00467 signal(SIGXFSZ, SnmpdCatchRandomSignal);
00468 #endif
00469
00470 #ifdef NETSNMP_NO_ROOT_ACCESS
00471
00472
00473
00474 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00475 NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
00476 #endif
00477
00478
00479
00480 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00481 NETSNMP_DS_AGENT_AGENTX_MASTER, 0);
00482 netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
00483 NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1);
00484 netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
00485 NETSNMP_DS_AGENT_AGENTX_RETRIES, -1);
00486
00487 netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
00488 NETSNMP_DS_AGENT_CACHE_TIMEOUT, 5);
00489
00490
00491
00492 #if HAVE_UNISTD_H
00493 strcat(options, "g:u:");
00494 #endif
00495 #if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
00496 strcat(options, "x:");
00497 #endif
00498 #ifdef USING_AGENTX_SUBAGENT_MODULE
00499 strcat(options, "X");
00500 #endif
00501
00502
00503
00504
00505
00506 for (i=0; i<argc; i++) {
00507 if (!strcmp(argv[i], "-L"))
00508 argv[i] = option_compatability;
00509 }
00510
00511 #ifdef WIN32
00512 snmp_log_syslogname(app_name_long);
00513 #else
00514 snmp_log_syslogname(app_name);
00515 #endif
00516 netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
00517 NETSNMP_DS_LIB_APPTYPE, app_name);
00518
00519
00520
00521
00522 while ((arg = getopt(argc, argv, options)) != EOF) {
00523 switch (arg) {
00524 case '-':
00525 if (strcasecmp(optarg, "help") == 0) {
00526 usage(argv[0]);
00527 }
00528 if (strcasecmp(optarg, "version") == 0) {
00529 version();
00530 }
00531
00532 handle_long_opt(optarg);
00533 break;
00534
00535 case 'a':
00536 log_addresses++;
00537 break;
00538
00539 case 'A':
00540 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
00541 NETSNMP_DS_LIB_APPEND_LOGFILES, 1);
00542 break;
00543
00544 case 'c':
00545 if (optarg != NULL) {
00546 netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
00547 NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
00548 } else {
00549 usage(argv[0]);
00550 }
00551 break;
00552
00553 case 'C':
00554 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
00555 NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
00556 break;
00557
00558 case 'd':
00559 snmp_set_dump_packet(++snmp_dump_packet);
00560 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00561 NETSNMP_DS_AGENT_VERBOSE, 1);
00562 break;
00563
00564 case 'D':
00565 debug_register_tokens(optarg);
00566 snmp_set_do_debugging(1);
00567 break;
00568
00569 case 'f':
00570 dont_fork = 1;
00571 break;
00572
00573 #if HAVE_UNISTD_H
00574 case 'g':
00575 if (optarg != NULL) {
00576 netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
00577 NETSNMP_DS_AGENT_GROUPID, atoi(optarg));
00578 } else {
00579 usage(argv[0]);
00580 }
00581 break;
00582 #endif
00583
00584 case 'h':
00585 usage(argv[0]);
00586 break;
00587
00588 case 'H':
00589 do_help = 1;
00590 break;
00591
00592 case 'I':
00593 if (optarg != NULL) {
00594 add_to_init_list(optarg);
00595 } else {
00596 usage(argv[0]);
00597 }
00598 break;
00599
00600 case 'l':
00601 printf("Warning: -l option is deprecated, use -Lf <file> instead\n");
00602 if (optarg != NULL) {
00603 if (strlen(optarg) > PATH_MAX) {
00604 fprintf(stderr,
00605 "%s: logfile path too long (limit %d chars)\n",
00606 argv[0], PATH_MAX);
00607 exit(1);
00608 }
00609 snmp_enable_filelog(optarg,
00610 netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
00611 NETSNMP_DS_LIB_APPEND_LOGFILES));
00612 log_set = 1;
00613 } else {
00614 usage(argv[0]);
00615 }
00616 break;
00617
00618 case 'L':
00619 if (snmp_log_options( optarg, argc, argv ) < 0 ) {
00620 usage(argv[0]);
00621 }
00622 log_set = 1;
00623 break;
00624
00625 case 'm':
00626 if (optarg != NULL) {
00627 setenv("MIBS", optarg, 1);
00628 } else {
00629 usage(argv[0]);
00630 }
00631 break;
00632
00633 case 'M':
00634 if (optarg != NULL) {
00635 setenv("MIBDIRS", optarg, 1);
00636 } else {
00637 usage(argv[0]);
00638 }
00639 break;
00640
00641 case 'n':
00642 if (optarg != NULL) {
00643 app_name = optarg;
00644 netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
00645 NETSNMP_DS_LIB_APPTYPE, app_name);
00646 } else {
00647 usage(argv[0]);
00648 }
00649 break;
00650
00651 case 'P':
00652 printf("Warning: -P option is deprecated, use -p instead\n");
00653 case 'p':
00654 if (optarg != NULL) {
00655 pid_file = optarg;
00656 } else {
00657 usage(argv[0]);
00658 }
00659 break;
00660
00661 case 'q':
00662 snmp_set_quick_print(1);
00663 break;
00664
00665 case 'r':
00666 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
00667 NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
00668 break;
00669
00670 case 's':
00671 printf("Warning: -s option is deprecated, use -Lsd instead\n");
00672 snmp_enable_syslog();
00673 log_set = 1;
00674 break;
00675
00676 case 'S':
00677 printf("Warning: -S option is deprecated, use -Ls <facility> instead\n");
00678 if (optarg != NULL) {
00679 switch (*optarg) {
00680 case 'd':
00681 case 'D':
00682 Facility = LOG_DAEMON;
00683 break;
00684 case 'i':
00685 case 'I':
00686 Facility = LOG_INFO;
00687 break;
00688 case '0':
00689 Facility = LOG_LOCAL0;
00690 break;
00691 case '1':
00692 Facility = LOG_LOCAL1;
00693 break;
00694 case '2':
00695 Facility = LOG_LOCAL2;
00696 break;
00697 case '3':
00698 Facility = LOG_LOCAL3;
00699 break;
00700 case '4':
00701 Facility = LOG_LOCAL4;
00702 break;
00703 case '5':
00704 Facility = LOG_LOCAL5;
00705 break;
00706 case '6':
00707 Facility = LOG_LOCAL6;
00708 break;
00709 case '7':
00710 Facility = LOG_LOCAL7;
00711 break;
00712 default:
00713 fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
00714 usage(argv[0]);
00715 }
00716 snmp_enable_syslog_ident(snmp_log_syslogname(NULL), Facility);
00717 log_set = 1;
00718 } else {
00719 fprintf(stderr, "no syslog facility specified\n");
00720 usage(argv[0]);
00721 }
00722 break;
00723
00724 case 'U':
00725 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
00726 NETSNMP_DS_AGENT_LEAVE_PIDFILE);
00727 break;
00728
00729 #if HAVE_UNISTD_H
00730 case 'u':
00731 if (optarg != NULL) {
00732 char *ecp;
00733 int uid;
00734
00735 uid = strtoul(optarg, &ecp, 10);
00736 if (*ecp) {
00737 #if HAVE_GETPWNAM && HAVE_PWD_H
00738 struct passwd *info;
00739 info = getpwnam(optarg);
00740 if (info) {
00741 uid = info->pw_uid;
00742 } else {
00743 #endif
00744 fprintf(stderr, "Bad user id: %s\n", optarg);
00745 exit(1);
00746 #if HAVE_GETPWNAM && HAVE_PWD_H
00747 }
00748 #endif
00749 }
00750 netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
00751 NETSNMP_DS_AGENT_USERID, uid);
00752 } else {
00753 usage(argv[0]);
00754 }
00755 break;
00756 #endif
00757
00758 case 'v':
00759 version();
00760
00761 case 'V':
00762 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00763 NETSNMP_DS_AGENT_VERBOSE, 1);
00764 break;
00765
00766 #if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
00767 case 'x':
00768 if (optarg != NULL) {
00769 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
00770 NETSNMP_DS_AGENT_X_SOCKET, optarg);
00771 } else {
00772 usage(argv[0]);
00773 }
00774 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00775 NETSNMP_DS_AGENT_AGENTX_MASTER, 1);
00776 break;
00777 #endif
00778
00779 case 'X':
00780 #if defined(USING_AGENTX_SUBAGENT_MODULE)
00781 agent_mode = SUB_AGENT;
00782 #else
00783 fprintf(stderr, "%s: Illegal argument -X:"
00784 "AgentX support not compiled in.\n", argv[0]);
00785 usage(argv[0]);
00786 exit(1);
00787 #endif
00788 break;
00789
00790 case 'Y':
00791 netsnmp_config_remember(optarg);
00792 break;
00793
00794 default:
00795 usage(argv[0]);
00796 break;
00797 }
00798 }
00799
00800 if (do_help) {
00801 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00802 NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
00803 init_agent(app_name);
00804 init_mib_modules();
00805 init_snmp(app_name);
00806 fprintf(stderr, "Configuration directives understood:\n");
00807 read_config_print_usage(" ");
00808 exit(0);
00809 }
00810
00811 if (optind < argc) {
00812
00813
00814
00815 DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
00816 for (i = optind; i < argc; i++) {
00817 char *c, *astring;
00818 if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
00819 NETSNMP_DS_AGENT_PORTS))) {
00820 astring = malloc(strlen(c) + 2 + strlen(argv[i]));
00821 if (astring == NULL) {
00822 fprintf(stderr, "malloc failure processing argv[%d]\n", i);
00823 exit(1);
00824 }
00825 sprintf(astring, "%s,%s", c, argv[i]);
00826 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
00827 NETSNMP_DS_AGENT_PORTS, astring);
00828 SNMP_FREE(astring);
00829 } else {
00830 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
00831 NETSNMP_DS_AGENT_PORTS, argv[i]);
00832 }
00833 }
00834 DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
00835 netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
00836 NETSNMP_DS_AGENT_PORTS)));
00837 }
00838
00839 #ifdef NETSNMP_LOGFILE
00840 if (0 == log_set)
00841 snmp_enable_filelog(NETSNMP_LOGFILE,
00842 netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
00843 NETSNMP_DS_LIB_APPEND_LOGFILES));
00844 #endif
00845
00846
00847
00848
00849 argvrestartp = (char **)malloc((argc + 2) * sizeof(char *));
00850 argvptr = argvrestartp;
00851 for (i = 0, ret = 1; i < argc; i++) {
00852 ret += strlen(argv[i]) + 1;
00853 }
00854 argvrestart = (char *) malloc(ret);
00855 argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
00856 if (!argvrestartp || !argvrestart || !argvrestartname) {
00857 fprintf(stderr, "malloc failure processing argvrestart\n");
00858 exit(1);
00859 }
00860 strcpy(argvrestartname, argv[0]);
00861 if (agent_mode == -1) {
00862 if (strstr(argvrestartname, "agentxd") != NULL) {
00863 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00864 NETSNMP_DS_AGENT_ROLE, SUB_AGENT);
00865 } else {
00866 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00867 NETSNMP_DS_AGENT_ROLE, MASTER_AGENT);
00868 }
00869 } else {
00870 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00871 NETSNMP_DS_AGENT_ROLE, agent_mode);
00872 }
00873
00874 for (cptr = argvrestart, i = 0; i < argc; i++) {
00875 strcpy(cptr, argv[i]);
00876 *(argvptr++) = cptr;
00877 cptr += strlen(argv[i]) + 1;
00878 }
00879 *cptr = 0;
00880 *argvptr = NULL;
00881
00882 #ifdef BUFSIZ
00883 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
00884 #endif
00885
00886
00887
00888 if(!dont_fork) {
00889 int quit = ! netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00890 NETSNMP_DS_AGENT_QUIT_IMMEDIATELY);
00891 ret = netsnmp_daemonize(quit, snmp_stderrlog_status());
00892
00893
00894
00895 if(ret != 0)
00896 Exit(1);
00897 }
00898
00899 SOCK_STARTUP;
00900 init_agent(app_name);
00901 init_mib_modules();
00902
00903
00904
00905
00906 init_snmp(app_name);
00907
00908 if ((ret = init_master_agent()) != 0) {
00909
00910
00911
00912 Exit(1);
00913 }
00914
00915 #if HAVE_GETPID
00916 if (pid_file != NULL) {
00917
00918
00919
00920
00921
00922 unlink(pid_file);
00923 fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
00924 if (fd == -1) {
00925 snmp_log_perror(pid_file);
00926 if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00927 NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00928 exit(1);
00929 }
00930 } else {
00931 if ((PID = fdopen(fd, "w")) == NULL) {
00932 snmp_log_perror(pid_file);
00933 exit(1);
00934 } else {
00935 fprintf(PID, "%d\n", (int) getpid());
00936 fclose(PID);
00937 }
00938 close(fd);
00939 }
00940 }
00941 #endif
00942
00943 #if HAVE_UNISTD_H
00944 cptr = get_persistent_directory();
00945 mkdirhier( cptr, NETSNMP_AGENT_DIRECTORY_MODE, 0 );
00946
00947 uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
00948 NETSNMP_DS_AGENT_USERID);
00949 gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
00950 NETSNMP_DS_AGENT_GROUPID);
00951
00952 #ifdef HAVE_CHOWN
00953 if ( uid != 0 || gid != 0 )
00954 chown( cptr, uid, gid );
00955 #endif
00956
00957 #ifdef HAVE_SETGID
00958 if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
00959 NETSNMP_DS_AGENT_GROUPID)) != 0) {
00960 DEBUGMSGTL(("snmpd/main", "Changing gid to %d.\n", gid));
00961 if (setgid(gid) == -1
00962 #ifdef HAVE_SETGROUPS
00963 || setgroups(1, (gid_t *)&gid) == -1
00964 #endif
00965 ) {
00966 snmp_log_perror("setgid failed");
00967 if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00968 NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00969 exit(1);
00970 }
00971 }
00972 }
00973 #endif
00974 #ifdef HAVE_SETUID
00975 if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
00976 NETSNMP_DS_AGENT_USERID)) != 0) {
00977 DEBUGMSGTL(("snmpd/main", "Changing uid to %d.\n", uid));
00978 if (setuid(uid) == -1) {
00979 snmp_log_perror("setuid failed");
00980 if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00981 NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00982 exit(1);
00983 }
00984 }
00985 }
00986 #endif
00987 #endif
00988
00989
00990
00991
00992 snmp_store(app_name);
00993
00994 #ifdef SIGHUP
00995 DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n"));
00996 signal(SIGHUP, SnmpdReconfig);
00997 #endif
00998
00999
01000
01001
01002 send_easy_trap(0, 0);
01003
01004
01005
01006
01007 snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
01008 #ifdef WIN32SERVICE
01009 agent_status = AGENT_RUNNING;
01010 #endif
01011 netsnmp_addrcache_initialise();
01012
01013
01014
01015
01016 DEBUGMSGTL(("snmpd/main", "We're up. Starting to process data.\n"));
01017 if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
01018 NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
01019 receive();
01020 DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n"));
01021 SnmpTrapNodeDown();
01022 DEBUGMSGTL(("snmpd/main", "Bye...\n"));
01023 snmp_shutdown(app_name);
01024 #ifdef SHUTDOWN_AGENT_CLEANLY
01025
01026 shutdown_master_agent();
01027 shutdown_agent();
01028 #endif
01029
01030 if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
01031 NETSNMP_DS_AGENT_LEAVE_PIDFILE) &&
01032 (pid_file != NULL)) {
01033 unlink(pid_file);
01034 }
01035 #ifdef WIN32SERVICE
01036 agent_status = AGENT_STOPPED;
01037 #endif
01038
01039 SNMP_FREE(argvrestartname);
01040 SNMP_FREE(argvrestart);
01041 SNMP_FREE(argvrestartp);
01042 SOCK_CLEANUP;
01043 return 0;
01044 }
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 static int
01060 receive(void)
01061 {
01062 int numfds;
01063 fd_set readfds, writefds, exceptfds;
01064 struct timeval timeout, *tvp = &timeout;
01065 int count, block, i;
01066 #ifdef USING_SMUX_MODULE
01067 int sd;
01068 #endif
01069
01070
01071
01072
01073 reconfig = 0;
01074
01075
01076
01077
01078 while (netsnmp_running) {
01079 if (reconfig) {
01080 #if HAVE_SIGHOLD
01081 sighold(SIGHUP);
01082 #endif
01083 reconfig = 0;
01084 snmp_log(LOG_INFO, "Reconfiguring daemon\n");
01085
01086
01087 netsnmp_logging_restart();
01088 snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
01089 netsnmp_get_version());
01090 update_config();
01091 send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 3);
01092 #if HAVE_SIGHOLD
01093 sigrelse(SIGHUP);
01094 #endif
01095 }
01096
01097 for (i = 0; i < NUM_EXTERNAL_SIGS; i++) {
01098 if (external_signal_scheduled[i]) {
01099 external_signal_scheduled[i]--;
01100 external_signal_handler[i](i);
01101 }
01102 }
01103
01104
01105
01106
01107
01108
01109 tvp = &timeout;
01110 tvp->tv_sec = INT_MAX;
01111 tvp->tv_usec = 0;
01112
01113 numfds = 0;
01114 FD_ZERO(&readfds);
01115 FD_ZERO(&writefds);
01116 FD_ZERO(&exceptfds);
01117 block = 0;
01118 snmp_select_info(&numfds, &readfds, tvp, &block);
01119 if (block == 1) {
01120 tvp = NULL;
01121 }
01122
01123 #ifdef USING_SMUX_MODULE
01124 if (smux_listen_sd >= 0) {
01125 FD_SET(smux_listen_sd, &readfds);
01126 numfds =
01127 smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;
01128
01129 for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
01130 sd = smux_snmp_select_list_get_SD_from_List(i);
01131 if (sd != 0)
01132 {
01133 FD_SET(sd, &readfds);
01134 numfds = sd >= numfds ? sd + 1 : numfds;
01135 }
01136 }
01137 }
01138 #endif
01139
01140 netsnmp_external_event_info(&numfds, &readfds, &writefds, &exceptfds);
01141
01142 reselect:
01143 DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
01144 numfds, tvp));
01145 if(tvp)
01146 DEBUGMSGTL(("timer", "tvp %d.%d\n", tvp->tv_sec, tvp->tv_usec));
01147 count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
01148 DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));
01149
01150 if (count > 0) {
01151
01152 #ifdef USING_SMUX_MODULE
01153
01154
01155
01156 if (smux_listen_sd >= 0) {
01157 for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
01158 sd = smux_snmp_select_list_get_SD_from_List(i);
01159 if (FD_ISSET(sd, &readfds)) {
01160 if (smux_process(sd) < 0) {
01161 smux_snmp_select_list_del(sd);
01162 }
01163 }
01164 }
01165
01166
01167
01168 if (FD_ISSET(smux_listen_sd, &readfds)) {
01169 if ((sd = smux_accept(smux_listen_sd)) >= 0) {
01170 smux_snmp_select_list_add(sd);
01171 }
01172 }
01173 }
01174
01175 #endif
01176 netsnmp_dispatch_external_events(&count, &readfds,
01177 &writefds, &exceptfds);
01178
01179 if (count > 0) {
01180 snmp_read(&readfds);
01181 }
01182 } else
01183 switch (count) {
01184 case 0:
01185 snmp_timeout();
01186 break;
01187 case -1:
01188 DEBUGMSGTL(("snmpd/select", " errno = %d\n", errno));
01189 if (errno == EINTR) {
01190
01191
01192
01193
01194 if (netsnmp_running && !reconfig) {
01195 goto reselect;
01196 }
01197 continue;
01198 } else {
01199 snmp_log_perror("select");
01200 }
01201 return -1;
01202 default:
01203 snmp_log(LOG_ERR, "select returned %d\n", count);
01204 return -1;
01205 }
01206
01207
01208
01209
01210 run_alarms();
01211
01212 netsnmp_check_outstanding_agent_requests();
01213
01214 }
01215
01216 snmp_log(LOG_INFO, "Received TERM or STOP signal... shutting down...\n");
01217 return 0;
01218
01219 }
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 int
01242 snmp_input(int op,
01243 netsnmp_session * session,
01244 int reqid, netsnmp_pdu *pdu, void *magic)
01245 {
01246 struct get_req_state *state = (struct get_req_state *) magic;
01247
01248 if (op == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
01249 if (pdu->command == SNMP_MSG_GET) {
01250 if (state->type == EVENT_GET_REQ) {
01251
01252
01253
01254 return 1;
01255 }
01256 }
01257 } else if (op == NETSNMP_CALLBACK_OP_TIMED_OUT) {
01258 if (state->type == ALARM_GET_REQ) {
01259
01260
01261
01262 }
01263 }
01264 return 1;
01265
01266 }
01267
01268
01269
01270
01271
01272
01273 #ifdef WIN32SERVICE
01274
01275
01276
01277
01278
01279
01280
01281 int
01282 __cdecl
01283 _tmain(int argc, TCHAR * argv[])
01284 {
01285
01286
01287
01288 LPCTSTR lpszServiceName = app_name_long;
01289 LPCTSTR lpszServiceDisplayName = _T("Net-SNMP Agent");
01290 LPCTSTR lpszServiceDescription =
01291 #ifdef IFDESCR
01292 _T("SNMPv2c / SNMPv3 command responder from Net-SNMP. Supports MIB objects for IP,ICMP,TCP,UDP, and network interface sub-layers.");
01293 #else
01294 _T("SNMPv2c / SNMPv3 command responder from Net-SNMP");
01295 #endif
01296 InputParams InputOptions;
01297
01298
01299 int nRunType = RUN_AS_CONSOLE;
01300 int quiet = 0;
01301
01302 nRunType = ParseCmdLineForServiceOption(argc, argv, &quiet);
01303
01304 switch (nRunType) {
01305 case REGISTER_SERVICE:
01306
01307
01308
01309 InputOptions.Argc = argc;
01310 InputOptions.Argv = argv;
01311 exit (RegisterService(lpszServiceName,
01312 lpszServiceDisplayName,
01313 lpszServiceDescription, &InputOptions, quiet));
01314 break;
01315 case UN_REGISTER_SERVICE:
01316
01317
01318
01319 exit (UnregisterService(lpszServiceName, quiet));
01320 break;
01321 case RUN_AS_SERVICE:
01322
01323
01324
01325
01326
01327
01328 RegisterStopFunction(StopSnmpAgent);
01329 return RunAsService(SnmpDaemonMain);
01330 break;
01331 default:
01332
01333
01334
01335 return SnmpDaemonMain(argc, argv);
01336 break;
01337 }
01338 }
01339
01340
01341
01342
01343
01344 void
01345 StopSnmpAgent(void)
01346 {
01347
01348
01349
01350 SnmpdShutDown(1);
01351
01352
01353
01354
01355
01356 while (agent_status != AGENT_STOPPED) {
01357 Sleep(100);
01358 }
01359 }
01360
01361 #endif