int main (int argc, char **argv)
{
	int argi;
	char *configfn = NULL;
	int cfgcheck = 0;
	int mibcheck = 0;

	libxymon_init(argv[0]);

	for (argi = 1; (argi < argc); argi++) {
		if (standardoption(argv[argi])) {
			if (showhelp) return 0;
		}
		else if (strcmp(argv[argi], "--cfgcheck") == 0) {
			cfgcheck = 1;
		}
		else if (strcmp(argv[argi], "--mibcheck") == 0) {
			mibcheck = 1;
		}
		else if (argnmatch(argv[argi], "--timeout=")) {
			char *p = strchr(argv[argi], '=');
			timeout = 1000000*atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--retries=")) {
			char *p = strchr(argv[argi], '=');
			retries = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--concurrency=")) {
			char *p = strchr(argv[argi], '=');
			max_pending_requests = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--report=")) {
			char *p = strchr(argv[argi], '=');
			reportcolumn = strdup(p+1);
			timing = 1;
		}
		else if (*argv[argi] != '-') {
			configfn = strdup(argv[argi]);
		}
	}

	add_timestamp("xymon-snmpcollect startup");

	netsnmp_register_loghandler(NETSNMP_LOGHANDLER_STDERR, 7);
	init_snmp("xymon-snmpcollect");
	snmp_mib_toggle_options("e");	/* Like -Pe: Dont show MIB parsing errors */
	snmp_out_toggle_options("qn");	/* Like -Oqn: OID's printed as numbers, values printed without type */

	readmibs(NULL, mibcheck);

	if (configfn == NULL) {
		configfn = (char *)malloc(PATH_MAX);
		sprintf(configfn, "%s/etc/snmphosts.cfg", xgetenv("XYMONHOME"));
	}
	readconfig(configfn, mibcheck);
	if (cfgcheck) return 0;
	add_timestamp("Configuration loaded");

	resolvekeys();
	add_timestamp("Keys lookup complete");

	getdata();
	stophosts();
	add_timestamp("Data retrieved");

	sendresult();
	add_timestamp("Results transmitted");

	if (reportcolumn) egoresult(COL_GREEN, reportcolumn);

	xfree(configfn);

	return 0;
}
int
main(int argc, char *argv[])
{
    int             arg;
    char           *current_name = NULL, *cp = NULL;
    oid             name[MAX_OID_LEN];
    size_t          name_length;
    int             description = 0;
    int             print = 0;
    int             find_all = 0;
    int             width = 1000000;

    /*
     * usage: snmptranslate name
     */
    while ((arg = getopt(argc, argv, "Vhm:M:w:D:P:T:O:I:L:")) != EOF) {
        switch (arg) {
        case 'h':
            usage();
            exit(1);

        case 'm':
            setenv("MIBS", optarg, 1);
            break;
        case 'M':
            setenv("MIBDIRS", optarg, 1);
            break;
        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;
        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n",
                    netsnmp_get_version());
            exit(0);
            break;
        case 'w':
	    width = atoi(optarg);
	    if (width <= 0) {
		fprintf(stderr, "Invalid width specification: %s\n", optarg);
		exit (1);
	    }
	    break;
#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */
        case 'O':
            cp = snmp_out_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown OID option to -O: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
        case 'I':
            cp = snmp_in_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown OID option to -I: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
        case 'T':
            for (cp = optarg; *cp; cp++) {
                switch (*cp) {
#ifndef NETSNMP_DISABLE_MIB_LOADING
                case 'l':
                    print = 3;
                    print_oid_report_enable_labeledoid();
                    break;
                case 'o':
                    print = 3;
                    print_oid_report_enable_oid();
                    break;
                case 's':
                    print = 3;
                    print_oid_report_enable_symbolic();
                    break;
                case 't':
                    print = 3;
                    print_oid_report_enable_suffix();
                    break;
                case 'z':
                    print = 3;
                    print_oid_report_enable_mibchildoid();
                    break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */
                case 'd':
                    description = 1;
                    snmp_set_save_descriptions(1);
                    break;
                case 'B':
                    find_all = 1;
                    break;
                case 'p':
                    print = 1;
                    break;
                case 'a':
                    print = 2;
                    break;
                default:
                    fprintf(stderr, "Invalid -T<lostpad> character: %c\n",
                            *cp);
                    usage();
                    exit(1);
                    break;
                }
            }
            break;
        case 'L':
            if (snmp_log_options(optarg, argc, argv) < 0) {
                return (-1);
            }
            break;
        default:
            fprintf(stderr, "invalid option: -%c\n", arg);
            usage();
            exit(1);
            break;
        }
    }

    init_snmp("snmpapp");
    if (optind < argc)
        current_name = argv[optind];

    if (current_name == NULL) {
        switch (print) {
        default:
            usage();
            exit(1);
#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 1:
            print_mib_tree(stdout, get_tree_head(), width);
            break;
        case 2:
            print_ascii_dump(stdout);
            break;
        case 3:
            print_oid_report(stdout);
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */
        }
        exit(0);
    }

    do {
        name_length = MAX_OID_LEN;
        if (snmp_get_random_access()) {
#ifndef NETSNMP_DISABLE_MIB_LOADING
            if (!get_node(current_name, name, &name_length)) {
#endif /* NETSNMP_DISABLE_MIB_LOADING */
                fprintf(stderr, "Unknown object identifier: %s\n",
                        current_name);
                exit(2);
#ifndef NETSNMP_DISABLE_MIB_LOADING
            }
#endif /* NETSNMP_DISABLE_MIB_LOADING */
        } else if (find_all) {
            if (0 == show_all_matched_objects(stdout, current_name,
                                              name, &name_length,
                                              description, width)) {
                fprintf(stderr,
                        "Unable to find a matching object identifier for \"%s\"\n",
                        current_name);
                exit(1);
            }
            exit(0);
        } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
					  NETSNMP_DS_LIB_REGEX_ACCESS)) {
#ifndef NETSNMP_DISABLE_MIB_LOADING
            if (0 == get_wild_node(current_name, name, &name_length)) {
#endif /* NETSNMP_DISABLE_MIB_LOADING */
                fprintf(stderr,
                        "Unable to find a matching object identifier for \"%s\"\n",
                        current_name);
                exit(1);
#ifndef NETSNMP_DISABLE_MIB_LOADING
            }
#endif /* NETSNMP_DISABLE_MIB_LOADING */
        } else {
            if (!read_objid(current_name, name, &name_length)) {
                snmp_perror(current_name);
                exit(2);
            }
        }


        if (print == 1) {
#ifndef NETSNMP_DISABLE_MIB_LOADING
            struct tree    *tp;
            tp = get_tree(name, name_length, get_tree_head());
            if (tp == NULL) {
#endif /* NETSNMP_DISABLE_MIB_LOADING */
                snmp_log(LOG_ERR,
                        "Unable to find a matching object identifier for \"%s\"\n",
                        current_name);
                exit(1);
#ifndef NETSNMP_DISABLE_MIB_LOADING
            }
            print_mib_tree(stdout, tp, width);
#endif /* NETSNMP_DISABLE_MIB_LOADING */
        } else {
            print_objid(name, name_length);
            if (description) {
#ifndef NETSNMP_DISABLE_MIB_LOADING
                print_description(name, name_length, width);
#endif /* NETSNMP_DISABLE_MIB_LOADING */
            }
        }
        current_name = argv[++optind];
        if (current_name != NULL)
            printf("\n");
    } while (optind < argc);

    return (0);
}
int
netsnmp_parse_args(int argc,
                   char **argv,
                   netsnmp_session * session, const char *localOpts,
                   void (*proc) (int, char *const *, int),
                   int flags)
{
    static char	   *sensitive[4] = { NULL, NULL, NULL, NULL };
    int             arg, sp = 0, testcase = 0;
    char           *cp;
    char           *Apsz = NULL;
    char           *Xpsz = NULL;
    char           *Cpsz = NULL;
    char            Opts[BUF_SIZE];
    int             zero_sensitive = !( flags & NETSNMP_PARSE_ARGS_NOZERO );
    char           *backup_NETSNMP_DS_LIB_OUTPUT_PRECISION = NULL;

    /*
     * initialize session to default values 
     */
    snmp_sess_init(session);
    strcpy(Opts, "Y:VhHm:M:O:I:P:D:dv:r:t:c:Z:e:E:n:u:l:x:X:a:A:p:T:-:3:s:S:L:");
    if (localOpts) {
        if (strlen(localOpts) + strlen(Opts) >= sizeof(Opts)) {
            snmp_log(LOG_ERR, "Too many localOpts in snmp_parse_args()\n");
            return -1;
        }
        strcat(Opts, localOpts);
    }

    /*
     * get the options 
     */
    DEBUGMSGTL(("snmp_parse_args", "starting: %d/%d\n", optind, argc));
    for (arg = 0; arg < argc; arg++) {
        DEBUGMSGTL(("snmp_parse_args", " arg %d = %s\n", arg, argv[arg]));
    }

    optind = 1;
    while ((arg = getopt(argc, argv, Opts)) != EOF) {
        DEBUGMSGTL(("snmp_parse_args", "handling (#%d): %c\n", optind, arg));
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            if (strcasecmp(optarg, "version") == 0) {
                fprintf(stderr,"NET-SNMP version: %s\n",netsnmp_get_version());
                return (NETSNMP_PARSE_ARGS_SUCCESS_EXIT);
            }

            handle_long_opt(optarg);
            break;

        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
            return (NETSNMP_PARSE_ARGS_SUCCESS_EXIT);

        case 'h':
            return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            break;

        case 'H':
            init_snmp("snmpapp");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            return (NETSNMP_PARSE_ARGS_SUCCESS_EXIT);

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

#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 'm':
            setenv("MIBS", optarg, 1);
            break;

        case 'M':
            netsnmp_get_mib_directory(); /* prepare the default directories */
            netsnmp_set_mib_directory(optarg);
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */

        case 'O':
            cp = snmp_out_options(optarg, argc, argv);
            if (cp != NULL) {
                fprintf(stderr, "Unknown output option passed to -O: %c.\n", 
			*cp);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'I':
            cp = snmp_in_options(optarg, argc, argv);
            if (cp != NULL) {
                fprintf(stderr, "Unknown input option passed to -I: %c.\n",
			*cp);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr,
                        "Unknown parsing option passed to -P: %c.\n", *cp);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */

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

        case 'd':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DUMP_PACKET, 1);
            break;

        case 'v':
            session->version = -1;
#ifndef NETSNMP_DISABLE_SNMPV1
            if (!strcmp(optarg, "1")) {
                session->version = SNMP_VERSION_1;
            }
#endif
#ifndef NETSNMP_DISABLE_SNMPV2C
            if (!strcasecmp(optarg, "2c")) {
                session->version = SNMP_VERSION_2c;
            }
#endif
            if (!strcasecmp(optarg, "3")) {
                session->version = SNMP_VERSION_3;
            }
            if (session->version == -1) {
                fprintf(stderr,
                        "Invalid version specified after -v flag: %s\n",
                        optarg);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'p':
            fprintf(stderr, "Warning: -p option is no longer used - ");
            fprintf(stderr, "specify the remote host as HOST:PORT\n");
            return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            break;

        case 'T':
        {
            char leftside[SNMP_MAXBUF_MEDIUM], rightside[SNMP_MAXBUF_MEDIUM];
            char *tmpcp, *tmpopt;
            
            /* ensure we have a proper argument */
            tmpopt = strdup(optarg);
            tmpcp = strchr(tmpopt, '=');
            if (!tmpcp) {
                fprintf(stderr, "-T expects a NAME=VALUE pair.\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            *tmpcp++ = '\0';

            /* create the transport config container if this is the first */
            if (!session->transport_configuration) {
                netsnmp_container_init_list();
                session->transport_configuration =
                    netsnmp_container_find("transport_configuration:fifo");
                if (!session->transport_configuration) {
                    fprintf(stderr, "failed to initialize the transport configuration container\n");
                    free(tmpopt);
                    return (NETSNMP_PARSE_ARGS_ERROR);
                }

                session->transport_configuration->compare =
                    (netsnmp_container_compare*)
                    netsnmp_transport_config_compare;
            }

            /* set the config */
            strlcpy(leftside, tmpopt, sizeof(leftside));
            strlcpy(rightside, tmpcp, sizeof(rightside));

            CONTAINER_INSERT(session->transport_configuration,
                             netsnmp_transport_create_config(leftside,
                                                             rightside));
            free(tmpopt);
        }
        break;
            
        case 't':
            session->timeout = (long)(atof(optarg) * 1000000L);
            if (session->timeout <= 0) {
                fprintf(stderr, "Invalid timeout in seconds after -t flag.\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'r':
            session->retries = atoi(optarg);
            if (session->retries < 0 || !isdigit((unsigned char)(optarg[0]))) {
                fprintf(stderr, "Invalid number of retries after -r flag.\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'c':
	    if (zero_sensitive) {
		if ((sensitive[sp] = strdup(optarg)) != NULL) {
		    Cpsz = sensitive[sp];
		    memset(optarg, '\0', strlen(optarg));
		    sp++;
		} else {
		    fprintf(stderr, "malloc failure processing -c flag.\n");
		    return NETSNMP_PARSE_ARGS_ERROR;
		}
	    } else {
		Cpsz = optarg;
	    }
            break;

        case '3':
	    /*  TODO: This needs to zero things too.  */
            if (snmpv3_options(optarg, session, &Apsz, &Xpsz, argc, argv) < 0){
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'L':
            if (snmp_log_options(optarg, argc, argv) < 0) {
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

#define SNMPV3_CMD_OPTIONS
#ifdef  SNMPV3_CMD_OPTIONS
        case 'Z':
            errno = 0;
            session->engineBoots = strtoul(optarg, &cp, 10);
            if (errno || cp == optarg) {
                fprintf(stderr, "Need engine boots value after -Z flag.\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            if (*cp == ',') {
                char *endptr;
                cp++;
                session->engineTime = strtoul(cp, &endptr, 10);
                if (errno || cp == endptr) {
                    fprintf(stderr, "Need engine time after \"-Z engineBoot,\".\n");
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
            }
            /*
             * Handle previous '-Z boot time' syntax 
             */
            else if (optind < argc) {
                session->engineTime = strtoul(argv[optind], &cp, 10);
                if (errno || cp == argv[optind]) {
                    fprintf(stderr, "Need engine time after \"-Z engineBoot\".\n");
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
            } else {
                fprintf(stderr, "Need engine time after \"-Z engineBoot\".\n");
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'e':{
                size_t ebuf_len = 32, eout_len = 0;
                u_char *ebuf = (u_char *)malloc(ebuf_len);

                if (ebuf == NULL) {
                    fprintf(stderr, "malloc failure processing -e flag.\n");
                    return (NETSNMP_PARSE_ARGS_ERROR);
                }
                if (!snmp_hex_to_binary
                    (&ebuf, &ebuf_len, &eout_len, 1, optarg)) {
                    fprintf(stderr, "Bad engine ID value after -e flag.\n");
                    free(ebuf);
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
                if ((eout_len < 5) || (eout_len > 32)) {
                    fprintf(stderr, "Invalid engine ID value after -e flag.\n");
                    free(ebuf);
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
                session->securityEngineID = ebuf;
                session->securityEngineIDLen = eout_len;
                break;
            }

        case 'E':{
                size_t ebuf_len = 32, eout_len = 0;
                u_char *ebuf = (u_char *)malloc(ebuf_len);

                if (ebuf == NULL) {
                    fprintf(stderr, "malloc failure processing -E flag.\n");
                    return (NETSNMP_PARSE_ARGS_ERROR);
                }
                if (!snmp_hex_to_binary(&ebuf, &ebuf_len,
					&eout_len, 1, optarg)) {
                    fprintf(stderr, "Bad engine ID value after -E flag.\n");
                    free(ebuf);
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
                if ((eout_len < 5) || (eout_len > 32)) {
                    fprintf(stderr, "Invalid engine ID value after -E flag.\n");
                    free(ebuf);
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
                session->contextEngineID = ebuf;
                session->contextEngineIDLen = eout_len;
                break;
            }

        case 'n':
            session->contextName = optarg;
            session->contextNameLen = strlen(optarg);
            break;

        case 'u':
	    if (zero_sensitive) {
		if ((sensitive[sp] = strdup(optarg)) != NULL) {
		    session->securityName = sensitive[sp];
		    session->securityNameLen = strlen(sensitive[sp]);
		    memset(optarg, '\0', strlen(optarg));
		    sp++;
		} else {
		    fprintf(stderr, "malloc failure processing -u flag.\n");
		    return NETSNMP_PARSE_ARGS_ERROR;
		}
	    } else {
		session->securityName = optarg;
		session->securityNameLen = strlen(optarg);
	    }
            break;

        case 'l':
            if (!strcasecmp(optarg, "noAuthNoPriv") || !strcmp(optarg, "1")
                || !strcasecmp(optarg, "noauth")
                || !strcasecmp(optarg, "nanp")) {
                session->securityLevel = SNMP_SEC_LEVEL_NOAUTH;
            } else if (!strcasecmp(optarg, "authNoPriv")
                       || !strcmp(optarg, "2")
                       || !strcasecmp(optarg, "auth")
                       || !strcasecmp(optarg, "anp")) {
                session->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
            } else if (!strcasecmp(optarg, "authPriv")
                       || !strcmp(optarg, "3")
                       || !strcasecmp(optarg, "priv")
                       || !strcasecmp(optarg, "ap")) {
                session->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
            } else {
                fprintf(stderr,
                        "Invalid security level specified after -l flag: %s\n",
                        optarg);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }

            break;

#ifdef NETSNMP_SECMOD_USM
        case 'a':
#ifndef NETSNMP_DISABLE_MD5
            if (!strcasecmp(optarg, "MD5")) {
                session->securityAuthProto = usmHMACMD5AuthProtocol;
                session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
            } else
#endif
                if (!strcasecmp(optarg, "SHA")) {
                session->securityAuthProto = usmHMACSHA1AuthProtocol;
                session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
            } else {
                fprintf(stderr,
                        "Invalid authentication protocol specified after -a flag: %s\n",
                        optarg);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'x':
            testcase = 0;
#ifndef NETSNMP_DISABLE_DES
            if (!strcasecmp(optarg, "DES")) {
                testcase = 1;
                session->securityPrivProto = usmDESPrivProtocol;
                session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
            }
#endif
#ifdef HAVE_AES
            if (!strcasecmp(optarg, "AES128") ||
                !strcasecmp(optarg, "AES")) {
                testcase = 1;
                session->securityPrivProto = usmAESPrivProtocol;
                session->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
            }
#endif
            if (testcase == 0) {
                fprintf(stderr,
                      "Invalid privacy protocol specified after -x flag: %s\n",
                        optarg);
                return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            }
            break;

        case 'A':
	    if (zero_sensitive) {
		if ((sensitive[sp] = strdup(optarg)) != NULL) {
		    Apsz = sensitive[sp];
		    memset(optarg, '\0', strlen(optarg));
		    sp++;
		} else {
		    fprintf(stderr, "malloc failure processing -A flag.\n");
		    return NETSNMP_PARSE_ARGS_ERROR;
		}
	    } else {
		Apsz = optarg;
	    }
            break;

        case 'X':
	    if (zero_sensitive) {
		if ((sensitive[sp] = strdup(optarg)) != NULL) {
		    Xpsz = sensitive[sp];
		    memset(optarg, '\0', strlen(optarg));
		    sp++;
		} else {
		    fprintf(stderr, "malloc failure processing -X flag.\n");
		    return NETSNMP_PARSE_ARGS_ERROR;
		}
	    } else {
		Xpsz = optarg;
	    }
            break;
#endif                          /* SNMPV3_CMD_OPTIONS */
#endif /* NETSNMP_SECMOD_USM */

        case '?':
            return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
            break;

        default:
            proc(argc, argv, arg);
            break;
        }
    }
    DEBUGMSGTL(("snmp_parse_args", "finished: %d/%d\n", optind, argc));
    
    /*
     * save command line parameters which should have precedence above config file settings
     *    (There ought to be a more scalable approach than this....)
     */
    if (netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION)) {
        backup_NETSNMP_DS_LIB_OUTPUT_PRECISION = 
            strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION));
    }

    /*
     * read in MIB database and initialize the snmp library, read the config file
     */
    init_snmp("snmpapp");

    /*
     * restore command line parameters which should have precedence above config file settings
     */
    if(backup_NETSNMP_DS_LIB_OUTPUT_PRECISION) {
        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION, backup_NETSNMP_DS_LIB_OUTPUT_PRECISION);
        free(backup_NETSNMP_DS_LIB_OUTPUT_PRECISION);
    }

    /*
     * session default version 
     */
    if (session->version == SNMP_DEFAULT_VERSION) {
        /*
         * run time default version 
         */
        session->version = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 
					      NETSNMP_DS_LIB_SNMPVERSION);

        /*
         * compile time default version 
         */
        if (!session->version) {
            switch (NETSNMP_DEFAULT_SNMP_VERSION) {
#ifndef NETSNMP_DISABLE_SNMPV1
            case 1:
                session->version = SNMP_VERSION_1;
                break;
#endif

#ifndef NETSNMP_DISABLE_SNMPV2C
            case 2:
                session->version = SNMP_VERSION_2c;
                break;
#endif

            case 3:
                session->version = SNMP_VERSION_3;
                break;

            default:
                snmp_log(LOG_ERR, "Can't determine a valid SNMP version for the session\n");
                return(NETSNMP_PARSE_ARGS_ERROR);
            }
        } else {
#ifndef NETSNMP_DISABLE_SNMPV1
            if (session->version == NETSNMP_DS_SNMP_VERSION_1)  /* bogus value.  version 1 actually = 0 */
                session->version = SNMP_VERSION_1;
#endif
        }
    }

#ifdef NETSNMP_SECMOD_USM
    /* XXX: this should ideally be moved to snmpusm.c somehow */

    /*
     * make master key from pass phrases 
     */
    if (Apsz) {
        session->securityAuthKeyLen = USM_AUTH_KU_LEN;
        if (session->securityAuthProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_authtype(&session->securityAuthProtoLen);
            session->securityAuthProto =
                snmp_duplicate_objid(def, session->securityAuthProtoLen);
        }
        if (session->securityAuthProto == NULL) {
#ifndef NETSNMP_DISABLE_MD5
            /*
             * assume MD5
             */
            session->securityAuthProto =
                snmp_duplicate_objid(usmHMACMD5AuthProtocol,
                                     USM_AUTH_PROTO_MD5_LEN);
            session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
#else
            session->securityAuthProto =
                snmp_duplicate_objid(usmHMACSHA1AuthProtocol,
                                     USM_AUTH_PROTO_SHA_LEN);
            session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
#endif
        }
        if (generate_Ku(session->securityAuthProto,
                        session->securityAuthProtoLen,
                        (u_char *) Apsz, strlen(Apsz),
                        session->securityAuthKey,
                        &session->securityAuthKeyLen) != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr,
                    "Error generating a key (Ku) from the supplied authentication pass phrase. \n");
            return (NETSNMP_PARSE_ARGS_ERROR);
        }
    }
    if (Xpsz) {
        session->securityPrivKeyLen = USM_PRIV_KU_LEN;
        if (session->securityPrivProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_privtype(&session->securityPrivProtoLen);
            session->securityPrivProto =
                snmp_duplicate_objid(def, session->securityPrivProtoLen);
        }
        if (session->securityPrivProto == NULL) {
            /*
             * assume DES 
             */
#ifndef NETSNMP_DISABLE_DES
            session->securityPrivProto =
                snmp_duplicate_objid(usmDESPrivProtocol,
                                     USM_PRIV_PROTO_DES_LEN);
            session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
#else
            session->securityPrivProto =
                snmp_duplicate_objid(usmAESPrivProtocol,
                                     USM_PRIV_PROTO_AES_LEN);
            session->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
#endif

        }
        if (generate_Ku(session->securityAuthProto,
                        session->securityAuthProtoLen,
                        (u_char *) Xpsz, strlen(Xpsz),
                        session->securityPrivKey,
                        &session->securityPrivKeyLen) != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr,
                    "Error generating a key (Ku) from the supplied privacy pass phrase. \n");
            return (NETSNMP_PARSE_ARGS_ERROR);
        }
    }
#endif /* NETSNMP_SECMOD_USM */

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

#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
    /*
     * If v1 or v2c, check community has been set, either by a -c option above,
     * or via a default token somewhere.  
     * If neither, it will be taken from the incoming request PDU.
     */

#if defined(NETSNMP_DISABLE_SNMPV1)
    if (session->version == SNMP_VERSION_2c)
#else 
#if defined(NETSNMP_DISABLE_SNMPV2C)
    if (session->version == SNMP_VERSION_1)
#else
    if (session->version == SNMP_VERSION_1 ||
	session->version == SNMP_VERSION_2c)
#endif
#endif
    {
        if (Cpsz == NULL) {
            Cpsz = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					 NETSNMP_DS_LIB_COMMUNITY);
	    if (Cpsz == NULL) {
                if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                           NETSNMP_DS_LIB_IGNORE_NO_COMMUNITY)){
                    DEBUGMSGTL(("snmp_parse_args",
                                "ignoring that the community string is not present\n"));
                    session->community = NULL;
                    session->community_len = 0;
                } else {
                    fprintf(stderr, "No community name specified.\n");
                    return (NETSNMP_PARSE_ARGS_ERROR_USAGE);
                }
	    }
	} else {
            session->community = (unsigned char *)Cpsz;
            session->community_len = strlen(Cpsz);
        }
    }
#endif /* support for community based SNMP */

    return optind;
}
Exemple #4
0
int
main(int argc, char *argv[])
{
    int             arg;
    char           *prognam;
    char           *cp = NULL;
    const char*     sysUpTime = NULL;

    /* initialize tcpip, if necessary */
    SOCK_STARTUP;

    prognam = strrchr(argv[0], '/');
    if (prognam)
        ++prognam;
    else
        prognam = argv[0];

    putenv(strdup("POSIXLY_CORRECT=1"));

    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                           NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD, 1);
    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                           NETSNMP_DS_LIB_DISABLE_PERSISTENT_SAVE, 1);

    while ((arg = getopt(argc, argv, ":Vhm:M:D:dP:L:U:c:x:")) != -1) {
        switch (arg) {
        case 'h':
            usage(prognam);
            result = 0;
            goto out;
        case 'm':
            setenv("MIBS", optarg, 1);
            break;
        case 'M':
            setenv("MIBDIRS", optarg, 1);
            break;
        case 'c':
            context = optarg;
            contextLen = strlen(context);
            break;
        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;
        case 'd':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_DUMP_PACKET, 1);
            break;
        case 'U':
            sysUpTime = optarg;
            break;
        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
            result = 0;
            goto out;
#ifndef DISABLE_MIB_LOADING
        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
                usage(prognam);
                goto out;
            }
            break;
#endif /* DISABLE_MIB_LOADING */
        case 'L':
            if (snmp_log_options(optarg, argc, argv) < 0)
                goto out;
            break;
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else
                usage(argv[0]);
            break;

        case ':':
            fprintf(stderr, "Option -%c requires an operand\n", optopt);
            usage(prognam);
            goto out;
        case '?':
            fprintf(stderr, "Unrecognized option: -%c\n", optopt);
            usage(prognam);
            goto out;
        }
    }

    arg = optind;

    init_snmp(NETSNMP_APPLICATION_CONFIG_TYPE);
    agentx_config_init();

    /* NOTIFY varlist */
    pdu = pdu_create_opt_context(AGENTX_MSG_NOTIFY, context, contextLen);

    if (sysUpTime)
        snmp_add_var(pdu, sysuptime_oid, sysuptime_oid_len, 't', sysUpTime);

    if (arg == argc) {
        fprintf(stderr, "Missing trap-oid parameter\n");
        usage(prognam);
        goto out;
    }

    if (snmp_add_var(pdu, snmptrap_oid, snmptrap_oid_len, 'o', argv[arg])) {
        snmp_perror(argv[arg]);
        goto out;
    }
    ++arg;

    while (arg < argc) {
        oid    name[MAX_OID_LEN];
        size_t name_length = MAX_OID_LEN;
        arg += 3;
        if (arg > argc) {
            fprintf(stderr, "%s: Missing type/value for variable\n",
                    argv[arg - 3]);
            goto out;
        }
        if (!snmp_parse_oid(argv[arg - 3], name, &name_length)) {
            snmp_perror(argv[arg - 3]);
            goto out;
        }
        if (snmp_add_var(pdu, name, name_length, argv[arg - 2][0],
                         argv[arg - 1]) != 0) {
            snmp_perror(argv[arg - 3]);
            goto out;
        }
    }

    packetid = 0;

    state = &Connecting;
    next_state = NULL;
    if(state->entry) state->entry(state);

    /* main loop here... */
    for(;;) {
        int block = 1;
        int numfds = 0;
        int count;
        fd_set fdset;
        struct timeval timeout;

        while(next_state) {
            if(state->exit) state->exit(state);
            DEBUGMSGTL(("process", "State transition: %s -> %s\n",
                        state->name, next_state->name));
            state = next_state;
            next_state = NULL;
            if(state->entry) state->entry(state);
        }

        if(state == &Exit)
            break;

        FD_ZERO(&fdset);
        snmp_sess_select_info(sessp, &numfds, &fdset, &timeout, &block);
        count = select(numfds, &fdset, NULL, NULL, !block ? &timeout : NULL);
        if (count > 0)
            snmp_sess_read(sessp, &fdset);
        else if (count == 0)
            snmp_sess_timeout(sessp);
        else if (errno != EINTR) {
            snmp_log(LOG_ERR, "select error [%s]\n", strerror(errno));
            change_state(&Exit);
        }
    }

    /* at shutdown time */
    snmp_free_pdu(pdu);
    pdu = NULL;

    snmp_shutdown(NETSNMP_APPLICATION_CONFIG_TYPE);

out:
    SOCK_CLEANUP;
    return result;
}
int
snmp_parse_args(int argc,
                char *const *argv,
                netsnmp_session * session, const char *localOpts,
                void (*proc) (int, char *const *, int))
{
    int             arg;
    char           *cp;
    char           *Apsz = NULL;
    char           *Xpsz = NULL;
    char           *Cpsz = NULL;
    char            Opts[BUF_SIZE];

    /*
     * initialize session to default values 
     */
    snmp_sess_init(session);
    strcpy(Opts, "Y:VhHm:M:O:I:P:D:dv:r:t:c:Z:e:E:n:u:l:x:X:a:A:p:T:-:3:");
    if (localOpts)
        strcat(Opts, localOpts);

    /*
     * get the options 
     */
    DEBUGMSGTL(("snmp_parse_args", "starting: %d/%d\n", optind, argc));
    for (arg = 0; arg < argc; arg++) {
        DEBUGMSGTL(("snmp_parse_args", " arg %d = %s\n", arg, argv[arg]));
    }

    optind = 1;
    while ((arg = getopt(argc, argv, Opts)) != EOF) {
        DEBUGMSGTL(("snmp_parse_args", "handling (#%d): %c\n", optind,
                    arg));
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                return (-1);
            }
            if (strcasecmp(optarg, "version") == 0) {
                fprintf(stderr, "NET-SNMP version: %s\n",
                        netsnmp_get_version());
                return (-2);
            }

            handle_long_opt(optarg);
            break;

        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n",
                    netsnmp_get_version());
            return (-2);

        case 'h':
            return (-1);
            break;

        case 'H':
            init_snmp("snmpapp");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            return (-2);

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

        case 'm':
            setenv("MIBS", optarg, 1);
            break;

        case 'M':
            setenv("MIBDIRS", optarg, 1);
            break;

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

        case 'I':
            cp = snmp_in_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown input option passed to -I: %c.\n",
                        *cp);
                return (-1);
            }
            break;

        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr,
                        "Unknown parsing option passed to -P: %c.\n", *cp);
                return (-1);
            }
            break;

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

        case 'd':
            ds_set_boolean(DS_LIBRARY_ID, DS_LIB_DUMP_PACKET, 1);
            break;

        case 'v':
            if (!strcmp(optarg, "1")) {
                session->version = SNMP_VERSION_1;
            } else if (!strcasecmp(optarg, "2c")) {
                session->version = SNMP_VERSION_2c;
            } else if (!strcasecmp(optarg, "3")) {
                session->version = SNMP_VERSION_3;
            } else {
                fprintf(stderr,
                        "Invalid version specified after -v flag: %s\n",
                        optarg);
                return (-1);
            }
            break;

        case 'p':
            fprintf(stderr, "Warning: -p option is no longer used - ");
            fprintf(stderr, "specify the remote host as HOST:PORT\n");
            return (-1);
            break;

        case 'T':
            fprintf(stderr, "Warning: -T option is no longer used - ");
            fprintf(stderr, "specify the remote host as TRANSPORT:HOST\n");
            return (-1);
            break;

        case 't':
            session->timeout = atoi(optarg) * 1000000L;
            if (session->timeout < 0 || !isdigit(optarg[0])) {
                fprintf(stderr,
                        "Invalid timeout in seconds after -t flag.\n");
                return (-1);
            }
            break;

        case 'r':
            session->retries = atoi(optarg);
            if (session->retries < 0 || !isdigit(optarg[0])) {
                fprintf(stderr,
                        "Invalid number of retries after -r flag.\n");
                return (-1);
            }
            break;

        case 'c':
            Cpsz = optarg;
            break;

        case '3':
            if (snmpv3_options(optarg, session, &Apsz, &Xpsz, argc, argv) <
                0) {
                return (-1);
            }
            break;

#define SNMPV3_CMD_OPTIONS
#ifdef  SNMPV3_CMD_OPTIONS
        case 'Z':
            session->engineBoots = strtoul(optarg, NULL, 10);
            if (session->engineBoots == 0 || !isdigit(optarg[0])) {
                fprintf(stderr,
                        "Need engine boots value after -Z flag.\n");
                return (-1);
            }
            cp = strchr(optarg, ',');
            if (cp && *(++cp) && isdigit(*cp))
                session->engineTime = strtoul(cp, NULL, 10);
            /*
             * Handle previous '-Z boot time' syntax 
             */
            else if ((optind < argc) && isdigit(argv[optind][0]))
                session->engineTime = strtoul(argv[optind], NULL, 10);
            else {
                fprintf(stderr, "Need engine time value after -Z flag.\n");
                return (-1);
            }
            break;

        case 'e':{
                size_t          ebuf_len = 32, eout_len = 0;
                u_char         *ebuf = (u_char *) malloc(ebuf_len);

                if (ebuf == NULL) {
                    fprintf(stderr,
                            "malloc failure processing -e flag.\n");
                    return (-1);
                }
                if (!snmp_hex_to_binary
                    (&ebuf, &ebuf_len, &eout_len, 1, optarg)) {
                    fprintf(stderr,
                            "Bad engine ID value after -e flag.\n");
                    free(ebuf);
                    return (-1);
                }
                session->securityEngineID = ebuf;
                session->securityEngineIDLen = eout_len;
                break;
            }

        case 'E':{
                size_t          ebuf_len = 32, eout_len = 0;
                u_char         *ebuf = (u_char *) malloc(ebuf_len);

                if (ebuf == NULL) {
                    fprintf(stderr,
                            "malloc failure processing -E flag.\n");
                    return (-1);
                }
                if (!snmp_hex_to_binary
                    (&ebuf, &ebuf_len, &eout_len, 1, optarg)) {
                    fprintf(stderr,
                            "Bad engine ID value after -E flag.\n");
                    free(ebuf);
                    return (-1);
                }
                session->contextEngineID = ebuf;
                session->contextEngineIDLen = eout_len;
                break;
            }

        case 'n':
            session->contextName = optarg;
            session->contextNameLen = strlen(optarg);
            break;

        case 'u':
            session->securityName = optarg;
            session->securityNameLen = strlen(optarg);
            break;

        case 'l':
            if (!strcasecmp(optarg, "noAuthNoPriv") || !strcmp(optarg, "1")
                || !strcasecmp(optarg, "nanp")) {
                session->securityLevel = SNMP_SEC_LEVEL_NOAUTH;
            } else if (!strcasecmp(optarg, "authNoPriv")
                       || !strcmp(optarg, "2")
                       || !strcasecmp(optarg, "anp")) {
                session->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
            } else if (!strcasecmp(optarg, "authPriv")
                       || !strcmp(optarg, "3")
                       || !strcasecmp(optarg, "ap")) {
                session->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
            } else {
                fprintf(stderr,
                        "Invalid security level specified after -l flag: %s\n",
                        optarg);
                return (-1);
            }

            break;

        case 'a':
            if (!strcasecmp(optarg, "MD5")) {
                session->securityAuthProto = usmHMACMD5AuthProtocol;
                session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
            } else if (!strcasecmp(optarg, "SHA")) {
                session->securityAuthProto = usmHMACSHA1AuthProtocol;
                session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
            } else {
                fprintf(stderr,
                        "Invalid authentication protocol specified after -a flag: %s\n",
                        optarg);
                return (-1);
            }
            break;

        case 'x':
            if (!strcasecmp(optarg, "DES")) {
                session->securityPrivProto = usmDESPrivProtocol;
                session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
            } else {
                fprintf(stderr,
                        "Invalid privacy protocol specified after -x flag: %s\n",
                        optarg);
                return (-1);
            }
            break;

        case 'A':
            Apsz = optarg;
            break;

        case 'X':
            Xpsz = optarg;
            break;
#endif                          /* SNMPV3_CMD_OPTIONS */

        case '?':
            return (-1);
            break;

        default:
            proc(argc, argv, arg);
            break;
        }
    }
    DEBUGMSGTL(("snmp_parse_args", "finished: %d/%d\n", optind, argc));

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

    /*
     * session default version 
     */
    if (session->version == SNMP_DEFAULT_VERSION) {
        /*
         * run time default version 
         */
        session->version = ds_get_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION);

        /*
         * compile time default version 
         */
        if (!session->version) {
            switch (SNMP_DEFAULT_VERSION) {
            case 1:
                session->version = SNMP_VERSION_1;
                break;

            case 2:
                session->version = SNMP_VERSION_2c;
                break;

            case 3:
                session->version = SNMP_VERSION_3;
                break;
            }
        } else {
            if (session->version == DS_SNMP_VERSION_1)  /* bogus value.  version 1 actually = 0 */
                session->version = SNMP_VERSION_1;
        }
    }

    /*
     * make master key from pass phrases 
     */
    if (Apsz) {
        session->securityAuthKeyLen = USM_AUTH_KU_LEN;
        if (session->securityAuthProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_authtype(&session->securityAuthProtoLen);
            session->securityAuthProto =
                snmp_duplicate_objid(def, session->securityAuthProtoLen);
        }
        if (session->securityAuthProto == NULL) {
            /*
             * assume MD5 
             */
            session->securityAuthProto =
                snmp_duplicate_objid(usmHMACMD5AuthProtocol,
                                     USM_AUTH_PROTO_MD5_LEN);
            session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
        }
        if (generate_Ku(session->securityAuthProto,
                        session->securityAuthProtoLen,
                        (u_char *) Apsz, strlen(Apsz),
                        session->securityAuthKey,
                        &session->securityAuthKeyLen) != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr,
                    "Error generating a key (Ku) from the supplied authentication pass phrase. \n");
            return (-2);
        }
    }
    if (Xpsz) {
        session->securityPrivKeyLen = USM_PRIV_KU_LEN;
        if (session->securityPrivProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_privtype(&session->securityPrivProtoLen);
            session->securityPrivProto =
                snmp_duplicate_objid(def, session->securityPrivProtoLen);
        }
        if (session->securityPrivProto == NULL) {
            /*
             * assume DES 
             */
            session->securityPrivProto =
                snmp_duplicate_objid(usmDESPrivProtocol,
                                     USM_PRIV_PROTO_DES_LEN);
            session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
        }
        if (generate_Ku(session->securityAuthProto,
                        session->securityAuthProtoLen,
                        (u_char *) Xpsz, strlen(Xpsz),
                        session->securityPrivKey,
                        &session->securityPrivKeyLen) != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr,
                    "Error generating a key (Ku) from the supplied privacy pass phrase. \n");
            return (-2);
        }
    }
    /*
     * get the hostname 
     */
    if (optind == argc) {
        fprintf(stderr, "No hostname specified.\n");
        return (-1);
    }
    session->peername = argv[optind++]; /* hostname */

    /*
     * If v1 or v2c, check community has been set, either by a -c option above,
     * or via a default token somewhere.  
     */

    if (session->version == SNMP_VERSION_1 ||
        session->version == SNMP_VERSION_2c) {
        if (Cpsz == NULL) {
            Cpsz = ds_get_string(DS_LIBRARY_ID, DS_LIB_COMMUNITY);
        }
        if (Cpsz == NULL) {
            fprintf(stderr, "No community name specified.\n");
            return (-1);
        }
        session->community = (unsigned char *) Cpsz;
        session->community_len = strlen(Cpsz);
    }
    return optind;
}
int
main(int argc, char *argv[])
{
    int             arg;
    char           *current_name = NULL, *cp = NULL;
    oid             name[MAX_OID_LEN];
    size_t          name_length;
    int             description = 0;
    int             print = 0;
    int             find_all = 0;
    int             width = 1000000;

    /*
     * usage: snmptranslate name
     */
    while ((arg = getopt(argc, argv, "Vhm:M:w:D:P:T:O:I:L:")) != EOF) {
        switch (arg) {
        case 'h':
            usage();
            exit(1);

        case 'm':
            setenv("MIBS", optarg, 1);
            break;
        case 'M':
            setenv("MIBDIRS", optarg, 1);
            break;
        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;
        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n",
                    netsnmp_get_version());
            exit(0);
            break;
        case 'w':
	    width = atoi(optarg);
	    if (width <= 0) {
		fprintf(stderr, "Invalid width specification: %s\n", optarg);
		exit (1);
	    }
	    break;
#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */
        case 'O':
            cp = snmp_out_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown OID option to -O: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
        case 'I':
            cp = snmp_in_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown OID option to -I: %c.\n", *cp);
                usage();
                exit(1);
            }
            break;
        case 'T':
            for (cp = optarg; *cp; cp++) {
                switch (*cp) {
#ifndef NETSNMP_DISABLE_MIB_LOADING
                case 'l':
                    print = 3;
                    print_oid_report_enable_labeledoid();
                    break;
                case 'o':
                    print = 3;
                    print_oid_report_enable_oid();
                    break;
                case 's':
                    print = 3;
                    print_oid_report_enable_symbolic();
                    break;
                case 't':
                    print = 3;
                    print_oid_report_enable_suffix();
                    break;
                case 'z':
                    print = 3;
                    print_oid_report_enable_mibchildoid();
                    break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */
                case 'd':
                    description = 1;
                    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
                                           NETSNMP_DS_LIB_SAVE_MIB_DESCRS, 1);
                    break;
                case 'B':
                    find_all = 1;
                    break;
                case 'p':
                    print = 1;
                    break;
                case 'a':
                    print = 2;
                    break;
                default:
                    fprintf(stderr, "Invalid -T<lostpad> character: %c\n",
                            *cp);
                    usage();
                    exit(1);
                    break;
                }
            }
            break;
        case 'L':
            if (snmp_log_options(optarg, argc, argv) < 0) {
                return (-1);
            }
            break;
        default:
            fprintf(stderr, "invalid option: -%c\n", arg);
            usage();
Exemple #7
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;
}
Exemple #8
0
int
main (int argc, char **argv)
{
  int arg;
  char* cp = NULL;
  int dont_fork = 0, do_help = 0;

  while ((arg = getopt(argc, argv, "dD:fhHL:Xp"
#ifndef DISABLE_MIB_LOADING
                       "m:M:"
#endif /* DISABLE_MIB_LOADING */
                       "n:"
#ifndef DISABLE_MIB_LOADING
                       "P:"
#endif /* DISABLE_MIB_LOADING */
                       "vx:")) != EOF) {
    switch (arg) {
    case 'd':
      netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                             NETSNMP_DS_LIB_DUMP_PACKET, 1);
      break;

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

    case 'f':
      dont_fork = 1;
      break;

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

    case 'H':
      do_help = 1;
      break;

    case 'L':
      if (snmp_log_options(optarg, argc, argv) < 0) {
        exit(1);
      }
      break;
#ifndef DISABLE_MIB_LOADING
    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;
#endif /* DISABLE_MIB_LOADING */

    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;

#ifndef DISABLE_MIB_LOADING
    case 'P':
      cp = snmp_mib_toggle_options(optarg);
      if (cp != NULL) {
        fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
        usage(argv[0]);
      }
      break;
#endif /* DISABLE_MIB_LOADING */

    case 'v':
      version();
      break;

    case 'x':
      if (optarg != NULL) {
        netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                              NETSNMP_DS_AGENT_X_SOCKET, optarg);
      } else {
        usage(argv[0]);
      }
      break;

    default:
      fprintf(stderr, "invalid option: -%c\n", arg);
      usage(argv[0]);
      break;
    }
  }

  if (do_help) {
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
  } else {
    /* we are a subagent */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_ROLE, 1);

    if (!dont_fork) {
      if (netsnmp_daemonize(1, snmp_stderrlog_status()) != 0)
        exit(1);
    }

    /* initialize tcpip, if necessary */
    SOCK_STARTUP;
  }

  /* Parse file */
  m_parse(argv[argc-1]);

  /* initialize the agent library */
  init_agent(app_name);

  /* Initialize SNMP */
  init_snmp(app_name);

  if (do_help) {
    fprintf(stderr, "Configuration directives understood:\n");
    read_config_print_usage("  ");
    exit(0);
  }

  /* In case we received a request to stop (kill -TERM or kill -INT) */
  netsnmp_running = 1;
#ifdef SIGTERM
  signal(SIGTERM, stop_server);
#endif
#ifdef SIGINT
  signal(SIGINT, stop_server);
#endif

  /* main loop here... */
  while(netsnmp_running) {
    agent_check_and_process(1);
  }

  /* at shutdown time */
  snmp_shutdown(app_name);
  SOCK_CLEANUP;
  exit(0);
}