diff options
Diffstat (limited to 'usr.sbin/snmpctl/parser.c')
-rw-r--r-- | usr.sbin/snmpctl/parser.c | 215 |
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; } |