diff options
-rw-r--r-- | usr.sbin/snmpctl/parser.c | 4 | ||||
-rw-r--r-- | usr.sbin/snmpctl/snmpctl.c | 11 | ||||
-rw-r--r-- | usr.sbin/snmpd/buffer.c | 91 | ||||
-rw-r--r-- | usr.sbin/snmpd/control.c | 37 | ||||
-rw-r--r-- | usr.sbin/snmpd/imsg.c | 96 | ||||
-rw-r--r-- | usr.sbin/snmpd/imsg.h | 105 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.c | 41 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.h | 100 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpe.c | 27 | ||||
-rw-r--r-- | usr.sbin/snmpd/trap.c | 6 |
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) |