diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2008-01-17 17:35:07 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2008-01-17 17:35:07 +0000 |
commit | c097341ea05ed19f678854416d3ac3520b26fcbc (patch) | |
tree | 4bb3a7e1c4869df7f0d2a39c327ca19cc6217a96 /usr.sbin/snmpd | |
parent | b3abc29b3c80b872be1af4f696895fa26b3834db (diff) |
allow to configure optional per trap receiver communities and to
restrict the receivers to a specified mib.
Diffstat (limited to 'usr.sbin/snmpd')
-rw-r--r-- | usr.sbin/snmpd/parse.y | 58 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.conf.5 | 18 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.h | 3 | ||||
-rw-r--r-- | usr.sbin/snmpd/trap.c | 27 |
4 files changed, 67 insertions, 39 deletions
diff --git a/usr.sbin/snmpd/parse.y b/usr.sbin/snmpd/parse.y index 9af9ee54ee9..ead9f57114b 100644 --- a/usr.sbin/snmpd/parse.y +++ b/usr.sbin/snmpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.9 2008/01/16 19:36:06 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.10 2008/01/17 17:35:06 reyk Exp $ */ /* * Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net> @@ -88,9 +88,9 @@ static struct addresslist *hlist; struct address *host_v4(const char *); struct address *host_v6(const char *); int host_dns(const char *, struct addresslist *, - int, in_port_t, const char *); + int, in_port_t, struct ber_oid *, char *); int host(const char *, struct addresslist *, - int, in_port_t, const char *); + int, in_port_t, struct ber_oid *, char *); typedef struct { union { @@ -117,9 +117,10 @@ typedef struct { %token ERROR %token <v.string> STRING %token <v.number> NUMBER +%type <v.string> hostcmn %type <v.number> optwrite %type <v.data> objtype -%type <v.oid> oid +%type <v.oid> oid hostoid %% @@ -160,7 +161,7 @@ main : LISTEN ON STRING { struct address *h; TAILQ_INIT(&al); - if (host($3, &al, 1, SNMPD_PORT, NULL) <= 0) { + if (host($3, &al, 1, SNMPD_PORT, NULL, NULL) <= 0) { yyerror("invalid ip address: %s", $3); free($3); YYERROR; @@ -305,9 +306,17 @@ oid : STRING { } ; -hostdef : STRING { +hostoid : /* empty */ { $$ = NULL; } + | OBJECTID oid { $$ = $2; } + ; + +hostcmn : /* empty */ { $$ = NULL; } + | COMMUNITY STRING { $$ = $2; } + ; + +hostdef : STRING hostoid hostcmn { if (host($1, hlist, 1, - SNMPD_TRAPPORT, NULL) <= 0) { + SNMPD_TRAPPORT, $2, $3) <= 0) { yyerror("invalid host: %s", $1); free($1); YYERROR; @@ -868,7 +877,7 @@ host_v6(const char *s) int host_dns(const char *s, struct addresslist *al, int max, - in_port_t port, const char *ifname) + in_port_t port, struct ber_oid *oid, char *cmn) { struct addrinfo hints, *res0, *res; int error, cnt = 0; @@ -896,12 +905,16 @@ host_dns(const char *s, struct addresslist *al, int max, fatal(NULL); h->port = port; - if (ifname != NULL) { - if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= - sizeof(h->ifname)) - log_warnx("host_dns: interface name truncated"); - return (-1); + if (oid != NULL) { + if ((h->sa_oid = calloc(1, sizeof(*oid))) == NULL) + fatal(NULL); + bcopy(oid, h->sa_oid, sizeof(*oid)); } + if (cmn != NULL) { + if ((h->sa_community = strdup(cmn)) == NULL) + fatal(NULL); + } + h->ss.ss_family = res->ai_family; if (res->ai_family == AF_INET) { sain = (struct sockaddr_in *)&h->ss; @@ -923,14 +936,18 @@ host_dns(const char *s, struct addresslist *al, int max, s, max); } freeaddrinfo(res0); + if (oid != NULL) + free(oid); + if (cmn != NULL) + free(cmn); return (cnt); } int host(const char *s, struct addresslist *al, int max, - in_port_t port, const char *ifname) + in_port_t port, struct ber_oid *oid, char *cmn) { - struct address *h; + struct address *h; h = host_v4(s); @@ -940,17 +957,12 @@ host(const char *s, struct addresslist *al, int max, if (h != NULL) { h->port = port; - if (ifname != NULL) { - if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= - sizeof(h->ifname)) { - log_warnx("host: interface name truncated"); - return (-1); - } - } + h->sa_oid = oid; + h->sa_community = cmn; TAILQ_INSERT_HEAD(al, h, entry); return (1); } - return (host_dns(s, al, max, port, ifname)); + return (host_dns(s, al, max, port, oid, cmn)); } diff --git a/usr.sbin/snmpd/snmpd.conf.5 b/usr.sbin/snmpd/snmpd.conf.5 index aed1e961c62..b70c90629cf 100644 --- a/usr.sbin/snmpd/snmpd.conf.5 +++ b/usr.sbin/snmpd/snmpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: snmpd.conf.5,v 1.4 2008/01/16 19:46:46 reyk Exp $ +.\" $OpenBSD: snmpd.conf.5,v 1.5 2008/01/17 17:35:06 reyk Exp $ .\" .\" Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 16 2008 $ +.Dd $Mdocdate: January 17 2008 $ .Dt SNMPD.CONF 5 .Os .Sh NAME @@ -84,11 +84,6 @@ The default value is Specify the name of the read-write community. The default value is .Ar private . -.\".Pp -.\".It Ic trap community Ar string -.\"Specify the name of the trap community. -.\"The default value is -.\".Ar public . .Pp .It Ic system contact Ar string Specify the name or description of the system contact, typically a @@ -138,13 +133,20 @@ Specify the name of the trap community. The default value is .Ar public . .Pp -.It Ic trap receiver Ar string +.It Xo +.Ic trap receiver Ar string +.Op Ic oid Ar oid-string +.Op Ic community Ar string +.Xc Specify the address or FQDN of a remote trap receiver for outgoing traps sent by .Xr snmpd 8 . This option may be specified for multiple times. The daemon will send outgoing traps using the revised SNMPv2 format and the configured trap community. +The default community is specified by the global +.Ic trap community +option. .Pp .El .Sh OID CONFIGURATION diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h index c9d34e4b32e..a8aee636262 100644 --- a/usr.sbin/snmpd/snmpd.h +++ b/usr.sbin/snmpd/snmpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: snmpd.h,v 1.15 2008/01/16 21:43:19 reyk Exp $ */ +/* $OpenBSD: snmpd.h,v 1.16 2008/01/17 17:35:06 reyk Exp $ */ /* * Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net> @@ -301,7 +301,6 @@ struct snmp_stats { struct address { struct sockaddr_storage ss; in_port_t port; - char ifname[IFNAMSIZ]; TAILQ_ENTRY(address) entry; diff --git a/usr.sbin/snmpd/trap.c b/usr.sbin/snmpd/trap.c index 6df145b5f7f..7304e140ad1 100644 --- a/usr.sbin/snmpd/trap.c +++ b/usr.sbin/snmpd/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.4 2008/01/16 21:43:19 reyk Exp $ */ +/* $OpenBSD: trap.c,v 1.5 2008/01/17 17:35:06 reyk Exp $ */ /* * Copyright (c) 2008 Reyk Floeter <reyk@vantronix.net> @@ -209,6 +209,7 @@ trap_send(struct ber_oid *oid, struct ber_element *elm) struct ber_oid uptime = OID(MIB_sysUpTime); struct ber_oid trapoid = OID(MIB_snmpTrapOID); char ostr[SNMP_MAX_OID_LEN]; + struct oid oa, ob; if (TAILQ_EMPTY(&env->sc_trapreceivers)) return (0); @@ -217,6 +218,17 @@ trap_send(struct ber_oid *oid, struct ber_element *elm) smi_oidlen(&trapoid); smi_oidlen(oid); + smi_oidstring(oid, ostr, sizeof(ostr)); + log_debug("trap_send: oid %s", ostr); + + /* Setup OIDs to compare against the trap receiver MIB */ + bzero(&oa, sizeof(oa)); + bcopy(oid->bo_id, &oa.o_oid, sizeof(oa.o_oid)); + oa.o_oidlen = oid->bo_n; + bzero(&ob, sizeof(ob)); + ob.o_flags = OID_TABLE; + + /* Add mandatory varbind elements */ trap = ber_add_sequence(NULL); c = ber_printf_elements(trap, "{Oit}{OO}", &uptime, smi_getticks(), @@ -228,12 +240,15 @@ trap_send(struct ber_oid *oid, struct ber_element *elm) bzero(&ber, sizeof(ber)); ber.fd = -1; - smi_oidstring(oid, ostr, sizeof(ostr)); - log_debug("trap_send: oid %s", ostr); - TAILQ_FOREACH(tr, &env->sc_trapreceivers, entry) { - if (tr->sa_oid != NULL && tr->sa_oid->bo_n) - /* XXX only send if the OID is specified */; + if (tr->sa_oid != NULL && tr->sa_oid->bo_n) { + /* The trap receiver may want only a specified MIB */ + bcopy(&tr->sa_oid->bo_id, &ob.o_oid, + sizeof(ob.o_oid)); + ob.o_oidlen = tr->sa_oid->bo_n; + if (smi_oid_cmp(&oa, &ob) != 0) + continue; + } if ((s = snmpd_socket_af(&tr->ss, htons(tr->port))) == -1) { ret = -1; |