summaryrefslogtreecommitdiff
path: root/snmplib/snmp_parse_args.c
diff options
context:
space:
mode:
Diffstat (limited to 'snmplib/snmp_parse_args.c')
-rw-r--r--snmplib/snmp_parse_args.c832
1 files changed, 832 insertions, 0 deletions
diff --git a/snmplib/snmp_parse_args.c b/snmplib/snmp_parse_args.c
new file mode 100644
index 0000000..c73b84c
--- /dev/null
+++ b/snmplib/snmp_parse_args.c
@@ -0,0 +1,832 @@
+/*
+ * snmp_parse_args.c
+ */
+/* Portions of this file are subject to the following copyright(s). See
+ * the Net-SNMP's COPYING file for more details and other copyrights
+ * that may apply:
+ */
+/*
+ * Portions of this file are copyrighted by:
+ * Copyright @ 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms specified in the COPYING file
+ * distributed with the Net-SNMP package.
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <errno.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <ctype.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/types.h>
+#include <net-snmp/output_api.h>
+#include <net-snmp/config_api.h>
+#include <net-snmp/library/snmp_parse_args.h> /* for "internal" definitions */
+#include <net-snmp/utilities.h>
+
+#include <net-snmp/library/snmp_api.h>
+#include <net-snmp/library/snmp_client.h>
+#include <net-snmp/library/mib.h>
+#include <net-snmp/library/scapi.h>
+#include <net-snmp/library/keytools.h>
+
+#include <net-snmp/version.h>
+#include <net-snmp/library/parse.h>
+#include <net-snmp/library/snmpv3.h>
+#include <net-snmp/library/transform_oids.h>
+
+int random_access = 0;
+
+void
+snmp_parse_args_usage(FILE * outf)
+{
+ fprintf(outf, "[OPTIONS] AGENT");
+}
+
+void
+snmp_parse_args_descriptions(FILE * outf)
+{
+ fprintf(outf, " Version: %s\n", netsnmp_get_version());
+ fprintf(outf, " Web: http://www.net-snmp.org/\n");
+ fprintf(outf,
+ " Email: net-snmp-coders@lists.sourceforge.net\n\nOPTIONS:\n");
+ fprintf(outf, " -h, --help\t\tdisplay this help message\n");
+ fprintf(outf,
+ " -H\t\t\tdisplay configuration file directives understood\n");
+ fprintf(outf, " -v 1|2c|3\t\tspecifies SNMP version to use\n");
+ fprintf(outf, " -V, --version\t\tdisplay package version number\n");
+#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
+ fprintf(outf, "SNMP Version 1 or 2c specific\n");
+ fprintf(outf, " -c COMMUNITY\t\tset the community string\n");
+#endif /* support for community based SNMP */
+ fprintf(outf, "SNMP Version 3 specific\n");
+ fprintf(outf,
+ " -a PROTOCOL\t\tset authentication protocol (MD5|SHA)\n");
+ fprintf(outf,
+ " -A PASSPHRASE\t\tset authentication protocol pass phrase\n");
+ fprintf(outf,
+ " -e ENGINE-ID\t\tset security engine ID (e.g. 800000020109840301)\n");
+ fprintf(outf,
+ " -E ENGINE-ID\t\tset context engine ID (e.g. 800000020109840301)\n");
+ fprintf(outf,
+ " -l LEVEL\t\tset security level (noAuthNoPriv|authNoPriv|authPriv)\n");
+ fprintf(outf, " -n CONTEXT\t\tset context name (e.g. bridge1)\n");
+ fprintf(outf, " -u USER-NAME\t\tset security name (e.g. bert)\n");
+#ifdef HAVE_AES
+ fprintf(outf, " -x PROTOCOL\t\tset privacy protocol (DES|AES)\n");
+#else
+ fprintf(outf, " -x PROTOCOL\t\tset privacy protocol (DES)\n");
+#endif
+ fprintf(outf, " -X PASSPHRASE\t\tset privacy protocol pass phrase\n");
+ fprintf(outf,
+ " -Z BOOTS,TIME\t\tset destination engine boots/time\n");
+ fprintf(outf, "General communication options\n");
+ fprintf(outf, " -r RETRIES\t\tset the number of retries\n");
+ fprintf(outf,
+ " -t TIMEOUT\t\tset the request timeout (in seconds)\n");
+ fprintf(outf, "Debugging\n");
+ fprintf(outf, " -d\t\t\tdump input/output packets in hexadecimal\n");
+ fprintf(outf,
+ " -D[TOKEN[,...]]\tturn on debugging output for the specified TOKENs\n\t\t\t (ALL gives extremely verbose debugging output)\n");
+ fprintf(outf, "General options\n");
+ fprintf(outf,
+ " -m MIB[:...]\t\tload given list of MIBs (ALL loads everything)\n");
+ fprintf(outf,
+ " -M DIR[:...]\t\tlook in given list of directories for MIBs\n");
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ fprintf(outf,
+ " (default: %s)\n", netsnmp_get_mib_directory());
+ fprintf(outf,
+ " -P MIBOPTS\t\tToggle various defaults controlling MIB parsing:\n");
+ snmp_mib_toggle_options_usage("\t\t\t ", outf);
+#endif
+ fprintf(outf,
+ " -O OUTOPTS\t\tToggle various defaults controlling output display:\n");
+ snmp_out_toggle_options_usage("\t\t\t ", outf);
+ fprintf(outf,
+ " -I INOPTS\t\tToggle various defaults controlling input parsing:\n");
+ snmp_in_toggle_options_usage("\t\t\t ", outf);
+ fprintf(outf,
+ " -L LOGOPTS\t\tToggle various defaults controlling logging:\n");
+ snmp_log_options_usage("\t\t\t ", outf);
+ fflush(outf);
+}
+
+#define BUF_SIZE 512
+
+void
+handle_long_opt(const char *myoptarg)
+{
+ char *cp, *cp2;
+ /*
+ * else it's a long option, so process it like name=value
+ */
+ cp = (char *)malloc(strlen(myoptarg) + 3);
+ if (!cp)
+ return;
+ strcpy(cp, myoptarg);
+ cp2 = strchr(cp, '=');
+ if (!cp2 && !strchr(cp, ' ')) {
+ /*
+ * well, they didn't specify an argument as far as we
+ * can tell. Give them a '1' as the argument (which
+ * works for boolean tokens and a few others) and let
+ * them suffer from there if it's not what they
+ * wanted
+ */
+ strcat(cp, " 1");
+ } else {
+ /*
+ * replace the '=' with a ' '
+ */
+ if (cp2)
+ *cp2 = ' ';
+ }
+ netsnmp_config(cp);
+ free(cp);
+}
+
+extern int snmpv3_options(char *optarg, netsnmp_session * session,
+ char **Apsz, char **Xpsz, int argc,
+ char *const *argv);
+
+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 );
+
+ /*
+ * 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_toggle_options(optarg);
+ 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));
+
+ /*
+ * 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 = 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;
+}
+
+int
+snmp_parse_args(int argc,
+ char **argv,
+ netsnmp_session * session, const char *localOpts,
+ void (*proc) (int, char *const *, int))
+{
+ return netsnmp_parse_args(argc, argv, session, localOpts, proc, 0);
+}