diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2013-10-01 17:20:40 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2013-10-01 17:20:40 +0000 |
commit | 28c9a1a99df355fd5e9b1014a1cfa3bdc8c7b2fc (patch) | |
tree | 4bc0c05a4dd2642e4ebfa55724897a37143277d4 /usr.sbin | |
parent | 652e85cf0b115bd304a83798418dda078c140d5a (diff) |
Initial support for the "bulkwalk" command.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/snmpctl/parser.c | 3 | ||||
-rw-r--r-- | usr.sbin/snmpctl/parser.h | 5 | ||||
-rw-r--r-- | usr.sbin/snmpctl/snmpclient.c | 71 | ||||
-rw-r--r-- | usr.sbin/snmpctl/snmpctl.8 | 7 | ||||
-rw-r--r-- | usr.sbin/snmpctl/snmpctl.c | 5 |
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); |