Link the result of each mps_getbulkreq() to the end of the previous list
authorsthen <sthen@openbsd.org>
Thu, 8 Oct 2015 08:17:30 +0000 (08:17 +0000)
committersthen <sthen@openbsd.org>
Thu, 8 Oct 2015 08:17:30 +0000 (08:17 +0000)
and not the start of it. Fixes getbulk requests for multiple OIDs.

From Gerhard Roth, ok blambert@

usr.sbin/snmpd/mps.c
usr.sbin/snmpd/snmpd.h
usr.sbin/snmpd/snmpe.c

index 79bd847..506c1d0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mps.c,v 1.21 2015/07/18 16:54:43 blambert Exp $       */
+/*     $OpenBSD: mps.c,v 1.22 2015/10/08 08:17:30 sthen Exp $  */
 
 /*
  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -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, struct ber_element **root,
 
        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, struct ber_element **root,
                if (d != NULL)
                        ber_link_elements(d, e);
                d = e;
+               *end = d;
        }
 
        *root = c;
index 03ad652..fff5cc2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: snmpd.h,v 1.61 2015/10/05 15:29:14 uebayasi Exp $     */
+/*     $OpenBSD: snmpd.h,v 1.62 2015/10/08 08:17:30 sthen Exp $        */
 
 /*
  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -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 *, struct ber_element *,
 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 0096b24..e32e253 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: snmpe.c,v 1.40 2015/01/16 00:05:13 deraadt Exp $      */
+/*     $OpenBSD: snmpe.c,v 1.41 2015/10/08 08:17:30 sthen Exp $        */
 
 /*
  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -374,6 +374,7 @@ snmpe_parsevarbinds(struct snmp_message *msg)
                                break;
                        case 1:
                                msg->sm_c = NULL;
+                               msg->sm_end = NULL;
 
                                switch (msg->sm_context) {
 
@@ -409,7 +410,8 @@ snmpe_parsevarbinds(struct snmp_message *msg)
 
                                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 *msg)
                                }
                                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;
                        }
                }