summaryrefslogtreecommitdiff
path: root/usr.sbin/snmpd
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2008-01-17 17:35:07 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2008-01-17 17:35:07 +0000
commitc097341ea05ed19f678854416d3ac3520b26fcbc (patch)
tree4bb3a7e1c4869df7f0d2a39c327ca19cc6217a96 /usr.sbin/snmpd
parentb3abc29b3c80b872be1af4f696895fa26b3834db (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.y58
-rw-r--r--usr.sbin/snmpd/snmpd.conf.518
-rw-r--r--usr.sbin/snmpd/snmpd.h3
-rw-r--r--usr.sbin/snmpd/trap.c27
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;