svn commit: r229933 - in head/usr.sbin/bsnmpd/tools: bsnmptools libbsnmptools

Shteryana Shopova syrinx at FreeBSD.org
Tue Jan 10 15:29:04 UTC 2012


Author: syrinx
Date: Tue Jan 10 15:29:03 2012
New Revision: 229933
URL: http://svn.freebsd.org/changeset/base/229933

Log:
  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

Modified:
  head/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
  head/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
  head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
  head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h

Modified: head/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
==============================================================================
--- head/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1	Tue Jan 10 13:41:14 2012	(r229932)
+++ head/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1	Tue Jan 10 15:29:03 2012	(r229933)
@@ -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, w
 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
 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 wh
 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.

Modified: head/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
==============================================================================
--- head/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c	Tue Jan 10 13:41:14 2012	(r229932)
+++ head/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c	Tue Jan 10 15:29:03 2012	(r229933)
@@ -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_tooli
 
 	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 *snmpt
 		}
 
 		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 *snmp
 	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 *snmp
 		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 *snmp
 				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 *snmp
 				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 *snmp
 			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 *snmpt
 
 		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;
 		}
 

Modified: head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
==============================================================================
--- head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c	Tue Jan 10 13:41:14 2012	(r229932)
+++ head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c	Tue Jan 10 15:29:03 2012	(r229933)
@@ -132,6 +132,7 @@ snmptool_init(struct snmp_toolinfo *snmp
 	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_toolinf
 }
 
 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 *s
 			}
 		}
 		error |= snmp_output_numval(snmptoolctx, &(pdu->bindings[i]), object.info);
+		i++;
 	}
 
-	return (error);
+	if (error)
+		return (-1);
+
+	return (i);
 }
 
 void

Modified: head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
==============================================================================
--- head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h	Tue Jan 10 13:41:14 2012	(r229932)
+++ head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h	Tue Jan 10 15:29:03 2012	(r229933)
@@ -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 
 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);


More information about the svn-src-all mailing list