Index: usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c =================================================================== --- usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c (revision 229852) +++ usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c (working copy) @@ -76,8 +76,9 @@ (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 @@ 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 @@ } if (snmp_parse_resp(&resp, &req) >= 0) { - snmp_output_resp(snmptoolctx, &resp); + snmp_output_resp(snmptoolctx, &resp, NULL); break; } @@ -460,9 +461,15 @@ 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 @@ 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 @@ break; } - if (!(asn_is_suboid(&root, &(resp.bindings[0].var)))) { + rc = snmp_output_resp(snmptoolctx, &resp, &root); + if (rc < 0) { snmp_pdu_free(&resp); + outputs = -1; break; } - if (snmp_output_resp(snmptoolctx, &resp)!= 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 @@ 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 @@ break; } - snmp_pdu_create(&req, SNMP_PDU_GETNEXT); + snmp_pdu_create(&req, op); } if (rc == 0) @@ -1076,7 +1090,7 @@ 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; } Index: usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1 =================================================================== --- usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1 (revision 229852) +++ usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1 (working copy) @@ -112,7 +112,7 @@ 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 @@ 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 @@ 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. Index: usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c =================================================================== --- usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c (revision 229852) +++ usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c (working copy) @@ -132,6 +132,7 @@ 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 @@ } 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 @@ } } error |= snmp_output_numval(snmptoolctx, &(pdu->bindings[i]), object.info); + i++; } - return (error); + if (error) + return (-1); + + return (i); } void Index: usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h =================================================================== --- usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h (revision 229852) +++ usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h (working copy) @@ -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_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);