ping. I think this (or similar) fix should go in before release.
On 10/3/19 5:33 PM, Martijn van Duren wrote:
> As discussed with semarie@ this morning: We're a bit too loose when it
> comes to accessing indexes based directly from the pdu.
>
> Diff below allows only indexes within the range of the pdu.
> If user supplied oid and returned oid on index match the user supplied
> input is shown (for easier reference). If they don't match then show
> the oid based on the -O flag. If the index is out of range throw an
> additional error message and show a "?".
>
> Since it apparently is hard to get a proper error status with the
> daemons available to me, this is only compile tested. Testers welcome.
>
> This also adds a missing NULL-check, which could be committed
> separately.
>
> OK?
>
> martijn@
>
> Index: snmpc.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
> retrieving revision 1.13
> diff -u -p -r1.13 snmpc.c
> --- snmpc.c 3 Oct 2019 11:02:26 -0000 1.13
> +++ snmpc.c 3 Oct 2019 15:30:50 -0000
> @@ -52,7 +52,8 @@ int snmpc_mibtree(int, char *[]);
> struct snmp_agent *snmpc_connect(char *, char *);
> int snmpc_parseagent(char *, char *);
> int snmpc_print(struct ber_element *);
> -__dead void snmpc_printerror(enum snmp_error, char *);
> +__dead void snmpc_printerror(enum snmp_error, struct ber_element *, int,
> + const char *);
> char *snmpc_hex2bin(char *, size_t *);
> struct ber_element *snmpc_varbindparse(int, char *[]);
> void usage(void);
> @@ -480,6 +481,7 @@ snmpc_get(int argc, char *argv[])
> int i;
> int class;
> unsigned type;
> + char *hint = NULL;
>
> if (argc < 2)
> usage();
> @@ -519,9 +521,12 @@ snmpc_get(int argc, char *argv[])
>
> (void) ber_scanf_elements(pdu, "t{Sdd{e", &class, &type, &errorstatus,
> &errorindex, &varbind);
> - if (errorstatus != 0)
> - snmpc_printerror((enum snmp_error) errorstatus,
> - argv[errorindex - 1]);
> + if (errorstatus != 0) {
> + if (errorindex >= 1 && errorindex <= argc)
> + hint = argv[errorindex - 1];
> + snmpc_printerror((enum snmp_error) errorstatus, varbind,
> + errorindex, hint);
> + }
>
> if (class == BER_CLASS_CONTEXT && type == SNMP_C_REPORT)
> printf("Received report:\n");
> @@ -542,7 +547,6 @@ snmpc_walk(int argc, char *argv[])
> struct timespec start, finish;
> struct snmp_agent *agent;
> const char *oids;
> - char oidstr[SNMP_MAX_OID_STRLEN];
> int n = 0, prev_cmp;
> int errorstatus, errorindex;
> int class;
> @@ -574,8 +578,8 @@ snmpc_walk(int argc, char *argv[])
> (void) ber_scanf_elements(pdu, "t{Sdd{e", &class, &type,
> &errorstatus, &errorindex, &varbind);
> if (errorstatus != 0)
> - snmpc_printerror((enum snmp_error) errorstatus,
> - argv[errorindex - 1]);
> + snmpc_printerror((enum snmp_error) errorstatus, varbind,
> + errorindex, oids);
>
> if (class == BER_CLASS_CONTEXT && type == SNMP_C_REPORT)
> printf("Received report:\n");
> @@ -600,9 +604,8 @@ snmpc_walk(int argc, char *argv[])
> (void) ber_scanf_elements(pdu, "t{Sdd{e", &class, &type,
> &errorstatus, &errorindex, &varbind);
> if (errorstatus != 0) {
> - smi_oid2string(&noid, oidstr, sizeof(oidstr),
> - oid_lookup);
> - snmpc_printerror((enum snmp_error) errorstatus, oidstr);
> + snmpc_printerror((enum snmp_error) errorstatus, varbind,
> + errorindex, NULL);
> }
>
> if (class == BER_CLASS_CONTEXT && type == SNMP_C_REPORT)
> @@ -639,8 +642,8 @@ snmpc_walk(int argc, char *argv[])
> (void) ber_scanf_elements(pdu, "t{Sdd{e", &class, &type,
> &errorstatus, &errorindex, &varbind);
> if (errorstatus != 0)
> - snmpc_printerror((enum snmp_error) errorstatus,
> - argv[errorindex - 1]);
> + snmpc_printerror((enum snmp_error) errorstatus, varbind,
> + errorindex, oids);
>
> if (class == BER_CLASS_CONTEXT && type == SNMP_C_REPORT)
> printf("Received report:\n");
> @@ -676,6 +679,7 @@ snmpc_set(int argc, char *argv[])
> int errorstatus, errorindex;
> int class;
> unsigned type;
> + char *hint = NULL;
>
> if (argc < 4)
> usage();
> @@ -687,13 +691,17 @@ snmpc_set(int argc, char *argv[])
> if (pledge("stdio", NULL) == -1)
> err(1, "pledge");
>
> - pdu = snmp_set(agent, snmpc_varbindparse(argc, argv));
> + if ((pdu = snmp_set(agent, snmpc_varbindparse(argc, argv))) == NULL)
> + err(1, "set");
>
> (void) ber_scanf_elements(pdu, "t{Sdd{e", &class, &type, &errorstatus,
> &errorindex, &varbind);
> - if (errorstatus != 0)
> - snmpc_printerror((enum snmp_error) errorstatus,
> - argv[errorindex - 1]);
> + if (errorstatus != 0) {
> + if (errorindex >= 1 && errorindex <= argc / 3)
> + hint = argv[(errorindex - 1) * 3];
> + snmpc_printerror((enum snmp_error) errorstatus, varbind,
> + errorindex, hint);
> + }
>
> if (class == BER_CLASS_CONTEXT && type == SNMP_C_REPORT)
> printf("Received report:\n");
> @@ -805,8 +813,36 @@ snmpc_print(struct ber_element *elm)
> }
>
> __dead void
> -snmpc_printerror(enum snmp_error error, char *oid)
> +snmpc_printerror(enum snmp_error error, struct ber_element *varbind,
> + int index, const char *hint)
> {
> + struct ber_oid hoid, vboid;
> + char oids[SNMP_MAX_OID_STRLEN];
> + const char *oid = NULL;
> + int i;
> +
> + if (index >= 1) {
> + /* Only print if the index is in the reply */
> + for (i = 1; varbind != NULL && i <= index;
> + varbind = varbind->be_next)
> + i++;
> + if (varbind != NULL &&
> + ber_get_oid(varbind->be_sub, &vboid) == 0) {
> + /* If user and reply conform print user input */
> + if (smi_string2oid(hint, &hoid) == 0 &&
> + ber_oid_cmp(&hoid, &vboid) == 0 &&
> + hint != NULL)
> + oid = hint;
> + else
> + oid = smi_oid2string(&vboid, oids,
> + sizeof(oids), oid_lookup);
> + }
> + }
> + if (oid == NULL) {
> + fprintf(stderr, "Invalid varbind error-index received\n");
> + oid = "?";
> + }
> +
> switch (error) {
> case SNMP_ERROR_NONE:
> errx(1, "No error, how did I get here?");
>