예제 #1
0
int main(int argc, char *argv[])
{
    char *hostname = NULL;
    struct protoent *p;
    struct protox *tp = NULL;	/* for printing cblocks & stats */
    int allprotos = 1;
    char *community = NULL;
    char *argp;
    struct snmp_session session;
    int dest_port = SNMP_PORT;
    int timeout = SNMP_DEFAULT_TIMEOUT;
    int version = SNMP_VERSION_1;
    int arg;

    init_mib();
    /*
     * Usage: snmpnetstatwalk -v 1 [-q] hostname community ...      or:
     * Usage: snmpnetstat [-v 2 ] [-q] hostname noAuth     ...
     */
    for(arg = 1; arg < argc; arg++){
	if (argv[arg][0] == '-'){
	    switch(argv[arg][1]){
              case 'V':
                fprintf(stderr,"UCD-snmp version: %s\n", VersionInfo);
                exit(0);
                break;

	      case 'h':
		usage();
		exit(0);

	      case 'd':
		snmp_set_dump_packet(1);
		break;

	      case 'q':
		snmp_set_quick_print(1);
		break;

	      case 'D':
                debug_register_tokens(&argv[arg][2]);
		snmp_set_do_debugging(1);
		break;
	      case 'p':
		if (argv[arg][2] != 0) dest_port = atoi(argv[arg]+2);
		else if (++arg == argc) {
		    usage();
		    exit(1);
		}
		else dest_port = atoi(argv[arg]);
		break;

	      case 't':
		if (argv[arg][2] != 0) timeout = atoi(argv[arg]+2);
		else if (++arg == argc) {
		    usage();
		    exit(1);
		}
		else timeout = atoi(argv[arg]);
		timeout *= 1000000;
		break;

	      case 'c':
		if (argv[arg][2] != 0) community = argv[arg]+2;
		else if (++arg == argc) {
		    usage();
		    exit(1);
		}
		else community = argv[arg];
		break;

	      case 'v':
		if (argv[arg][2] != 0) argp = argv[arg]+2;
		else if (arg == argc) {
		    usage();
		    exit(1);
		}
		else argp = argv[arg];
		if (!strcmp(argp,"1"))
		    version = SNMP_VERSION_1;
		else if (!strcmp(argp,"2c"))
		    version = SNMP_VERSION_2c;
		else {
		    fprintf(stderr, "Invalid version: %s\n", argp);
		    usage();
		    exit(1);
		}
		break;

	      case 'a':
		aflag++;
		break;

	      case 'i':
		iflag++;
		break;

	      case 'o':
		oflag++;
		break;

	      case 'n':
		nflag++;
		break;

	      case 'r':
		rflag++;
		break;

	      case 's':
		sflag++;
		break;

	      case 'P':
		if (++arg == argc) {
		    usage();
		    exit(1);
		}
		if ((tp = name2protox(argv [arg])) == NULLPROTOX) {
		  fprintf(stderr, "%s: unknown or uninstrumented protocol\n",
			  argv [arg]);
		  exit(1);
		}
		allprotos = 0;
		tp->pr_wanted = 1;
		break;

	      case 'I':
		iflag++;
		if (*(intrface = argv[arg] + 2) == 0) {
		  if (++arg == argc) {
		      usage();
		      exit(1);
		  }
		  if ((intrface = argv[arg]) == 0)
		    break;
		}
		break;

	      default:
		printf("invalid option: -%c\n", argv[arg][1]);
		break;
	    }
	    continue;
	}
	if (hostname == NULL){
	    hostname = argv[arg];
	} else if ((version == SNMP_VERSION_1 || version == SNMP_VERSION_2c)
                   && community == NULL){
	    community = argv[arg]; 
	} else if (isdigit(argv[arg][0])) {
            interval = atoi(argv[arg]);
            if (interval <= 0){
		usage();
		exit(1);
	    }
	    iflag++;
	} else {
	    usage();
	    exit(1);
	}
    }
    
    if (!hostname ||
	((version == SNMP_VERSION_1 || version == SNMP_VERSION_2c) && !community)) {
	usage();
	exit(1);
    }

    snmp_sess_init(&session);
    session.peername = hostname;
    session.remote_port = dest_port;
    session.timeout = timeout;
    if (version == SNMP_VERSION_1 || version == SNMP_VERSION_2c){
        session.version = version;
        session.community = (u_char *)community;
        session.community_len = strlen((char *)community);
    }

    SOCK_STARTUP;

    /* open an SNMP session */
    Session = snmp_open(&session);
    if (Session == NULL){
      /* diagnose snmp_open errors with the input struct snmp_session pointer */
        snmp_sess_perror("snmpnetstat", &session);
        SOCK_CLEANUP;
	exit(1);
    }

    /*
     * Keep file descriptors open to avoid overhead
     * of open/close on each call to get* routines.
     */
    sethostent(1);
    setnetent(1);
    setprotoent(1);
    setservent(1);

    if (iflag) {
	intpr(interval);
    }
    if (oflag) {
	intpro(interval);
    }
    if (rflag) {
	if (sflag)
	    rt_stats();
	else
	    routepr();
    }
    
    if (iflag || rflag || oflag)
	;
    else {

    while ((p = getprotoent46())) {
	for (tp = protox; tp->pr_name; tp++) {
	    if (strcmp(tp->pr_name, p->p_name) == 0)
		break;
	}
	if (tp->pr_name == 0 || (tp->pr_wanted == 0 && allprotos == 0))
	    continue;
	if (sflag) {
	    if (tp->pr_stats)
		(*tp->pr_stats)();
	} else
	    if (tp->pr_cblocks)
		(*tp->pr_cblocks)(tp->pr_name);
    }
    } /* ! iflag, rflag, oflag */

    endprotoent();
    endservent();
    endnetent();
    endhostent();

    snmp_close(Session);

    SOCK_CLEANUP;
    return 0;
}
예제 #2
0
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::fhHI:l:L:m:M:n:p:P:qrsS:UvV-:Y:";
    int             arg, i, ret;
    int             dont_fork = 0, do_help = 0;
    int             log_set = 0;
    int             uid = 0, gid = 0;
    int             agent_mode = -1;
    char           *cptr, **argvptr;
    char           *pid_file = NULL;
    char            option_compatability[] = "-Le";
#if HAVE_GETPID
    int fd;
    FILE           *PID;
#endif

#ifndef WIN32
    /*
     * close all non-standard file descriptors we may have
     * inherited from the shell.
     */
    for (i = getdtablesize() - 1; i > 2; --i) {
        (void) close(i);
    }
#endif /* #WIN32 */
    
    /*
     * register signals ASAP to prevent default action (usually core)
     * for signals during startup...
     */
#ifdef SIGTERM
    DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n"));
    signal(SIGTERM, SnmpdShutDown);
#endif
#ifdef SIGINT
    DEBUGMSGTL(("signal", "registering SIGINT signal handler\n"));
    signal(SIGINT, SnmpdShutDown);
#endif
#ifdef SIGHUP
    signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
#endif
#ifdef SIGUSR1
    DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n"));
    signal(SIGUSR1, SnmpdDump);
#endif
#ifdef SIGPIPE
    DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n"));
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
#endif
#ifdef SIGXFSZ
    signal(SIGXFSZ, SnmpdCatchRandomSignal);
#endif

#ifdef NETSNMP_NO_ROOT_ACCESS
    /*
     * Default to no.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
#endif
    /*
     * Default to NOT running an AgentX master.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_AGENTX_MASTER, 0);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_RETRIES, -1);

    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_CACHE_TIMEOUT, 5);
    /*
     * Add some options if they are available.  
     */
#if HAVE_UNISTD_H
    strcat(options, "g:u:");
#endif
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
    strcat(options, "x:");
#endif
#ifdef USING_AGENTX_SUBAGENT_MODULE
    strcat(options, "X");
#endif

    /*
     * This is incredibly ugly, but it's probably the simplest way
     *  to handle the old '-L' option as well as the new '-Lx' style
     */
    for (i=0; i<argc; i++) {
        if (!strcmp(argv[i], "-L"))
            argv[i] = option_compatability;            
    }

#ifdef WIN32
    snmp_log_syslogname(app_name_long);
#else
    snmp_log_syslogname(app_name);
#endif
    netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                          NETSNMP_DS_LIB_APPTYPE, app_name);

    /*
     * Now process options normally.  
     */
    while ((arg = getopt(argc, argv, options)) != EOF) {
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                usage(argv[0]);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            log_addresses++;
            break;

        case 'A':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_APPEND_LOGFILES, 1);
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage(argv[0]);
            }
            break;

        case 'C':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
            break;

        case 'd':
            snmp_set_dump_packet(++snmp_dump_packet);
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 'f':
            dont_fork = 1;
            break;

#if HAVE_UNISTD_H
        case 'g':
            if (optarg != NULL) {
                char           *ecp;
                int             gid;

                gid = strtoul(optarg, &ecp, 10);
                if (*ecp) {
#if HAVE_GETPWNAM && HAVE_PWD_H
                    struct group  *info;
                    info = getgrnam(optarg);
                    if (info) {
                        gid = info->gr_gid;
                    } else {
#endif
                        fprintf(stderr, "Bad group id: %s\n", optarg);
                        exit(1);
#if HAVE_GETPWNAM && HAVE_PWD_H
                    }
#endif
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_GROUPID, gid);
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'h':
            usage(argv[0]);
            break;

        case 'H':
            do_help = 1;
            break;

        case 'I':
            if (optarg != NULL) {
                add_to_init_list(optarg);
            } else {
                usage(argv[0]);
            }
            break;

        case 'l':
            printf("Warning: -l option is deprecated, use -Lf <file> instead\n");
            if (optarg != NULL) {
                if (strlen(optarg) > PATH_MAX) {
                    fprintf(stderr,
                            "%s: logfile path too long (limit %d chars)\n",
                            argv[0], PATH_MAX);
                    exit(1);
                }
                snmp_enable_filelog(optarg,
                                    netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                           NETSNMP_DS_LIB_APPEND_LOGFILES));
                log_set = 1;
            } else {
                usage(argv[0]);
            }
            break;

        case 'L':
	    if  (snmp_log_options( optarg, argc, argv ) < 0 ) {
                usage(argv[0]);
            }
            log_set = 1;
            break;

        case 'm':
            if (optarg != NULL) {
                setenv("MIBS", optarg, 1);
            } else {
                usage(argv[0]);
            }
            break;

        case 'M':
            if (optarg != NULL) {
                setenv("MIBDIRS", optarg, 1);
            } else {
                usage(argv[0]);
            }
            break;

        case 'n':
            if (optarg != NULL) {
                app_name = optarg;
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                                      NETSNMP_DS_LIB_APPTYPE, app_name);
            } else {
                usage(argv[0]);
            }
            break;

        case 'P':
            printf("Warning: -P option is deprecated, use -p instead\n");
        case 'p':
            if (optarg != NULL) {
                pid_file = optarg;
            } else {
                usage(argv[0]);
            }
            break;

        case 'q':
            snmp_set_quick_print(1);
            break;

        case 'r':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
            break;

        case 's':
            printf("Warning: -s option is deprecated, use -Lsd instead\n");
            snmp_enable_syslog();
            log_set = 1;
            break;

        case 'S':
            printf("Warning: -S option is deprecated, use -Ls <facility> instead\n");
            if (optarg != NULL) {
                switch (*optarg) {
                case 'd':
                case 'D':
                    Facility = LOG_DAEMON;
                    break;
                case 'i':
                case 'I':
                    Facility = LOG_INFO;
                    break;
                case '0':
                    Facility = LOG_LOCAL0;
                    break;
                case '1':
                    Facility = LOG_LOCAL1;
                    break;
                case '2':
                    Facility = LOG_LOCAL2;
                    break;
                case '3':
                    Facility = LOG_LOCAL3;
                    break;
                case '4':
                    Facility = LOG_LOCAL4;
                    break;
                case '5':
                    Facility = LOG_LOCAL5;
                    break;
                case '6':
                    Facility = LOG_LOCAL6;
                    break;
                case '7':
                    Facility = LOG_LOCAL7;
                    break;
                default:
                    fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
                    usage(argv[0]);
                }
                snmp_enable_syslog_ident(snmp_log_syslogname(NULL), Facility);
                log_set = 1;
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage(argv[0]);
            }
            break;

        case 'U':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_LEAVE_PIDFILE);
            break;

#if HAVE_UNISTD_H
        case 'u':
            if (optarg != NULL) {
                char           *ecp;
                int             uid;

                uid = strtoul(optarg, &ecp, 10);
                if (*ecp) {
#if HAVE_GETPWNAM && HAVE_PWD_H
                    struct passwd  *info;
                    info = getpwnam(optarg);
                    if (info) {
                        uid = info->pw_uid;
                    } else {
#endif
                        fprintf(stderr, "Bad user id: %s\n", optarg);
                        exit(1);
#if HAVE_GETPWNAM && HAVE_PWD_H
                    }
#endif
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_USERID, uid);
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'v':
            version();

        case 'V':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage(argv[0]);
            }
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_AGENTX_MASTER, 1);
            break;
#endif

        case 'X':
#if defined(USING_AGENTX_SUBAGENT_MODULE)
            agent_mode = SUB_AGENT;
#else
            fprintf(stderr, "%s: Illegal argument -X:"
		            "AgentX support not compiled in.\n", argv[0]);
            usage(argv[0]);
            exit(1);
#endif
            break;

        case 'Y':
            netsnmp_config_remember(optarg);
            break;

        default:
            usage(argv[0]);
            break;
        }
    }

    if (do_help) {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
                               NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
        init_agent(app_name);        /* register our .conf handlers */
        init_mib_modules();
        init_snmp(app_name);
        fprintf(stderr, "Configuration directives understood:\n");
        read_config_print_usage("  ");
        exit(0);
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
        for (i = optind; i < argc; i++) {
            char *c, *astring;
            if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					   NETSNMP_DS_AGENT_PORTS))) {
                astring = malloc(strlen(c) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", c, argv[i]);
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, astring);
                SNMP_FREE(astring);
            } else {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, argv[i]);
            }
        }
        DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
                    netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					  NETSNMP_DS_AGENT_PORTS)));
    }

#ifdef NETSNMP_LOGFILE
    if (0 == log_set)
        snmp_enable_filelog(NETSNMP_LOGFILE,
                            netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                   NETSNMP_DS_LIB_APPEND_LOGFILES));
#endif

    /*
     * Initialize a argv set to the current for restarting the agent.   
     */
    argvrestartp = (char **)malloc((argc + 2) * sizeof(char *));
    argvptr = argvrestartp;
    for (i = 0, ret = 1; i < argc; i++) {
        ret += strlen(argv[i]) + 1;
    }
    argvrestart = (char *) malloc(ret);
    argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
    if (!argvrestartp || !argvrestart || !argvrestartname) {
        fprintf(stderr, "malloc failure processing argvrestart\n");
        exit(1);
    }
    strcpy(argvrestartname, argv[0]);
    if (agent_mode == -1) {
        if (strstr(argvrestartname, "agentxd") != NULL) {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, SUB_AGENT);
        } else {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, MASTER_AGENT);
        }
    } else {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_ROLE, agent_mode);
    }

    for (cptr = argvrestart, i = 0; i < argc; i++) {
        strcpy(cptr, argv[i]);
        *(argvptr++) = cptr;
        cptr += strlen(argv[i]) + 1;
    }
    *cptr = 0;
    *argvptr = NULL;

#ifdef BUFSIZ
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif
    /*
     * Initialize the world.  Detach from the shell.  Create initial user.  
     */
    if(!dont_fork) {
        int quit = ! netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                            NETSNMP_DS_AGENT_QUIT_IMMEDIATELY);
        ret = netsnmp_daemonize(quit, snmp_stderrlog_status());
        /*
         * xxx-rks: do we care if fork fails? I think we should...
         */
        if(ret != 0)
            Exit(1);                /*  Exit logs exit val for us  */
    }

    SOCK_STARTUP;
    init_agent(app_name);        /* do what we need to do first. */
    init_mib_modules();

    /*
     * start library 
     */
    init_snmp(app_name);

    if ((ret = init_master_agent()) != 0) {
        /*
         * Some error opening one of the specified agent transports.  
         */
        Exit(1);                /*  Exit logs exit val for us  */
    }

#if HAVE_GETPID
    if (pid_file != NULL) {
        /*
         * unlink the pid_file, if it exists, prior to open.  Without
         * doing this the open will fail if the user specified pid_file
         * already exists.
         */
        unlink(pid_file);
        fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
        if (fd == -1) {
            snmp_log_perror(pid_file);
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
                                        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        } else {
            if ((PID = fdopen(fd, "w")) == NULL) {
                snmp_log_perror(pid_file);
                exit(1);
            } else {
                fprintf(PID, "%d\n", (int) getpid());
                fclose(PID);
            }
            close(fd);
        }
    }
#endif

#if HAVE_UNISTD_H
    cptr = get_persistent_directory();
    mkdirhier( cptr, NETSNMP_AGENT_DIRECTORY_MODE, 0 );
   
    uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
			     NETSNMP_DS_AGENT_USERID);
    gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
			     NETSNMP_DS_AGENT_GROUPID);
    
#ifdef HAVE_CHOWN
    if ( uid != 0 || gid != 0 )
        chown( cptr, uid, gid );
#endif

#ifdef HAVE_SETGID
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_GROUPID)) != 0) {
        DEBUGMSGTL(("snmpd/main", "Changing gid to %d.\n", gid));
        if (setgid(gid) == -1
#ifdef HAVE_SETGROUPS
            || setgroups(1, (gid_t *)&gid) == -1
#endif
            ) {
            snmp_log_perror("setgid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#ifdef HAVE_SETUID
    if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_USERID)) != 0) {
        DEBUGMSGTL(("snmpd/main", "Changing uid to %d.\n", uid));
        if (setuid(uid) == -1) {
            snmp_log_perror("setuid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#endif

    /*
     * Store persistent data immediately in case we crash later.  
     */
    snmp_store(app_name);

#ifdef SIGHUP
    DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n"));
    signal(SIGHUP, SnmpdReconfig);
#endif

    /*
     * Send coldstart trap if possible.  
     */
    send_easy_trap(0, 0);

    /*
     * We're up, log our version number.  
     */
    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
#ifdef WIN32SERVICE
    agent_status = AGENT_RUNNING;
#endif
    netsnmp_addrcache_initialise();

    /*
     * Forever monitor the dest_port for incoming PDUs.  
     */
    DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
        receive();
    DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n"));
    SnmpTrapNodeDown();
    DEBUGMSGTL(("snmpd/main", "Bye...\n"));
    snmp_shutdown(app_name);
    shutdown_master_agent();
    shutdown_agent();

    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_LEAVE_PIDFILE) &&
	(pid_file != NULL)) {
        unlink(pid_file);
    }
#ifdef WIN32SERVICE
    agent_status = AGENT_STOPPED;
#endif

    SNMP_FREE(argvrestartname);
    SNMP_FREE(argvrestart);
    SNMP_FREE(argvrestartp);
    SOCK_CLEANUP;
    return 0;
}                               /* End main() -- snmpd */
예제 #3
0
파일: main.c 프로젝트: DYFeng/infinidb
int
main(int argc, char *argv[])
{
    char           *hostname = NULL;
    struct protoent *p;
    struct protox  *tp = NULL;  /* for printing cblocks & stats */
    int             allprotos = 1;
    char           *community = NULL;
    char           *argp;
    netsnmp_session session;
    int             timeout = SNMP_DEFAULT_TIMEOUT;
    int             version = SNMP_DEFAULT_VERSION;
    int             arg;

#ifndef DISABLE_MIB_LOADING
    init_mib();
#endif /* DISABLE_MIB_LOADING */
    /*
     * Usage: snmpnetstatwalk -v 1 [-q] hostname community ...      or:
     * Usage: snmpnetstat [-v 2 ] [-q] hostname noAuth     ...
     */
    while ((arg = getopt(argc, argv, "VhdqD:t:c:v:aionrsP:I:")) != EOF) {
        switch (arg) {
        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n",
                    netsnmp_get_version());
            exit(0);
            break;

        case 'h':
            usage();
            exit(0);

        case 'd':
            snmp_set_dump_packet(1);
            break;

        case 'q':
            snmp_set_quick_print(1);
            break;

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 't':
            timeout = atoi(optarg);
            timeout *= 1000000;
            break;

        case 'c':
            community = optarg;
            break;

        case 'v':
            argp = optarg;
            version = -1;
#ifndef DISABLE_SNMPV1
            if (!strcasecmp(argp, "1"))
                version = SNMP_VERSION_1;
#endif
#ifndef DISABLE_SNMPV2C
            if (!strcasecmp(argp, "2c"))
                version = SNMP_VERSION_2c;
#endif
            if (version == -1) {
                fprintf(stderr, "Invalid version: %s\n", argp);
                usage();
                exit(1);
            }
            break;

        case 'a':
            aflag++;
            break;

        case 'i':
            iflag++;
            break;

        case 'o':
            oflag++;
            break;

        case 'n':
            nflag++;
            break;

        case 'r':
            rflag++;
            break;

        case 's':
            sflag++;
            break;

        case 'P':
            if ((tp = name2protox(optarg)) == NULLPROTOX) {
                fprintf(stderr, "%s: unknown or uninstrumented protocol\n",
                        optarg);
                exit(1);
            }
            allprotos = 0;
            tp->pr_wanted = 1;
            break;

        case 'I':
            iflag++;
            intrface = optarg;
            break;

        default:
            exit(1);
            break;
        }
        continue;
    }

    init_snmp("snmpapp");
    snmp_enable_stderrlog();
    if (version == SNMP_DEFAULT_VERSION) {
        version = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
		                     NETSNMP_DS_LIB_SNMPVERSION);
        if (!version) {
            switch (DEFAULT_SNMP_VERSION) {
#ifndef DISABLE_SNMPV1
            case 1:
                version = SNMP_VERSION_1;
                break;
#endif
#ifndef DISABLE_SNMPV2C
            case 2:
                version = SNMP_VERSION_2c;
                break;
#endif
            case 3:
                version = SNMP_VERSION_3;
                break;
            }
#ifndef DISABLE_SNMPV1
        } else if (version == NETSNMP_DS_SNMP_VERSION_1) {
                          /* Bogus value. version1 = 0 */
            version = SNMP_VERSION_1;
#endif
        }
    }
    if (optind < argc) {
        hostname = argv[optind++];
    }
    else {
        fprintf(stderr, "Missing host name.\n");
        exit(1);
    }
    if (community == NULL) {
	community = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
		                          NETSNMP_DS_LIB_COMMUNITY);
    }
    if (optind < argc && isdigit(argv[optind][0])) {
        interval = atoi(argv[optind++]);
        if (interval <= 0) {
            usage();
            exit(1);
        }
        iflag++;
    }
    if (optind < argc) {
        usage();
        exit(1);
    }


    snmp_sess_init(&session);
    session.peername = hostname;
    session.timeout = timeout;
#if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
    if (version != SNMP_VERSION_3) {
        if (!community) {
            fprintf(stderr, "Missing community name.\n");
            exit(1);
        }
        session.version = version;
        session.community = (u_char *) community;
        session.community_len = strlen(community);
    }
#endif

    SOCK_STARTUP;

    /*
     * open an SNMP session 
     */
    Session = snmp_open(&session);
    if (Session == NULL) {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror("snmpnetstat", &session);
        SOCK_CLEANUP;
        exit(1);
    }

    /*
     * Keep file descriptors open to avoid overhead
     * of open/close on each call to get* routines.
     */
    sethostent(1);
    setnetent(1);
    setprotoent(1);
    setservent(1);

    if (iflag) {
        intpr(interval);
    }
    if (oflag) {
        intpro(interval);
    }
    if (rflag) {
        if (sflag)
            rt_stats();
        else
            routepr();
    }

    if (!(iflag || rflag || oflag)) {
        while ((p = getprotoent46())) {
            for (tp = protox; tp->pr_name; tp++) {
                if (strcmp(tp->pr_name, p->p_name) == 0)
                    break;
            }
            if (tp->pr_name == 0 || (tp->pr_wanted == 0 && allprotos == 0))
                continue;
            if (sflag) {
                if (tp->pr_stats)
                    (*tp->pr_stats) ();
            } else if (tp->pr_cblocks)
                (*tp->pr_cblocks) (tp->pr_name);
        }
    }                           /* ! iflag, rflag, oflag */

    endprotoent();
    endservent();
    endnetent();
    endhostent();

    snmp_close(Session);

    SOCK_CLEANUP;
    return 0;
}
예제 #4
0
파일: snmptrapd.c 프로젝트: Undrizzle/apps
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::efF:g:hHI:L:m:M:no:O:PqsS:tu:vx:-:";
    netsnmp_session *sess_list = NULL, *ss = NULL;
    netsnmp_transport *transport = NULL;
    int             arg, i = 0, depmsg = 0;
    int             uid = 0, gid = 0;
    int             count, numfds, block;
    fd_set          readfds,writefds,exceptfds;
    struct timeval  timeout, *tvp;
    char           *cp, *listen_ports = NULL;
#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
    int             agentx_subagent = 1;
#endif
    netsnmp_trapd_handler *traph;
#ifdef NETSNMP_EMBEDDED_PERL
    extern void init_perl(void);
#endif

#ifndef WIN32
    /*
     * close all non-standard file descriptors we may have
     * inherited from the shell.
     */
    for (i = getdtablesize() - 1; i > 2; --i) {
        (void) close(i);
    }
#endif /* #WIN32 */
    
#ifdef SIGTERM
    signal(SIGTERM, term_handler);
#endif
#ifdef SIGHUP
    signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
#endif
#ifdef SIGINT
    signal(SIGINT, term_handler);
#endif
#ifdef SIGPIPE
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
#endif

#ifdef SIGHUP
    signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
#endif

    /*
     * register our configuration handlers now so -H properly displays them 
     */
    snmptrapd_register_configs( );
    init_usm_conf( "snmptrapd" );
    register_config_handler("snmptrapd", "snmpTrapdAddr",
                            parse_trapd_address, free_trapd_address, "string");

    register_config_handler("snmptrapd", "doNotLogTraps",
                            parse_config_doNotLogTraps, NULL, "(1|yes|true|0|no|false)");
#if HAVE_GETPID
    register_config_handler("snmptrapd", "pidFile",
                            parse_config_pidFile, NULL, "string");
#endif
#ifdef HAVE_UNISTD_H
    register_config_handler("snmptrapd", "agentuser",
                            parse_config_agentuser, NULL, "userid");
    register_config_handler("snmptrapd", "agentgroup",
                            parse_config_agentgroup, NULL, "groupid");
#endif
    
    register_config_handler("snmptrapd", "logOption",
                            parse_config_logOption, NULL, "string");

    register_config_handler("snmptrapd", "doNotFork",
                            parse_config_doNotFork, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "printEventNumbers",
                            parse_config_printEventNumbers, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "ignoreAuthFailure",
                            parse_config_ignoreAuthFailure, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "outputOption",
                            parse_config_outputOption, NULL, "string");

#ifdef WIN32
    setvbuf(stdout, NULL, _IONBF, BUFSIZ);
#else
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif

    /*
     * Add some options if they are available.  
     */
#if HAVE_GETPID
    strcat(options, "p:");
#endif

#ifdef WIN32
    snmp_log_syslogname(app_name_long);
#else
    snmp_log_syslogname(app_name);
#endif

    /*
     * Now process options normally.  
     */

    while ((arg = getopt(argc, argv, options)) != EOF) {
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                usage();
                exit(0);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
                exit(0);
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            dropauth = 1;
            break;

        case 'A':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_APPEND_LOGFILES, 1);
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'C':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
            break;

        case 'd':
            snmp_set_dump_packet(1);
            break;

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 'e':
            Event++;
            break;

        case 'f':
            dofork = 0;
            break;

        case 'F':
            if (optarg != NULL) {
                trap1_fmt_str_remember = optarg;
            } else {
                usage();
                exit(1);
            }
            break;

#if HAVE_UNISTD_H
        case 'g':
            if (optarg != NULL) {
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_GROUPID, gid = atoi(optarg));
            } else {
                usage();
                exit(1);
            }
            break;
#endif

        case 'h':
            usage();
            exit(0);

        case 'H':
            init_agent("snmptrapd");
#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE
            init_notification_log();
#endif
#ifdef NETSNMP_EMBEDDED_PERL
            init_perl();
#endif
            init_snmp("snmptrapd");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            exit(0);

        case 'I':
            if (optarg != NULL) {
                add_to_init_list(optarg);
            } else {
                usage();
            }
            break;

	case 'S':
            fprintf(stderr,
                    "Warning: -S option is deprecated; use -Ls <facility> instead\n");
            depmsg = 1;
            if (optarg != NULL) {
                switch (*optarg) {
                case 'd':
                case 'D':
                    Facility = LOG_DAEMON;
                    break;
                case 'i':
                case 'I':
                    Facility = LOG_INFO;
                    break;
                case '0':
                    Facility = LOG_LOCAL0;
                    break;
                case '1':
                    Facility = LOG_LOCAL1;
                    break;
                case '2':
                    Facility = LOG_LOCAL2;
                    break;
                case '3':
                    Facility = LOG_LOCAL3;
                    break;
                case '4':
                    Facility = LOG_LOCAL4;
                    break;
                case '5':
                    Facility = LOG_LOCAL5;
                    break;
                case '6':
                    Facility = LOG_LOCAL6;
                    break;
                case '7':
                    Facility = LOG_LOCAL7;
                    break;
                default:
                    fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
                    usage();
                    exit(1);
                }
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage();
                exit(1);
            }
            break;

        case 'm':
            if (optarg != NULL) {
                setenv("MIBS", optarg, 1);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'M':
            if (optarg != NULL) {
                setenv("MIBDIRS", optarg, 1);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'n':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_APP_NUMERIC_IP, 1);
            break;

        case 'o':
            fprintf(stderr,
                    "Warning: -o option is deprecated; use -Lf <file> instead\n");
            if (optarg != NULL) {
                logfile = optarg;
                snmp_enable_filelog(optarg, 
                                    netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                           NETSNMP_DS_LIB_APPEND_LOGFILES));
            } else {
                usage();
                exit(1);
            }
            break;

        case 'O':
            cp = snmp_out_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown output option passed to -O: %c\n",
			*cp);
                usage();
                exit(1);
            }
            break;

        case 'L':
	    if  (snmp_log_options( optarg, argc, argv ) < 0 ) {
                usage();
                exit(1);
            }
            break;

#if HAVE_GETPID
        case 'p':
            if (optarg != NULL) {
                parse_config_pidFile(NULL, optarg);
            } else {
                usage();
                exit(1);
            }
            break;
#endif

        case 'P':
            fprintf(stderr,
                    "Warning: -P option is deprecated; use -f -Le instead\n");
            dofork = 0;
            snmp_enable_stderrlog();
            break;

        case 's':
            fprintf(stderr,
                    "Warning: -s option is deprecated; use -Lsd instead\n");
            depmsg = 1;
#ifdef WIN32
            snmp_enable_syslog_ident(app_name_long, Facility);
#else
            snmp_enable_syslog_ident(app_name, Facility);
#endif
            break;

        case 't':
            SyslogTrap++;
            break;

#if HAVE_UNISTD_H
        case 'u':
            if (optarg != NULL) {
                char           *ecp;

                uid = strtoul(optarg, &ecp, 10);
                if (*ecp) {
#if HAVE_GETPWNAM && HAVE_PWD_H
                    struct passwd  *info;
                    info = getpwnam(optarg);
                    if (info) {
                        uid = info->pw_uid;
                    } else {
#endif
                        fprintf(stderr, "Bad user id: %s\n", optarg);
                        exit(1);
#if HAVE_GETPWNAM && HAVE_PWD_H
                    }
#endif
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_USERID, uid);
            } else {
                usage();
                exit(1);
            }
            break;
#endif

        case 'v':
            version();
            exit(0);
            break;

        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage();
                exit(1);
            }
            break;

        default:
            fprintf(stderr, "invalid option: -%c\n", arg);
            usage();
            exit(1);
            break;
        }
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        for (i = optind; i < argc; i++) {
            char *astring;
            if (listen_ports != NULL) {
                astring = malloc(strlen(listen_ports) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", listen_ports, argv[i]);
                free(listen_ports);
                listen_ports = astring;
            } else {
                listen_ports = strdup(argv[i]);
                if (listen_ports == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
            }
        }
    }

    SOCK_STARTUP;

    /*
     * I'm being lazy here, and not checking the
     * return value from these registration calls.
     * Don't try this at home, children!
     */
    if (0 == snmp_get_do_logging()) {
        traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
                                               syslog_handler);
        traph->authtypes = TRAP_AUTH_LOG;
        snmp_enable_syslog();
    } else {
        traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
                                               print_handler);
        traph->authtypes = TRAP_AUTH_LOG;
    }

    if (Event) {
        traph = netsnmp_add_traphandler(event_handler, risingAlarm,
                                        OID_LENGTH(risingAlarm));
        traph->authtypes = TRAP_AUTH_LOG;

        traph = netsnmp_add_traphandler(event_handler, fallingAlarm,
                                        OID_LENGTH(fallingAlarm));
        traph->authtypes = TRAP_AUTH_LOG;

        traph = netsnmp_add_traphandler(event_handler, unavailableAlarm,
                                        OID_LENGTH(unavailableAlarm));
        traph->authtypes = TRAP_AUTH_LOG;
	/* XXX - might be worth setting some "magic data"
	 * in the traphandler structure that 'event_handler'
	 * can use to avoid checking the trap OID values.
	 */
    }

#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
    /*
     * we're an agentx subagent? 
     */
    if (agentx_subagent) {
        /*
         * make us a agentx client. 
         */
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_AGENT_ROLE, 1);
    }
#endif

    /*
     * don't fail if we can't do agentx (ie, socket not there, or not root) 
     */
    netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
			      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
    /*
     * ignore any warning messages.
     */
    netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
			      NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS);

    /*
     * initialize the agent library 
     */
    init_agent("snmptrapd");

#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
    /*
     * initialize local modules 
     */
    if (agentx_subagent) {
#ifdef USING_SNMPV3_SNMPENGINE_MODULE
        extern void register_snmpEngine_scalars_context(const char *);
#endif
        subagent_init();
#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE
        /* register the notification log table */
        if (should_init("notificationLogMib")) {
            netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_NOTIF_LOG_CTX,
                              "snmptrapd");
            traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER,
                                                   notification_handler);
            traph->authtypes = TRAP_AUTH_LOG;
            init_notification_log();
        }
#endif
#ifdef USING_SNMPV3_SNMPENGINE_MODULE
        /*
         * register scalars from SNMP-FRAMEWORK-MIB::snmpEngineID group;
         * allows engineID probes via the master agent under the
         * snmptrapd context
         */
        register_snmpEngine_scalars_context("snmptrapd");
#endif
    }
#endif /* USING_AGENTX_SUBAGENT_MODULE && !NETSNMP_SNMPTRAPD_DISABLE_AGENTX */

    /* register our authorization handler */
    init_netsnmp_trapd_auth();

#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
    if (agentx_subagent) {
#ifdef USING_AGENT_NSVACMACCESSTABLE_MODULE
        extern void init_register_nsVacm_context(const char *);
#endif
#ifdef USING_SNMPV3_USMUSER_MODULE
        extern void init_register_usmUser_context(const char *);
        /* register ourselves as having a USM user database */
        init_register_usmUser_context("snmptrapd");
#endif
#ifdef USING_AGENT_NSVACMACCESSTABLE_MODULE
        /* register net-snmp vacm extensions */
        init_register_nsVacm_context("snmptrapd");
#endif
    }
#endif

#ifdef NETSNMP_EMBEDDED_PERL
    init_perl();
    {
        /* set the default path to load */
        char            init_file[SNMP_MAXBUF];
        snprintf(init_file, sizeof(init_file) - 1,
                 "%s/%s", SNMPSHAREPATH, "snmp_perl_trapd.pl");
        netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_AGENT_PERL_INIT_FILE,
                              init_file);
    }
#endif

    /*
     * Initialize the world.
     */
    init_snmp("snmptrapd");

#ifdef SIGHUP
    signal(SIGHUP, hup_handler);
#endif

    if (trap1_fmt_str_remember) {
        free_trap1_fmt();
        free_trap2_fmt();
        print_format1 = strdup(trap1_fmt_str_remember);
        print_format2 = strdup(trap1_fmt_str_remember);
    }

    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) {
        /*
         * just starting up to process specific configuration and then
         * shutting down immediately. 
         */
        netsnmp_running = 0;
    }

    /*
     * if no logging options on command line or in conf files, use syslog
     */
    if (0 == snmp_get_do_logging()) {
#ifdef WIN32
        snmp_enable_syslog_ident(app_name_long, Facility);
#else
        snmp_enable_syslog_ident(app_name, Facility);
#endif        
    }

#ifndef WIN32
    /*
     * fork the process to the background if we are not printing to stderr 
     */
    if (dofork && netsnmp_running) {
        int             fd;

        switch (fork()) {
        case -1:
            fprintf(stderr, "bad fork - %s\n", strerror(errno));
            _exit(1);

        case 0:
            /*
             * become process group leader 
             */
            if (setsid() == -1) {
                fprintf(stderr, "bad setsid - %s\n", strerror(errno));
                _exit(1);
            }

            /*
             * if we are forked, we don't want to print out to stdout or stderr 
             */
            fd = open("/dev/null", O_RDWR);
            dup2(fd, STDIN_FILENO);
            dup2(fd, STDOUT_FILENO);
            dup2(fd, STDERR_FILENO);
            close(fd);
            break;

        default:
            _exit(0);
        }
    }
#endif                          /* WIN32 */
#if HAVE_GETPID
    if (pid_file != NULL) {
        if ((PID = fopen(pid_file, "w")) == NULL) {
            snmp_log_perror("fopen");
            exit(1);
        }
        fprintf(PID, "%d\n", (int) getpid());
        fclose(PID);
        free_config_pidFile();
    }
#endif

    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
    if (depmsg) {
        snmp_log(LOG_WARNING, "-s and -S options are deprecated; use -Ls <facility> instead\n");
    }
    
    if (listen_ports)
        cp = listen_ports;
    else
        cp = default_port;

    while (cp != NULL) {
        char *sep = strchr(cp, ',');

        if (sep != NULL) {
            *sep = 0;
        }

        transport = netsnmp_transport_open_server("snmptrap", cp);
        if (transport == NULL) {
            snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n",
                     cp, errno, strerror(errno));
            snmptrapd_close_sessions(sess_list);
            SOCK_CLEANUP;
            exit(1);
        } else {
            ss = snmptrapd_add_session(transport);
            if (ss == NULL) {
                /*
                 * Shouldn't happen?  We have already opened the transport
                 * successfully so what could have gone wrong?  
                 */
                snmptrapd_close_sessions(sess_list);
                netsnmp_transport_free(transport);
                snmp_log(LOG_ERR, "couldn't open snmp - %s", strerror(errno));
                SOCK_CLEANUP;
                exit(1);
            } else {
                ss->next = sess_list;
                sess_list = ss;
            }
        }

        /*
         * Process next listen address, if there is one.  
         */

        if (sep != NULL) {
            *sep = ',';
            cp = sep + 1;
        } else {
            cp = NULL;
        }
    }

    /*
     * ignore early sighup during startup
     */
    reconfig = 0;

#if HAVE_UNISTD_H
#ifdef HAVE_SETGID
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_GROUPID)) != 0) {
        DEBUGMSGTL(("snmptrapd/main", "Changing gid to %d.\n", gid));
        if (setgid(gid) == -1
#ifdef HAVE_SETGROUPS
            || setgroups(1, (gid_t *)&gid) == -1
#endif
            ) {
            snmp_log_perror("setgid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#ifdef HAVE_SETUID
    if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_USERID)) != 0) {
        DEBUGMSGTL(("snmptrapd/main", "Changing uid to %d.\n", uid));
        if (setuid(uid) == -1) {
            snmp_log_perror("setuid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#endif

#ifdef WIN32SERVICE
    trapd_status = SNMPTRAPD_RUNNING;
#endif
    while (netsnmp_running) {
        if (reconfig) {
                /*
                 * If we are logging to a file, receipt of SIGHUP also
                 * indicates the the log file should be closed and
                 * re-opened.  This is useful for users that want to
                 * rotate logs in a more predictable manner.
                 */
                netsnmp_logging_restart();
                snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
                         netsnmp_get_version());
            trapd_update_config();
            if (trap1_fmt_str_remember) {
                free_trap1_fmt();
                free_trap2_fmt();
                print_format1 = strdup(trap1_fmt_str_remember);
                print_format2 = strdup(trap1_fmt_str_remember);
            }
            reconfig = 0;
        }
        numfds = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        FD_ZERO(&exceptfds);
        block = 0;
        tvp = &timeout;
        timerclear(tvp);
        tvp->tv_sec = 5;
        snmp_select_info(&numfds, &readfds, tvp, &block);
        if (block == 1)
            tvp = NULL;         /* block without timeout */
        netsnmp_external_event_info(&numfds, &readfds, &writefds, &exceptfds);
        count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
        gettimeofday(&Now, 0);
        if (count > 0) {
            netsnmp_dispatch_external_events(&count, &readfds, &writefds,
                                             &exceptfds);
            /* If there are any more events after external events, then
             * try SNMP events. */
            if (count > 0) {
                snmp_read(&readfds);
            }
        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                if (errno == EINTR)
                    continue;
                snmp_log_perror("select");
                netsnmp_running = 0;
                break;
            default:
                fprintf(stderr, "select returned %d\n", count);
                netsnmp_running = 0;
            }
	run_alarms();
    }

    if (snmp_get_do_logging()) {
        struct tm      *tm;
        time_t          timer;
        time(&timer);
        tm = localtime(&timer);
        snmp_log(LOG_INFO,
                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Stopped.\n",
                 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
                 tm->tm_min, tm->tm_sec, netsnmp_get_version());
    }
    snmp_log(LOG_INFO, "Stopping snmptrapd");
    
    snmptrapd_close_sessions(sess_list);
    snmp_shutdown("snmptrapd");
#ifdef WIN32SERVICE
    trapd_status = SNMPTRAPD_STOPPED;
#endif
    snmp_disable_log();
    SOCK_CLEANUP;
    return 0;
}
예제 #5
0
파일: snmpd.c 프로젝트: AllardJ/Tomato
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::fhHI:l:LP:qrsS:UvV-:";
    int             arg, i, ret;
    int             dont_fork = 0;
    int             dont_zero_log = 0;
    int             stderr_log = 0, syslog_log = 0;
    int             uid = 0, gid = 0;
    int             agent_mode = -1;
    char            logfile[PATH_MAX + 1] = { 0 };
    char           *cptr, **argvptr;
    char           *pid_file = NULL;
#if HAVE_GETPID
    int fd;
    FILE           *PID;
#endif

#ifdef LOGFILE
    strncpy(logfile, LOGFILE, PATH_MAX);
#endif

#ifdef NO_ROOT_ACCESS
    /*
     * Default to no.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
#endif
    /*
     * Default to NOT running an AgentX master.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_AGENTX_MASTER, 0);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_RETRIES, -1);

    /*
     * Add some options if they are available.  
     */
#if HAVE_UNISTD_H
    strcat(options, "g:u:");
#endif
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
    strcat(options, "x:");
#endif
#ifdef USING_AGENTX_SUBAGENT_MODULE
    strcat(options, "X");
#endif

    /*
     * Now process options normally.  
     */

    while ((arg = getopt(argc, argv, options)) != EOF) {
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                usage(argv[0]);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            log_addresses++;
            break;

        case 'A':
            dont_zero_log = 1;
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage(argv[0]);
            }
            break;

        case 'C':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
            break;

        case 'd':
            snmp_set_dump_packet(++snmp_dump_packet);
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 'f':
            dont_fork = 1;
            break;

#if HAVE_UNISTD_H
        case 'g':
            if (optarg != NULL) {
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_GROUPID, atoi(optarg));
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'h':
            usage(argv[0]);
            break;

        case 'H':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
            init_agent("snmpd");        /* register our .conf handlers */
            init_mib_modules();
            init_snmp("snmpd");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            exit(0);

        case 'I':
            if (optarg != NULL) {
                add_to_init_list(optarg);
            } else {
                usage(argv[0]);
            }
            break;

        case 'l':
            if (optarg != NULL) {
                if (strlen(optarg) > PATH_MAX) {
                    fprintf(stderr,
                            "%s: logfile path too long (limit %d chars)\n",
                            argv[0], PATH_MAX);
                    exit(1);
                }
                strncpy(logfile, optarg, PATH_MAX);
            } else {
                usage(argv[0]);
            }
            break;

        case 'L':
            stderr_log = 1;
            break;

        case 'P':
            if (optarg != NULL) {
                pid_file = optarg;
            } else {
                usage(argv[0]);
            }
            break;

        case 'q':
            snmp_set_quick_print(1);
            break;

        case 'r':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
            break;

        case 's':
            syslog_log = 1;
            break;

        case 'S':
            if (optarg != NULL) {
                switch (*optarg) {
                case 'd':
                case 'D':
                    Facility = LOG_DAEMON;
                    break;
                case 'i':
                case 'I':
                    Facility = LOG_INFO;
                    break;
                case '0':
                    Facility = LOG_LOCAL0;
                    break;
                case '1':
                    Facility = LOG_LOCAL1;
                    break;
                case '2':
                    Facility = LOG_LOCAL2;
                    break;
                case '3':
                    Facility = LOG_LOCAL3;
                    break;
                case '4':
                    Facility = LOG_LOCAL4;
                    break;
                case '5':
                    Facility = LOG_LOCAL5;
                    break;
                case '6':
                    Facility = LOG_LOCAL6;
                    break;
                case '7':
                    Facility = LOG_LOCAL7;
                    break;
                default:
                    fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
                    usage(argv[0]);
                }
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage(argv[0]);
            }
            break;

        case 'U':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_LEAVE_PIDFILE);
            break;

#if HAVE_UNISTD_H
        case 'u':
            if (optarg != NULL) {
                char           *ecp;
                int             uid;

                uid = strtoul(optarg, &ecp, 10);
                if (*ecp) {
#if HAVE_GETPWNAM && HAVE_PWD_H
                    struct passwd  *info;
                    info = getpwnam(optarg);
                    if (info) {
                        uid = info->pw_uid;
                    } else {
#endif
                        fprintf(stderr, "Bad user id: %s\n", optarg);
                        exit(1);
#if HAVE_GETPWNAM && HAVE_PWD_H
                    }
#endif
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_USERID, uid);
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'v':
            version();

        case 'V':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage(argv[0]);
            }
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_AGENTX_MASTER, 1);
            break;
#endif

        case 'X':
#if defined(USING_AGENTX_SUBAGENT_MODULE)
            agent_mode = SUB_AGENT;
#else
            fprintf(stderr, "%s: Illegal argument -X:"
		            "AgentX support not compiled in.\n", argv[0]);
            usage(argv[0]);
            exit(1);
#endif
            break;

        default:
            usage(argv[0]);
            break;
        }
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
        for (i = optind; i < argc; i++) {
            char *c, *astring;
            if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					   NETSNMP_DS_AGENT_PORTS))) {
                astring = malloc(strlen(c) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", c, argv[i]);
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, astring);
                free(astring);
            } else {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, argv[i]);
            }
        }
        DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
                    netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					  NETSNMP_DS_AGENT_PORTS)));
    }

    setup_log(0, dont_zero_log, stderr_log, syslog_log, logfile);

    /*
     * Initialize a argv set to the current for restarting the agent.   
     */
    argvrestartp = (char **)malloc((argc + 2) * sizeof(char *));
    argvptr = argvrestartp;
    for (i = 0, ret = 1; i < argc; i++) {
        ret += strlen(argv[i]) + 1;
    }
    argvrestart = (char *) malloc(ret);
    argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
    if (!argvrestartp || !argvrestart || !argvrestartname) {
        fprintf(stderr, "malloc failure processing argvrestart\n");
        exit(1);
    }
    strcpy(argvrestartname, argv[0]);
    if (agent_mode == -1) {
        if (strstr(argvrestartname, "agentxd") != NULL) {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, SUB_AGENT);
        } else {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, MASTER_AGENT);
        }
    } else {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_ROLE, agent_mode);
    }

    for (cptr = argvrestart, i = 0; i < argc; i++) {
        strcpy(cptr, argv[i]);
        *(argvptr++) = cptr;
        cptr += strlen(argv[i]) + 1;
    }
    *cptr = 0;
    *argvptr = NULL;

#ifdef BUFSIZ
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif
    /*
     * Initialize the world.  Detach from the shell.  Create initial user.  
     */
#if HAVE_FORK
    if (!dont_fork) {
        /*
         * Fork to return control to the invoking process and to
         * guarantee that we aren't a process group leader.
         */
        if (fork() != 0) {
            /* Parent. */
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                        NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) {
                exit(0);
            }
        } else {
            /* Child. */
#ifdef HAVE_SETSID
            /* Become a process/session group leader. */
            setsid();
#endif
            /*
             * Fork to let the process/session group leader exit.
             */
            if (fork() != 0) {
                /* Parent. */
                exit(0);
            }
#ifndef WIN32
            else {
                /* Child. */

                /* Avoid keeping any directory in use. */
                chdir("/");

                if (!stderr_log) {
                    /*
                     * Close inherited file descriptors to avoid
                     * keeping unnecessary references.
                     */
                    close(0);
                    close(1);
                    close(2);

                    /*
                     * Redirect std{in,out,err} to /dev/null, just in
                     * case.
                     */
                    open("/dev/null", O_RDWR);
                    dup(0);
                    dup(0);
                }
            }
#endif /* !WIN32 */
        }
    }
#endif /* HAVE_FORK */

    SOCK_STARTUP;
    init_agent("snmpd");        /* do what we need to do first. */
    init_mib_modules();

    /*
     * start library 
     */
    init_snmp("snmpd");

    if ((ret = init_master_agent()) != 0) {
        /*
         * Some error opening one of the specified agent transports.  
         */
        Exit(1);                /*  Exit logs exit val for us  */
    }
#ifdef SIGTERM
    DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n"));
    signal(SIGTERM, SnmpdShutDown);
#endif
#ifdef SIGINT
    DEBUGMSGTL(("signal", "registering SIGINT signal handler\n"));
    signal(SIGINT, SnmpdShutDown);
#endif
#ifdef SIGHUP
    DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n"));
    signal(SIGHUP, SnmpdReconfig);
#endif
#ifdef SIGUSR1
    DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n"));
    signal(SIGUSR1, SnmpdDump);
#endif
#ifdef SIGPIPE
    DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n"));
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
#endif

    /*
     * Store persistent data immediately in case we crash later.  
     */
    snmp_store("snmpd");

    /*
     * Send coldstart trap if possible.  
     */
    send_easy_trap(0, 0);

#if HAVE_GETPID
    if (pid_file != NULL) {
	    /*
	     * unlink the pid_file, if it exists, prior to open.  Without
	     * doing this the open will fail if the user specified pid_file
	     * already exists.
	     */
	    unlink(pid_file);
	    fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
	    if (fd == -1) {
		    snmp_log_perror(pid_file);
		    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
			NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
			    exit(1);
		    }
	    } else {
		    if ((PID = fdopen(fd, "w")) == NULL) {
			    snmp_log_perror(pid_file);
			    exit(1);
		    } else {
			    fprintf(PID, "%d\n", (int) getpid());
			    fclose(PID);
		    }
		    close(fd);
	    }
    }
#endif

#if HAVE_UNISTD_H
#ifdef HAVE_SETGID
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_GROUPID)) != 0) {
        DEBUGMSGTL(("snmpd/main", "Changing gid to %d.\n", gid));
        if (setgid(gid) == -1
#ifdef HAVE_SETGROUPS
            || setgroups(1, (gid_t *)&gid) == -1
#endif
            ) {
            snmp_log_perror("setgid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#ifdef HAVE_SETUID
    if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_USERID)) != 0) {
        DEBUGMSGTL(("snmpd/main", "Changing uid to %d.\n", uid));
        if (setuid(uid) == -1) {
            snmp_log_perror("setuid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#endif

    /*
     * We're up, log our version number.  
     */
    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
#ifdef WIN32
    agent_status = AGENT_RUNNING;
#endif
    netsnmp_addrcache_initialise();

    /*
     * Forever monitor the dest_port for incoming PDUs.  
     */
    DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
        receive();
#include "mib_module_shutdown.h"
    DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n"));
    SnmpTrapNodeDown();
    DEBUGMSGTL(("snmpd/main", "Bye...\n"));
    snmp_shutdown("snmpd");
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_LEAVE_PIDFILE) &&
	(pid_file != NULL)) {
        unlink(pid_file);
    }
#ifdef WIN32
    agent_status = AGENT_STOPPED;
#endif
    return 0;
}                               /* End main() -- snmpd */
예제 #6
0
int
main(int argc, char *argv[])
{
    int             arg, i;
    int             ret;
    u_short         dest_port = SNMP_PORT;
    int             dont_fork = 0;
    char            logfile[SNMP_MAXBUF_SMALL];
    char           *cptr, **argvptr;
    char           *pid_file = NULL;
#if HAVE_GETPID
    FILE           *PID;
#endif
    int             dont_zero_log = 0;
    int             stderr_log=0, syslog_log=0;
    int             uid=0, gid=0;

    logfile[0]		= 0;

#ifdef LOGFILE
    strcpy(logfile, LOGFILE);
#endif


    /*
     * usage: snmpd
     */
    for (arg = 1; arg < argc; arg++)
    {
        if (argv[arg][0] == '-') {
            switch (argv[arg][1]) {

            case 'c':
                if (++arg == argc)
                    usage(argv[0]);
                ds_set_string(DS_LIBRARY_ID, DS_LIB_OPTIONALCONFIG,
                              argv[arg]);
                break;

            case 'C':
                ds_set_boolean(DS_LIBRARY_ID, DS_LIB_DONT_READ_CONFIGS, 1);
                break;

            case 'd':
                snmp_set_dump_packet(++snmp_dump_packet);
                ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE, 1);
                break;

            case 'q':
                snmp_set_quick_print(1);
                break;

            case 'T':
                if (argv[arg][2] != '\0')
                    cptr = &argv[arg][2];
                else if (++arg>argc) {
                    fprintf(stderr,"Need UDP or TCP after -T flag.\n");
                    usage(argv[0]);
                    exit(1);
                } else {
                    cptr = argv[arg];
                }
                if (strcasecmp(cptr,"TCP") == 0) {
                    ds_set_int(DS_APPLICATION_ID, DS_AGENT_FLAGS,
                               ds_get_int(DS_APPLICATION_ID, DS_AGENT_FLAGS)
                               | SNMP_FLAGS_STREAM_SOCKET);
                } else if (strcasecmp(cptr,"UDP") == 0) {
                    /* default, do nothing */
                } else {
                    fprintf(stderr,
                            "Unknown transport \"%s\" after -T flag.\n",
                            cptr);
                    usage(argv[0]);
                    exit(1);
                }
                break;

            case 'D':
                debug_register_tokens(&argv[arg][2]);
                snmp_set_do_debugging(1);
                break;

            case 'p':
                if (++arg == argc)
                    usage(argv[0]);
                dest_port = atoi(argv[arg]);
                if (dest_port <= 0)
                    usage(argv[0]);
                break;

            case 'x':
                if (++arg == argc)
                    usage(argv[0]);
                ds_set_string(DS_APPLICATION_ID, DS_AGENT_X_SOCKET, argv[arg]);
                break;

            case 'r':
                ds_set_boolean(DS_APPLICATION_ID,
                               DS_AGENT_NO_ROOT_ACCESS, 1);
                break;

            case 'P':
                if (++arg == argc)
                    usage(argv[0]);
                pid_file = argv[arg];

            case 'a':
                log_addresses++;
                break;

            case 'V':
                ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE, 1);
                break;

            case 'f':
                dont_fork = 1;
                break;

            case 'l':
                if (++arg == argc)
                    usage(argv[0]);
                strcpy(logfile, argv[arg]);
                break;

            case 'L':
                stderr_log=1;
                break;

            case 's':
                syslog_log=1;
                break;

            case 'A':
                dont_zero_log = 1;
                break;
#if HAVE_UNISTD_H
            case 'u':
                if (++arg == argc) usage(argv[0]);
                uid = atoi(argv[arg]);
                break;
            case 'g':
                if (++arg == argc) usage(argv[0]);
                gid = atoi(argv[arg]);
                break;
#endif
            case 'h':
                usage(argv[0]);
                break;
            case 'H':
                init_agent("snmpd");   /* register our .conf handlers */
                init_mib_modules();
                init_snmp("snmpd");
                fprintf(stderr, "Configuration directives understood:\n");
                read_config_print_usage("  ");
                exit(0);
            case 'v':
                printf("\nUCD-snmp version:  %s\n",VersionInfo);
                printf("Author:            Wes Hardaker\n");
                printf("Email:             [email protected]\n\n");
                exit (0);
            case '-':
                switch(argv[arg][2]) {
                case 'v':
                    printf("\nUCD-snmp version:  %s\n",VersionInfo);
                    printf("Author:            Wes Hardaker\n");
                    printf("Email:             [email protected]\n\n");
                    exit (0);
                case 'h':
                    usage(argv[0]);
                    exit(0);
                }

            default:
                printf("invalid option: %s\n", argv[arg]);
                usage(argv[0]);
                break;
            }
            continue;
        }
    }  /* end-for */

    /*
     * Initialize a argv set to the current for restarting the agent.
     */
    argvrestartp = (char **) malloc((argc + 2) * sizeof(char *));
    argvptr = argvrestartp;
    for (i = 0, ret = 1; i < argc; i++) {
        ret += strlen(argv[i]) + 1;
    }
    argvrestart = (char *) malloc(ret);
    argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
    strcpy(argvrestartname, argv[0]);
    if ( strstr(argvrestartname, "agentxd") != NULL)
        ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, SUB_AGENT);
    else
        ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);
    for (cptr = argvrestart, i = 0; i < argc; i++) {
        strcpy(cptr, argv[i]);
        *(argvptr++) = cptr;
        cptr += strlen(argv[i]) + 1;
    }
    *cptr = 0;
    *argvptr = NULL;


    /*
     * Open the logfile if necessary.
     */

    /* Should open logfile and/or syslog based on arguments */
    if (logfile[0])
        snmp_enable_filelog(logfile, dont_zero_log);
    if (syslog_log)
        snmp_enable_syslog();
#ifdef BUFSIZ
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif
    /*
     * Initialize the world.  Detach from the shell.
     * Create initial user.
     */
#if HAVE_FORK
    if (!dont_fork && fork() != 0) {
        exit(0);
    }
#endif

#if HAVE_GETPID
    if (pid_file != NULL) {
        if ((PID = fopen(pid_file, "w")) == NULL) {
            snmp_log_perror("fopen");
            if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
                exit(1);
        }
        else {
            fprintf(PID, "%d\n", (int)getpid());
            fclose(PID);
        }
    }
#endif

#else /* __ECOS environment: */
void snmpd( void *initfunc( void ) ) {
    int             ret;
    u_short         dest_port = SNMP_PORT;
#define stderr_log 1
#endif

    // ---------
    // En-bloc reinitialization of statics.
    running = 1;
    // ---------

    SOCK_STARTUP;
    init_agent("snmpd");		/* do what we need to do first. */
    init_mib_modules();


    /* start library */
    init_snmp("snmpd");

    ret = init_master_agent( dest_port,
                             snmp_check_packet,
                             snmp_check_parse );
    if( ret != 0 )
        Exit(1); /* Exit logs exit val for us */

#ifdef SIGTERM
    signal(SIGTERM, SnmpdShutDown);
#endif
#ifdef SIGINT
    signal(SIGINT, SnmpdShutDown);
#endif
#ifdef SIGHUP
    signal(SIGHUP, SnmpdReconfig);
#endif
#ifdef SIGUSR1
    signal(SIGUSR1, SnmpdDump);
#endif

    /* send coldstart trap via snmptrap(1) if possible */
    send_easy_trap (0, 0);

#if HAVE_UNISTD_H
    if (gid) {
        DEBUGMSGTL(("snmpd", "Changing gid to %d.\n", gid));
        if (setgid(gid)==-1) {
            snmp_log_perror("setgid failed");
            if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
                exit(1);
        }
    }
    if (uid) {
        DEBUGMSGTL(("snmpd", "Changing uid to %d.\n", uid));
        if(setuid(uid)==-1) {
            snmp_log_perror("setuid failed");
            if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS))
                exit(1);
        }
    }
#endif

    /* honor selection of standard error output */
    if (!stderr_log)
        snmp_disable_stderrlog();

    /* we're up, log our version number */
    snmp_log(LOG_INFO, "UCD-SNMP version %s\n", VersionInfo);

    memset(addrCache, 0, sizeof(addrCache));

    /*
     * Call initialization function if necessary
     */
    DEBUGMSGTL(("snmpd", "Calling initfunc().\n"));
    if ( initfunc )
        (initfunc)();

    /*
     * Forever monitor the dest_port for incoming PDUs.
     */
    DEBUGMSGTL(("snmpd", "We're up.  Starting to process data.\n"));
    receive();
#include "mib_module_shutdown.h"
    DEBUGMSGTL(("snmpd", "sending shutdown trap\n"));
    SnmpTrapNodeDown();
    DEBUGMSGTL(("snmpd", "Bye...\n"));
    snmp_shutdown("snmpd");

}  /* End main() -- snmpd */
예제 #7
0
파일: snmptrapd.c 프로젝트: DYFeng/infinidb
main(int argc, char *argv[])
#endif
{
    char            options[128] = "ac:CdD::efF:hHl:L:m:M:no:PqsS:tvO:-:";
    netsnmp_session *sess_list = NULL, *ss = NULL;
    netsnmp_transport *transport = NULL;
    int             arg, i = 0;
    int             count, numfds, block;
    fd_set          fdset;
    struct timeval  timeout, *tvp;
    char           *cp, *listen_ports = NULL;
    int             agentx_subagent = 1, depmsg = 0;

    /*
     * register our configuration handlers now so -H properly displays them 
     */
    snmptrapd_register_configs( );
    init_usm_conf( "snmptrapd" );
    register_config_handler("snmptrapd", "snmptrapdaddr",
                            parse_trapd_address, free_trapd_address, "string");

    register_config_handler("snmptrapd", "doNotLogTraps",
                            parse_config_doNotLogTraps, NULL, "(1|yes|true|0|no|false)");
#if HAVE_GETPID
    register_config_handler("snmptrapd", "pidFile",
                            parse_config_pidFile, NULL, "string");
#endif
    
    register_config_handler("snmptrapd", "logOption",
                            parse_config_logOption, NULL, "string");

    register_config_handler("snmptrapd", "doNotFork",
                            parse_config_doNotFork, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "printEventNumbers",
                            parse_config_printEventNumbers, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "ignoreAuthFailure",
                            parse_config_ignoreAuthFailure, NULL, "(1|yes|true|0|no|false)");

    register_config_handler("snmptrapd", "outputOption",
                            parse_config_outputOption, NULL, "string");
    
#ifdef WIN32
    setvbuf(stdout, NULL, _IONBF, BUFSIZ);
#else
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif

    /*
     * Add some options if they are available.  
     */
#if HAVE_GETPID
    strcat(options, "p:u:");
#endif

    snmp_log_syslogname(app_name);

    /*
     * Now process options normally.  
     */

    while ((arg = getopt(argc, argv, options)) != EOF) {
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                usage();
                exit(0);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
                exit(0);
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            dropauth = 1;
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'C':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
            break;

        case 'd':
            snmp_set_dump_packet(1);
            break;

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 'e':
            Event++;
            break;

        case 'f':
            dofork = 0;
            break;

        case 'F':
            if (optarg != NULL) {
                trap1_fmt_str_remember = optarg;
            } else {
                usage();
                exit(1);
            }
            break;

        case 'h':
            usage();
            exit(0);

        case 'H':
            init_notification_log();
            init_snmp("snmptrapd");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            exit(0);

	case 'S':
            fprintf(stderr,
                    "Warning: -S option is deprecated; use -Ls <facility> instead\n");
            depmsg = 1;
            if (optarg != NULL) {
                switch (*optarg) {
                case 'd':
                case 'D':
                    Facility = LOG_DAEMON;
                    break;
                case 'i':
                case 'I':
                    Facility = LOG_INFO;
                    break;
                case '0':
                    Facility = LOG_LOCAL0;
                    break;
                case '1':
                    Facility = LOG_LOCAL1;
                    break;
                case '2':
                    Facility = LOG_LOCAL2;
                    break;
                case '3':
                    Facility = LOG_LOCAL3;
                    break;
                case '4':
                    Facility = LOG_LOCAL4;
                    break;
                case '5':
                    Facility = LOG_LOCAL5;
                    break;
                case '6':
                    Facility = LOG_LOCAL6;
                    break;
                case '7':
                    Facility = LOG_LOCAL7;
                    break;
                default:
                    fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
                    usage();
                    exit(1);
                }
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage();
                exit(1);
            }
            break;

        case 'm':
            if (optarg != NULL) {
                setenv("MIBS", optarg, 1);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'M':
            if (optarg != NULL) {
                setenv("MIBDIRS", optarg, 1);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'n':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_APP_NUMERIC_IP, 1);
            break;

        case 'o':
            fprintf(stderr,
                    "Warning: -o option is deprecated; use -Lf <file> instead\n");
            Print++;
            if (optarg != NULL) {
                logfile = optarg;
                snmp_enable_filelog(optarg, 0);
            } else {
                usage();
                exit(1);
            }
            break;

        case 'O':
            cp = snmp_out_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown output option passed to -O: %c\n",
			*cp);
                usage();
                exit(1);
            }
            break;

        case 'L':
	    if  (snmp_log_options( optarg, argc, argv ) < 0 ) {
                usage();
                exit(1);
            }
            Log++;
            break;

        case 'P':
            fprintf(stderr,
                    "Warning: -P option is deprecated; use -f -Le instead\n");
            dofork = 0;
            snmp_enable_stderrlog();
            Print++;
            break;

        case 's':
            fprintf(stderr,
                    "Warning: -s option is deprecated; use -Lsd instead\n");
            depmsg = 1;
            Syslog++;
            break;

        case 't':
            SyslogTrap++;
            break;


#if HAVE_GETPID
        case 'u':
            fprintf(stderr,
                    "Warning: -u option is deprecated; use -p instead\n");
        case 'p':
            if (optarg != NULL) {
                parse_config_pidFile(NULL, optarg);
            } else {
                usage();
                exit(1);
            }
            break;
#endif

        case 'v':
            version();
            exit(0);
            break;

        default:
            fprintf(stderr, "invalid option: -%c\n", arg);
            usage();
            exit(1);
            break;
        }
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        for (i = optind; i < argc; i++) {
            char *astring;
            if (listen_ports != NULL) {
                astring = malloc(strlen(listen_ports) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", listen_ports, argv[i]);
                free(listen_ports);
                listen_ports = astring;
            } else {
                listen_ports = strdup(argv[i]);
                if (listen_ports == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
            }
        }
    }

    /*
     * I'm being lazy here, and not checking the
     * return value from these registration calls.
     * Don't try this at home, children!
     */
    if (!Log && !Print) {
        Syslog = 1;
        netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER, syslog_handler);
    } else {
        netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER, print_handler);
    }
    netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER, notification_handler);

    if (Event) {
        netsnmp_add_traphandler(event_handler, risingAlarm,
                                    OID_LENGTH(risingAlarm));
        netsnmp_add_traphandler(event_handler, fallingAlarm,
                                    OID_LENGTH(fallingAlarm));
        netsnmp_add_traphandler(event_handler, unavailableAlarm,
                                    OID_LENGTH(unavailableAlarm));
	/* XXX - might be worth setting some "magic data"
	 * in the traphandler structure that 'event_handler'
	 * can use to avoid checking the trap OID values.
	 */
    }

#ifdef USING_AGENTX_SUBAGENT_MODULE
    /*
     * we're an agentx subagent? 
     */
    if (agentx_subagent) {
        /*
         * make us a agentx client. 
         */
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
			       NETSNMP_DS_AGENT_ROLE, 1);
    }
#endif

    /*
     * don't fail if we can't do agentx (ie, socket not there, or not root) 
     */
    netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
			      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
    /*
     * ignore any warning messages.
     */
    netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
			      NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS);

    /*
     * initialize the agent library 
     */
    init_agent("snmptrapd");

    /*
     * initialize local modules 
     */
    if (agentx_subagent) {
        extern void init_register_usmUser_context(const char *);
#ifdef USING_AGENTX_SUBAGENT_MODULE
	void  init_subagent(void);
        init_subagent();
#endif
        /* register the notification log table */
        init_notification_log();

        /* register ourselves as having a USM user database */
        init_register_usmUser_context("snmptrapd");
    }

#ifdef NETSNMP_EMBEDDED_PERL
    init_perl();
    {
        /* set the default path to load */
        char            init_file[SNMP_MAXBUF];
        snprintf(init_file, sizeof(init_file) - 1,
                 "%s/%s", SNMPSHAREPATH, "snmp_perl_trapd.pl");
        netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_AGENT_PERL_INIT_FILE,
                              init_file);
    }
#endif

    /*
     * Initialize the world.
     */
    init_snmp("snmptrapd");

    if (trap1_fmt_str_remember) {
        free_trap1_fmt();
        free_trap2_fmt();
        print_format1 = strdup(trap1_fmt_str_remember);
        print_format2 = strdup(trap1_fmt_str_remember);
    }

    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) {
        /*
         * just starting up to process specific configuration and then
         * shutting down immediately. 
         */
        running = 0;
    }
#ifndef WIN32
    /*
     * fork the process to the background if we are not printing to stderr 
     */
    if (dofork && running) {
        int             fd;

        switch (fork()) {
        case -1:
            fprintf(stderr, "bad fork - %s\n", strerror(errno));
            _exit(1);

        case 0:
            /*
             * become process group leader 
             */
            if (setsid() == -1) {
                fprintf(stderr, "bad setsid - %s\n", strerror(errno));
                _exit(1);
            }

            /*
             * if we are forked, we don't want to print out to stdout or stderr 
             */
            fd = open("/dev/null", O_RDWR);
            dup2(fd, STDIN_FILENO);
            dup2(fd, STDOUT_FILENO);
            dup2(fd, STDERR_FILENO);
            close(fd);
            break;

        default:
            _exit(0);
        }
    }
#endif                          /* WIN32 */
#if HAVE_GETPID
    if (pid_file != NULL) {
        if ((PID = fopen(pid_file, "w")) == NULL) {
            snmp_log_perror("fopen");
            exit(1);
        }
        fprintf(PID, "%d\n", (int) getpid());
        fclose(PID);
        free_config_pidFile();
    }
#endif

    if (Syslog) {
        snmp_enable_syslog_ident(app_name, Facility);
        snmp_log(LOG_INFO, "Starting snmptrapd %s\n", netsnmp_get_version());
	if (depmsg) {
	    snmp_log(LOG_WARNING, "-s and -S options are deprecated; use -Ls <facility> instead\n");
	}
    }
    if (Print || Log) {
        struct tm      *tm;
        time_t          timer;
        time(&timer);
        tm = localtime(&timer);
        snmp_log(LOG_INFO,
                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Started.\n",
                 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
                 tm->tm_hour, tm->tm_min, tm->tm_sec,
                 netsnmp_get_version());
    }

    SOCK_STARTUP;

    if (listen_ports)
        cp = listen_ports;
    else
        cp = default_port;

    while (cp != NULL) {
        char *sep = strchr(cp, ',');
        char  listen_name[128];
        char *cp2 = strchr(cp, ':');

        if (sep != NULL) {
            *sep = 0;
        }

           /*
            * Make sure this defaults to listening on port 162
            */
        if (!cp2) {
            snprintf(listen_name, sizeof(listen_name), "%s:162", cp);
            cp2 = listen_name;
        } else {
            cp2 = cp;
        }
        transport = netsnmp_tdomain_transport(cp2, 1, "udp");
        if (transport == NULL) {
            snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n",
                     cp2, errno, strerror(errno));
            snmptrapd_close_sessions(sess_list);
            SOCK_CLEANUP;
            exit(1);
        } else {
            ss = snmptrapd_add_session(transport);
            if (ss == NULL) {
                /*
                 * Shouldn't happen?  We have already opened the transport
                 * successfully so what could have gone wrong?  
                 */
                snmptrapd_close_sessions(sess_list);
                netsnmp_transport_free(transport);
                if (Syslog) {
                    snmp_log(LOG_ERR, "couldn't open snmp - %m");
                }
                SOCK_CLEANUP;
                exit(1);
            } else {
                ss->next = sess_list;
                sess_list = ss;
            }
        }

        /*
         * Process next listen address, if there is one.  
         */

        if (sep != NULL) {
            *sep = ',';
            cp = sep + 1;
        } else {
            cp = NULL;
        }
    }

    signal(SIGTERM, term_handler);
#ifdef SIGHUP
    signal(SIGHUP, hup_handler);
#endif
    signal(SIGINT, term_handler);

#ifdef WIN32SERVICE
    trapd_status = SNMPTRAPD_RUNNING;
#endif
    while (running) {
        if (reconfig) {
            if (Print || Log) {
                struct tm      *tm;
                time_t          timer;
                time(&timer);
                tm = localtime(&timer);

                /*
                 * If we are logging to a file, receipt of SIGHUP also
                 * indicates the the log file should be closed and
                 * re-opened.  This is useful for users that want to
                 * rotate logs in a more predictable manner.
                 */
                if (logfile)
                    snmp_enable_filelog(logfile, 1);

                snmp_log(LOG_INFO,
                         "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Reconfigured.\n",
                         tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
                         tm->tm_hour, tm->tm_min, tm->tm_sec,
                         netsnmp_get_version());
            }
            if (Syslog)
                snmp_log(LOG_INFO, "Snmptrapd reconfiguring");
            trapd_update_config();
            if (trap1_fmt_str_remember) {
                free_trap1_fmt();
                print_format1 = strdup(trap1_fmt_str_remember);
            }
            reconfig = 0;
        }
        numfds = 0;
        FD_ZERO(&fdset);
        block = 0;
        tvp = &timeout;
        timerclear(tvp);
        tvp->tv_sec = 5;
        snmp_select_info(&numfds, &fdset, tvp, &block);
        if (block == 1)
            tvp = NULL;         /* block without timeout */
        count = select(numfds, &fdset, 0, 0, tvp);
        gettimeofday(&Now, 0);
        if (count > 0) {
            snmp_read(&fdset);
        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                if (errno == EINTR)
                    continue;
                snmp_log_perror("select");
                running = 0;
                break;
            default:
                fprintf(stderr, "select returned %d\n", count);
                running = 0;
            }
	run_alarms();
    }

    if (Print || Log) {
        struct tm      *tm;
        time_t          timer;
        time(&timer);
        tm = localtime(&timer);
        snmp_log(LOG_INFO,
                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Stopped.\n",
                 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
                 tm->tm_min, tm->tm_sec, netsnmp_get_version());
    }
    if (Syslog) {
        snmp_log(LOG_INFO, "Stopping snmptrapd");
    }

    snmptrapd_close_sessions(sess_list);
    snmp_shutdown("snmptrapd");
#ifdef WIN32SERVICE
    trapd_status = SNMPTRAPD_STOPPED;
#endif
    snmp_disable_log();
    SOCK_CLEANUP;
    return 0;
}
예제 #8
0
int
snmp_parse_args(int argc, 
		char *argv[], 
		struct snmp_session *session)
{
  int arg;
  char *psz, *cp;
#ifdef USE_V2PARTY_PROTOCOL
  static oid src[MAX_OID_LEN];
  static oid dst[MAX_OID_LEN];
  static oid context[MAX_OID_LEN];
  struct partyEntry *pp;
  struct contextEntry *cxp;
  struct hostent *hp;
  char ctmp[300];
  in_addr_t destAddr;
  int clock_flag = 0;
  u_long srcclock = 0;
  u_long dstclock = 0;
#endif

  /* initialize session to default values */
  snmp_sess_init( session );

  /* get the options */
  for(arg = 1; (arg < argc) && (argv[arg][0] == '-'); arg++){
    switch(argv[arg][1]){
      case 'd':
        snmp_set_dump_packet(1);
        break;

      case 'R':
        random_access = 1;
        break;

      case 'q':
        snmp_set_quick_print(1);
        break;

      case 'D':
        debug_register_tokens(&argv[arg][2]);
        snmp_set_do_debugging(1);
        break;
        
      case 'm':
        if (argv[arg][2] != 0)
          setenv("MIBS",&argv[arg][2], 1);
        else if (++arg < argc)
          setenv("MIBS",argv[arg], 1);
        else {
          fprintf(stderr,"Need MIBS after -m flag.\n");
          usage();
          exit(1);
        }
        break;

      case 'M':
        if (argv[arg][2] != 0)
          setenv("MIBDIRS",&argv[arg][2], 1);
        else if (++arg < argc)
          setenv("MIBDIRS",argv[arg], 1);
        else {
          fprintf(stderr,"Need MIBDIRS after -M flag.\n");
          usage();
          exit(1);
        }
        break;
        
      case 'f':
	snmp_set_full_objid(1);
	break;

      case 's':
	snmp_set_suffix_only(1);
	break;

      case 'S':
	snmp_set_suffix_only(2);
	break;

      case 'p':
        if (isdigit(argv[arg][2]))
          session->remote_port = atoi(&(argv[arg][2]));
        else if ((++arg<argc) && isdigit(argv[arg][0]))
          session->remote_port = atoi(argv[arg]);
        else {
          fprintf(stderr,"Need port number after -p flag.\n");
          usage();
          exit(1);
        }
        break;

      case 't':
        if (isdigit(argv[arg][2]))
          session->timeout = atoi(&(argv[arg][2])) * 1000000L;
        else if ((++arg<argc) && isdigit(argv[arg][0]))
          session->timeout = atoi(argv[arg]) * 1000000L;
        else {
          fprintf(stderr,"Need time in seconds after -t flag.\n");
          usage();
          exit(1);
        }
        break;

      case 'r':
        if (isdigit(argv[arg][2]))
          session->retries = atoi(&(argv[arg][2]));
        else if ((++arg<argc) && isdigit(argv[arg][0]))
          session->retries = atoi(argv[arg]);
        else {
          fprintf(stderr,"Need number of retries after -r flag.\n");
          usage();
          exit(1);
        }
        break;

#ifdef USE_V2PARTY_PROTOCOL
      case 'c':
        clock_flag++;
        if (isdigit(argv[arg][2]))
          srcclock = (u_long)(atol(&(argv[arg][2])));
        else if ((++arg<argc) && isdigit(argv[arg][0]))
          srcclock = (u_long)(atol(argv[arg]));
        else {
          fprintf(stderr,"Need source clock value after -c flag.\n");
          usage();
          exit(1);
        }
        if ((++arg<argc) && isdigit(argv[arg][0]))
          dstclock = (u_long)(atol(argv[arg]));
        else {
          fprintf(stderr,"Need destination clock value after -c flag.\n");
          usage();
          exit(1);
        }
        break;
#endif /* USE_V2PARTY_PROTOCOL */

      case 'V':
        fprintf(stderr,"UCD-snmp version: %s\n", VersionInfo);
        exit(0);

      case 'v':
        if (argv[arg][2] != 0)
          psz = &(argv[arg][2]);
        else
          psz = argv[++arg];
        if( psz == NULL) {
          fprintf(stderr,"Need version value after -v flag. \n");
          usage();
          exit(1);
        }
        if (!strcmp(psz,"1")) {
          session->version = SNMP_VERSION_1;
        } else if (!strcasecmp(psz,"2c")) {
          session->version = SNMP_VERSION_2c;
        } else if (!strcasecmp(psz,"2p")) {
          session->version = SNMP_VERSION_2p;
        } else {
          fprintf(stderr,"Invalid version specified after -v flag: %s\n", psz);
          usage();
          exit(1);
        }
        break;

      case 'h':
        usage();
        exit(0);
        break;

      case 'H':
        init_snmp();
        fprintf(stderr, "Configuration directives understood:\n");
        read_config_print_usage("  ");
        exit(0);

      case 'P':
        if (argv[arg][2] != 0)
          cp = &argv[arg][2];
        else if (++arg<argc)
          cp = &argv[arg][2];
        else {
          fprintf(stderr,"Need option arguments after -P flag.\n");
          usage();
          exit(1);
        }
        cp = snmp_mib_toggle_options(cp);
        if (cp != NULL) {
          fprintf(stderr,"Unknown parsing option passed to -P: %c.\n", *cp);
          usage();
          exit(1);
        }
        break;

      default:
        /* This should be removed to support options in clients that
           have more parameters than the defaults above! */
        fprintf(stderr, "invalid option: -%c\n", argv[arg][1]);
        usage();
        exit(1);
        break;
    }
  }

  /* read in MIB database and initialize the snmp library*/
  init_snmp();

  /* get the hostname */
  if (arg == argc) {
    fprintf(stderr,"No hostname specified.\n");
    usage();
    exit(1);
  }
  session->peername = argv[arg++];     /* hostname */

  /* get community or party */
  if ((session->version == SNMP_VERSION_1) ||
      (session->version == SNMP_VERSION_2c)) {
    /* v1 and v2c - so get community string */
    if (arg == argc) {
      fprintf(stderr,"No community name specified.\n");
      usage();
      exit(1);
    }
    session->community = (unsigned char *)argv[arg];
    session->community_len = strlen((char *)argv[arg]);
    arg++;
#ifdef USE_V2PARTY_PROTOCOL
  } else {
    /* v2p - so get party info */
    if (arg == argc) {
      fprintf(stderr,"Neither a source party nor noAuth was specified.\n");
      usage();
      exit(1);
    }

    session->srcParty = src;
    session->dstParty = dst;
    session->context = context;

    if (!strcasecmp(argv[arg], "noauth")){
      if ((destAddr = inet_addr(session->peername)) == -1){
        hp = gethostbyname(session->peername);
        if (hp == NULL){
          fprintf(stderr, "unknown host: %s\n", session->peername);
          exit(1);
        } else {
          memmove(&destAddr, hp->h_addr, hp->h_length);
        }
      }
      session->srcPartyLen = session->dstPartyLen =
                    session->contextLen = MAX_OID_LEN;
      ms_party_init(destAddr, session->srcParty, &(session->srcPartyLen),
                    session->dstParty, &(session->dstPartyLen),
                    session->context, &(session->contextLen));
      arg++;
    } else {
      sprintf(ctmp,"%s/party.conf",SNMPSHAREPATH);
      if (read_party_database(ctmp) != 0){
	snmp_perror(argv[0]);
        exit(1);
      }
      sprintf(ctmp,"%s/context.conf",SNMPSHAREPATH);
      if (read_context_database(ctmp) != 0){
	snmp_perror(argv[0]);
        exit(1);
      }
      sprintf(ctmp,"%s/acl.conf",SNMPSHAREPATH);
      if (read_acl_database(ctmp) != 0){
	snmp_perror(argv[0]);
        exit(1);
      }

      /* source party */
      
      party_scanInit();
      session->srcPartyLen = MAX_OID_LEN;
      for(pp = party_scanNext(); pp; pp = party_scanNext()){
        if (!strcasecmp(pp->partyName, argv[arg])){
          session->srcPartyLen = pp->partyIdentityLen;
          memmove(session->srcParty, pp->partyIdentity,
                  session->srcPartyLen * sizeof(oid));
          break;
        }
      }
      if (!pp){
        session->srcPartyLen = MAX_OID_LEN;
        if (!read_objid(argv[arg], session->srcParty, &(session->srcPartyLen))){
          fprintf(stderr,"Invalid source party: %s.\n", argv[arg]);
          session->srcPartyLen = 0;
          usage();
          exit(1);
        }
      }
      arg++;

      if (arg == argc) {
        fprintf(stderr,"No destination party specified.\n");
        usage();
        exit(1);
      }

      /* destination party */
      
      session->dstPartyLen = MAX_OID_LEN;
      party_scanInit();
      for(pp = party_scanNext(); pp; pp = party_scanNext()){
        if (!strcasecmp(pp->partyName, argv[arg])){
          session->dstPartyLen = pp->partyIdentityLen;
          memmove(session->dstParty, pp->partyIdentity,
                  session->dstPartyLen * sizeof(oid));
          break;
        }
      }
      if (!pp){
        if (!read_objid(argv[arg], session->dstParty, &(session->dstPartyLen))){
          fprintf(stderr,"Invalid destination party: %s.\n", argv[arg]);
          session->dstPartyLen = 0;
          usage();
          exit(1);
        }
      }
      arg++;

      /* context */

      if (arg == argc) {
        fprintf(stderr,"No context specified.\n");
        usage();
        exit(1);
      }

      session->contextLen = MAX_OID_LEN;
      context_scanInit();
      for(cxp = context_scanNext(); cxp; cxp = context_scanNext()){
        if (!strcasecmp(cxp->contextName, argv[arg])){
          session->contextLen = cxp->contextIdentityLen;
          memmove(session->context, cxp->contextIdentity,
                  session->contextLen * sizeof(oid));
          break;
        }
      }
      if (!cxp){
        if (!read_objid(argv[arg], session->context, &(session->contextLen))){
          fprintf(stderr,"Invalid context: %s.\n", argv[arg]);
          session->contextLen = 0;
          usage();
          exit(1);
        }
      }
      arg++;

      if (clock_flag){
        pp = party_getEntry(session->srcParty, session->srcPartyLen);
        if (pp){
            pp->partyAuthClock = srcclock;
            gettimeofday(&pp->tv, (struct timezone *)0);
            pp->tv.tv_sec -= pp->partyAuthClock;
        }
        pp = party_getEntry(session->dstParty, session->dstPartyLen);
        if (pp){
            pp->partyAuthClock = dstclock;
            gettimeofday(&pp->tv, (struct timezone *)0);
            pp->tv.tv_sec -= pp->partyAuthClock;
        }
      }
    }
#endif /* USE_V2PARTY_PROTOCOL */
  }
  return arg;
}