summaryrefslogtreecommitdiff
path: root/usr.sbin/snmpctl/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/snmpctl/parser.c')
-rw-r--r--usr.sbin/snmpctl/parser.c215
1 files changed, 207 insertions, 8 deletions
diff --git a/usr.sbin/snmpctl/parser.c b/usr.sbin/snmpctl/parser.c
index 60175a81079..f03983bb701 100644
--- a/usr.sbin/snmpctl/parser.c
+++ b/usr.sbin/snmpctl/parser.c
@@ -1,6 +1,7 @@
-/* $OpenBSD: parser.c,v 1.3 2007/12/28 17:22:32 reyk Exp $ */
+/* $OpenBSD: parser.c,v 1.4 2008/01/18 02:09:30 reyk Exp $ */
/*
+ * Copyright (c) 2008 Reyk Floeter <reyk@vantronix.net>
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
*
@@ -21,6 +22,7 @@
#include <sys/socket.h>
#include <sys/queue.h>
#include <sys/tree.h>
+#include <sys/uio.h>
#include <netinet/in.h>
#include <net/if.h>
@@ -31,16 +33,25 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#include <event.h>
#include "snmpd.h"
+#include "snmp.h"
#include "parser.h"
enum token_type {
NOTOKEN,
ENDTOKEN,
- KEYWORD
+ KEYWORD,
+ TRAPOID,
+ ELEMENTOBJECT,
+ VALTYPE,
+ INT32VAL,
+ UINT32VAL,
+ INT64VAL,
+ STRINGVAL
};
struct token {
@@ -52,19 +63,93 @@ struct token {
static const struct token t_main[];
static const struct token t_show[];
+static const struct token t_trap[];
+static const struct token t_trapoid[];
+static const struct token t_element[];
+static const struct token t_oid[];
+static const struct token t_type[];
+static const struct token t_int32[];
+static const struct token t_uint32[];
+static const struct token t_int64[];
+static const struct token t_string[];
static const struct token t_main[] = {
{KEYWORD, "monitor", MONITOR, NULL},
{KEYWORD, "show", NONE, t_show},
+ {KEYWORD, "trap", NONE, t_trap},
{ENDTOKEN, "", NONE, NULL}
};
static const struct token t_show[] = {
- {KEYWORD, "mib" , SHOW_MIB, NULL},
+ {KEYWORD, "mib", SHOW_MIB, NULL},
{ENDTOKEN, "", NONE, NULL}
};
-static struct parse_result res;
+static const struct token t_trap[] = {
+ {KEYWORD, "send", TRAP, t_trapoid},
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_trapoid[] = {
+ {TRAPOID, "", NONE, t_element},
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_element[] = {
+ {NOTOKEN, "", NONE, NULL},
+ {KEYWORD, "oid", NONE, t_oid},
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_oid[] = {
+ {ELEMENTOBJECT, "", NONE, t_type},
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_type[] = {
+ {VALTYPE, "ip", SNMP_IPADDR, t_int32 },
+ {VALTYPE, "counter", SNMP_COUNTER32, t_int32 },
+ {VALTYPE, "gauge", SNMP_GAUGE32, t_int32 },
+ {VALTYPE, "unsigned", SNMP_GAUGE32, t_uint32 },
+ {VALTYPE, "ticks", SNMP_TIMETICKS, t_int32 },
+ {VALTYPE, "opaque", SNMP_OPAQUE, t_int32 },
+ {VALTYPE, "nsap", SNMP_NSAPADDR, t_int32 },
+ {VALTYPE, "counter64", SNMP_COUNTER64, t_int64 },
+ {VALTYPE, "uint", SNMP_UINTEGER32, t_uint32 },
+ {VALTYPE, "int", SNMP_INTEGER32, t_int32 },
+ {VALTYPE, "bitstring", SNMP_BITSTRING, t_string },
+ {VALTYPE, "string", SNMP_OCTETSTRING, t_string },
+ {VALTYPE, "null", SNMP_NULL, t_element },
+ {VALTYPE, "oid", SNMP_OBJECT, t_string },
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_int32[] = {
+ {INT32VAL, "", NONE, t_element},
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_uint32[] = {
+ {UINT32VAL, "", NONE, t_element},
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_int64[] = {
+ {INT64VAL, "", NONE, t_element},
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static const struct token t_string[] = {
+ {STRINGVAL, "", NONE, t_element},
+ {ENDTOKEN, "", NONE, NULL}
+};
+
+static struct parse_result res;
+static struct imsgbuf *ibuf;
+static struct snmp_imsg sm;
+
+const struct token *match_token(char *, const struct token []);
+void show_valid_args(const struct token []);
struct parse_result *
parse(int argc, char *argv[])
@@ -99,12 +184,18 @@ parse(int argc, char *argv[])
}
const struct token *
-match_token(const char *word, const struct token table[])
+match_token(char *word, const struct token table[])
{
- u_int i, match;
+ u_int i, match = 0;
const struct token *t = NULL;
+ const char *errs = NULL;
+ u_int32_t u;
+ int32_t d;
+ int64_t l;
+ struct iovec iov[2];
+ int iovcnt = 0;
- match = 0;
+ bzero(&iov, sizeof(iov));
for (i = 0; table[i].type != ENDTOKEN; i++) {
switch (table[i].type) {
@@ -123,12 +214,101 @@ match_token(const char *word, const struct token table[])
res.action = t->value;
}
break;
+ case VALTYPE:
+ if (word != NULL && strncmp(word, table[i].keyword,
+ strlen(word)) == 0) {
+ match++;
+ t = &table[i];
+ sm.snmp_type = t->value;
+ if (t->value == SNMP_NULL)
+ iovcnt = 1;
+ }
+ break;
+ case TRAPOID:
+ if (word == NULL || strlen(word) == 0)
+ break;
+ if (ibuf == NULL &&
+ (ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
+ err(1, "malloc");
+ res.ibuf = ibuf;
+ imsg_init(ibuf, -1, NULL);
+
+ /* Create a new trap */
+ imsg_compose(ibuf, IMSG_SNMP_TRAP,
+ 0, 0, -1, NULL, 0);
+
+ /* First element must be the trap OID. */
+ bzero(&sm, sizeof(sm));
+ sm.snmp_type = SNMP_NULL;
+ if (strlcpy(sm.snmp_oid, word,
+ sizeof(sm.snmp_oid)) >= sizeof(sm.snmp_oid))
+ errx(1, "trap oid too long");
+ if (imsg_compose(ibuf, IMSG_SNMP_ELEMENT, 0, 0, -1,
+ &sm, sizeof(sm)) == -1)
+ errx(1, "imsg");
+
+ match++;
+ t = &table[i];
+ break;
+ case ELEMENTOBJECT:
+ if (word == NULL || strlen(word) == 0)
+ break;
+ bzero(&sm, sizeof(sm));
+ if (strlcpy(sm.snmp_oid, word,
+ sizeof(sm.snmp_oid)) >= sizeof(sm.snmp_oid))
+ errx(1, "oid too long");
+ match++;
+ t = &table[i];
+ break;
+ case INT32VAL:
+ if (word == NULL || strlen(word) == 0)
+ break;
+ d = strtonum(word, INT_MIN, INT_MAX, &errs);
+ iov[1].iov_len = sizeof(d);
+ iov[1].iov_base = &d;
+ iovcnt = 2;
+ break;
+ case UINT32VAL:
+ if (word == NULL || strlen(word) == 0)
+ break;
+ u = strtonum(word, 0, UINT_MAX, &errs);
+ iov[1].iov_len = sizeof(u);
+ iov[1].iov_base = &u;
+ iovcnt = 2;
+ break;
+ case INT64VAL:
+ if (word == NULL || strlen(word) == 0)
+ break;
+ l = strtonum(word, INT64_MIN, INT64_MAX, &errs);
+ iov[1].iov_len = sizeof(l);
+ iov[1].iov_base = &l;
+ iovcnt = 2;
+ break;
+ case STRINGVAL:
+ if (word == NULL || strlen(word) == 0)
+ break;
+ iov[1].iov_len = strlen(word) + 1;
+ iov[1].iov_base = word;
+ iovcnt = 2;
+ break;
case ENDTOKEN:
break;
}
+ if (iovcnt)
+ break;
}
- if (match != 1) {
+ if (iovcnt) {
+ /* Write trap varbind element */
+ sm.snmp_len = iov[1].iov_len;
+ iov[0].iov_len = sizeof(sm);
+ iov[0].iov_base = &sm;
+ if (imsg_composev(ibuf, IMSG_SNMP_ELEMENT, 0, 0, -1,
+ iov, iovcnt) == -1)
+ err(1, "imsg");
+
+ t = &table[i];
+ } else if (match != 1) {
if (word == NULL)
fprintf(stderr, "missing argument:\n");
else if (match > 1)
@@ -154,6 +334,25 @@ show_valid_args(const struct token table[])
case KEYWORD:
fprintf(stderr, " %s\n", table[i].keyword);
break;
+ case VALTYPE:
+ fprintf(stderr, " %s <value>\n", table[i].keyword);
+ break;
+ case TRAPOID:
+ case ELEMENTOBJECT:
+ fprintf(stderr, " <oid-string>\n");
+ break;
+ case INT32VAL:
+ fprintf(stderr, " <int32>\n");
+ break;
+ case UINT32VAL:
+ fprintf(stderr, " <uint32>\n");
+ break;
+ case INT64VAL:
+ fprintf(stderr, " <int64>\n");
+ break;
+ case STRINGVAL:
+ fprintf(stderr, " <string>\n");
+ break;
case ENDTOKEN:
break;
}