From 0081bf83ec8252ae3df34a8dd49405c13ee5d595 Mon Sep 17 00:00:00 2001 From: sthen Date: Thu, 8 Oct 2015 08:17:30 +0000 Subject: [PATCH] Link the result of each mps_getbulkreq() to the end of the previous list and not the start of it. Fixes getbulk requests for multiple OIDs. From Gerhard Roth, ok blambert@ --- usr.sbin/snmpd/mps.c | 10 +++++++--- usr.sbin/snmpd/snmpd.h | 5 +++-- usr.sbin/snmpd/snmpe.c | 10 +++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/usr.sbin/snmpd/mps.c b/usr.sbin/snmpd/mps.c index 79bd84734d8..506c1d0cb82 100644 --- a/usr.sbin/snmpd/mps.c +++ b/usr.sbin/snmpd/mps.c @@ -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 @@ -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; diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h index 03ad652678b..fff5cc235a2 100644 --- a/usr.sbin/snmpd/snmpd.h +++ b/usr.sbin/snmpd/snmpd.h @@ -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 @@ -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); diff --git a/usr.sbin/snmpd/snmpe.c b/usr.sbin/snmpd/snmpe.c index 0096b24f55f..e32e2533d1e 100644 --- a/usr.sbin/snmpd/snmpe.c +++ b/usr.sbin/snmpd/snmpe.c @@ -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 @@ -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; } } -- 2.20.1