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
This commit is contained in:
parent
756e2ef0ff
commit
b9288caaf6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=229933
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user