Disregard for now. I found an infinite recursion.

On 12/11/18 2:05 PM, Martijn van Duren wrote:
> As requested by deraadt@, here's a diff that includes the leaf value
> itself.
> 
> $ ./snmpctl snmp walk host oid 1.3.6.1.4.1.9.9.273.1.1.2.1.1  
> 1.1=1
> 1.2=5
> $ ./snmpctl snmp walk host oid 1.3.6.1.4.1.9.9.273.1.1.2.1.1.1
> 1=1
> $
> 
> On 12/11/18 1:10 PM, Martijn van Duren wrote:
>> So I got puzzled because of a behavioural difference between snmpwalk
>> and snmpctl walk.
>>
>> snmp returns the next element after the requested element for a
>> getNextRequest. So for a leaf-element this can be it's closest
>> neighbour. e.g.
>> $ make && snmpctl snmp walk host oid 1.3.6.1.4.1.9.9.273.1.1.2.1.1
>> 1.1=1
>> 1.2=5
>> icinga2$ make && snmpctl snmp walk host oid 1.3.6.1.4.1.9.9.273.1.1.2.1.1.1
>> 2=5
>> icinga2$ make && snmpctl snmp walk host oid 1.3.6.1.4.1.9.9.273.1.1.2.1.1.2
>> 1=0
>>
>> snmpwalk returns the requested leaf if no subelements can be found:
>> $ snmpwalk -v2c -c public host 1.3.6.1.4.1.9.9.273.1.1.2.1.1.1               
>>  
>> SNMPv2-SMI::enterprises.9.9.273.1.1.2.1.1.1 = Gauge32: 1
>> $ snmpwalk -v2c -c public host 1.3.6.1.4.1.9.9.273.1.1.2.1.1.2
>> SNMPv2-SMI::enterprises.9.9.273.1.1.2.1.1.2 = Gauge32: 5
>>
>> The problem for snmpctl is that we always return the first match, even
>> if even if it's not in our scope. The diff below removes that
>> requirement and also makes sure we also match itself, so to keep
>> "snmp get" working.
>>
>> Note that this diff doesn't include the value of the leaf itself, unlike 
>> snmpwalk, since that would require extra wiring and isn't exactly what's
>> being asked. If people would like this it could probably be added.
>>
>> $ ./snmpctl snmp walk host oid 1.3.6.1.4.1.9.9.273.1.1.2.1.1.1
>> $ ./snmpctl snmp get 10.17.11.27 oid 1.3.6.1.4.1.9.9.273.1.1.2.1.1.1
>> 1=1
>> $
>>
>> OK?
>>
>> martijn@
>>
> 
> Index: snmpclient.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpctl/snmpclient.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 snmpclient.c
> --- snmpclient.c      25 Nov 2018 14:58:28 -0000      1.18
> +++ snmpclient.c      11 Dec 2018 13:02:06 -0000
> @@ -220,6 +220,11 @@ snmpc_request(struct snmpc *sc, unsigned
>       if ((ret = snmpc_response(sc)) != 0) { 
>               if (ret == -1)
>                       err(1, "response");
> +             if (sc->sc_nresp == 0) {
> +                     bcopy(&sc->sc_root_oid, &sc->sc_oid,
> +                         sizeof(sc->sc_oid));
> +                     snmpc_request(sc, SNMP_C_GETREQ);
> +             }
>               return;
>       }       
>  
> @@ -235,7 +240,7 @@ snmpc_response(struct snmpc *sc)
>       char                     buf[BUFSIZ];
>       struct ber_element      *resp = NULL, *s, *e;
>       char                    *value = NULL, *p;
> -     int                      ret = 0;
> +     int                      ret = 0, bercmp;
>  
>       /* Receive response */
>       if (snmpc_recvresp(sc->sc_fd, sc->sc_version,
> @@ -250,12 +255,12 @@ snmpc_response(struct snmpc *sc)
>                       goto fail;
>  
>               /* Break if the returned OID is not a child of the root. */
> -             if (sc->sc_nresp &&
> -                 (ber_oid_cmp(&sc->sc_root_oid, &sc->sc_oid) != 2 ||
> +             bercmp = ber_oid_cmp(&sc->sc_root_oid, &sc->sc_oid);
> +             if ((bercmp != 0 && bercmp != 2) ||
>                   e->be_class == BER_CLASS_CONTEXT ||
> -                 e->be_type == BER_TYPE_NULL)) {
> -                     ret = 1; 
> -                     break;
> +                 e->be_type == BER_TYPE_NULL) {
> +                     ber_free_elements(resp);
> +                     return 1;
>               }               
>  
>               if ((value = smi_print_element(e)) != NULL) {
> 

Reply via email to