summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2013-10-01 17:20:40 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2013-10-01 17:20:40 +0000
commit28c9a1a99df355fd5e9b1014a1cfa3bdc8c7b2fc (patch)
tree4bc0c05a4dd2642e4ebfa55724897a37143277d4 /usr.sbin
parent652e85cf0b115bd304a83798418dda078c140d5a (diff)
Initial support for the "bulkwalk" command.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/snmpctl/parser.c3
-rw-r--r--usr.sbin/snmpctl/parser.h5
-rw-r--r--usr.sbin/snmpctl/snmpclient.c71
-rw-r--r--usr.sbin/snmpctl/snmpctl.87
-rw-r--r--usr.sbin/snmpctl/snmpctl.c5
5 files changed, 59 insertions, 32 deletions
diff --git a/usr.sbin/snmpctl/parser.c b/usr.sbin/snmpctl/parser.c
index 14710973fe3..140b4e1e054 100644
--- a/usr.sbin/snmpctl/parser.c
+++ b/usr.sbin/snmpctl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.12 2013/10/01 14:16:20 reyk Exp $ */
+/* $OpenBSD: parser.c,v 1.13 2013/10/01 17:20:39 reyk Exp $ */
/*
* Copyright (c) 2008 Reyk Floeter <reyk@openbsd.org>
@@ -100,6 +100,7 @@ static const struct token t_show[] = {
};
static const struct token t_snmp[] = {
+ {KEYWORD, "bulkwalk", BULKWALK, t_snmphost},
{KEYWORD, "get", GET, t_snmphost},
{KEYWORD, "walk", WALK, t_snmphost},
{ENDTOKEN, "", NONE, NULL}
diff --git a/usr.sbin/snmpctl/parser.h b/usr.sbin/snmpctl/parser.h
index 05c069ce4ed..875f86963e4 100644
--- a/usr.sbin/snmpctl/parser.h
+++ b/usr.sbin/snmpctl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.6 2013/10/01 12:41:48 reyk Exp $ */
+/* $OpenBSD: parser.h,v 1.7 2013/10/01 17:20:39 reyk Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
@@ -22,7 +22,8 @@ enum actions {
SHOW_MIB,
TRAP,
GET,
- WALK
+ WALK,
+ BULKWALK
};
struct parse_result {
diff --git a/usr.sbin/snmpctl/snmpclient.c b/usr.sbin/snmpctl/snmpclient.c
index fa78ffb7c98..5e2c79a7a08 100644
--- a/usr.sbin/snmpctl/snmpclient.c
+++ b/usr.sbin/snmpctl/snmpclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpclient.c,v 1.4 2013/10/01 15:06:01 reyk Exp $ */
+/* $OpenBSD: snmpclient.c,v 1.5 2013/10/01 17:20:39 reyk Exp $ */
/*
* Copyright (c) 2013 Reyk Floeter <reyk@openbsd.org>
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
-#include <sys/un.h>
#include <sys/tree.h>
#include <net/if.h>
@@ -30,6 +29,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <event.h>
@@ -65,6 +65,7 @@ struct snmpc {
#define SNMPC_RETRY_MAX 3
#define SNMPC_COMMUNITY "public"
#define SNMPC_OID "system"
+#define SNMPC_MAXREPETITIONS 10
void snmpc_request(struct snmpc *, u_long);
int snmpc_response(struct snmpc *);
@@ -92,6 +93,10 @@ snmpclient(struct parse_result *res)
if (res->oid == NULL || res->community == NULL)
err(1, "strdup");
+ /* Checks */
+ if ((res->action == BULKWALK) && (res->version < SNMP_V2))
+ errx(1, "invalid version for bulkwalk");
+
/* Resolve target host name */
bzero(&hints, sizeof(hints));
hints.ai_family = PF_UNSPEC;
@@ -152,6 +157,8 @@ snmpclient(struct parse_result *res)
if (res->action == GET)
snmpc_request(&sc, SNMP_C_GETREQ);
+ else if (res->action == BULKWALK)
+ snmpc_request(&sc, SNMP_C_GETBULKREQ);
else
snmpc_request(&sc, SNMP_C_GETNEXTREQ);
@@ -191,7 +198,7 @@ snmpc_request(struct snmpc *sc, u_long type)
return;
}
- if (type != SNMP_C_GETNEXTREQ)
+ if (type == SNMP_C_GETREQ)
return;
snmpc_request(sc, type);
@@ -201,40 +208,50 @@ int
snmpc_response(struct snmpc *sc)
{
char buf[BUFSIZ];
- struct ber_element *resp = NULL, *e;
+ struct ber_element *resp = NULL, *s, *e;
char *value = NULL, *p;
+ int c, ret = 0;
/* Receive response */
if (snmpc_recvresp(sc->sc_fd, sc->sc_version,
sc->sc_msgid, &resp) == -1)
return (-1);
- if (ber_scanf_elements(resp, "{SS{SSSS{{oe}}}",
- &sc->sc_oid, &e) != 0)
+ if (ber_scanf_elements(resp, "{SS{SSSS{e}}", &s) != 0)
goto fail;
- /* Return if the returned OID is not a child of the requested root */
- if (sc->sc_nresp++ &&
- (ber_oid_cmp(&sc->sc_root_oid, &sc->sc_oid) != 2 ||
- e->be_type == BER_TYPE_NULL)) {
- ber_free_elements(resp);
- return (1); /* ignore response */
- }
+ for (c = 0; s != NULL; s = s->be_next, c++) {
+ if (ber_scanf_elements(s, "{oe}", &sc->sc_oid, &e) != 0)
+ goto fail;
+
+ if (c && ber_oid_cmp(&sc->sc_oid, &sc->sc_last_oid) == 0)
+ continue;
- if ((value = smi_print_element(e)) != NULL) {
- smi_oid2string(&sc->sc_oid, buf, sizeof(buf), sc->sc_root_len);
- p = buf;
- if (*p != '\0')
- printf("%s=%s\n", p, value);
- else
- printf("%s\n", value);
- free(value);
+ /* Break if the returned OID is not a child of the root. */
+ if (sc->sc_nresp &&
+ (ber_oid_cmp(&sc->sc_root_oid, &sc->sc_oid) != 2 ||
+ e->be_type == BER_TYPE_NULL)) {
+ ret = 1;
+ break;
+ }
+
+ if ((value = smi_print_element(e)) != NULL) {
+ smi_oid2string(&sc->sc_oid, buf, sizeof(buf),
+ sc->sc_root_len);
+ p = buf;
+ if (*p != '\0')
+ printf("%s=%s\n", p, value);
+ else
+ printf("%s\n", value);
+ free(value);
+ }
+ bcopy(&sc->sc_oid, &sc->sc_last_oid, sizeof(sc->sc_last_oid));
}
- ber_free_elements(resp);
- bcopy(&sc->sc_oid, &sc->sc_last_oid, sizeof(sc->sc_last_oid));
+ sc->sc_nresp++;
- return (0);
+ ber_free_elements(resp);
+ return (ret);
fail:
if (resp != NULL)
@@ -250,13 +267,17 @@ snmpc_sendreq(struct snmpc *sc, u_long type)
struct ber ber;
ssize_t len;
u_int8_t *ptr;
+ int erroridx = 0;
+
+ if (type == SNMP_C_GETBULKREQ)
+ erroridx = SNMPC_MAXREPETITIONS;
/* SNMP header */
sc->sc_msgid = arc4random();
if ((root = ber_add_sequence(NULL)) == NULL ||
(b = ber_printf_elements(root, "ds{tddd{{O0}}",
sc->sc_version, sc->sc_community, BER_CLASS_CONTEXT, type,
- sc->sc_msgid, 0, 0, &sc->sc_oid)) == NULL) {
+ sc->sc_msgid, 0, erroridx, &sc->sc_oid)) == NULL) {
errno = EINVAL;
return (-1);
}
diff --git a/usr.sbin/snmpctl/snmpctl.8 b/usr.sbin/snmpctl/snmpctl.8
index 95f689a3369..2bc78596e46 100644
--- a/usr.sbin/snmpctl/snmpctl.8
+++ b/usr.sbin/snmpctl/snmpctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: snmpctl.8,v 1.17 2013/10/01 14:53:56 jmc Exp $
+.\" $OpenBSD: snmpctl.8,v 1.18 2013/10/01 17:20:39 reyk Exp $
.\"
.\" Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
.\"
@@ -67,9 +67,10 @@ Request information from an SNMP agent that is running on the specified
The
.Ar request
can be either
-.Ic get
-or
+.Ic get ,
.Ic walk
+or
+.Ic bulkwalk
to retrieve a single SNMP value or a subtree.
The following
.Ar options
diff --git a/usr.sbin/snmpctl/snmpctl.c b/usr.sbin/snmpctl/snmpctl.c
index 2db33233860..8c18f822689 100644
--- a/usr.sbin/snmpctl/snmpctl.c
+++ b/usr.sbin/snmpctl/snmpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpctl.c,v 1.17 2013/10/01 12:41:49 reyk Exp $ */
+/* $OpenBSD: snmpctl.c,v 1.18 2013/10/01 17:20:39 reyk Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
@@ -124,6 +124,7 @@ main(int argc, char *argv[])
break;
case WALK:
case GET:
+ case BULKWALK:
snmpclient(res);
break;
default:
@@ -171,6 +172,7 @@ main(int argc, char *argv[])
case SHOW_MIB:
case WALK:
case GET:
+ case BULKWALK:
break;
case TRAP:
imsg_compose(ibuf, IMSG_SNMP_END, 0, 0, -1, NULL, 0);
@@ -203,6 +205,7 @@ main(int argc, char *argv[])
case SHOW_MIB:
case WALK:
case GET:
+ case BULKWALK:
break;
}
imsg_free(&imsg);