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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to