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