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