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?");
> 

Reply via email to