summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/snmpd/control.c4
-rw-r--r--usr.sbin/snmpd/parse.y40
-rw-r--r--usr.sbin/snmpd/snmpd.h16
-rw-r--r--usr.sbin/snmpd/snmpe.c35
-rw-r--r--usr.sbin/snmpd/traphandler.c43
5 files changed, 87 insertions, 51 deletions
diff --git a/usr.sbin/snmpd/control.c b/usr.sbin/snmpd/control.c
index c4240d14f3b..833d2be7725 100644
--- a/usr.sbin/snmpd/control.c
+++ b/usr.sbin/snmpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.39 2016/09/02 13:28:36 eric Exp $ */
+/* $OpenBSD: control.c,v 1.40 2016/11/18 16:16:39 jca Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -592,7 +592,7 @@ control_dispatch_agentx(int fd, short event, void *arg)
}
}
dispatch:
- snmpe_dispatchmsg(msg);
+ snmpe_dispatchmsg(msg, fd);
break;
}
diff --git a/usr.sbin/snmpd/parse.y b/usr.sbin/snmpd/parse.y
index f173650fcab..533db0b2ab7 100644
--- a/usr.sbin/snmpd/parse.y
+++ b/usr.sbin/snmpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.40 2016/11/09 20:31:56 jca Exp $ */
+/* $OpenBSD: parse.y,v 1.41 2016/11/18 16:16:39 jca Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -198,25 +198,13 @@ yesno : STRING {
;
main : LISTEN ON STRING {
- struct addresslist al;
- struct address *h;
-
- TAILQ_INIT(&al);
- if (host($3, &al, 1, SNMPD_PORT, NULL, NULL, NULL)
- <= 0) {
+ if (host($3, &conf->sc_addresses, 16, SNMPD_PORT, NULL,
+ NULL, NULL) <= 0) {
yyerror("invalid ip address: %s", $3);
free($3);
YYERROR;
}
free($3);
- h = TAILQ_FIRST(&al);
- bcopy(&h->ss, &conf->sc_address.ss, sizeof(*h));
- conf->sc_address.port = h->port;
-
- while ((h = TAILQ_FIRST(&al)) != NULL) {
- TAILQ_REMOVE(&al, h, entry);
- free(h);
- }
}
| READONLY COMMUNITY STRING {
if (strlcpy(conf->sc_rdcommunity, $3,
@@ -989,8 +977,8 @@ parse_config(const char *filename, u_int flags)
conf->sc_flags = flags;
conf->sc_confpath = filename;
- conf->sc_address.ss.ss_family = AF_INET;
- conf->sc_address.port = SNMPD_PORT;
+ TAILQ_INIT(&conf->sc_addresses);
+ TAILQ_INIT(&conf->sc_sockets);
conf->sc_ps.ps_csock.cs_name = SNMPD_SOCKET;
TAILQ_INIT(&conf->sc_ps.ps_rcsocks);
strlcpy(conf->sc_rdcommunity, "public", SNMPD_MAXCOMMUNITYLEN);
@@ -1011,6 +999,20 @@ parse_config(const char *filename, u_int flags)
endservent();
+ if (TAILQ_EMPTY(&conf->sc_addresses)) {
+ struct address *h;
+ if ((h = calloc(1, sizeof(*h))) == NULL)
+ fatal("snmpe: %s", __func__);
+ h->ss.ss_family = AF_INET;
+ h->port = SNMPD_PORT;
+ TAILQ_INSERT_TAIL(&conf->sc_addresses, h, entry);
+ if ((h = calloc(1, sizeof(*h))) == NULL)
+ fatal("snmpe: %s", __func__);
+ h->ss.ss_family = AF_INET6;
+ h->port = SNMPD_PORT;
+ TAILQ_INSERT_TAIL(&conf->sc_addresses, h, entry);
+ }
+
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
next = TAILQ_NEXT(sym, entry);
@@ -1215,7 +1217,7 @@ host_dns(const char *s, struct addresslist *al, int max,
h->sa_srcaddr = src;
- TAILQ_INSERT_HEAD(al, h, entry);
+ TAILQ_INSERT_TAIL(al, h, entry);
cnt++;
}
if (cnt == max && res) {
@@ -1262,7 +1264,7 @@ host(const char *s, struct addresslist *al, int max,
}
h->sa_srcaddr = src;
- TAILQ_INSERT_HEAD(al, h, entry);
+ TAILQ_INSERT_TAIL(al, h, entry);
return (1);
}
diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h
index 38d01f0f5bd..46782c3f46d 100644
--- a/usr.sbin/snmpd/snmpd.h
+++ b/usr.sbin/snmpd/snmpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.h,v 1.72 2016/11/09 20:31:56 jca Exp $ */
+/* $OpenBSD: snmpd.h,v 1.73 2016/11/18 16:16:39 jca Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -518,6 +518,13 @@ struct address {
};
TAILQ_HEAD(addresslist, address);
+struct listen_sock {
+ int s_fd;
+ struct event s_ev;
+ TAILQ_ENTRY(listen_sock) entry;
+};
+TAILQ_HEAD(socklist, listen_sock);
+
enum usmauth {
AUTH_NONE = 0,
AUTH_MD5, /* HMAC-MD5-96, RFC3414 */
@@ -556,9 +563,8 @@ struct snmpd {
#define SNMPD_F_NONAMES 0x02
const char *sc_confpath;
- struct address sc_address;
- int sc_sock;
- struct event sc_ev;
+ struct addresslist sc_addresses;
+ struct socklist sc_sockets;
struct timeval sc_starttime;
u_int32_t sc_engine_boots;
@@ -652,7 +658,7 @@ struct kif_arp *karp_getaddr(struct sockaddr *, u_short, int);
/* snmpe.c */
void snmpe(struct privsep *, struct privsep_proc *);
void snmpe_shutdown(void);
-void snmpe_dispatchmsg(struct snmp_message *);
+void snmpe_dispatchmsg(struct snmp_message *, int);
/* trap.c */
void trap_init(void);
diff --git a/usr.sbin/snmpd/snmpe.c b/usr.sbin/snmpd/snmpe.c
index 23d0dfe32c5..7bb2ea6ee32 100644
--- a/usr.sbin/snmpd/snmpe.c
+++ b/usr.sbin/snmpd/snmpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpe.c,v 1.45 2016/11/09 20:31:56 jca Exp $ */
+/* $OpenBSD: snmpe.c,v 1.46 2016/11/18 16:16:39 jca Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -61,7 +61,9 @@ static struct privsep_proc procs[] = {
void
snmpe(struct privsep *ps, struct privsep_proc *p)
{
- struct snmpd *env = ps->ps_env;
+ struct snmpd *env = ps->ps_env;
+ struct address *h;
+ struct listen_sock *so;
#ifdef DEBUG
char buf[BUFSIZ];
struct oid *oid;
@@ -74,9 +76,13 @@ snmpe(struct privsep *ps, struct privsep_proc *p)
}
#endif
- /* bind SNMP UDP socket */
- if ((env->sc_sock = snmpe_bind(&env->sc_address)) == -1)
- fatalx("snmpe: failed to bind SNMP UDP socket");
+ TAILQ_FOREACH(h, &env->sc_addresses, entry) {
+ if ((so = calloc(1, sizeof(*so))) == NULL)
+ fatal("snmpe: %s", __func__);
+ if ((so->s_fd = snmpe_bind(h)) == -1)
+ fatal("snmpe: failed to bind SNMP UDP socket");
+ TAILQ_INSERT_TAIL(&env->sc_sockets, so, entry);
+ }
proc_run(ps, p, procs, nitems(procs), snmpe_init, NULL);
}
@@ -85,7 +91,8 @@ snmpe(struct privsep *ps, struct privsep_proc *p)
void
snmpe_init(struct privsep *ps, struct privsep_proc *p, void *arg)
{
- struct snmpd *env = ps->ps_env;
+ struct snmpd *env = ps->ps_env;
+ struct listen_sock *so;
kr_init();
trap_init();
@@ -93,9 +100,11 @@ snmpe_init(struct privsep *ps, struct privsep_proc *p, void *arg)
usm_generate_keys();
/* listen for incoming SNMP UDP messages */
- event_set(&env->sc_ev, env->sc_sock, EV_READ|EV_PERSIST,
- snmpe_recvmsg, env);
- event_add(&env->sc_ev, NULL);
+ TAILQ_FOREACH(so, &env->sc_sockets, entry) {
+ event_set(&so->s_ev, so->s_fd, EV_READ|EV_PERSIST,
+ snmpe_recvmsg, env);
+ event_add(&so->s_ev, NULL);
+ }
}
void
@@ -156,7 +165,7 @@ snmpe_bind(struct address *addr)
if (print_host(&addr->ss, buf, sizeof(buf)) == NULL)
goto bad;
- log_info("snmpe_bind: binding to address %s:%d", buf, addr->port);
+ log_info("snmpe: listening on %s:%d", buf, addr->port);
return (s);
@@ -519,18 +528,18 @@ snmpe_recvmsg(int fd, short sig, void *arg)
}
}
- snmpe_dispatchmsg(msg);
+ snmpe_dispatchmsg(msg, fd);
}
void
-snmpe_dispatchmsg(struct snmp_message *msg)
+snmpe_dispatchmsg(struct snmp_message *msg, int sock)
{
if (snmpe_parsevarbinds(msg) == 1)
return;
/* not dispatched to subagent; respond directly */
msg->sm_context = SNMP_C_GETRESP;
- snmpe_response(snmpd_env->sc_sock, msg);
+ snmpe_response(sock, msg);
}
void
diff --git a/usr.sbin/snmpd/traphandler.c b/usr.sbin/snmpd/traphandler.c
index a89ac42c120..76f48bfa031 100644
--- a/usr.sbin/snmpd/traphandler.c
+++ b/usr.sbin/snmpd/traphandler.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: traphandler.c,v 1.6 2016/10/28 09:07:08 rzalamena Exp $ */
+/* $OpenBSD: traphandler.c,v 1.7 2016/11/18 16:16:39 jca Exp $ */
/*
* Copyright (c) 2014 Bret Stephen Lambert <blambert@openbsd.org>
@@ -43,8 +43,6 @@
#include "snmpd.h"
#include "mib.h"
-int trapsock;
-struct event trapev;
char trap_path[PATH_MAX];
void traphandler_init(struct privsep *, struct privsep_proc *, void *arg);
@@ -76,10 +74,18 @@ void
traphandler(struct privsep *ps, struct privsep_proc *p)
{
struct snmpd *env = ps->ps_env;
-
- if (env->sc_traphandler &&
- (trapsock = traphandler_bind(&env->sc_address)) == -1)
- fatal("could not create trap listener socket");
+ struct address *h;
+ struct listen_sock *so;
+
+ if (env->sc_traphandler) {
+ TAILQ_FOREACH(h, &env->sc_addresses, entry) {
+ if ((so = calloc(1, sizeof(*so))) == NULL)
+ fatal("%s", __func__);
+ if ((so->s_fd = traphandler_bind(h)) == -1)
+ fatal("could not create trap listener socket");
+ TAILQ_INSERT_TAIL(&env->sc_sockets, so, entry);
+ }
+ }
proc_run(ps, p, procs, nitems(procs), traphandler_init, NULL);
}
@@ -88,20 +94,24 @@ void
traphandler_init(struct privsep *ps, struct privsep_proc *p, void *arg)
{
struct snmpd *env = ps->ps_env;
+ struct listen_sock *so;
if (!env->sc_traphandler)
return;
/* listen for SNMP trap messages */
- event_set(&trapev, trapsock, EV_READ|EV_PERSIST, traphandler_recvmsg,
- ps);
- event_add(&trapev, NULL);
+ TAILQ_FOREACH(so, &env->sc_sockets, entry) {
+ event_set(&so->s_ev, so->s_fd, EV_READ|EV_PERSIST,
+ traphandler_recvmsg, ps);
+ event_add(&so->s_ev, NULL);
+ }
}
int
traphandler_bind(struct address *addr)
{
int s;
+ char buf[512];
if ((s = snmpd_socket_af(&addr->ss, htons(SNMPD_TRAPPORT))) == -1)
return (-1);
@@ -112,6 +122,11 @@ traphandler_bind(struct address *addr)
if (bind(s, (struct sockaddr *)&addr->ss, addr->ss.ss_len) == -1)
goto bad;
+ if (print_host(&addr->ss, buf, sizeof(buf)) == NULL)
+ goto bad;
+
+ log_info("traphandler: listening on %s:%d", buf, SNMPD_TRAPPORT);
+
return (s);
bad:
close (s);
@@ -121,8 +136,12 @@ traphandler_bind(struct address *addr)
void
traphandler_shutdown(void)
{
- event_del(&trapev);
- close(trapsock);
+ struct listen_sock *so;
+
+ TAILQ_FOREACH(so, &snmpd_env->sc_sockets, entry) {
+ event_del(&so->s_ev);
+ close(so->s_fd);
+ }
}
int