summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/snmpctl/parser.c4
-rw-r--r--usr.sbin/snmpctl/snmpctl.c11
-rw-r--r--usr.sbin/snmpd/buffer.c91
-rw-r--r--usr.sbin/snmpd/control.c37
-rw-r--r--usr.sbin/snmpd/imsg.c96
-rw-r--r--usr.sbin/snmpd/imsg.h105
-rw-r--r--usr.sbin/snmpd/snmpd.c41
-rw-r--r--usr.sbin/snmpd/snmpd.h100
-rw-r--r--usr.sbin/snmpd/snmpe.c27
-rw-r--r--usr.sbin/snmpd/trap.c6
10 files changed, 302 insertions, 216 deletions
diff --git a/usr.sbin/snmpctl/parser.c b/usr.sbin/snmpctl/parser.c
index 74224408fe0..67d7cf2dbdf 100644
--- a/usr.sbin/snmpctl/parser.c
+++ b/usr.sbin/snmpctl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.7 2008/01/18 13:23:02 reyk Exp $ */
+/* $OpenBSD: parser.c,v 1.8 2009/06/06 05:52:00 pyr Exp $ */
/*
* Copyright (c) 2008 Reyk Floeter <reyk@vantronix.net>
@@ -240,7 +240,7 @@ match_token(char *word, const struct token table[])
(ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
err(1, "malloc");
res.ibuf = ibuf;
- imsg_init(ibuf, -1, NULL);
+ imsg_init(ibuf, -1);
/* Create a new trap */
imsg_compose(ibuf, IMSG_SNMP_TRAP,
diff --git a/usr.sbin/snmpctl/snmpctl.c b/usr.sbin/snmpctl/snmpctl.c
index d78f1ed1667..14c68346702 100644
--- a/usr.sbin/snmpctl/snmpctl.c
+++ b/usr.sbin/snmpctl/snmpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpctl.c,v 1.10 2008/09/26 19:26:24 jmc Exp $ */
+/* $OpenBSD: snmpctl.c,v 1.11 2009/06/06 05:52:00 pyr Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -78,13 +78,6 @@ usage(void)
exit(1);
}
-/* dummy function so that snmpctl does not need libevent */
-void
-imsg_event_add(struct imsgbuf *i)
-{
- /* nothing */
-}
-
int
main(int argc, char *argv[])
{
@@ -161,7 +154,7 @@ main(int argc, char *argv[])
else
if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
err(1, "malloc");
- imsg_init(ibuf, ctl_sock, NULL);
+ imsg_init(ibuf, ctl_sock);
done = 0;
/* process user request */
diff --git a/usr.sbin/snmpd/buffer.c b/usr.sbin/snmpd/buffer.c
index d7f3505bc20..c7de4476655 100644
--- a/usr.sbin/snmpd/buffer.c
+++ b/usr.sbin/snmpd/buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.c,v 1.6 2008/10/03 15:20:29 eric Exp $ */
+/* $OpenBSD: buffer.c,v 1.7 2009/06/06 05:52:01 pyr Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -16,24 +16,17 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/uio.h>
-#include <sys/param.h>
-#include <sys/tree.h>
-
-#include <net/if.h>
#include <errno.h>
-#include <event.h>
-#include <limits.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "snmpd.h"
+#include "imsg.h"
int buf_realloc(struct buf *, size_t);
void buf_enqueue(struct msgbuf *, struct buf *);
@@ -94,7 +87,7 @@ buf_realloc(struct buf *buf, size_t len)
}
int
-buf_add(struct buf *buf, void *data, size_t len)
+buf_add(struct buf *buf, const void *data, size_t len)
{
if (buf->wpos + len > buf->size)
if (buf_realloc(buf, len) == -1)
@@ -119,11 +112,77 @@ buf_reserve(struct buf *buf, size_t len)
return (b);
}
-int
+void *
+buf_seek(struct buf *buf, size_t pos, size_t len)
+{
+ /* only allowed to seek in already written parts */
+ if (pos + len > buf->wpos)
+ return (NULL);
+
+ return (buf->buf + pos);
+}
+
+size_t
+buf_size(struct buf *buf)
+{
+ return (buf->wpos);
+}
+
+size_t
+buf_left(struct buf *buf)
+{
+ return (buf->max - buf->wpos);
+}
+
+void
buf_close(struct msgbuf *msgbuf, struct buf *buf)
{
buf_enqueue(msgbuf, buf);
- return (1);
+}
+
+int
+buf_write(struct msgbuf *msgbuf)
+{
+ struct iovec iov[IOV_MAX];
+ struct buf *buf, *next;
+ unsigned int i = 0;
+ ssize_t n;
+
+ bzero(&iov, sizeof(iov));
+ TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
+ if (i >= IOV_MAX)
+ break;
+ iov[i].iov_base = buf->buf + buf->rpos;
+ iov[i].iov_len = buf->size - buf->rpos;
+ i++;
+ }
+
+ if ((n = writev(msgbuf->fd, iov, i)) == -1) {
+ if (errno == EAGAIN || errno == ENOBUFS ||
+ errno == EINTR) /* try later */
+ return (0);
+ else
+ return (-1);
+ }
+
+ if (n == 0) { /* connection closed */
+ errno = 0;
+ return (-2);
+ }
+
+ for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
+ buf = next) {
+ next = TAILQ_NEXT(buf, entry);
+ if (buf->rpos + n >= buf->size) {
+ n -= buf->size - buf->rpos;
+ buf_dequeue(msgbuf, buf);
+ } else {
+ buf->rpos += n;
+ n = 0;
+ }
+ }
+
+ return (0);
}
void
@@ -170,7 +229,7 @@ msgbuf_write(struct msgbuf *msgbuf)
if (i >= IOV_MAX)
break;
iov[i].iov_base = buf->buf + buf->rpos;
- iov[i].iov_len = buf->size - buf->rpos;
+ iov[i].iov_len = buf->wpos - buf->rpos;
i++;
if (buf->fd != -1)
break;
@@ -214,8 +273,8 @@ msgbuf_write(struct msgbuf *msgbuf)
for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
buf = next) {
next = TAILQ_NEXT(buf, entry);
- if (buf->rpos + n >= buf->size) {
- n -= buf->size - buf->rpos;
+ if (buf->rpos + n >= buf->wpos) {
+ n -= buf->wpos - buf->rpos;
buf_dequeue(msgbuf, buf);
} else {
buf->rpos += n;
diff --git a/usr.sbin/snmpd/control.c b/usr.sbin/snmpd/control.c
index a8f3a08c612..634ded674dd 100644
--- a/usr.sbin/snmpd/control.c
+++ b/usr.sbin/snmpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.9 2009/02/25 17:09:55 claudio Exp $ */
+/* $OpenBSD: control.c,v 1.10 2009/06/06 05:52:01 pyr Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -154,11 +154,12 @@ control_accept(int listenfd, short event, void *arg)
return;
}
- imsg_init(&c->ibuf, connfd, control_dispatch_imsg);
- c->ibuf.events = EV_READ;
- event_set(&c->ibuf.ev, c->ibuf.fd, c->ibuf.events,
- c->ibuf.handler, cs);
- event_add(&c->ibuf.ev, NULL);
+ imsg_init(&c->iev.ibuf, connfd);
+ c->iev.handler = control_dispatch_imsg;
+ c->iev.events = EV_READ;
+ event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
+ c->iev.handler, cs);
+ event_add(&c->iev.ev, NULL);
TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
}
@@ -168,7 +169,7 @@ control_connbyfd(int fd)
{
struct ctl_conn *c;
- for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->ibuf.fd != fd;
+ for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->iev.ibuf.fd != fd;
c = TAILQ_NEXT(c, entry))
; /* nothing */
@@ -185,11 +186,11 @@ control_close(int fd)
return;
}
- msgbuf_clear(&c->ibuf.w);
+ msgbuf_clear(&c->iev.ibuf.w);
TAILQ_REMOVE(&ctl_conns, c, entry);
- event_del(&c->ibuf.ev);
- close(c->ibuf.fd);
+ event_del(&c->iev.ev);
+ close(c->iev.ibuf.fd);
free(c);
}
@@ -209,24 +210,24 @@ control_dispatch_imsg(int fd, short event, void *arg)
switch (event) {
case EV_READ:
- if ((n = imsg_read(&c->ibuf)) == -1 || n == 0) {
+ if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) {
control_close(fd);
return;
}
break;
case EV_WRITE:
- if (msgbuf_write(&c->ibuf.w) < 0) {
+ if (msgbuf_write(&c->iev.ibuf.w) < 0) {
control_close(fd);
return;
}
- imsg_event_add(&c->ibuf);
+ imsg_event_add(&c->iev);
return;
default:
fatalx("unknown event");
}
for (;;) {
- if ((n = imsg_get(&c->ibuf, &imsg)) == -1) {
+ if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
control_close(fd);
return;
}
@@ -254,7 +255,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
if (c->flags & CTL_CONN_NOTIFY) {
log_debug("control_dispatch_imsg: "
"client requested notify more than once");
- imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1,
+ imsg_compose(&c->iev.ibuf, IMSG_CTL_FAIL, 0, 0, -1,
NULL, 0);
break;
}
@@ -265,7 +266,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
c->flags |= CTL_CONN_LOCKED;
break;
case IMSG_SNMP_TRAP:
- if (trap_imsg(&c->ibuf, imsg.hdr.pid) == -1) {
+ if (trap_imsg(&c->iev, imsg.hdr.pid) == -1) {
log_debug("control_dispatch_imsg: "
"received invalid trap (pid %d)",
imsg.hdr.pid);
@@ -282,7 +283,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
imsg_free(&imsg);
}
- imsg_event_add(&c->ibuf);
+ imsg_event_add(&c->iev);
}
void
@@ -292,7 +293,7 @@ control_imsg_forward(struct imsg *imsg)
TAILQ_FOREACH(c, &ctl_conns, entry)
if (c->flags & CTL_CONN_NOTIFY)
- imsg_compose(&c->ibuf, imsg->hdr.type, 0, imsg->hdr.pid,
+ imsg_compose(&c->iev.ibuf, imsg->hdr.type, 0, imsg->hdr.pid,
-1, imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE);
}
diff --git a/usr.sbin/snmpd/imsg.c b/usr.sbin/snmpd/imsg.c
index a7671183bec..cc1d07e0466 100644
--- a/usr.sbin/snmpd/imsg.c
+++ b/usr.sbin/snmpd/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.5 2008/03/24 16:11:05 deraadt Exp $ */
+/* $OpenBSD: imsg.c,v 1.6 2009/06/06 05:52:01 pyr Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -16,35 +16,27 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <sys/param.h>
#include <sys/queue.h>
+#include <sys/socket.h>
#include <sys/uio.h>
-#include <sys/param.h>
-#include <sys/tree.h>
-
-#include <net/if.h>
#include <errno.h>
-#include <event.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "snmpd.h"
+#include "imsg.h"
void
-imsg_init(struct imsgbuf *ibuf, int fd, void (*handler)(int, short, void *))
+imsg_init(struct imsgbuf *ibuf, int fd)
{
- if (!ibuf->pid) {
- msgbuf_init(&ibuf->w);
- bzero(&ibuf->r, sizeof(ibuf->r));
- ibuf->pid = getpid();
- ibuf->handler = handler;
- TAILQ_INIT(&ibuf->fds);
- }
+ msgbuf_init(&ibuf->w);
+ bzero(&ibuf->r, sizeof(ibuf->r));
ibuf->fd = fd;
ibuf->w.fd = fd;
+ ibuf->pid = getpid();
+ TAILQ_INIT(&ibuf->fds);
}
ssize_t
@@ -54,7 +46,7 @@ imsg_read(struct imsgbuf *ibuf)
struct cmsghdr *cmsg;
union {
struct cmsghdr hdr;
- char buf[CMSG_SPACE(sizeof(int) * 16)];
+ char buf[CMSG_SPACE(sizeof(int) * 16)];
} cmsgbuf;
struct iovec iov;
ssize_t n;
@@ -72,7 +64,6 @@ imsg_read(struct imsgbuf *ibuf)
if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
if (errno != EINTR && errno != EAGAIN) {
- log_warn("imsg_read: pipe read error");
return (-1);
}
return (-2);
@@ -85,13 +76,14 @@ imsg_read(struct imsgbuf *ibuf)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
fd = (*(int *)CMSG_DATA(cmsg));
- if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
- fatal("imsg_read calloc");
+ if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) {
+ /* XXX: this return can leak */
+ return (-1);
+ }
ifd->fd = fd;
TAILQ_INSERT_TAIL(&ibuf->fds, ifd, entry);
- } else
- log_warn("imsg_read: got unexpected ctl data level %d "
- "type %d", cmsg->cmsg_level, cmsg->cmsg_type);
+ }
+ /* we do not handle other ctl data level */
}
return (n);
@@ -110,8 +102,7 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
if (imsg->hdr.len < IMSG_HEADER_SIZE ||
imsg->hdr.len > MAX_IMSGSIZE) {
- log_warnx("imsg_get: imsg hdr len %u out of bounds, type=%u",
- imsg->hdr.len, imsg->hdr.type);
+ errno = ERANGE;
return (-1);
}
if (imsg->hdr.len > av)
@@ -119,7 +110,6 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
if ((imsg->data = malloc(datalen)) == NULL) {
- log_warn("imsg_get");
return (-1);
}
memcpy(imsg->data, ibuf->r.rptr, datalen);
@@ -135,11 +125,10 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
}
int
-imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
+imsg_compose(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid,
pid_t pid, int fd, void *data, u_int16_t datalen)
{
struct buf *wbuf;
- int n;
if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
return (-1);
@@ -149,18 +138,16 @@ imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
wbuf->fd = fd;
- if ((n = imsg_close(ibuf, wbuf)) < 0)
- return (-1);
+ imsg_close(ibuf, wbuf);
- return (n);
+ return (1);
}
int
-imsg_composev(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
+imsg_composev(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid,
pid_t pid, int fd, const struct iovec *iov, int iovcnt)
{
struct buf *wbuf;
- int n;
int i, datalen = 0;
for (i = 0; i < iovcnt; i++)
@@ -175,15 +162,14 @@ imsg_composev(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
wbuf->fd = fd;
- if ((n = imsg_close(ibuf, wbuf)) < 0)
- return (-1);
+ imsg_close(ibuf, wbuf);
- return (n);
+ return (1);
}
/* ARGSUSED */
struct buf *
-imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
+imsg_create(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid,
pid_t pid, u_int16_t datalen)
{
struct buf *wbuf;
@@ -191,9 +177,7 @@ imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
datalen += IMSG_HEADER_SIZE;
if (datalen > MAX_IMSGSIZE) {
- log_warnx("imsg_create: len %u > MAX_IMSGSIZE; "
- "type %u peerid %lu", datalen + IMSG_HEADER_SIZE,
- type, peerid);
+ errno = ERANGE;
return (NULL);
}
@@ -202,7 +186,6 @@ imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
if ((hdr.pid = pid) == 0)
hdr.pid = ibuf->pid;
if ((wbuf = buf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
- log_warn("imsg_create: buf_open");
return (NULL);
}
if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
@@ -216,29 +199,20 @@ imsg_add(struct buf *msg, void *data, u_int16_t datalen)
{
if (datalen)
if (buf_add(msg, data, datalen) == -1) {
- log_warnx("imsg_add: buf_add error");
buf_free(msg);
return (-1);
}
return (datalen);
}
-int
+void
imsg_close(struct imsgbuf *ibuf, struct buf *msg)
{
- int n;
struct imsg_hdr *hdr;
hdr = (struct imsg_hdr *)msg->buf;
hdr->len = (u_int16_t)msg->wpos;
- if ((n = buf_close(&ibuf->w, msg)) < 0) {
- log_warnx("imsg_close: buf_close error");
- buf_free(msg);
- return (-1);
- }
- imsg_event_add(ibuf);
-
- return (n);
+ buf_close(&ibuf->w, msg);
}
void
@@ -262,3 +236,19 @@ imsg_get_fd(struct imsgbuf *ibuf)
return (fd);
}
+
+int
+imsg_flush(struct imsgbuf *ibuf)
+{
+ while (ibuf->w.queued)
+ if (msgbuf_write(&ibuf->w) < 0)
+ return (-1);
+ return (0);
+}
+
+void
+imsg_clear(struct imsgbuf *ibuf)
+{
+ while (ibuf->w.queued)
+ msgbuf_clear(&ibuf->w);
+}
diff --git a/usr.sbin/snmpd/imsg.h b/usr.sbin/snmpd/imsg.h
new file mode 100644
index 00000000000..6f58fab1b0b
--- /dev/null
+++ b/usr.sbin/snmpd/imsg.h
@@ -0,0 +1,105 @@
+/* $OpenBSD: imsg.h,v 1.1 2009/06/06 05:52:01 pyr Exp $ */
+
+/*
+ * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
+ * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/tree.h>
+
+#define READ_BUF_SIZE 65535
+#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr)
+#define MAX_IMSGSIZE 16384
+
+struct buf {
+ TAILQ_ENTRY(buf) entry;
+ u_char *buf;
+ size_t size;
+ size_t max;
+ size_t wpos;
+ size_t rpos;
+ int fd;
+};
+
+struct msgbuf {
+ TAILQ_HEAD(, buf) bufs;
+ u_int32_t queued;
+ int fd;
+};
+
+struct buf_read {
+ u_char buf[READ_BUF_SIZE];
+ u_char *rptr;
+ size_t wpos;
+};
+
+struct imsg_fd {
+ TAILQ_ENTRY(imsg_fd) entry;
+ int fd;
+};
+
+struct imsgbuf {
+ TAILQ_HEAD(, imsg_fd) fds;
+ struct buf_read r;
+ struct msgbuf w;
+ int fd;
+ pid_t pid;
+};
+
+struct imsg_hdr {
+ u_int16_t type;
+ u_int16_t len;
+ u_int32_t peerid;
+ pid_t pid;
+};
+
+struct imsg {
+ struct imsg_hdr hdr;
+ void *data;
+};
+
+
+/* buffer.c */
+struct buf *buf_open(size_t);
+struct buf *buf_dynamic(size_t, size_t);
+int buf_add(struct buf *, const void *, size_t);
+void *buf_reserve(struct buf *, size_t);
+void *buf_seek(struct buf *, size_t, size_t);
+size_t buf_size(struct buf *);
+size_t buf_left(struct buf *);
+void buf_close(struct msgbuf *, struct buf *);
+int buf_write(struct msgbuf *);
+void buf_free(struct buf *);
+void msgbuf_init(struct msgbuf *);
+void msgbuf_clear(struct msgbuf *);
+int msgbuf_write(struct msgbuf *);
+
+/* imsg.c */
+void imsg_init(struct imsgbuf *, int);
+ssize_t imsg_read(struct imsgbuf *);
+ssize_t imsg_get(struct imsgbuf *, struct imsg *);
+int imsg_compose(struct imsgbuf *, u_int16_t, u_int32_t, pid_t,
+ int, void *, u_int16_t);
+int imsg_composev(struct imsgbuf *, u_int16_t, u_int32_t, pid_t,
+ int, const struct iovec *, int);
+struct buf *imsg_create(struct imsgbuf *, u_int16_t, u_int32_t, pid_t,
+ u_int16_t);
+int imsg_add(struct buf *, void *, u_int16_t);
+void imsg_close(struct imsgbuf *, struct buf *);
+void imsg_free(struct imsg *);
+int imsg_get_fd(struct imsgbuf *);
+int imsg_flush(struct imsgbuf *);
+void imsg_clear(struct imsgbuf *);
diff --git a/usr.sbin/snmpd/snmpd.c b/usr.sbin/snmpd/snmpd.c
index fad785ecabf..6a3bd9d6130 100644
--- a/usr.sbin/snmpd/snmpd.c
+++ b/usr.sbin/snmpd/snmpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.c,v 1.8 2008/09/26 15:19:55 reyk Exp $ */
+/* $OpenBSD: snmpd.c,v 1.9 2009/06/06 05:52:01 pyr Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -48,7 +48,7 @@ int check_child(pid_t, const char *);
struct snmpd *snmpd_env;
int pipe_parent2snmpe[2];
-struct imsgbuf *ibuf_snmpe;
+struct imsgev *iev_snmpe;
pid_t snmpe_pid = 0;
void
@@ -198,15 +198,16 @@ main(int argc, char *argv[])
close(pipe_parent2snmpe[1]);
- if ((ibuf_snmpe = calloc(1, sizeof(struct imsgbuf))) == NULL)
+ if ((iev_snmpe = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
- imsg_init(ibuf_snmpe, pipe_parent2snmpe[0], snmpd_dispatch_snmpe);
+ imsg_init(&iev_snmpe->ibuf, pipe_parent2snmpe[0]);
+ iev_snmpe->handler = snmpd_dispatch_snmpe;
- ibuf_snmpe->events = EV_READ;
- event_set(&ibuf_snmpe->ev, ibuf_snmpe->fd, ibuf_snmpe->events,
- ibuf_snmpe->handler, ibuf_snmpe);
- event_add(&ibuf_snmpe->ev, NULL);
+ iev_snmpe->events = EV_READ;
+ event_set(&iev_snmpe->ev, iev_snmpe->ibuf.fd, iev_snmpe->events,
+ iev_snmpe->handler, iev_snmpe);
+ event_add(&iev_snmpe->ev, NULL);
event_dispatch();
@@ -254,32 +255,34 @@ check_child(pid_t pid, const char *pname)
}
void
-imsg_event_add(struct imsgbuf *ibuf)
+imsg_event_add(struct imsgev *iev)
{
- ibuf->events = EV_READ;
- if (ibuf->w.queued)
- ibuf->events |= EV_WRITE;
+ iev->events = EV_READ;
+ if (iev->ibuf.w.queued)
+ iev->events |= EV_WRITE;
- event_del(&ibuf->ev);
- event_set(&ibuf->ev, ibuf->fd, ibuf->events, ibuf->handler, ibuf);
- event_add(&ibuf->ev, NULL);
+ event_del(&iev->ev);
+ event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
+ event_add(&iev->ev, NULL);
}
void
snmpd_dispatch_snmpe(int fd, short event, void * ptr)
{
+ struct imsgev *iev;
struct imsgbuf *ibuf;
struct imsg imsg;
ssize_t n;
- ibuf = ptr;
+ iev = ptr;
+ ibuf = &iev->ibuf;
switch (event) {
case EV_READ:
if ((n = imsg_read(ibuf)) == -1)
fatal("imsg_read error");
if (n == 0) {
/* this pipe is dead, so remove the event handler */
- event_del(&ibuf->ev);
+ event_del(&iev->ev);
event_loopexit(NULL);
return;
}
@@ -287,7 +290,7 @@ snmpd_dispatch_snmpe(int fd, short event, void * ptr)
case EV_WRITE:
if (msgbuf_write(&ibuf->w) == -1)
fatal("msgbuf_write");
- imsg_event_add(ibuf);
+ imsg_event_add(iev);
return;
default:
fatalx("unknown event");
@@ -307,7 +310,7 @@ snmpd_dispatch_snmpe(int fd, short event, void * ptr)
}
imsg_free(&imsg);
}
- imsg_event_add(ibuf);
+ imsg_event_add(iev);
}
int
diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h
index b84d33299ac..5b03fb7edbf 100644
--- a/usr.sbin/snmpd/snmpd.h
+++ b/usr.sbin/snmpd/snmpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.h,v 1.23 2008/12/23 08:06:10 reyk Exp $ */
+/* $OpenBSD: snmpd.h,v 1.24 2009/06/06 05:52:01 pyr Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -27,6 +27,8 @@
#include <ber.h>
#include <snmp.h>
+#include "imsg.h"
+
/*
* common definitions for snmpd
*/
@@ -47,51 +49,6 @@
#define RT_BUF_SIZE 16384
#define MAX_RTSOCK_BUF (128 * 1024)
-/*
- * imsg framework and privsep
- */
-
-struct buf {
- TAILQ_ENTRY(buf) entry;
- u_char *buf;
- size_t size;
- size_t max;
- size_t wpos;
- size_t rpos;
- int fd;
-};
-
-struct msgbuf {
- TAILQ_HEAD(, buf) bufs;
- u_int32_t queued;
- int fd;
-};
-
-#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr)
-#define MAX_IMSGSIZE 8192
-
-struct buf_read {
- u_char buf[READ_BUF_SIZE];
- u_char *rptr;
- size_t wpos;
-};
-
-struct imsg_fd {
- TAILQ_ENTRY(imsg_fd) entry;
- int fd;
-};
-
-struct imsgbuf {
- TAILQ_HEAD(, imsg_fd) fds;
- struct buf_read r;
- struct msgbuf w;
- struct event ev;
- void (*handler)(int, short, void *);
- int fd;
- pid_t pid;
- short events;
-};
-
enum imsg_type {
IMSG_NONE,
IMSG_CTL_OK, /* answer to snmpctl requests */
@@ -100,18 +57,6 @@ enum imsg_type {
IMSG_CTL_NOTIFY
};
-struct imsg_hdr {
- u_int16_t type;
- u_int16_t len;
- u_int32_t peerid;
- pid_t pid;
-};
-
-struct imsg {
- struct imsg_hdr hdr;
- void *data;
-};
-
enum {
PROC_PARENT, /* Parent process and application interface */
PROC_SNMPE /* SNMP engine */
@@ -130,12 +75,20 @@ enum blockmodes {
BM_NONBLOCK
};
+struct imsgev {
+ struct imsgbuf ibuf;
+ void (*handler)(int, short, void *);
+ struct event ev;
+ void *data;
+ short events;
+};
+
struct ctl_conn {
TAILQ_ENTRY(ctl_conn) entry;
u_int8_t flags;
#define CTL_CONN_NOTIFY 0x01
#define CTL_CONN_LOCKED 0x02 /* restricted mode */
- struct imsgbuf ibuf;
+ struct imsgev iev;
};
TAILQ_HEAD(ctl_connlist, ctl_conn);
@@ -363,32 +316,9 @@ __dead void fatal(const char *);
__dead void fatalx(const char *);
const char *print_host(struct sockaddr_storage *, char *, size_t);
-/* buffer.c */
-struct buf *buf_open(size_t);
-struct buf *buf_dynamic(size_t, size_t);
-int buf_add(struct buf *, void *, size_t);
-void *buf_reserve(struct buf *, size_t);
-int buf_close(struct msgbuf *, struct buf *);
-void buf_free(struct buf *);
-void msgbuf_init(struct msgbuf *);
-void msgbuf_clear(struct msgbuf *);
-int msgbuf_write(struct msgbuf *);
-
-/* imsg.c */
-void imsg_init(struct imsgbuf *, int, void (*)(int, short, void *));
-ssize_t imsg_read(struct imsgbuf *);
-ssize_t imsg_get(struct imsgbuf *, struct imsg *);
-int imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t,
+void imsg_event_add(struct imsgev *);
+int imsg_compose_event(struct imsgev *, enum imsg_type, u_int32_t,
pid_t, int, void *, u_int16_t);
-int imsg_composev(struct imsgbuf *, enum imsg_type , u_int32_t,
- pid_t, int, const struct iovec *, int);
-struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t,
- pid_t, u_int16_t);
-int imsg_add(struct buf *, void *, u_int16_t);
-int imsg_close(struct imsgbuf *, struct buf *);
-void imsg_free(struct imsg *);
-void imsg_event_add(struct imsgbuf *); /* provided externally */
-int imsg_get_fd(struct imsgbuf *);
/* kroute.c */
int kr_init(void);
@@ -408,7 +338,7 @@ void snmpe_debug_elements(struct ber_element *);
/* trap.c */
void trap_init(void);
-int trap_imsg(struct imsgbuf *, pid_t);
+int trap_imsg(struct imsgev *, pid_t);
int trap_send(struct ber_oid *, struct ber_element *);
/* mps.c */
diff --git a/usr.sbin/snmpd/snmpe.c b/usr.sbin/snmpd/snmpe.c
index 2b671a6a162..ef21047d489 100644
--- a/usr.sbin/snmpd/snmpe.c
+++ b/usr.sbin/snmpd/snmpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpe.c,v 1.23 2008/12/08 11:34:55 reyk Exp $ */
+/* $OpenBSD: snmpe.c,v 1.24 2009/06/06 05:52:01 pyr Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -51,7 +51,7 @@ void snmpe_recvmsg(int fd, short, void *);
struct snmpd *env = NULL;
-struct imsgbuf *ibuf_parent;
+struct imsgev *iev_parent;
void
snmpe_sig_handler(int sig, short event, void *arg)
@@ -137,15 +137,16 @@ snmpe(struct snmpd *x_env, int pipe_parent2snmpe[2])
close(pipe_parent2snmpe[0]);
- if ((ibuf_parent = calloc(1, sizeof(struct imsgbuf))) == NULL)
+ if ((iev_parent = calloc(1, sizeof(struct imsgev))) == NULL)
fatal("snmpe");
- imsg_init(ibuf_parent, pipe_parent2snmpe[1], snmpe_dispatch_parent);
+ imsg_init(&iev_parent->ibuf, pipe_parent2snmpe[1]);
+ iev_parent->handler = snmpe_dispatch_parent;
- ibuf_parent->events = EV_READ;
- event_set(&ibuf_parent->ev, ibuf_parent->fd, ibuf_parent->events,
- ibuf_parent->handler, ibuf_parent);
- event_add(&ibuf_parent->ev, NULL);
+ iev_parent->events = EV_READ;
+ event_set(&iev_parent->ev, iev_parent->ibuf.fd, iev_parent->events,
+ iev_parent->handler, iev_parent);
+ event_add(&iev_parent->ev, NULL);
TAILQ_INIT(&ctl_conns);
@@ -180,18 +181,20 @@ snmpe_shutdown(void)
void
snmpe_dispatch_parent(int fd, short event, void * ptr)
{
+ struct imsgev *iev;
struct imsgbuf *ibuf;
struct imsg imsg;
ssize_t n;
- ibuf = ptr;
+ iev = ptr;
+ ibuf = &iev->ibuf;
switch (event) {
case EV_READ:
if ((n = imsg_read(ibuf)) == -1)
fatal("imsg_read error");
if (n == 0) {
/* this pipe is dead, so remove the event handler */
- event_del(&ibuf->ev);
+ event_del(&iev->ev);
event_loopexit(NULL);
return;
}
@@ -199,7 +202,7 @@ snmpe_dispatch_parent(int fd, short event, void * ptr)
case EV_WRITE:
if (msgbuf_write(&ibuf->w) == -1)
fatal("msgbuf_write");
- imsg_event_add(ibuf);
+ imsg_event_add(iev);
return;
default:
fatalx("snmpe_dispatch_parent: unknown event");
@@ -219,7 +222,7 @@ snmpe_dispatch_parent(int fd, short event, void * ptr)
}
imsg_free(&imsg);
}
- imsg_event_add(ibuf);
+ imsg_event_add(iev);
}
int
diff --git a/usr.sbin/snmpd/trap.c b/usr.sbin/snmpd/trap.c
index bcd02506772..b04f61bcaff 100644
--- a/usr.sbin/snmpd/trap.c
+++ b/usr.sbin/snmpd/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.13 2008/10/09 14:14:40 reyk Exp $ */
+/* $OpenBSD: trap.c,v 1.14 2009/06/06 05:52:01 pyr Exp $ */
/*
* Copyright (c) 2008 Reyk Floeter <reyk@vantronix.net>
@@ -55,8 +55,9 @@ trap_init(void)
}
int
-trap_imsg(struct imsgbuf *ibuf, pid_t pid)
+trap_imsg(struct imsgev *iev, pid_t pid)
{
+ struct imsgbuf *ibuf;
struct imsg imsg;
int ret = -1, n, x = 0, state = 0;
int done = 0;
@@ -69,6 +70,7 @@ trap_imsg(struct imsgbuf *ibuf, pid_t pid)
size_t len = 0;
struct ber_oid o;
+ ibuf = &iev->ibuf;
while (!done) {
while (!done) {
if ((n = imsg_get(ibuf, &imsg)) == -1)