On 2015/10/08 01:02, Stuart Henderson wrote:
> > $ snmpbulkget -Cn2 -Cr4 -v2c -c public 127.0.0.1 SNMPv2-MIB::sysDescr 
> > IP-MIB::ipForwarding IF-MIB::ifName IF-MIB::ifInOctets
> > SNMPv2-MIB::sysDescr.0 = STRING: some host description
> > IP-MIB::ipForwarding.0 = INTEGER: notForwarding(2)
> > IF-MIB::ifName.1 = STRING: em0
> > IF-MIB::ifName.2 = STRING: em1
> > IF-MIB::ifName.3 = STRING: enc0
> > IF-MIB::ifName.4 = STRING: lo0
> > IF-MIB::ifInOctets.1 = Counter32: 4019922211
> > IF-MIB::ifInOctets.2 = Counter32: 0
> > IF-MIB::ifInOctets.3 = Counter32: 0
> > IF-MIB::ifInOctets.4 = Counter32: 1433448428
> > 
> > (the answers don't have to be in the same order as the query, I have
> > just formatted them that way for the example to make it clearer).
> 
> Ohhhh. And now I find Gerhard Roth's post....
> 
> https://marc.info/?l=openbsd-tech&m=143375327425321&w=2
> 
> In a nutshell: the mps_getbulkreq() calls subsequent to the first one
> link the elements to the *first* element of the previous call, not the
> last element. Gerhard's diff passes in the address of the last element
> so it can be linked correctly.
> 
> I'll look at it again tomorrow but that looks correct for the -Cr case,
> nonreps and I think also len counting are still a problem but I'll look
> at those again on top of Gerhard's diff.

Gerhard's diff (repeated below) is correct for -Cr. Any OKs to commit it?

$ snmpbulkget -Cr4 -v2c -c public 127.0.0.1 SNMPv2-MIB::sysDescr 
IP-MIB::ipForwarding IF-MIB::ifName IF-MIB::ifInOctets

before:

SNMPv2-MIB::sysDescr.0 = STRING: sym
IP-MIB::ipForwarding.0 = INTEGER: 0
IF-MIB::ifName.1 = STRING: em0
IF-MIB::ifInOctets.1 = Counter32: 2305271272
IF-MIB::ifInOctets.2 = Counter32: 0
IF-MIB::ifInOctets.3 = Counter32: 0
IF-MIB::ifInOctets.4 = Counter32: 2091665909

after:

SNMPv2-MIB::sysDescr.0 = STRING: sym
SNMPv2-MIB::sysObjectID.0 = OID: OPENBSD-BASE-MIB::openBSDDefaultObjectID
SNMPv2-MIB::sysUpTime.0 = Timeticks: (10069) 0:01:40.69
SNMPv2-MIB::sysContact.0 = STRING: r...@symphytum.spacehopper.org
IP-MIB::ipForwarding.0 = INTEGER: 0
IP-MIB::ipDefaultTTL.0 = INTEGER: 64
IP-MIB::ipInReceives.0 = Counter32: 11634146
IP-MIB::ipInHdrErrors.0 = Counter32: 2
IF-MIB::ifName.1 = STRING: em0
IF-MIB::ifName.2 = STRING: em1
IF-MIB::ifName.3 = STRING: enc0
IF-MIB::ifName.4 = STRING: lo0
IF-MIB::ifInOctets.1 = Counter32: 2305182489
IF-MIB::ifInOctets.2 = Counter32: 0
IF-MIB::ifInOctets.3 = Counter32: 0
IF-MIB::ifInOctets.4 = Counter32: 2091496232

Index: mps.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/mps.c,v
retrieving revision 1.21
diff -u -p -r1.21 mps.c
--- mps.c       18 Jul 2015 16:54:43 -0000      1.21
+++ mps.c       8 Oct 2015 07:37:54 -0000
@@ -300,7 +300,7 @@ fail:
 
 int
 mps_getbulkreq(struct snmp_message *msg, struct ber_element **root,
-    struct ber_oid *o, int max)
+    struct ber_element **end, struct ber_oid *o, int max)
 {
        struct ber_element *c, *d, *e;
        size_t len;
@@ -308,14 +308,17 @@ mps_getbulkreq(struct snmp_message *msg,
 
        j = max;
        c = *root;
+       *end = NULL;
 
        for (d = NULL, len = 0; j > 0; j--) {
                e = ber_add_sequence(NULL);
                if (c == NULL)
                        c = e;
                ret = mps_getnextreq(msg, e, o);
-               if (ret == 1)
+               if (ret == 1) {
+                       *root = c;
                        return (1);
+               }
                if (ret == -1) {
                        ber_free_elements(e);
                        if (d == NULL)
@@ -330,6 +333,7 @@ mps_getbulkreq(struct snmp_message *msg,
                if (d != NULL)
                        ber_link_elements(d, e);
                d = e;
+               *end = d;
        }
 
        *root = c;
Index: snmpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
retrieving revision 1.61
diff -u -p -r1.61 snmpd.h
--- snmpd.h     5 Oct 2015 15:29:14 -0000       1.61
+++ snmpd.h     8 Oct 2015 07:37:54 -0000
@@ -397,6 +397,7 @@ struct snmp_message {
        struct ber_element      *sm_c;
        struct ber_element      *sm_next;
        struct ber_element      *sm_last;
+       struct ber_element      *sm_end;
 
        u_int8_t                 sm_data[READ_BUF_SIZE];
        size_t                   sm_datalen;
@@ -639,7 +640,7 @@ int          mps_getreq(struct snmp_message *, 
 int             mps_getnextreq(struct snmp_message *, struct ber_element *,
                    struct ber_oid *);
 int             mps_getbulkreq(struct snmp_message *, struct ber_element **,
-                   struct ber_oid *, int);
+                   struct ber_element **, struct ber_oid *, int);
 int             mps_setreq(struct snmp_message *, struct ber_element *,
                    struct ber_oid *);
 int             mps_set(struct ber_oid *, void *, long long);
Index: snmpe.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.40
diff -u -p -r1.40 snmpe.c
--- snmpe.c     16 Jan 2015 00:05:13 -0000      1.40
+++ snmpe.c     8 Oct 2015 07:37:54 -0000
@@ -374,6 +374,7 @@ snmpe_parsevarbinds(struct snmp_message 
                                break;
                        case 1:
                                msg->sm_c = NULL;
+                               msg->sm_end = NULL;
 
                                switch (msg->sm_context) {
 
@@ -409,7 +410,8 @@ snmpe_parsevarbinds(struct snmp_message 
 
                                case SNMP_C_GETBULKREQ:
                                        ret = mps_getbulkreq(msg, &msg->sm_c,
-                                           &o, msg->sm_maxrepetitions);
+                                           &msg->sm_end, &o,
+                                           msg->sm_maxrepetitions);
                                        if (ret == 0 || ret == 1)
                                                break;
                                        msg->sm_error = SNMP_ERROR_NOSUCHNAME;
@@ -420,11 +422,13 @@ snmpe_parsevarbinds(struct snmp_message 
                                }
                                if (msg->sm_c == NULL)
                                        break;
+                               if (msg->sm_end == NULL)
+                                       msg->sm_end = msg->sm_c;
                                if (msg->sm_last == NULL)
                                        msg->sm_varbindresp = msg->sm_c;
                                else
                                        ber_link_elements(msg->sm_last, 
msg->sm_c);
-                               msg->sm_last = msg->sm_c;
+                               msg->sm_last = msg->sm_end;
                                break;
                        }
                }

Reply via email to