On Tue, Oct 08, 2019 at 09:36:27AM +0200, Martijn van Duren wrote:
> 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?

A little bit of bikeshedding below.

> > 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)

Why not move the hint != NULL to the start of that if condition. It is the
quickest check.

> > +                           oid = hint;
> > +                   else
> > +                           oid = smi_oid2string(&vboid, oids,
> > +                               sizeof(oids), oid_lookup);
> > +           }
> > +   }
> > +   if (oid == NULL) {
> > +           fprintf(stderr, "Invalid varbind error-index received\n");

Isn't the '?' for OID enough? Do we really need this extra fprintf here?

> > +           oid = "?";
> > +   }
> > +
> >     switch (error) {
> >     case SNMP_ERROR_NONE:
> >             errx(1, "No error, how did I get here?");
> > 

Apart from that OK claudio@
-- 
:wq Claudio

Reply via email to