The diff below allows me to walk oids that contain a 0, while at the same time disallow the walking of neighbouring nodes.
I only lightly tested this with snmpctl walk and I haven't looked at how snmpd hooks into this, but considering reyk put the function there with the "Add initial SNMP client utility to snmpctl(8)." commit I reckon it's unused. Some input from snmpd experts would be welcome though. $ snmpctl -n snmp walk 10.17.11.26 oid 0.0 | head -1 1.0.8802.1.1.2.1.3.1.0=4 $ ./snmpctl -n snmp walk 10.17.11.26 oid 0.0 | head -1 $ snmpctl -n snmp walk 10.17.11.26 oid 1.0.8802 1.0.8802.1.1.2.1.3.1.0=4 $ ./snmpctl -n snmp walk 10.17.11.26 oid 1.0.8802 1.0.8802.1.1.2.1.3.1.0=4 1.0.8802.1.1.2.1.3.2.0="<vis(3) output>" 1.0.8802.1.1.2.1.3.3.0="<hostname>" ... $ snmpwalk -v2c -cpublic 10.17.11.26 1.0.8802 iso.0.8802.1.1.2.1.3.1.0 = INTEGER: 4 iso.0.8802.1.1.2.1.3.2.0 = Hex-STRING: XX XX XX XX XX XX iso.0.8802.1.1.2.1.3.3.0 = STRING: "<hostname>" ... martijn@ Index: ber.c =================================================================== RCS file: /cvs/src/usr.sbin/snmpd/ber.c,v retrieving revision 1.50 diff -u -p -r1.50 ber.c --- ber.c 27 Nov 2018 12:10:29 -0000 1.50 +++ ber.c 11 Dec 2018 12:41:18 -0000 @@ -456,23 +456,23 @@ int ber_oid_cmp(struct ber_oid *a, struct ber_oid *b) { size_t i; - for (i = 0; i < BER_MAX_OID_LEN; i++) { - if (a->bo_id[i] != 0) { - if (a->bo_id[i] == b->bo_id[i]) - continue; - else if (a->bo_id[i] < b->bo_id[i]) { - /* b is a successor of a */ - return (1); - } else { - /* b is a predecessor of a */ - return (-1); - } - } else if (b->bo_id[i] != 0) { - /* b is larger, but a child of a */ - return (2); - } else - break; + /* b is a predecessor of a */ + if (a->bo_n > b->bo_n) + return -1; + for (i = 0; i < a->bo_n; i++) { + if (a->bo_id[i] == b->bo_id[i]) + continue; + else if (a->bo_id[i] < b->bo_id[i]) { + /* b is a successor of a */ + return (1); + } else { + /* b is a predecessor of a */ + return (-1); + } } + /* b is larger, but a child of a */ + if (a->bo_n < b->bo_n) + return (2); /* b and a are identical */ return (0);