Re: Bulkget & snmpd

2015-10-09 Thread Denis Fondras
On Thu, Oct 08, 2015 at 08:39:40AM +0100, Stuart Henderson wrote:
> > O. And now I find Gerhard Roth's post
> > 
> > https://marc.info/?l=openbsd-tech&m=143375327425321&w=2
> > 

Oh! I missed this one. Thank you very much Stuart.

Denis



Re: Bulkget & snmpd

2015-10-08 Thread Stuart Henderson
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).
> 
> O. 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 -  1.21
+++ mps.c   8 Oct 2015 07:37:54 -
@@ -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 -   1.61
+++ snmpd.h 8 Oct 2015 07:37:54 -
@@ -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
===

Re: Bulkget & snmpd

2015-10-07 Thread Stuart Henderson
On 2015/10/07 23:41, Stuart Henderson wrote:
> Moving post from misc@.
> 
> On 2015-10-07, Denis Fondras  wrote:
> > Hello,
> >
> > I'm using snmpd from base on 5.8 and while playing with snmpbulkget (from
> > net-snmp), I noticed a weirdness.
> >
> > * 'snmpbulkget -v2c -c public 10.100.200.19 iso.3.6.1.2.1.1' is ok
> > * 'snmpbulkget -v2c -c public 10.100.200.19 iso.3.6.1.2.1.31.1.1' is ok
> >
> > By "ok", I mean it returns the correct MIB results. However,
> >
> > * 'snmpbulkget -v2c -c public 10.100.200.19 iso.3.6.1.2.1.31.1.1
> >  iso.3.6.1.2.1.1' is not ok :
> > -8<-
> >  iso.3.6.1.2.1.31.1.1.1.1.1 = STRING: "em0"
> >  iso.3.6.1.2.1.1.1.0 = STRING: "OpenBSD test.my.domain 5.8 GENERIC#3 i386"
> >  iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.30155.23.1
> >  iso.3.6.1.2.1.1.3.0 = Timeticks: (217) 0:00:02.17
> >  iso.3.6.1.2.1.1.4.0 = STRING: "r...@test.my.domain"
> >  iso.3.6.1.2.1.1.5.0 = STRING: "test.my.domain"
> >  iso.3.6.1.2.1.1.6.0 = ""
> >  iso.3.6.1.2.1.1.7.0 = INTEGER: 74
> >  iso.3.6.1.2.1.1.8.0 = Timeticks: (0) 0:00:00.00
> >  iso.3.6.1.2.1.1.9.1.1.1 = INTEGER: 1
> >  iso.3.6.1.2.1.1.9.1.1.2 = INTEGER: 2
> > -8<-
> >
> > As you can see, only the first sub-OID of iso.3.6.1.2.1.31.1.1 is returned.
> 
> To make it clear, that last command is meant to return 10x results starting
> from iso.3.6.1.2.1.1 and 10x results starting from iso.3.6.1.2.1.31.1.1.
> 
> There are two parameters involved in GetBulkReq, "non-repeaters"
> (snmpbulkget -Cn# which defaults to 0) and "max-repetitions"
> (-Cr# defaulting to 10).
> 
> The response should be single results for the first "non-repeaters"
> requests (allowing you to fetch e.g. the uptime and maybe some other
> individual values of interest without a bunch of unwanted extras),
> followed by "maxrep" number of values for any subsequent requests.
> 
> $ 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).

O. 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.



Re: Bulkget & snmpd

2015-10-07 Thread Stuart Henderson
Moving post from misc@.

On 2015-10-07, Denis Fondras  wrote:
> Hello,
>
> I'm using snmpd from base on 5.8 and while playing with snmpbulkget (from
> net-snmp), I noticed a weirdness.
>
> * 'snmpbulkget -v2c -c public 10.100.200.19 iso.3.6.1.2.1.1' is ok
> * 'snmpbulkget -v2c -c public 10.100.200.19 iso.3.6.1.2.1.31.1.1' is ok
>
> By "ok", I mean it returns the correct MIB results. However,
>
> * 'snmpbulkget -v2c -c public 10.100.200.19 iso.3.6.1.2.1.31.1.1
>  iso.3.6.1.2.1.1' is not ok :
> -8<-
>  iso.3.6.1.2.1.31.1.1.1.1.1 = STRING: "em0"
>  iso.3.6.1.2.1.1.1.0 = STRING: "OpenBSD test.my.domain 5.8 GENERIC#3 i386"
>  iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.30155.23.1
>  iso.3.6.1.2.1.1.3.0 = Timeticks: (217) 0:00:02.17
>  iso.3.6.1.2.1.1.4.0 = STRING: "r...@test.my.domain"
>  iso.3.6.1.2.1.1.5.0 = STRING: "test.my.domain"
>  iso.3.6.1.2.1.1.6.0 = ""
>  iso.3.6.1.2.1.1.7.0 = INTEGER: 74
>  iso.3.6.1.2.1.1.8.0 = Timeticks: (0) 0:00:00.00
>  iso.3.6.1.2.1.1.9.1.1.1 = INTEGER: 1
>  iso.3.6.1.2.1.1.9.1.1.2 = INTEGER: 2
> -8<-
>
> As you can see, only the first sub-OID of iso.3.6.1.2.1.31.1.1 is returned.

To make it clear, that last command is meant to return 10x results starting
from iso.3.6.1.2.1.1 and 10x results starting from iso.3.6.1.2.1.31.1.1.

There are two parameters involved in GetBulkReq, "non-repeaters"
(snmpbulkget -Cn# which defaults to 0) and "max-repetitions"
(-Cr# defaulting to 10).

The response should be single results for the first "non-repeaters"
requests (allowing you to fetch e.g. the uptime and maybe some other
individual values of interest without a bunch of unwanted extras),
followed by "maxrep" number of values for any subsequent requests.

$ 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).

> It seems that the loop surrounding mps_getbulkreq() in snmpe.c is breaking
> the return of multiple OIDs but I can't find where exactly lies the bug.
>
> Can anyone help ?

One bug is that there's no support for non-repeaters yet;
msg->sm_nonrepeaters is filled in correctly from the request but
it isn't handled at all.

The getBulk request is processed within the outer loop in
snmpe_parsevarbinds(). There is one run of the inner loop for each
requested variable in the request which calls mps_getbulkreq() each
time.

I think something like the diff below (*NOT FOR COMMIT*) might be
part of the answer, there are problems though:

- "tooBig" error return when nonreps is set to anything other
than 0 (I can't even figure out where this is sent from..)

- still doesn't fix your problem where repetitions are broken
for all but the last requested variable. I've been looking at it and
trying things but haven't figured it out yet.

- not new, but the len counting in mps_getbulkreq only relates to
the individual call of that function, but in reality the response is
being built up from multiple calls to that function. so I think len
needs to be passed in as a pointer so that it can totalled up and
stop adding vars when the whole response packet is too full.

Anyway perhaps this gives some more ideas..

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 -  1.40
+++ snmpe.c 7 Oct 2015 22:28:05 -
@@ -335,7 +335,7 @@ snmpe_parsevarbinds(struct snmp_message 
struct snmp_stats   *stats = &env->sc_stats;
char buf[BUFSIZ];
struct ber_oid   o;
-   int  ret = 0;
+   int  bulk_oid = 0, ret = 0, nreps;
 
msg->sm_errstr = "invalid varbind element";
 
@@ -408,8 +408,12 @@ snmpe_parsevarbinds(struct snmp_message 
goto varfail;
 
case SNMP_C_GETBULKREQ:
+   nreps = bulk_oid <
+   msg->sm_nonrepeaters ?
+   1 : msg->sm_maxrepetitions;
+   bulk_oid++;
ret = mps_getbulkreq(msg, &msg->sm_c,
-   &o, msg->sm_maxrepetitions);
+   &o, nreps);
if (ret ==