summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsyrinx <syrinx@FreeBSD.org>2012-01-10 15:29:03 +0000
committersyrinx <syrinx@FreeBSD.org>2012-01-10 15:29:03 +0000
commitd4a4d0726568facb84d6fd9be8da8d94aaf01799 (patch)
tree7139b337e38d7cc392ee06748d7bab1c6d86647c
parent0730e7f5bed7d8a8c749f0b81c900c9dc3f0b5c9 (diff)
downloadFreeBSD-src-d4a4d0726568facb84d6fd9be8da8d94aaf01799.zip
FreeBSD-src-d4a4d0726568facb84d6fd9be8da8d94aaf01799.tar.gz
Implement an option to execute SNMP walks using GETBULK requests in bsnmpwalk(1)
retrieving multiple values with a Single PDU. Reviewed by: philip@ Tested by: tsanand129 (at) gmail (dot) com
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.119
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c48
-rwxr-xr-xusr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c17
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h4
4 files changed, 62 insertions, 26 deletions
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1 b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
index 18b7eb6d..950c114 100644
--- a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 17, 2007
+.Dd January 10, 2012
.Dt BSNMPGET 1
.Os
.Sh NAME
@@ -112,7 +112,7 @@ objects whose values will be retrived, waits for a response and prints it if
received successfully.
.Pp
.Nm Bsnmpwalk
-queries an agent with SMNP GetNextRequest packets,
+queries an agent with ether SMNP GetNextRequest or GetBulkRequest packets,
asking for values of OID instances that are a part of the object subtree
rooted at the provided OIDs.
.Pp
@@ -220,7 +220,7 @@ The path of the posix local (unix domain) socket if local
transport is used.
.It Fl M Ar max-repetitions
The value for the max-repetitions field in a GetBulk PDU.
-Default is 1.
+Default is 10.
.It Fl N Ar non-repeaters
The value for the non-repeaters field in a GetBulk PDU.
Default is 0.
@@ -251,8 +251,17 @@ A binary localized privacy key to use when encypting/decrypting SNMPv3 PDU data.
By default plain text SNMPv3 PDUs are sent.
.It Fl p Ar [get|getnext|getbulk]
The PDU type to send by
-.Nm bsmpget .
-Default is get.
+.Nm bsmpget
+and
+.Nm bsnmpwalk .
+Default is get
+for
+.Nm bsmpget
+and getnext for
+.Nm bsnmpwalk .
+Getbulk allows executing the so called SNMP "bulkwalks" allowing the values of
+multiple columns to be retrived in a single PDU by
+.Nm bsnmpwalk .
.It Fl r Ar retries
Number of resends of request packets before giving up if the agent does
not respond after the first try.
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
index b3c57b7..fb0c7e5 100644
--- a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
@@ -76,8 +76,9 @@ usage(void)
(program == BSNMPWALK) ? "[-dhnK]" :
(program == BSNMPSET) ? "[-adehnK]" :
"",
- (program == BSNMPGET) ? " [-M max-repetitions] [-N non-repeaters]" : "",
- (program == BSNMPGET) ? "[-p pdu] " : "",
+ (program == BSNMPGET || program == BSNMPWALK) ?
+ " [-M max-repetitions] [-N non-repeaters]" : "",
+ (program == BSNMPGET || program == BSNMPWALK) ? "[-p pdu] " : "",
(program == BSNMPGET) ? " OID [OID ...]" :
(program == BSNMPWALK || program == BSNMPSET) ? " [OID ...]" :
""
@@ -150,7 +151,7 @@ snmptool_parse_options(struct snmp_toolinfo *snmptoolctx, int argc, char **argv)
switch (program) {
case BSNMPWALK:
- opts = "dhnKA:b:C:I:i:l:o:P:r:s:t:U:v:";
+ opts = "dhnKA:b:C:I:i:l:M:N:o:P:p:r:s:t:U:v:";
break;
case BSNMPGET:
opts = "aDdehnKA:b:C:I:i:l:M:N:o:P:p:r:s:t:U:v:";
@@ -398,7 +399,7 @@ snmptool_get(struct snmp_toolinfo *snmptoolctx)
}
if (snmp_parse_resp(&resp, &req) >= 0) {
- snmp_output_resp(snmptoolctx, &resp);
+ snmp_output_resp(snmptoolctx, &resp, NULL);
break;
}
@@ -460,8 +461,14 @@ snmptool_walk(struct snmp_toolinfo *snmptoolctx)
struct snmp_pdu req, resp;
struct asn_oid root; /* Keep the initial oid. */
int32_t outputs, rc;
+ uint32_t op;
- snmp_pdu_create(&req, SNMP_PDU_GETNEXT);
+ if (GET_PDUTYPE(snmptoolctx) == SNMP_PDU_GETBULK)
+ op = SNMP_PDU_GETBULK;
+ else
+ op = SNMP_PDU_GETNEXT;
+
+ snmp_pdu_create(&req, op);
while ((rc = snmp_pdu_add_bindings(snmptoolctx, NULL,
snmptool_add_vbind, &req, 1)) > 0) {
@@ -470,6 +477,10 @@ snmptool_walk(struct snmp_toolinfo *snmptoolctx)
memset(&root, 0, sizeof(struct asn_oid));
asn_append_oid(&root, &(req.bindings[0].var));
+ if (op == SNMP_PDU_GETBULK)
+ snmpget_fix_getbulk(&req, GET_MAXREP(snmptoolctx),
+ GET_NONREP(snmptoolctx));
+
outputs = 0;
while (snmp_dialog(&req, &resp) >= 0) {
if ((snmp_parse_resp(&resp, &req)) < 0) {
@@ -479,21 +490,24 @@ snmptool_walk(struct snmp_toolinfo *snmptoolctx)
break;
}
- if (!(asn_is_suboid(&root, &(resp.bindings[0].var)))) {
- snmp_pdu_free(&resp);
- break;
- }
-
- if (snmp_output_resp(snmptoolctx, &resp)!= 0) {
+ rc = snmp_output_resp(snmptoolctx, &resp, &root);
+ if (rc < 0) {
snmp_pdu_free(&resp);
outputs = -1;
break;
}
- outputs++;
+
+ outputs += rc;
snmp_pdu_free(&resp);
- snmpwalk_nextpdu_create(SNMP_PDU_GETNEXT,
- &(resp.bindings[0].var), &req);
+ if (rc < resp.nbindings)
+ break;
+
+ snmpwalk_nextpdu_create(op,
+ &(resp.bindings[resp.nbindings - 1].var), &req);
+ if (op == SNMP_PDU_GETBULK)
+ snmpget_fix_getbulk(&req, GET_MAXREP(snmptoolctx),
+ GET_NONREP(snmptoolctx));
}
/* Just in case our root was a leaf. */
@@ -503,7 +517,7 @@ snmptool_walk(struct snmp_toolinfo *snmptoolctx)
if (snmp_parse_resp(&resp,&req) < 0)
snmp_output_err_resp(snmptoolctx, &resp);
else
- snmp_output_resp(snmptoolctx, &(resp));
+ snmp_output_resp(snmptoolctx, &(resp), NULL);
snmp_pdu_free(&resp);
} else
@@ -515,7 +529,7 @@ snmptool_walk(struct snmp_toolinfo *snmptoolctx)
break;
}
- snmp_pdu_create(&req, SNMP_PDU_GETNEXT);
+ snmp_pdu_create(&req, op);
}
if (rc == 0)
@@ -1076,7 +1090,7 @@ snmptool_set(struct snmp_toolinfo *snmptoolctx)
if (snmp_pdu_check(&req, &resp) > 0) {
if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET)
- snmp_output_resp(snmptoolctx, &resp);
+ snmp_output_resp(snmptoolctx, &resp, NULL);
break;
}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
index 53deff7..52aa1a9 100755
--- a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
@@ -132,6 +132,7 @@ snmptool_init(struct snmp_toolinfo *snmptoolctx)
snmptoolctx->flags = SNMP_PDU_GET; /* XXX */
SLIST_INIT(&snmptoolctx->filelist);
snmp_client_init(&snmp_client);
+ SET_MAXREP(snmptoolctx, SNMP_MAX_REPETITIONS);
if (add_filename(snmptoolctx, bsnmpd_defs, &IsoOrgDod_OID, 0) < 0)
warnx("Error adding file %s to list", bsnmpd_defs);
@@ -2039,14 +2040,20 @@ snmp_output_err_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu)
}
int32_t
-snmp_output_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu)
+snmp_output_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu,
+ struct asn_oid *root)
{
int32_t error;
char p[ASN_OIDSTRLEN];
uint32_t i;
struct snmp_object object;
- for (i = 0, error = 0; i < pdu->nbindings; i++) {
+ i = error = 0;
+ while (i < pdu->nbindings) {
+ if (root != NULL && !(asn_is_suboid(root,
+ &(pdu->bindings[i].var))))
+ break;
+
if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET) {
if (!ISSET_NUMERIC(snmptoolctx) &&
(snmp_fill_object(snmptoolctx, &object,
@@ -2058,9 +2065,13 @@ snmp_output_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu)
}
}
error |= snmp_output_numval(snmptoolctx, &(pdu->bindings[i]), object.info);
+ i++;
}
- return (error);
+ if (error)
+ return (-1);
+
+ return (i);
}
void
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
index ee28385..c14fe52 100644
--- a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
@@ -47,6 +47,8 @@
#define SNMP_DEFS_DIR "/usr/share/snmp/defs/"
#define SNMP_DEFAULT_LOCAL "/var/run/snmpd.sock"
+#define SNMP_MAX_REPETITIONS 10
+
enum snmp_access {
SNMP_ACCESS_NONE = 0,
SNMP_ACCESS_GET,
@@ -323,7 +325,7 @@ int32_t snmp_parse_resp(struct snmp_pdu *, struct snmp_pdu *);
int32_t snmp_output_numval(struct snmp_toolinfo *, struct snmp_value *,
struct snmp_oid2str *);
void snmp_output_val(struct snmp_value *);
-int32_t snmp_output_resp(struct snmp_toolinfo *, struct snmp_pdu *);
+int32_t snmp_output_resp(struct snmp_toolinfo *, struct snmp_pdu *, struct asn_oid *);
void snmp_output_err_resp(struct snmp_toolinfo *, struct snmp_pdu *);
void snmp_output_engine(void);
void snmp_output_keys(void);
OpenPOWER on IntegriCloud