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

Reply via email to