aboutsummaryrefslogtreecommitdiffstats
path: root/glougloud
diff options
context:
space:
mode:
Diffstat (limited to 'glougloud')
-rw-r--r--glougloud/BUGS.txt10
-rw-r--r--glougloud/Makefile12
-rw-r--r--glougloud/README.txt51
-rw-r--r--glougloud/external/README.txt8
-rw-r--r--glougloud/external/imsg-buffer.c305
-rw-r--r--glougloud/external/imsg.c301
-rw-r--r--glougloud/external/imsg.h118
-rw-r--r--glougloud/external/imsgev.c170
-rw-r--r--glougloud/external/imsgev.h49
-rw-r--r--glougloud/external/queue.h568
-rw-r--r--glougloud/glougloud.c487
-rw-r--r--glougloud/glougloud.h79
-rw-r--r--glougloud/server.c238
-rw-r--r--glougloud/user.c806
-rw-r--r--glougloud/util.c192
15 files changed, 0 insertions, 3394 deletions
diff --git a/glougloud/BUGS.txt b/glougloud/BUGS.txt
deleted file mode 100644
index 8380e70..0000000
--- a/glougloud/BUGS.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-#0000 TITLE
-DESCRIPTION
-
-=== TODO ===
-
-#0001 fatal() messages should be printed on stderr
-see util.c fatal()
-
-
-=== DONE ===
diff --git a/glougloud/Makefile b/glougloud/Makefile
deleted file mode 100644
index d37dde2..0000000
--- a/glougloud/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-PROG = glougloud
-OBJS = glougloud.o server.o user.o util.o external/imsgev.o external/imsg-buffer.o external/imsg.o
-CFLAGS+=-Wall -g
-LDFLAGS=-lpcap -levent -lutil
-
-all:
- make $(OBJS)
- $(CC) $(OBJS) -o $(PROG) $(LDFLAGS)
-
-clean:
- rm -f $(PROG) *~ *.o external/*.o
-
diff --git a/glougloud/README.txt b/glougloud/README.txt
deleted file mode 100644
index 8a8c702..0000000
--- a/glougloud/README.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-glougloud - glouglou daemon, for network traffic visualisation in real time
-
-
-=== Requirements ===
-
-* libglouglou
-
-Known to work on OpenBSD 5.1 and Linux 3.4
-
-
-=== Installation ===
-
-git clone git@meg:glouglou
-
-sudo useradd -d /var/empty/ -s /sbin/nologin _glougloud
-
-
-=== Usage ===
-
-* Run the daemon
-
-cd glouglou/glougloud/
-sudo ./glougloud
-
-It logs to /var/log/glougloud.
-For the moment it monitors lo0 interface.
-
-* Connect to the daemon
-
-nc -vvv -u 127.0.0.1 4430 |hexdump -C
-
-You get informations of traffic flowing on the monitored interface.
-
-
-=== Notes on architecture and security ===
-
-glougloud is architectured in 3 processes:
- * main process, runs as root, opens the capture interfaces with
-libpcap and resolves DNS names
- * server process, runs as _glougloud user and chrooted in _glougloud
-home, listens and accepts or refuses clients connections
- * user process, runs as _glougloud user and chrooted in _glougloud
-home, parses the captured network traffic and sends a summary to the
-connected clients
-
-The 3 processes exchanges messages througt messages, with OpenBSD imsg
-framework.
-
-Note that glougloud activates extra protections on pcap capture only
-on OpenBSD by reimplementing some of libpcap functions, see
-glougloud.c my_pcap_open_live()
diff --git a/glougloud/external/README.txt b/glougloud/external/README.txt
deleted file mode 100644
index 7e7509f..0000000
--- a/glougloud/external/README.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-- imsg framework, and IPC mechanism from OpenBSD -
-imsg-buffer.c
-imsg.c
-imsg.h
-imsgev.c
-imsgev.h
-- queue implementation, from OpenBSD -
-queue.h
diff --git a/glougloud/external/imsg-buffer.c b/glougloud/external/imsg-buffer.c
deleted file mode 100644
index 9f04757..0000000
--- a/glougloud/external/imsg-buffer.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/* $OpenBSD: imsg-buffer.c,v 1.2 2012/06/02 21:46:53 gilles Exp $ */
-
-/*
- * 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/param.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "imsg.h"
-
-int ibuf_realloc(struct ibuf *, size_t);
-void ibuf_enqueue(struct msgbuf *, struct ibuf *);
-void ibuf_dequeue(struct msgbuf *, struct ibuf *);
-
-struct ibuf *
-ibuf_open(size_t len)
-{
- struct ibuf *buf;
-
- if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
- return (NULL);
- if ((buf->buf = malloc(len)) == NULL) {
- free(buf);
- return (NULL);
- }
- buf->size = buf->max = len;
- buf->fd = -1;
-
- return (buf);
-}
-
-struct ibuf *
-ibuf_dynamic(size_t len, size_t max)
-{
- struct ibuf *buf;
-
- if (max < len)
- return (NULL);
-
- if ((buf = ibuf_open(len)) == NULL)
- return (NULL);
-
- if (max > 0)
- buf->max = max;
-
- return (buf);
-}
-
-int
-ibuf_realloc(struct ibuf *buf, size_t len)
-{
- u_char *b;
-
- /* on static buffers max is eq size and so the following fails */
- if (buf->wpos + len > buf->max) {
- errno = ENOMEM;
- return (-1);
- }
-
- b = realloc(buf->buf, buf->wpos + len);
- if (b == NULL)
- return (-1);
- buf->buf = b;
- buf->size = buf->wpos + len;
-
- return (0);
-}
-
-int
-ibuf_add(struct ibuf *buf, const void *data, size_t len)
-{
- if (buf->wpos + len > buf->size)
- if (ibuf_realloc(buf, len) == -1)
- return (-1);
-
- memcpy(buf->buf + buf->wpos, data, len);
- buf->wpos += len;
- return (0);
-}
-
-void *
-ibuf_reserve(struct ibuf *buf, size_t len)
-{
- void *b;
-
- if (buf->wpos + len > buf->size)
- if (ibuf_realloc(buf, len) == -1)
- return (NULL);
-
- b = buf->buf + buf->wpos;
- buf->wpos += len;
- return (b);
-}
-
-void *
-ibuf_seek(struct ibuf *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
-ibuf_size(struct ibuf *buf)
-{
- return (buf->wpos);
-}
-
-size_t
-ibuf_left(struct ibuf *buf)
-{
- return (buf->max - buf->wpos);
-}
-
-void
-ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
-{
- ibuf_enqueue(msgbuf, buf);
-}
-
-int
-ibuf_write(struct msgbuf *msgbuf)
-{
- struct iovec iov[IOV_MAX];
- struct ibuf *buf;
- 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->wpos - buf->rpos;
- i++;
- }
-
-again:
- if ((n = writev(msgbuf->fd, iov, i)) == -1) {
- if (errno == EAGAIN || errno == EINTR)
- goto again;
- if (errno == ENOBUFS)
- errno = EAGAIN;
- return (-1);
- }
-
- if (n == 0) { /* connection closed */
- errno = 0;
- return (0);
- }
-
- msgbuf_drain(msgbuf, n);
-
- return (1);
-}
-
-void
-ibuf_free(struct ibuf *buf)
-{
- free(buf->buf);
- free(buf);
-}
-
-void
-msgbuf_init(struct msgbuf *msgbuf)
-{
- msgbuf->queued = 0;
- msgbuf->fd = -1;
- TAILQ_INIT(&msgbuf->bufs);
-}
-
-void
-msgbuf_drain(struct msgbuf *msgbuf, size_t n)
-{
- struct ibuf *buf, *next;
-
- for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
- buf = next) {
- next = TAILQ_NEXT(buf, entry);
- if (buf->rpos + n >= buf->wpos) {
- n -= buf->wpos - buf->rpos;
- ibuf_dequeue(msgbuf, buf);
- } else {
- buf->rpos += n;
- n = 0;
- }
- }
-}
-
-void
-msgbuf_clear(struct msgbuf *msgbuf)
-{
- struct ibuf *buf;
-
- while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
- ibuf_dequeue(msgbuf, buf);
-}
-
-int
-msgbuf_write(struct msgbuf *msgbuf)
-{
- struct iovec iov[IOV_MAX];
- struct ibuf *buf;
- unsigned int i = 0;
- ssize_t n;
- struct msghdr msg;
- struct cmsghdr *cmsg;
- union {
- struct cmsghdr hdr;
- char buf[CMSG_SPACE(sizeof(int))];
- } cmsgbuf;
-
- bzero(&iov, sizeof(iov));
- bzero(&msg, sizeof(msg));
- TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
- if (i >= IOV_MAX)
- break;
- iov[i].iov_base = buf->buf + buf->rpos;
- iov[i].iov_len = buf->wpos - buf->rpos;
- i++;
- if (buf->fd != -1)
- break;
- }
-
- msg.msg_iov = iov;
- msg.msg_iovlen = i;
-
- if (buf != NULL && buf->fd != -1) {
- msg.msg_control = (caddr_t)&cmsgbuf.buf;
- msg.msg_controllen = sizeof(cmsgbuf.buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- *(int *)CMSG_DATA(cmsg) = buf->fd;
- }
-
-again:
- if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
- if (errno == EAGAIN || errno == EINTR)
- goto again;
- if (errno == ENOBUFS)
- errno = EAGAIN;
- return (-1);
- }
-
- if (n == 0) { /* connection closed */
- errno = 0;
- return (0);
- }
-
- /*
- * assumption: fd got sent if sendmsg sent anything
- * this works because fds are passed one at a time
- */
- if (buf != NULL && buf->fd != -1) {
- close(buf->fd);
- buf->fd = -1;
- }
-
- msgbuf_drain(msgbuf, n);
-
- return (1);
-}
-
-void
-ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
-{
- TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
- msgbuf->queued++;
-}
-
-void
-ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
-{
- TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
-
- if (buf->fd != -1)
- close(buf->fd);
-
- msgbuf->queued--;
- ibuf_free(buf);
-}
diff --git a/glougloud/external/imsg.c b/glougloud/external/imsg.c
deleted file mode 100644
index 05e57c7..0000000
--- a/glougloud/external/imsg.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/* $OpenBSD: imsg.c,v 1.2 2012/06/02 21:46:53 gilles Exp $ */
-
-/*
- * 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/param.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "imsg.h"
-
-int imsg_fd_overhead = 0;
-
-int imsg_get_fd(struct imsgbuf *);
-
-void
-imsg_init(struct imsgbuf *ibuf, int fd)
-{
- 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
-imsg_read(struct imsgbuf *ibuf)
-{
- struct msghdr msg;
- struct cmsghdr *cmsg;
- union {
- struct cmsghdr hdr;
- char buf[CMSG_SPACE(sizeof(int) * 1)];
- } cmsgbuf;
- struct iovec iov;
- ssize_t n = -1;
- int fd;
- struct imsg_fd *ifd;
-
- bzero(&msg, sizeof(msg));
-
- iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
- iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = &cmsgbuf.buf;
- msg.msg_controllen = sizeof(cmsgbuf.buf);
-
- if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
- return (-1);
-
-again:
- if (getdtablecount() + imsg_fd_overhead +
- (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int)
- >= getdtablesize()) {
- errno = EAGAIN;
- return (-1);
- }
-
- if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
- if (errno == EMSGSIZE)
- goto fail;
- if (errno != EINTR && errno != EAGAIN)
- goto fail;
- goto again;
- }
-
- ibuf->r.wpos += n;
-
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
- cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS) {
- int i;
- int j;
-
- /*
- * We only accept one file descriptor. Due to C
- * padding rules, our control buffer might contain
- * more than one fd, and we must close them.
- */
- j = ((char *)cmsg + cmsg->cmsg_len -
- (char *)CMSG_DATA(cmsg)) / sizeof(int);
- for (i = 0; i < j; i++) {
- fd = ((int *)CMSG_DATA(cmsg))[i];
- if (i == 0) {
- ifd->fd = fd;
- TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
- entry);
- ifd = NULL;
- } else
- close(fd);
- }
- }
- /* we do not handle other ctl data level */
- }
-
-fail:
- if (ifd)
- free(ifd);
- return (n);
-}
-
-ssize_t
-imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
-{
- size_t av, left, datalen;
-
- av = ibuf->r.wpos;
-
- if (IMSG_HEADER_SIZE > av)
- return (0);
-
- memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
- if (imsg->hdr.len < IMSG_HEADER_SIZE ||
- imsg->hdr.len > MAX_IMSGSIZE) {
- errno = ERANGE;
- return (-1);
- }
- if (imsg->hdr.len > av)
- return (0);
- datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
- ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
- if ((imsg->data = malloc(datalen)) == NULL)
- return (-1);
-
- if (imsg->hdr.flags & IMSGF_HASFD)
- imsg->fd = imsg_get_fd(ibuf);
- else
- imsg->fd = -1;
-
- memcpy(imsg->data, ibuf->r.rptr, datalen);
-
- if (imsg->hdr.len < av) {
- left = av - imsg->hdr.len;
- memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
- ibuf->r.wpos = left;
- } else
- ibuf->r.wpos = 0;
-
- return (datalen + IMSG_HEADER_SIZE);
-}
-
-int
-imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
- pid_t pid, int fd, void *data, u_int16_t datalen)
-{
- struct ibuf *wbuf;
-
- if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
- return (-1);
-
- if (imsg_add(wbuf, data, datalen) == -1)
- return (-1);
-
- wbuf->fd = fd;
-
- imsg_close(ibuf, wbuf);
-
- return (1);
-}
-
-int
-imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
- pid_t pid, int fd, const struct iovec *iov, int iovcnt)
-{
- struct ibuf *wbuf;
- int i, datalen = 0;
-
- for (i = 0; i < iovcnt; i++)
- datalen += iov[i].iov_len;
-
- if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
- return (-1);
-
- for (i = 0; i < iovcnt; i++)
- if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
- return (-1);
-
- wbuf->fd = fd;
-
- imsg_close(ibuf, wbuf);
-
- return (1);
-}
-
-/* ARGSUSED */
-struct ibuf *
-imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
- pid_t pid, u_int16_t datalen)
-{
- struct ibuf *wbuf;
- struct imsg_hdr hdr;
-
- datalen += IMSG_HEADER_SIZE;
- if (datalen > MAX_IMSGSIZE) {
- errno = ERANGE;
- return (NULL);
- }
-
- hdr.type = type;
- hdr.flags = 0;
- hdr.peerid = peerid;
- if ((hdr.pid = pid) == 0)
- hdr.pid = ibuf->pid;
- if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
- return (NULL);
- }
- if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
- return (NULL);
-
- return (wbuf);
-}
-
-int
-imsg_add(struct ibuf *msg, void *data, u_int16_t datalen)
-{
- if (datalen)
- if (ibuf_add(msg, data, datalen) == -1) {
- ibuf_free(msg);
- return (-1);
- }
- return (datalen);
-}
-
-void
-imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
-{
- struct imsg_hdr *hdr;
-
- hdr = (struct imsg_hdr *)msg->buf;
-
- hdr->flags &= ~IMSGF_HASFD;
- if (msg->fd != -1)
- hdr->flags |= IMSGF_HASFD;
-
- hdr->len = (u_int16_t)msg->wpos;
-
- ibuf_close(&ibuf->w, msg);
-}
-
-void
-imsg_free(struct imsg *imsg)
-{
- free(imsg->data);
-}
-
-int
-imsg_get_fd(struct imsgbuf *ibuf)
-{
- int fd;
- struct imsg_fd *ifd;
-
- if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
- return (-1);
-
- fd = ifd->fd;
- TAILQ_REMOVE(&ibuf->fds, ifd, entry);
- free(ifd);
-
- 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)
-{
- int fd;
-
- msgbuf_clear(&ibuf->w);
- while ((fd = imsg_get_fd(ibuf)) != -1)
- close(fd);
-}
diff --git a/glougloud/external/imsg.h b/glougloud/external/imsg.h
deleted file mode 100644
index 25cc2c4..0000000
--- a/glougloud/external/imsg.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* $OpenBSD: imsg.h,v 1.2 2010/06/23 07:53:55 nicm 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.
- */
-
-#ifndef _IMSG_H_
-#define _IMSG_H_
-
-/* compat hacks added by laurent */
-#if !defined(__OpenBSD__)
-#define IOV_MAX 1024
-#define getdtablecount(x) 3
-#endif
-
-#define IBUF_READ_SIZE 65535
-#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr)
-#define MAX_IMSGSIZE 16384
-
-struct ibuf {
- TAILQ_ENTRY(ibuf) entry;
- u_char *buf;
- size_t size;
- size_t max;
- size_t wpos;
- size_t rpos;
- int fd;
-};
-
-struct msgbuf {
- TAILQ_HEAD(, ibuf) bufs;
- u_int32_t queued;
- int fd;
-};
-
-struct ibuf_read {
- u_char buf[IBUF_READ_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 ibuf_read r;
- struct msgbuf w;
- int fd;
- pid_t pid;
-};
-
-#define IMSGF_HASFD 1
-
-struct imsg_hdr {
- u_int32_t type;
- u_int16_t len;
- u_int16_t flags;
- u_int32_t peerid;
- u_int32_t pid;
-};
-
-struct imsg {
- struct imsg_hdr hdr;
- int fd;
- void *data;
-};
-
-
-/* buffer.c */
-struct ibuf *ibuf_open(size_t);
-struct ibuf *ibuf_dynamic(size_t, size_t);
-int ibuf_add(struct ibuf *, const void *, size_t);
-void *ibuf_reserve(struct ibuf *, size_t);
-void *ibuf_seek(struct ibuf *, size_t, size_t);
-size_t ibuf_size(struct ibuf *);
-size_t ibuf_left(struct ibuf *);
-void ibuf_close(struct msgbuf *, struct ibuf *);
-int ibuf_write(struct msgbuf *);
-void ibuf_free(struct ibuf *);
-void msgbuf_init(struct msgbuf *);
-void msgbuf_clear(struct msgbuf *);
-int msgbuf_write(struct msgbuf *);
-void msgbuf_drain(struct msgbuf *, size_t);
-
-/* 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_int32_t, u_int32_t, pid_t,
- int, void *, u_int16_t);
-int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
- int, const struct iovec *, int);
-struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
- u_int16_t);
-int imsg_add(struct ibuf *, void *, u_int16_t);
-void imsg_close(struct imsgbuf *, struct ibuf *);
-void imsg_free(struct imsg *);
-int imsg_flush(struct imsgbuf *);
-void imsg_clear(struct imsgbuf *);
-
-#endif
diff --git a/glougloud/external/imsgev.c b/glougloud/external/imsgev.c
deleted file mode 100644
index 6b92d79..0000000
--- a/glougloud/external/imsgev.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2009 Eric Faurot <eric@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/param.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "imsgev.h"
-
-void imsgev_add(struct imsgev *);
-void imsgev_dispatch(int, short, void *);
-void imsgev_disconnect(struct imsgev *, int);
-
-void
-imsgev_init(struct imsgev *iev, int fd, void *data,
- void (*callback)(struct imsgev *, int, struct imsg *),
- void (*needfd)(struct imsgev *))
-{
- imsg_init(&iev->ibuf, fd);
- iev->terminate = 0;
-
- iev->data = data;
- iev->handler = imsgev_dispatch;
- iev->callback = callback;
- iev->needfd = needfd;
-
- iev->events = EV_READ;
- event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
- event_add(&iev->ev, NULL);
-}
-
-int
-imsgev_compose(struct imsgev *iev, u_int16_t type, u_int32_t peerid,
- uint32_t pid, int fd, void *data, u_int16_t datalen)
-{
- int r;
-
- r = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen);
- if (r != -1)
- imsgev_add(iev);
-
- return (r);
-}
-
-void
-imsgev_close(struct imsgev *iev)
-{
- iev->terminate = 1;
- imsgev_add(iev);
-}
-
-void
-imsgev_clear(struct imsgev *iev)
-{
- event_del(&iev->ev);
- msgbuf_clear(&iev->ibuf.w);
- close(iev->ibuf.fd);
-}
-
-void
-imsgev_add(struct imsgev *iev)
-{
- short events = 0;
-
- if (!iev->terminate)
- events = EV_READ;
- if (iev->ibuf.w.queued || iev->terminate)
- events |= EV_WRITE;
-
- /* optimization: skip event_{del/set/add} if already set */
- if (events == iev->events)
- return;
-
- iev->events = events;
- event_del(&iev->ev);
- event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
- event_add(&iev->ev, NULL);
-}
-
-void
-imsgev_dispatch(int fd, short ev, void *humppa)
-{
- struct imsgev *iev = humppa;
- struct imsgbuf *ibuf = &iev->ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev->events = 0;
-
- if (ev & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1) {
- /* if we don't have enough fds, free one up and retry */
- if (errno == EAGAIN) {
- iev->needfd(iev);
- n = imsg_read(ibuf);
- }
-
- if (n == -1) {
- imsgev_disconnect(iev, IMSGEV_EREAD);
- return;
- }
- }
- if (n == 0) {
- /*
- * Connection is closed for reading, and we assume
- * it is also closed for writing, so we error out
- * if write data is pending.
- */
- imsgev_disconnect(iev,
- (iev->ibuf.w.queued) ? IMSGEV_EWRITE : IMSGEV_DONE);
- return;
- }
- }
-
- if (ev & EV_WRITE) {
- /*
- * We wanted to write data out but the connection is either
- * closed, or some error occured. Both case are not recoverable
- * from the imsg perspective, so we treat it as a WRITE error.
- */
- if ((n = msgbuf_write(&ibuf->w)) != 1) {
- imsgev_disconnect(iev, IMSGEV_EWRITE);
- return;
- }
- }
-
- while (iev->terminate == 0) {
- if ((n = imsg_get(ibuf, &imsg)) == -1) {
- imsgev_disconnect(iev, IMSGEV_EIMSG);
- return;
- }
- if (n == 0)
- break;
- iev->callback(iev, IMSGEV_IMSG, &imsg);
- imsg_free(&imsg);
- }
-
- if (iev->terminate && iev->ibuf.w.queued == 0) {
- imsgev_disconnect(iev, IMSGEV_DONE);
- return;
- }
-
- imsgev_add(iev);
-}
-
-void
-imsgev_disconnect(struct imsgev *iev, int code)
-{
- iev->callback(iev, code, NULL);
-}
diff --git a/glougloud/external/imsgev.h b/glougloud/external/imsgev.h
deleted file mode 100644
index a0d0947..0000000
--- a/glougloud/external/imsgev.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2009 Eric Faurot <eric@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.
- */
-
-#ifndef __IMSGEV_H__
-#define __IMSGEV_H__
-
-#include <event.h>
-#include "imsg.h"
-
-#define IMSG_LEN(m) ((m)->hdr.len - IMSG_HEADER_SIZE)
-
-struct imsgev {
- struct imsgbuf ibuf;
- void (*handler)(int, short, void *);
- struct event ev;
- void *data;
- short events;
- int terminate;
- void (*callback)(struct imsgev *, int, struct imsg *);
- void (*needfd)(struct imsgev *);
-};
-
-#define IMSGEV_IMSG 0
-#define IMSGEV_DONE 1
-#define IMSGEV_EREAD 2
-#define IMSGEV_EWRITE 3
-#define IMSGEV_EIMSG 4
-
-void imsgev_init(struct imsgev *, int, void *, void (*)(struct imsgev *,
- int, struct imsg *), void (*)(struct imsgev *));
-int imsgev_compose(struct imsgev *, u_int16_t, u_int32_t, u_int32_t, int,
- void *, u_int16_t);
-void imsgev_close(struct imsgev *);
-void imsgev_clear(struct imsgev *);
-
-#endif /* __IMSGEV_H__ */
diff --git a/glougloud/external/queue.h b/glougloud/external/queue.h
deleted file mode 100644
index 622301d..0000000
--- a/glougloud/external/queue.h
+++ /dev/null
@@ -1,568 +0,0 @@
-/* $OpenBSD: queue.h,v 1.36 2012/04/11 13:29:14 naddy Exp $ */
-/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
-
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-/*
- * This file defines five types of data structures: singly-linked lists,
- * lists, simple queues, tail queues, and circular queues.
- *
- *
- * A singly-linked list is headed by a single forward pointer. The elements
- * are singly linked for minimum space and pointer manipulation overhead at
- * the expense of O(n) removal for arbitrary elements. New elements can be
- * added to the list after an existing element or at the head of the list.
- * Elements being removed from the head of the list should use the explicit
- * macro for this purpose for optimum efficiency. A singly-linked list may
- * only be traversed in the forward direction. Singly-linked lists are ideal
- * for applications with large datasets and few or no removals or for
- * implementing a LIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A simple queue is headed by a pair of pointers, one the head of the
- * list and the other to the tail of the list. The elements are singly
- * linked to save space, so elements can only be removed from the
- * head of the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the
- * list. A simple queue may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
-#define _Q_INVALIDATE(a) (a) = ((void *)-1)
-#else
-#define _Q_INVALIDATE(a)
-#endif
-
-/*
- * Singly-linked List definitions.
- */
-#define SLIST_HEAD(name, type) \
-struct name { \
- struct type *slh_first; /* first element */ \
-}
-
-#define SLIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define SLIST_ENTRY(type) \
-struct { \
- struct type *sle_next; /* next element */ \
-}
-
-/*
- * Singly-linked List access methods.
- */
-#define SLIST_FIRST(head) ((head)->slh_first)
-#define SLIST_END(head) NULL
-#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
-#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
-
-#define SLIST_FOREACH(var, head, field) \
- for((var) = SLIST_FIRST(head); \
- (var) != SLIST_END(head); \
- (var) = SLIST_NEXT(var, field))
-
-#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = SLIST_FIRST(head); \
- (var) && ((tvar) = SLIST_NEXT(var, field), 1); \
- (var) = (tvar))
-
-/*
- * Singly-linked List functions.
- */
-#define SLIST_INIT(head) { \
- SLIST_FIRST(head) = SLIST_END(head); \
-}
-
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
- (elm)->field.sle_next = (slistelm)->field.sle_next; \
- (slistelm)->field.sle_next = (elm); \
-} while (0)
-
-#define SLIST_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.sle_next = (head)->slh_first; \
- (head)->slh_first = (elm); \
-} while (0)
-
-#define SLIST_REMOVE_AFTER(elm, field) do { \
- (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
-} while (0)
-
-#define SLIST_REMOVE_HEAD(head, field) do { \
- (head)->slh_first = (head)->slh_first->field.sle_next; \
-} while (0)
-
-#define SLIST_REMOVE(head, elm, type, field) do { \
- if ((head)->slh_first == (elm)) { \
- SLIST_REMOVE_HEAD((head), field); \
- } else { \
- struct type *curelm = (head)->slh_first; \
- \
- while (curelm->field.sle_next != (elm)) \
- curelm = curelm->field.sle_next; \
- curelm->field.sle_next = \
- curelm->field.sle_next->field.sle_next; \
- _Q_INVALIDATE((elm)->field.sle_next); \
- } \
-} while (0)
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List access methods
- */
-#define LIST_FIRST(head) ((head)->lh_first)
-#define LIST_END(head) NULL
-#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-#define LIST_FOREACH(var, head, field) \
- for((var) = LIST_FIRST(head); \
- (var)!= LIST_END(head); \
- (var) = LIST_NEXT(var, field))
-
-#define LIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = LIST_FIRST(head); \
- (var) && ((tvar) = LIST_NEXT(var, field), 1); \
- (var) = (tvar))
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) do { \
- LIST_FIRST(head) = LIST_END(head); \
-} while (0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- (elm)->field.le_next = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &(elm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-} while (0)
-
-#define LIST_REMOVE(elm, field) do { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
- _Q_INVALIDATE((elm)->field.le_prev); \
- _Q_INVALIDATE((elm)->field.le_next); \
-} while (0)
-
-#define LIST_REPLACE(elm, elm2, field) do { \
- if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
- (elm2)->field.le_next->field.le_prev = \
- &(elm2)->field.le_next; \
- (elm2)->field.le_prev = (elm)->field.le_prev; \
- *(elm2)->field.le_prev = (elm2); \
- _Q_INVALIDATE((elm)->field.le_prev); \
- _Q_INVALIDATE((elm)->field.le_next); \
-} while (0)
-
-/*
- * Simple queue definitions.
- */
-#define SIMPLEQ_HEAD(name, type) \
-struct name { \
- struct type *sqh_first; /* first element */ \
- struct type **sqh_last; /* addr of last next element */ \
-}
-
-#define SIMPLEQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).sqh_first }
-
-#define SIMPLEQ_ENTRY(type) \
-struct { \
- struct type *sqe_next; /* next element */ \
-}
-
-/*
- * Simple queue access methods.
- */
-#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
-#define SIMPLEQ_END(head) NULL
-#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
-#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
-
-#define SIMPLEQ_FOREACH(var, head, field) \
- for((var) = SIMPLEQ_FIRST(head); \
- (var) != SIMPLEQ_END(head); \
- (var) = SIMPLEQ_NEXT(var, field))
-
-#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = SIMPLEQ_FIRST(head); \
- (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
- (var) = (tvar))
-
-/*
- * Simple queue functions.
- */
-#define SIMPLEQ_INIT(head) do { \
- (head)->sqh_first = NULL; \
- (head)->sqh_last = &(head)->sqh_first; \
-} while (0)
-
-#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
- (head)->sqh_last = &(elm)->field.sqe_next; \
- (head)->sqh_first = (elm); \
-} while (0)
-
-#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.sqe_next = NULL; \
- *(head)->sqh_last = (elm); \
- (head)->sqh_last = &(elm)->field.sqe_next; \
-} while (0)
-
-#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
- (head)->sqh_last = &(elm)->field.sqe_next; \
- (listelm)->field.sqe_next = (elm); \
-} while (0)
-
-#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
- if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
- (head)->sqh_last = &(head)->sqh_first; \
-} while (0)
-
-#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
- if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
- == NULL) \
- (head)->sqh_last = &(elm)->field.sqe_next; \
-} while (0)
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
-}
-
-#define TAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).tqh_first }
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
-}
-
-/*
- * tail queue access methods
- */
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-#define TAILQ_END(head) NULL
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-#define TAILQ_LAST(head, headname) \
- (*(((struct headname *)((head)->tqh_last))->tqh_last))
-/* XXX */
-#define TAILQ_PREV(elm, headname, field) \
- (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-#define TAILQ_EMPTY(head) \
- (TAILQ_FIRST(head) == TAILQ_END(head))
-
-#define TAILQ_FOREACH(var, head, field) \
- for((var) = TAILQ_FIRST(head); \
- (var) != TAILQ_END(head); \
- (var) = TAILQ_NEXT(var, field))
-
-#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = TAILQ_FIRST(head); \
- (var) != TAILQ_END(head) && \
- ((tvar) = TAILQ_NEXT(var, field), 1); \
- (var) = (tvar))
-
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
- for((var) = TAILQ_LAST(head, headname); \
- (var) != TAILQ_END(head); \
- (var) = TAILQ_PREV(var, headname, field))
-
-#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
- for ((var) = TAILQ_LAST(head, headname); \
- (var) != TAILQ_END(head) && \
- ((tvar) = TAILQ_PREV(var, headname, field), 1); \
- (var) = (tvar))
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) do { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (head)->tqh_first->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- (elm)->field.tqe_next = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_REMOVE(head, elm, field) do { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
- _Q_INVALIDATE((elm)->field.tqe_prev); \
- _Q_INVALIDATE((elm)->field.tqe_next); \
-} while (0)
-
-#define TAILQ_REPLACE(head, elm, elm2, field) do { \
- if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
- (elm2)->field.tqe_next->field.tqe_prev = \
- &(elm2)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm2)->field.tqe_next; \
- (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
- *(elm2)->field.tqe_prev = (elm2); \
- _Q_INVALIDATE((elm)->field.tqe_prev); \
- _Q_INVALIDATE((elm)->field.tqe_next); \
-} while (0)
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_HEAD_INITIALIZER(head) \
- { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-/*
- * Circular queue access methods
- */
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-#define CIRCLEQ_END(head) ((void *)(head))
-#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
-#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
-#define CIRCLEQ_EMPTY(head) \
- (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
-
-#define CIRCLEQ_FOREACH(var, head, field) \
- for((var) = CIRCLEQ_FIRST(head); \
- (var) != CIRCLEQ_END(head); \
- (var) = CIRCLEQ_NEXT(var, field))
-
-#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = CIRCLEQ_FIRST(head); \
- (var) != CIRCLEQ_END(head) && \
- ((tvar) = CIRCLEQ_NEXT(var, field), 1); \
- (var) = (tvar))
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
- for((var) = CIRCLEQ_LAST(head); \
- (var) != CIRCLEQ_END(head); \
- (var) = CIRCLEQ_PREV(var, field))
-
-#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
- for ((var) = CIRCLEQ_LAST(head, headname); \
- (var) != CIRCLEQ_END(head) && \
- ((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \
- (var) = (tvar))
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) do { \
- (head)->cqh_first = CIRCLEQ_END(head); \
- (head)->cqh_last = CIRCLEQ_END(head); \
-} while (0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = CIRCLEQ_END(head); \
- if ((head)->cqh_last == CIRCLEQ_END(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.cqe_next = CIRCLEQ_END(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == CIRCLEQ_END(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-} while (0)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do { \
- if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
- _Q_INVALIDATE((elm)->field.cqe_prev); \
- _Q_INVALIDATE((elm)->field.cqe_next); \
-} while (0)
-
-#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
- if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
- CIRCLEQ_END(head)) \
- (head).cqh_last = (elm2); \
- else \
- (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
- if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
- CIRCLEQ_END(head)) \
- (head).cqh_first = (elm2); \
- else \
- (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
- _Q_INVALIDATE((elm)->field.cqe_prev); \
- _Q_INVALIDATE((elm)->field.cqe_next); \
-} while (0)
-
-#endif /* !_SYS_QUEUE_H_ */
diff --git a/glougloud/glougloud.c b/glougloud/glougloud.c
deleted file mode 100644
index 49a1608..0000000
--- a/glougloud/glougloud.c
+++ /dev/null
@@ -1,487 +0,0 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/ioctl.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-
-#include <netdb.h>
-#include <pcap.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <err.h>
-#include <errno.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-
-#include "glougloud.h"
-#include "external/imsgev.h"
-#if defined(__OpenBSD__)
-#include "pcap-int.h"
-#endif
-
-struct server_proc {
- pid_t pid;
- int fd[2];
- struct imsgev iev;
-};
-struct user_proc {
- pid_t pid;
- int fd[2];
- struct imsgev iev;
-};
-enum user_status {
- USER_REQUESTED,
- USER_ACCEPTED
-};
-struct user {
- LIST_ENTRY(user) entry;
- struct sockaddr_in addr;
- enum user_status status;
-};
-
-// XXX CONF
-#define PCAP_INTERFACE "lo"
-#define PCAP_SNAPLEN 100
-#define PCAP_FILTER "not port 4430 and not port 53"
-
-static void imsgev_server(struct imsgev *, int, struct imsg *);
-static void imsgev_user(struct imsgev *, int, struct imsg *);
-static void imsgev_server_needfd(struct imsgev *);
-static void imsgev_user_needfd(struct imsgev *);
-
-struct server_proc *srv_proc;
-struct user_proc *usr_proc;
-LIST_HEAD(, user) usr_list;
-int net_socket;
-
-#if defined(__OPENBSD__)
-void __dead
-#else
-void
-#endif
-usage(void)
-{
- extern char *__progname;
-
- fprintf(stderr, "usage: %s [-vi]",
- __progname);
- exit(1);
-}
-
-static void
-sig_handler(int sig, short why, void *data)
-{
- log_info("got signal %d", sig);
- if (sig == SIGINT || sig == SIGTERM)
- event_loopexit(NULL);
-}
-
-/*
- * reimplement pcap_open_live with more restrictions on the bpf fd :
- * - open device read only
- * - lock the fd
- * based on OpenBSD tcpdump, privsep_pcap.c v1.16
- */
-
-static pcap_t *
-my_pcap_open_live(const char *dev, int slen, int promisc, int to_ms,
- char *ebuf, u_int dlt, u_int dirfilt)
-{
-#if defined(__OpenBSD__)
- struct bpf_version bv;
- u_int v;
- pcap_t *p;
- char bpf[sizeof "/dev/bpf0000000000"];
- int fd, n = 0;
- struct ifreq ifr;
-
- p = xmalloc(sizeof(*p));
- bzero(p, sizeof(*p));
-
- /* priv part */
-
- do {
- snprintf(bpf, sizeof(bpf), "/dev/bpf%d", n++);
- fd = open(bpf, O_RDONLY);
- } while (fd < 0 && errno == EBUSY);
- if (fd < 0)
- return NULL;
-
- v = 32768; /* XXX this should be a user-accessible hook */
- ioctl(fd, BIOCSBLEN, &v);
-
- strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
- if (ioctl(fd, BIOCSETIF, &ifr) < 0)
- return NULL;
-
- if (dlt != (u_int) -1 && ioctl(fd, BIOCSDLT, &dlt))
- return NULL;
-
- if (promisc)
- /* this is allowed to fail */
- ioctl(fd, BIOCPROMISC, NULL);
- if (ioctl(fd, BIOCSDIRFILT, &dirfilt) < 0)
- return NULL;
-
- /* lock the descriptor */
- if (ioctl(fd, BIOCLOCK, NULL) < 0)
- return NULL;
-
- /* end of priv part */
-
- /* fd is locked, can only use 'safe' ioctls */
- if (ioctl(fd, BIOCVERSION, &bv) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
- pcap_strerror(errno));
- return NULL;
- }
-
- if (bv.bv_major != BPF_MAJOR_VERSION ||
- bv.bv_minor < BPF_MINOR_VERSION) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "kernel bpf filter out of date");
- return NULL;
- }
-
- p->fd = fd;
- p->snapshot = slen;
-
- /* Get the data link layer type. */
- if (ioctl(fd, BIOCGDLT, &v) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
- pcap_strerror(errno));
- return NULL;
- }
-#if _BSDI_VERSION - 0 >= 199510
- /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
- switch (v) {
-
- case DLT_SLIP:
- v = DLT_SLIP_BSDOS;
- break;
-
- case DLT_PPP:
- v = DLT_PPP_BSDOS;
- break;
- }
-#endif
- p->linktype = v;
-
- /* XXX hack from tcpdump */
- if (p->linktype == DLT_PFLOG && p->snapshot < 160)
- p->snapshot = 160;
-
- /* set timeout */
- if (to_ms != 0) {
- struct timeval to;
- to.tv_sec = to_ms / 1000;
- to.tv_usec = (to_ms * 1000) % 1000000;
- if (ioctl(p->fd, BIOCSRTIMEOUT, &to) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
- pcap_strerror(errno));
- return NULL;
- }
- }
-
- if (ioctl(fd, BIOCGBLEN, &v) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
- pcap_strerror(errno));
- return NULL;
- }
- p->bufsize = v;
- p->buffer = (u_char *)malloc(p->bufsize);
- if (p->buffer == NULL) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
- return NULL;
- }
- return p;
-#else /* defined(__OpenBSD__) */
- return pcap_open_live(dev, slen, promisc, to_ms, ebuf);
-#endif
-}
-
-int
-main(int argc, char **argv)
-{
- struct sockaddr_in sock_addr;
- struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup;
- char errbuf[PCAP_ERRBUF_SIZE];
- struct bpf_program bprog;
- pcap_t *pcap;
- int loglevel = 0, logpinvalid = 0;
- int op;
- int sock_on = 1;
-
- if (geteuid() != 0)
- errx(1, "need root privileges");
-
- while ((op = getopt(argc, argv, "hvi")) != -1) {
- switch (op) {
- case 'h':
- usage();
- /* NOTREACHED */
- case 'v':
- loglevel++;
- break;
- case 'i':
- logpinvalid = 1;
- break;
- default:
- usage();
- /* NOTREACHED */
- }
- }
-
- log_init(loglevel, logpinvalid);
- event_init();
-
- net_socket = socket(AF_INET, SOCK_DGRAM, 0);
- if (net_socket < 0)
- fatal("server: socket failed");
- setsockopt(net_socket, SOL_SOCKET, SO_REUSEADDR,
- &sock_on, sizeof(sock_on));
- memset(&sock_addr, 0, sizeof(sock_addr));
- sock_addr.sin_family = AF_INET;
- sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- sock_addr.sin_port = htons(4430);
- if (bind(net_socket, (struct sockaddr *)&sock_addr,
- sizeof(sock_addr)) != 0)
- fatal("server: socket bind failed, %s", strerror(errno));
- fd_nonblock(net_socket);
-
- srv_proc = xmalloc(sizeof(struct server_proc));
- socketpair_prepare(srv_proc->fd);
- srv_proc->pid = server_init(srv_proc->fd);
- close(srv_proc->fd[1]);
- imsgev_init(&srv_proc->iev, srv_proc->fd[0], NULL, imsgev_server, imsgev_server_needfd);
-
- pcap = my_pcap_open_live(PCAP_INTERFACE, PCAP_SNAPLEN, 1, PCAP_TO, errbuf, -1, 0);
- if (pcap == NULL)
- fatal("capture: pcap_open_live failed on interface %s\n"
- "with snaplen %d : %s",
- PCAP_INTERFACE, PCAP_SNAPLEN, errbuf);
- if (pcap_compile(pcap, &bprog, PCAP_FILTER, 0, 0) < 0)
- fatal("capture: pcap_compile failed with filter %s : %s",
- PCAP_FILTER, pcap_geterr(pcap));
- if (pcap_setfilter(pcap, &bprog) < 0)
- fatal("capture: pcap_setfilter failed : %s",
- pcap_geterr(pcap));
-
- usr_proc = xmalloc(sizeof(struct user_proc));
- socketpair_prepare(usr_proc->fd);
- usr_proc->pid = user_init(usr_proc->fd, pcap);
- close(usr_proc->fd[1]);
- imsgev_init(&usr_proc->iev, usr_proc->fd[0], NULL, imsgev_user, imsgev_user_needfd);
-
- signal_set(&ev_sigint, SIGINT, sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, sig_handler, NULL);
- signal_set(&ev_sigchld, SIGCHLD, sig_handler, NULL);
- signal_set(&ev_sighup, SIGHUP, sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
- signal_add(&ev_sigchld, NULL);
- signal_add(&ev_sighup, NULL);
- signal(SIGPIPE, SIG_IGN);
-
- log_info("entering event loop");
- event_dispatch();
-
- log_info("exiting");
- exit(0);
-}
-
-static struct user *
-finduser(struct sockaddr_in *remote) {
- struct user *usr;
- struct sockaddr_in *u;
-
- LIST_FOREACH(usr, &usr_list, entry) {
- u = &usr->addr;
- if (u->sin_addr.s_addr == remote->sin_addr.s_addr &&
- u->sin_port == remote->sin_port)
- return usr;
- }
- return NULL;
-}
-
-static void
-srvconn(struct imsgev *iev, struct imsg *imsg)
-{
- struct imsg_srvconn *req;
- struct imsg_srvconn res;
- struct imsg_usrconn req2;
- struct user *usr;
-
- req = imsg->data;
-
- if (req->deco) {
- log_tmp("srvconn deco");
- usr = finduser(&req->addr);
- if (!usr)
- fatal("trying to deco an inexistant user !");
-
- addrcpy(&req2.addr, &usr->addr);
- req2.deco = 1;
- imsgev_compose(&usr_proc->iev, IMSG_USRCONN_REQ, 0, 0, -1,
- &req2, sizeof(req2));
-
- LIST_REMOVE(usr, entry);
- free(usr);
-
- return;
- }
-
- if (req->addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
- log_tmp("srvconn accepted");
-
- usr = xmalloc(sizeof(struct user));
- addrcpy(&usr->addr, &req->addr);
- usr->status = USER_REQUESTED;
- LIST_INSERT_HEAD(&usr_list, usr, entry);
-
- addrcpy(&req2.addr, &req->addr);
- req2.deco = 0;
- imsgev_compose(&usr_proc->iev, IMSG_USRCONN_REQ, 0, 0, -1,
- &req2, sizeof(req2));
- }
- else
- {
- log_tmp("srvconn refused");
- res.ok = 0;
- addrcpy(&res.addr, &req->addr);
- imsgev_compose(iev, IMSG_SRVCONN_RES, 0, 0, -1,
- &res, sizeof(res));
- }
-
-}
-
-static void
-imsgev_server(struct imsgev *iev, int code, struct imsg *imsg)
-{
- switch (code) {
- case IMSGEV_IMSG:
- log_debug("%s, got imsg %i on fd %i",
- __func__, imsg->hdr.type, iev->ibuf.fd);
- switch (imsg->hdr.type) {
- case IMSG_SRVCONN_REQ:
- srvconn(iev, imsg);
- break;
- default:
- fatal("%s, unexpected imsg %d",
- __func__, imsg->hdr.type);
- }
- break;
- case IMSGEV_EREAD:
- case IMSGEV_EWRITE:
- case IMSGEV_EIMSG:
- fatal("imsgev server read/write error");
- /* NOTREACHED */
- break;
- case IMSGEV_DONE:
- event_loopexit(NULL);
- break;
- }
-}
-
-static void
-usrconn(struct imsgev *iev, struct imsg *imsg)
-{
- struct user *usr;
- struct imsg_usrconn *res;
- struct imsg_srvconn res2;
-
- res = imsg->data;
-
- usr = finduser(&res->addr);
- if (!usr || usr->status != USER_REQUESTED)
- fatal("received usrconn result that wasn't initiated !");
- usr->status = USER_ACCEPTED;
-
- addrcpy(&res2.addr, &res->addr);
- res2.ok = 1;
- imsgev_compose(&srv_proc->iev, IMSG_SRVCONN_RES, 0, 0, -1,
- &res2, sizeof(res2));
-}
-
-/* XXX drop imsg when msgbuf->queued is too high ? */
-/* XXX review that func for correctness and security */
-static void
-usrdns(struct imsgev *iev, struct imsg *imsg)
-{
- struct imsg_usrdns_req *req;
- struct imsg_usrdns_res res;
- struct hostent *ent;
- int len;
- char *name;
- extern int h_errno;
- struct in_addr addr;
-
- req = imsg->data;
-
- res.addr.s_addr = req->addr.s_addr;
- addr.s_addr = htonl(req->addr.s_addr);
- ent = gethostbyaddr(&addr, sizeof(addr), AF_INET);
- if (ent) {
- len = strlen(ent->h_name);
- if (len > DNSNAME_MAX)
- name = ent->h_name - DNSNAME_MAX; /* keep right part */
- else
- name = ent->h_name;
- strncpy(res.name, name, sizeof(res.name));
- } else {
- log_debug("usrdns failed for %x : %s",
- addr, hstrerror(h_errno));
- res.name[0] = '\0';
- }
-
- imsgev_compose(&usr_proc->iev, IMSG_USRDNS_RES, 0, 0, -1,
- &res, sizeof(res));
-}
-
-static void
-imsgev_user(struct imsgev *iev, int code, struct imsg *imsg)
-{
- switch (code) {
- case IMSGEV_IMSG:
- log_debug("%s, got imsg %i on fd %i",
- __func__, imsg->hdr.type, iev->ibuf.fd);
- switch (imsg->hdr.type) {
- case IMSG_USRCONN_RES:
- usrconn(iev, imsg);
- break;
- case IMSG_USRDNS_REQ:
- usrdns(iev, imsg);
- break;
- default:
- fatal("%s, unexpected imsg %d",
- __func__, imsg->hdr.type);
- }
- break;
- case IMSGEV_EREAD:
- case IMSGEV_EWRITE:
- case IMSGEV_EIMSG:
- fatal("imsgev user read/write error");
- /* NOTREACHED */
- break;
- case IMSGEV_DONE:
- event_loopexit(NULL);
- break;
- }
-}
-
-static void
-imsgev_server_needfd(struct imsgev *iev)
-{
- fatal("imsgev_server_needfd");
-}
-
-static void
-imsgev_user_needfd(struct imsgev *iev)
-{
- fatal("imsgev_user_needfd");
-}
diff --git a/glougloud/glougloud.h b/glougloud/glougloud.h
deleted file mode 100644
index c4f0a4a..0000000
--- a/glougloud/glougloud.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <pcap.h>
-
-#include <libglouglou.h>
-
-#include "external/queue.h"
-
-#if !defined(__OpenBSD__)
-#define setproctitle(x) {}
-#endif
-
-#define GLOUGLOUD_USER "_glougloud"
-#define PCAP_COUNT 20
-#define PCAP_TO 300
-
-/* ipc */
-
-enum imsg_type {
- IMSG_SRVCONN_REQ,
- IMSG_SRVCONN_RES,
- IMSG_USRCONN_REQ,
- IMSG_USRCONN_RES,
- IMSG_USRDNS_REQ,
- IMSG_USRDNS_RES
-};
-
-/* XXX restore the _req _res structs, so that we have less bytes going on
- * the pipe */
-struct imsg_srvconn {
- struct sockaddr_in addr;
- u_short ok;
- u_short deco;
-};
-struct imsg_usrconn {
- struct sockaddr_in addr;
- u_short ok;
- u_short deco;
-};
-struct imsg_usrdns_req {
- struct in_addr addr;
-};
-struct imsg_usrdns_res {
- struct in_addr addr;
- char name[DNSNAME_MAX];
-};
-
-/* glougloud.c */
-
-extern int net_socket;
-
-/* server.c */
-
-int server_init(int *);
-
-/* user.c */
-
-int user_init(int *, pcap_t *pcap);
-
-/* util.c */
-
-void log_init(int, int);
-void log_pinvalid(const char *, ...);
-void log_tmp(const char *, ...);
-void log_debug(const char *, ...);
-void log_info(const char *, ...);
-void log_warn(const char *, ...);
-void fatal(const char *, ...);
-
-void *xmalloc(size_t);
-void *xcalloc(size_t, size_t);
-void fd_nonblock(int);
-void droppriv();
-void addrcpy(struct sockaddr_in *, struct sockaddr_in *);
-void socketpair_prepare(int *);
-
diff --git a/glougloud/server.c b/glougloud/server.c
deleted file mode 100644
index 4fb0be6..0000000
--- a/glougloud/server.c
+++ /dev/null
@@ -1,238 +0,0 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <err.h>
-#include <errno.h>
-#include <time.h>
-
-#include "glougloud.h"
-#include "external/imsgev.h"
-
-#define USER_TIMEOUT 300
-#define USERTIMER 10
-
-struct server {
- struct imsgev iev;
- struct event ev;
-
- struct event usrtimer_ev;
- struct timeval usrtimer_tv;
- time_t time;
-};
-enum user_status {
- USER_REQUESTED,
- USER_ACCEPTED,
- USER_REFUSED
-};
-struct user {
- LIST_ENTRY(user) entry;
- struct sockaddr_in addr;
- enum user_status status;
- time_t lastseen;
-};
-
-static void imsgev_main(struct imsgev *, int, struct imsg *);
-static void imsgev_main_needfd(struct imsgev *);
-static void receive(int, short, void *);
-static void ev_usrtimer(int, short, void *);
-
-struct server *srv;
-LIST_HEAD(, user) usr_list;
-
-static void
-sig_handler(int sig, short why, void *data)
-{
- log_info("server: got signal %d", sig);
- if (sig == SIGINT || sig == SIGTERM)
- event_loopexit(NULL);
-}
-
-int
-server_init(int fd[2])
-{
- struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup;
- int pid;
-
- pid = fork();
- if (pid < 0)
- fatal("server fork");
- if (pid > 0)
- return pid;
-
- setproctitle("server");
- event_init();
- close(fd[0]);
-
- signal_set(&ev_sigint, SIGINT, sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, sig_handler, NULL);
- signal_set(&ev_sigchld, SIGCHLD, sig_handler, NULL);
- signal_set(&ev_sighup, SIGHUP, sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
- signal_add(&ev_sigchld, NULL);
- signal_add(&ev_sighup, NULL);
- signal(SIGPIPE, SIG_IGN);
-
- srv = xmalloc(sizeof(struct server));
- imsgev_init(&srv->iev, fd[1], NULL, imsgev_main, imsgev_main_needfd);
- srv->time = time(NULL);
-
- event_set(&srv->ev, net_socket, EV_READ|EV_PERSIST, receive, NULL);
- event_add(&srv->ev, NULL);
-
- srv->usrtimer_tv.tv_sec = USERTIMER;
- srv->usrtimer_tv.tv_usec = 0;
- evtimer_set(&srv->usrtimer_ev, ev_usrtimer, NULL);
- if (event_add(&srv->usrtimer_ev, &srv->usrtimer_tv) == -1)
- fatal("server: event_add usrtimr failed: %s", strerror(errno));
-
- droppriv();
-
- log_info("server: entering event loop");
- event_dispatch();
-
- log_info("server: exiting");
- exit(0);
-}
-
-static struct user *
-finduser(struct sockaddr_in *remote) {
- struct user *usr;
- struct sockaddr_in *u;
-
- LIST_FOREACH(usr, &usr_list, entry) {
- u = &usr->addr;
- if (u->sin_addr.s_addr == remote->sin_addr.s_addr &&
- u->sin_port == remote->sin_port)
- return usr;
- }
- return NULL;
-}
-
-static void
-srvconn(struct imsgev *iev, struct imsg *imsg)
-{
- struct imsg_srvconn *res;
- struct user *usr;
-
- res = imsg->data;
- usr = finduser(&res->addr);
- if (!usr || usr->status != USER_REQUESTED)
- fatal("server: received srvconn response for inexistant connection");
- if (res->ok) {
- usr->status = USER_ACCEPTED;
- } else {
- usr->status = USER_REFUSED;
- }
-}
-
-static void
-imsgev_main(struct imsgev *iev, int code, struct imsg *imsg)
-{
- switch (code) {
- case IMSGEV_IMSG:
- log_debug("server: %s got imsg %i on fd %i",
- __func__, imsg->hdr.type, iev->ibuf.fd);
- switch (imsg->hdr.type) {
- case IMSG_SRVCONN_RES:
- srvconn(iev, imsg);
- break;
- default:
- fatal("%s, unexpected imsg %d",
- __func__, imsg->hdr.type);
- }
- break;
- case IMSGEV_EREAD:
- case IMSGEV_EWRITE:
- case IMSGEV_EIMSG:
- fatal("server: imsgev read/write error (%d)", code);
- /* NOTREACHED */
- break;
- case IMSGEV_DONE:
- event_loopexit(NULL);
- /* NOTREACHED */
- break;
- }
-}
-
-static void
-imsgev_main_needfd(struct imsgev *iev)
-{
- fatal("server: imsgev_main_needfd");
-}
-
-static void
-receive(int fd, short why, void *data)
-{
- struct sockaddr_in remote;
- struct imsg_srvconn req;
- socklen_t len;
- char buf[16384];
- struct user *usr;
- int rv;
-
- len = sizeof(remote);
- rv = recvfrom(fd, buf, sizeof(buf), 0,
- (struct sockaddr *)&remote, &len);
- if (rv < 0) {
- log_warn("server: recvfrom failed");
- return;
- }
- usr = finduser(&remote);
- if (usr) {
- switch (usr->status) {
- case USER_ACCEPTED:
- log_tmp("server: data for existing user");
- break;
- case USER_REQUESTED:
- log_warn("server: data for not yet accepted user");
- break;
- case USER_REFUSED:
- log_warn("server: data for banned user !");
- break;
- }
- } else {
- log_debug("server: new user request");
-
- usr = xmalloc(sizeof(struct user));
- addrcpy(&usr->addr, &remote);
- usr->status = USER_REQUESTED;
- usr->lastseen = srv->time;
- LIST_INSERT_HEAD(&usr_list, usr, entry);
-
- addrcpy(&req.addr, &remote);
- req.deco = 0;
- imsgev_compose(&srv->iev, IMSG_SRVCONN_REQ, 0, 0, -1,
- &req, sizeof(req));
- }
-}
-
-static void
-ev_usrtimer(int fd, short why, void *data)
-{
- struct user *usr, *usrtmp;
- struct imsg_srvconn req;
-
- srv->time = time(NULL);
-
- LIST_FOREACH_SAFE(usr, &usr_list, entry, usrtmp) {
- if (srv->time > usr->lastseen + USER_TIMEOUT) {
- addrcpy(&req.addr, &usr->addr);
- req.deco = 1;
- imsgev_compose(&srv->iev, IMSG_SRVCONN_REQ, 0, 0, -1,
- &req, sizeof(req));
-
- LIST_REMOVE(usr, entry);
- free(usr);
- }
- }
-
- if (event_add(&srv->usrtimer_ev, &srv->usrtimer_tv) == -1)
- fatal("server: event_add usrtimer failed : %s", strerror(errno));
-}
diff --git a/glougloud/user.c b/glougloud/user.c
deleted file mode 100644
index ae9734f..0000000
--- a/glougloud/user.c
+++ /dev/null
@@ -1,806 +0,0 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/time.h>
-
-#if !defined(__OpenBSD__)
-#define __FAVOR_BSD
-#endif
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <netinet/in_systm.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-#include <pcap.h>
-
-#include "glougloud.h"
-#include "external/imsgev.h"
-
-/* XXX a user process should be able to have multiple clients, so that we
- * can send the same data to multiple machines with almost no overhead */
-
-#define NULL_HDRLEN 4 // XXX portable ?
-#define NODE_MAX_WITHOUT_TIMEOUT 1000
-#define NODE_TIMEOUT 300 // XXX conf ?
-#define CONN_TIMEOUT 300 // XXX conf ?
-#define CONN_TIMEOUT_UDP 20 // XXX conf ?
-#define CONN_TIMEOUT_ICMP 10 // XXX conf ?
-#define CONN_FREEIDS_COUNT 65536 /* 2^16 as long as freeids are u_int16_t */
-#define CONNTIMER 5 // XXX conf ?
-
-struct node {
- LIST_ENTRY(node) entry;
- struct in_addr addr;
- time_t lastseen;
- int used;
- short namelen;
-#define NODENAME_WAITING -1
-#define NODENAME_FAILED -2
- char *name;
-};
-
-enum connstate {
- CONNSTATE_ESTABLISHED,
- CONNSTATE_TCPFIN,
- CONNSTATE_TCPFIN2
-};
-
-struct conn {
- LIST_ENTRY(conn) entry;
- u_int id;
- enum connstate state;
- struct node *src;
- u_int src_port;
- struct node *dst;
- u_int dst_port;
- u_int proto;
- u_int size;
- time_t lastseen;
-};
-
-struct user {
- LIST_ENTRY(user) entry;
- struct sockaddr_in addr;
-};
-
-struct capture {
- int fd;
- struct imsgev iev;
-
- pcap_t *pcap;
- struct event pcap_ev;
- struct timeval pcap_tv;
- pcap_handler pcap_handler;
-
- LIST_HEAD(, conn) conn_list;
- LIST_HEAD(, node) node_list;
- int node_count;
- u_int16_t conn_freeids[CONN_FREEIDS_COUNT];
- int conn_freeids_ptr;
- struct event conntimer_ev;
- struct timeval conntimer_tv;
- time_t time;
-
- int pinvalid;
- int ptruncated;
-};
-
-struct phandler {
- pcap_handler f;
- int type;
-};
-
-static void ip_handle(struct ip *, const u_char *, u_int);
-static void sendto_all(struct packet *, int);
-static struct node *node_add(struct in_addr *);
-static void node_del(struct node *);
-static struct node *node_find(struct in_addr *);
-static void conn_add(struct in_addr *, int, struct in_addr *, int, int, int);
-static void conn_data(struct conn *, int, int);
-static void conn_del(struct conn *);
-static pcap_handler lookup_phandler(int);
-static struct user *finduser(struct sockaddr_in *);
-
-static void phandler_ether(u_char *,
- const struct pcap_pkthdr *, const u_char *);
-static void phandler_loop(u_char *,
- const struct pcap_pkthdr *, const u_char *);
-static void ev_pcap(int, short, void *);
-static void ev_timer(int, short, void *);
-
-static void usrconn(struct imsgev *, struct imsg *);
-static void imsgev_main(struct imsgev *, int, struct imsg *);
-static void imsgev_main_needfd(struct imsgev *);
-
-static struct phandler phandlers[] = {
- { phandler_ether, DLT_EN10MB },
- { phandler_ether, DLT_IEEE802 },
- { phandler_loop, DLT_LOOP },
- { NULL, 0 },
-};
-struct capture *cap;
-LIST_HEAD(, user) usr_list;
-int usr_count = 0;
-
-static void
-sig_handler(int sig, short why, void *data)
-{
- log_info("user: got signal %d", sig);
- if (sig == SIGINT || sig == SIGTERM)
- event_loopexit(NULL);
-}
-
-int
-user_init(int fd[2], pcap_t *pcap)
-{
- struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup;
- int pid, i;
-
- pid = fork();
- if (pid < 0)
- fatal("user fork");
- if (pid > 0)
- return pid;
-
- setproctitle("user");
- event_init();
- close(fd[0]);
-
- signal_set(&ev_sigint, SIGINT, sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, sig_handler, NULL);
- signal_set(&ev_sigchld, SIGCHLD, sig_handler, NULL);
- signal_set(&ev_sighup, SIGHUP, sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
- signal_add(&ev_sigchld, NULL);
- signal_add(&ev_sighup, NULL);
- signal(SIGPIPE, SIG_IGN);
-
- cap = xcalloc(1, sizeof(struct capture));
- cap->fd = fd[1];
- imsgev_init(&cap->iev, cap->fd, NULL, imsgev_main, imsgev_main_needfd);
- for (i=0; i<CONN_FREEIDS_COUNT-1; i++)
- cap->conn_freeids[i] = i;
- cap->time = time(NULL);
-
- cap->pcap = pcap;
- cap->pcap_handler = lookup_phandler(pcap_datalink(pcap));
- cap->pcap_tv.tv_sec = 0;
- cap->pcap_tv.tv_usec = PCAP_TO;
- event_set(&cap->pcap_ev, pcap_fileno(cap->pcap),
- EV_READ, ev_pcap, NULL);
-
- cap->conntimer_tv.tv_sec = CONNTIMER;
- cap->conntimer_tv.tv_usec = 0;
- evtimer_set(&cap->conntimer_ev, ev_timer, NULL);
- if (event_add(&cap->conntimer_ev, &cap->conntimer_tv) == -1)
- fatal("user: event_add conntimer failed: %s", strerror(errno));
-
- droppriv();
-
- log_info("user: entering event loop");
- event_dispatch();
-
- log_info("user: exiting");
- exit(0);
-}
-
-/*
- * Parse an IP packet and descide what to do with it.
- * 'ip' is a pointer the the captured IP packet
- * 'pend' is a pointer to the end of the captured IP packet
- * 'wirelen' is the size of the IP packet off the wire
- */
-#define NOTCAPTURED(v) ((u_char *)v > (u_char *)pend - sizeof(*v))
-#define NOTRECEIVED(v) (wirelen < sizeof(v))
-static void
-ip_handle(struct ip *ip, const u_char *pend, u_int wirelen)
-{
- u_int len, ip_hlen, off;
- const u_char *cp;
- struct tcphdr *tcph;
- struct udphdr *udph;
- struct icmp *icmp;
- struct in_addr src, dst;
- u_int src_port, dst_port;
- u_int size, proto, close, response;
- struct conn *c, *conn;
-
- if (NOTCAPTURED(ip)) {
- log_pinvalid("user: ip truncated (ip %x pend %x sizeof(ip) %d",
- ip, pend, sizeof(ip));
- cap->ptruncated++;
- return;
- }
-
- if (ip->ip_v != IPVERSION) {
- log_pinvalid("user: invalid ip version");
- cap->pinvalid++;
- return;
- }
-
- len = ntohs(ip->ip_len);
- if (wirelen < len) {
- log_pinvalid("user: ip too small");
- cap->pinvalid++;
- len = wirelen;
- }
-
- ip_hlen = ip->ip_hl * 4;
- if (ip_hlen < sizeof(struct ip) || ip_hlen > len) {
- log_pinvalid("user: ip_hlen invalid, %d", ip_hlen);
- cap->pinvalid++;
- return;
- }
- len -= ip_hlen;
-
- src.s_addr = ntohl(ip->ip_src.s_addr);
- dst.s_addr = ntohl(ip->ip_dst.s_addr);
- src_port = 0;
- dst_port = 0;
- proto = IPPROTO_IP;
- size = len;
- close = 0;
-
- off = ntohs(ip->ip_off);
- if ((off & IP_OFFMASK) == 0) {
- cp = (const u_char *)ip + ip_hlen;
- switch (ip->ip_p) {
-
- case IPPROTO_TCP:
- tcph = (struct tcphdr *)cp;
- if (NOTCAPTURED(&tcph->th_flags)) {
- log_pinvalid("user: tcp truncated");
- cap->ptruncated++;
- return;
- }
- if (NOTRECEIVED(*tcph)) {
- log_pinvalid("user: tcp too small");
- cap->pinvalid++;
- return;
- }
- src_port = ntohs(tcph->th_sport);
- dst_port = ntohs(tcph->th_dport);
- proto = IPPROTO_TCP;
- size = len - sizeof(*tcph);
- if ((tcph->th_flags & TH_FIN) &&
- (tcph->th_flags & TH_ACK))
- close = 1;
- break;
-
- case IPPROTO_UDP:
- udph = (struct udphdr *)cp;
- if (NOTCAPTURED(&udph->uh_dport)) {
- log_pinvalid("user: udp truncated, "
- "ip %x, udph %x, uh_port %x, pend %x, ip_hlen %d",
- ip, udph, &udph->uh_dport, pend, ip_hlen);
- cap->ptruncated++;
- return;
- }
- if (NOTRECEIVED(*udph)) {
- log_pinvalid("user: udp too small");
- cap->pinvalid++;
- return;
- }
- src_port = ntohs(udph->uh_sport);
- dst_port = ntohs(udph->uh_dport);
- proto = IPPROTO_UDP;
- size = len - sizeof(*udph);
- break;
-
- case IPPROTO_ICMP:
- icmp = (struct icmp *)cp;
- if (NOTRECEIVED(*icmp)) {
- log_pinvalid("user: icmp too small");
- cap->pinvalid++;
- return;
- }
- proto = IPPROTO_ICMP;
- size = len - sizeof(*icmp);
- break;
-
- default:
- log_warn("user: unknown ip protocol !");
- break;
- }
- } else {
- /*
- * if this isn't the first frag, we're missing the
- * next level protocol header.
- */
- log_tmp("user: got a fragmented ip packet !");
- }
-
- conn = NULL;
- LIST_FOREACH(c, &cap->conn_list, entry) {
- if (((c->src->addr.s_addr == src.s_addr &&
- c->src_port == src_port &&
- c->dst->addr.s_addr == dst.s_addr &&
- c->dst_port == dst_port) ||
- (c->src->addr.s_addr == dst.s_addr &&
- c->src_port == dst_port &&
- c->dst->addr.s_addr == src.s_addr &&
- c->dst_port == src_port)) &&
- c->proto == proto) {
- conn = c;
- if (c->src->addr.s_addr == src.s_addr)
- response = 0;
- else
- response = 1;
- break;
- }
- }
-
- if (conn) {
- if (!close) {
- conn_data(conn, size, response);
- } else {
- conn_del(conn);
- }
- } else {
- if (!close) {
- conn_add(&src, src_port, &dst, dst_port, proto, size);
- } else {
- log_warn("user: captured connection close w/o open !");
- }
- }
-}
-
-/* XXX all the packets must have data htos */
-static void
-sendto_all(struct packet *p, int size)
-{
- struct user *usr;
-
- log_debug("SEND PACKET (size %.2d): %x %x", size, p->ver, p->type);
-
- LIST_FOREACH(usr, &usr_list, entry) {
- if (sendto(net_socket, p, size, 0,
- (struct sockaddr *)&usr->addr, sizeof(usr->addr)) == -1)
- log_warn("send_to failed: %s", strerror(errno));
- }
-}
-
-static struct node *
-node_add(struct in_addr *addr)
-{
- struct node *n;
- struct imsg_usrdns_req req;
-
- log_debug("user: node_add");
-
- n = xcalloc(1, sizeof(struct node));
- n->addr.s_addr = addr->s_addr;
- n->namelen = NODENAME_WAITING;
- n->lastseen = cap->time;
- LIST_INSERT_HEAD(&cap->node_list, n, entry);
- cap->node_count++;
-
- req.addr.s_addr = addr->s_addr;
- imsgev_compose(&cap->iev, IMSG_USRDNS_REQ, 0, 0, -1,
- &req, sizeof(req));
-
- return n;
-}
-
-static void
-node_del(struct node *n)
-{
- if (n->used)
- fatal("user: trying to remove a used node !");
- log_debug("user: node_del");
-
- LIST_REMOVE(n, entry);
- free(n->name);
- free(n);
- cap->node_count--;
-}
-
-static struct node *
-node_find(struct in_addr *remote)
-{
- struct node *n;
-
- LIST_FOREACH(n, &cap->node_list, entry)
- if (n->addr.s_addr == remote->s_addr)
- return n;
- return NULL;
-}
-
-static void
-conn_add(struct in_addr *src, int src_port, struct in_addr *dst, int dst_port, int proto, int size)
-{
- struct packet p;
- struct conn *c;
- struct node *srcnode;
- struct node *dstnode;
- int id;
-
- log_debug("user: conn_add, %x:%d->%x:%d %d [%d]",
- src->s_addr, src_port, dst->s_addr, dst_port, proto, size);
- if (cap->conn_freeids_ptr == CONN_FREEIDS_COUNT) {
- log_warn("user: out of connection identifiers !");
- return;
- }
-
- id = cap->conn_freeids[cap->conn_freeids_ptr];
- cap->conn_freeids_ptr++;
-
- srcnode = node_find(src);
- if (!srcnode)
- srcnode = node_add(src);
- srcnode->used++;
- dstnode = node_find(dst);
- if (!dstnode)
- dstnode = node_add(dst);
- dstnode->used++;
-
- c = xmalloc(sizeof(struct conn));
- c->id = id;
- c->state = CONNSTATE_ESTABLISHED;
- c->src = srcnode;
- c->src_port = src_port;
- c->dst = dstnode;
- c->dst_port = dst_port;
- c->proto = proto;
- c->size = size;
- c->lastseen = cap->time;
- LIST_INSERT_HEAD(&cap->conn_list, c, entry);
-
- bzero(&p, sizeof(p));
- p.ver = PACKET_VERSION;
- p.type = PACKET_NEWCONN;
- p.newconn_id = id;
- p.newconn_src = htonl(src->s_addr);
- p.newconn_dst = htonl(dst->s_addr);
- p.newconn_proto = proto;
- p.newconn_size = htons(size << 8);
- sendto_all(&p, PACKET_NEWCONN_SIZE);
-}
-
-static void
-conn_data(struct conn *c, int size, int response)
-{
- struct packet p;
-
- log_debug("user: conn_data");
-
- c->lastseen = cap->time;
-
- bzero(&p, sizeof(p));
- p.ver = PACKET_VERSION;
- p.type = PACKET_DATA;
- p.data_connid = c->id;
- p.data_size = htons(size << 8 | response); //XXX
- sendto_all(&p, PACKET_DATA_SIZE);
-}
-
-static void
-conn_del(struct conn *c)
-{
- struct packet p;
-
- log_debug("user: conn_del");
-
- if (c->proto == IPPROTO_TCP) {
- switch (c->state) {
- case CONNSTATE_ESTABLISHED:
- c->state = CONNSTATE_TCPFIN;
- return;
- case CONNSTATE_TCPFIN:
- c->state = CONNSTATE_TCPFIN2;
- return;
- case CONNSTATE_TCPFIN2:
- break;
- }
- }
-
- bzero(&p, sizeof(p));
- p.ver = PACKET_VERSION;
- p.type = PACKET_DELCONN;
- p.delconn_id = c->id;
- sendto_all(&p, PACKET_DELCONN_SIZE);
-
- if (cap->conn_freeids_ptr == 0)
- fatal("cap->conn_freeids_ptr == 0");
- cap->conn_freeids_ptr--;
- cap->conn_freeids[cap->conn_freeids_ptr] = c->id;
-
- c->src->used--;
- c->dst->used--;
-
- LIST_REMOVE(c, entry);
- free(c);
-}
-
-static pcap_handler
-lookup_phandler(int type)
-{
- struct phandler *p;
-
- for (p = phandlers; p->f; ++p) {
- if (type == p->type)
- return p->f;
- }
- fatal("user: unknown data link type 0x%x", type);
- /* NOTREACHED */
- return NULL;
-}
-
-static struct user *
-finduser(struct sockaddr_in *remote)
-{
- struct user *usr;
- struct sockaddr_in *u;
-
- LIST_FOREACH(usr, &usr_list, entry) {
- u = &usr->addr;
- if (u->sin_addr.s_addr == remote->sin_addr.s_addr &&
- u->sin_port == remote->sin_port)
- return usr;
- }
- return NULL;
-}
-
-static void
-phandler_ether(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
-{
- struct ether_header *ep;
- struct ip *ip;
- u_short ether_type;
- const u_char *pend;
- u_int len;
-
- log_debug("user: pcap handler ethernet !");
-
- /* XXX here i assume that packets are alligned, which might not
- * be the case when using dump files, says tcpdump sources */
-
- ep = (struct ether_header *)p;
- pend = p + h->caplen;
- len = h->len - sizeof(struct ether_header);
-
-
- ether_type = ntohs(ep->ether_type);
- if (ether_type <= ETHERMTU)
- log_tmp("llc packet !");
- else {
- switch (ether_type) {
- case ETHERTYPE_IP:
- log_tmp("ether IP");
- ip = (struct ip *)((u_char *)ep + sizeof(struct ether_header));
- ip_handle(ip, pend, len);
- break;
- default:
- log_tmp("non ip packet !");
- break;
- }
- }
-}
-
-static void
-phandler_loop(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
-{
- struct ip *ip;
- struct ether_header *ep;
- u_short ether_type;
- u_int family;
- const u_char *pend;
- u_int len;
-
- log_debug("user: pcap handler loop !");
-
- /* XXX here i assume that packets are alligned, which might not
- * be the case when using dump files, says tcpdump sources */
-
- pend = p + h->caplen;
- len = h->len;
-
- memcpy((char *)&family, (char *)p, sizeof(family));
- family = ntohl(family);
- switch (family) {
- case AF_INET:
- log_tmp("loop family AF_INET");
- ip = (struct ip *)(p + NULL_HDRLEN);
- len -= NULL_HDRLEN;
- ip_handle(ip, pend, len);
- break;
-#if defined(__OpenBSD__)
- case AF_LINK:
-#else
- case AF_LOCAL:
-#endif
- ep = (struct ether_header *)(p + NULL_HDRLEN);
- ether_type = ntohs(ep->ether_type);
- if (ether_type <= ETHERMTU)
- log_tmp("llc packet !");
- else {
- switch (ether_type) {
- case ETHERTYPE_IP:
- log_tmp("loop family AF_LINK IP");
- ip = (struct ip *)((u_char *)ep + sizeof(*ep));
- len -= NULL_HDRLEN + sizeof(*ep);
- ip_handle(ip, pend, len);
- break;
- default:
- log_tmp("loop non ip packet !");
- break;
- }
- }
- default:
- log_tmp("unknown family %x !", family);
- break;
- }
-}
-
-static void
-ev_pcap(int fd, short why, void *data)
-{
- log_tmp("ev_pcap");
- pcap_dispatch(cap->pcap, PCAP_COUNT, cap->pcap_handler, NULL);
-
- /* reschedule */
- if (event_add(&cap->pcap_ev, &cap->pcap_tv) == -1)
- fatal("user: event_add pcap failed : %s", strerror(errno));
-}
-
-static void
-ev_timer(int fd, short why, void *data)
-{
- struct conn *c, *ctmp;
- struct node *n, *ntmp;
- int i, to;
-
- log_debug("ev_timer");
- cap->time = time(NULL);
-
- i = 0;
- LIST_FOREACH_SAFE(c, &cap->conn_list, entry, ctmp) {
- switch (c->proto) {
- case IPPROTO_UDP:
- to = CONN_TIMEOUT_UDP;
- break;
- case IPPROTO_ICMP:
- to = CONN_TIMEOUT_ICMP;
- break;
- default:
- to = CONN_TIMEOUT;
- break;
- }
- if (cap->time > c->lastseen + to)
- conn_del(c);
- else
- i++;
- }
-
- if (cap->node_count > NODE_MAX_WITHOUT_TIMEOUT) {
- LIST_FOREACH_SAFE(n, &cap->node_list, entry, ntmp) {
- if (n->used == 0 &&
- cap->time > n->lastseen + NODE_TIMEOUT)
- node_del(n);
- }
- }
-
- log_debug("user: ev_timer leaving with %d active connections and %d active nodes", i, cap->node_count);
- if (event_add(&cap->conntimer_ev, &cap->conntimer_tv) == -1)
- fatal("user: event_add conntimer failed : %s", strerror(errno));
-}
-
-static void
-usrconn(struct imsgev *iev, struct imsg *imsg)
-{
- struct imsg_usrconn *req;
- struct imsg_usrconn res;
- struct user *usr;
-
- req = imsg->data;
-
- if (req->deco) {
- usr = finduser(&req->addr);
- if (!usr)
- fatal("user: trying to deco an inexistant user !");
- LIST_REMOVE(usr, entry);
- free(usr);
- usr_count--;
- if (usr_count == 0)
- event_del(&cap->pcap_ev);
-
- return;
- }
-
- usr = xmalloc(sizeof(struct user));
- addrcpy(&usr->addr, &req->addr);
- LIST_INSERT_HEAD(&usr_list, usr, entry);
- if (usr_count == 0) {
- if (event_add(&cap->pcap_ev, &cap->pcap_tv) == -1)
- fatal("user: event_add failed : %s", strerror(errno));
- }
- usr_count++;
-
- addrcpy(&res.addr, &usr->addr);
- res.ok = 1;
- imsgev_compose(&cap->iev, IMSG_USRCONN_RES, 0, 0, -1,
- &res, sizeof(res));
-}
-
-static void
-usrdns(struct imsgev *iev, struct imsg *imsg)
-{
- struct imsg_usrdns_res *res;
- struct node *n;
- struct packet p;
-
- res = imsg->data;
-
- n = node_find(&res->addr);
- if (!n)
- fatal("user: received usrdns response for inexistant node !");
- if (n->namelen != NODENAME_WAITING)
- fatal("user: received usrdns response for a nonwaiting node!");
-
- if (res->name[0] == '\0') {
- log_debug("user: resolv for %x failed", res->addr.s_addr);
- n->namelen = NODENAME_FAILED;
- return;
- }
- n->namelen = strnlen(res->name, DNSNAME_MAX);
- n->name = strndup(res->name, DNSNAME_MAX);
-
- log_debug("user: sending node name of %x is %s",
- n->addr.s_addr, n->name);
- bzero(&p, sizeof(p));
- p.ver = PACKET_VERSION;
- p.type = PACKET_NAME;
- p.name_addr = htonl(n->addr.s_addr);
- p.name_len = n->namelen;
- strncpy(p.name_fqdn, n->name, sizeof(p.name_fqdn));
- sendto_all(&p, PACKET_NAME_SIZE + p.name_len);
-}
-
-static void
-imsgev_main(struct imsgev *iev, int code, struct imsg *imsg)
-{
- switch (code) {
- case IMSGEV_IMSG:
- log_debug("user: %s got imsg %i on fd %i",
- __func__, imsg->hdr.type, iev->ibuf.fd);
- switch (imsg->hdr.type) {
- case IMSG_USRCONN_REQ:
- usrconn(iev, imsg);
- break;
- case IMSG_USRDNS_RES:
- usrdns(iev, imsg);
- break;
- default:
- fatal("user: %s, unexpected imsg %d",
- __func__, imsg->hdr.type);
- }
- break;
- case IMSGEV_EREAD:
- case IMSGEV_EWRITE:
- case IMSGEV_EIMSG:
- fatal("user: imsgev read/write error");
- /* NOTREACHED */
- break;
- case IMSGEV_DONE:
- event_loopexit(NULL);
- /* NOTREACHED */
- break;
- }
-}
-
-static void
-imsgev_main_needfd(struct imsgev *iev)
-{
- fatal("server: imsgev_main_needfd");
-}
diff --git a/glougloud/util.c b/glougloud/util.c
deleted file mode 100644
index c077bd3..0000000
--- a/glougloud/util.c
+++ /dev/null
@@ -1,192 +0,0 @@
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <time.h>
-#include <pwd.h>
-#include <string.h>
-
-#include "glougloud.h"
-
-FILE *logfile;
-int loglevel;
-int logpinvalid;
-
-#define LOGFILE "/var/log/glougloud"
-#define LOG_FORCED -2
-#define LOG_FATAL -1
-#define LOG_WARN 0
-#define LOG_INFO 1
-#define LOG_DEBUG 2
-
-static void logit(int, const char *, const char *, va_list);
-
-void
-log_init(int level, int pinvalid)
-{
- logfile = fopen(LOGFILE, "a+");
- if (!logfile) {
- printf("cannot open log file %s!\n", LOGFILE);
- exit(1);
- }
- loglevel = level;
- logpinvalid = pinvalid;
-}
-
-void
-log_tmp(const char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- logit(LOG_FORCED, "XXX ", msg, ap);
- va_end(ap);
-}
-void
-log_pinvalid(const char *msg, ...)
-{
- va_list ap;
-
- if (!logpinvalid)
- return;
-
- va_start(ap, msg);
- logit(LOG_FORCED, "pinvalid: ", msg, ap);
- va_end(ap);
-}
-void
-log_debug(const char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- logit(LOG_DEBUG, "", msg, ap);
- va_end(ap);
-}
-void
-log_info(const char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- logit(LOG_INFO, "", msg, ap);
- va_end(ap);
-}
-void
-log_warn(const char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- logit(LOG_WARN, "", msg, ap);
- va_end(ap);
-}
-#if defined(__OpenBSD__)
-void __dead
-#else
-void
-#endif
-fatal(const char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- logit(LOG_FATAL, "fatal: ", msg, ap);
- va_end(ap);
-
- exit(1);
-}
-
-/* XXX mpsafe */
-static void
-logit(int level, const char *prefix, const char *msg, va_list ap)
-{
- time_t clock;
-
- if (level <= loglevel) {
- time(&clock);
- fprintf(logfile, "%d ", (int)clock);
- vfprintf(logfile, prefix, ap);
- vfprintf(logfile, msg, ap);
- fprintf(logfile, "\n");
- fflush(logfile);
- }
-}
-
-void *
-xmalloc(size_t size)
-{
- void *ptr;
-
- if (size == 0)
- fatal("xmalloc: zero size");
- ptr = malloc(size);
- if (ptr == NULL)
- fatal("xmalloc: out of memory (allocating %lu bytes)", (u_long) size);
- return ptr;
-}
-
-void *
-xcalloc(size_t nmemb, size_t size)
-{
- void *ptr;
-
- if (size == 0)
- fatal("xcalloc: zero size");
- ptr = calloc(nmemb, size);
- if (ptr == NULL)
- fatal("xcalloc: out of memory (allocating %lu bytes)", (u_long) size);
- return ptr;
-}
-
-void
-fd_nonblock(int fd)
-{
- int flags = fcntl(fd, F_GETFL, 0);
- int rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
- if (rc == -1)
- log_warn("failed to set fd %i non-blocking", fd);
-}
-
-void
-droppriv()
-{
- struct passwd *pw;
-
- pw = getpwnam(GLOUGLOUD_USER);
- if (!pw)
- fatal("unknown user %s", GLOUGLOUD_USER);
- if (chroot(pw->pw_dir) != 0)
- fatal("unable to chroot");
- if (chdir("/") != 0)
- fatal("unable to chdir");
- if (setgroups(1, &pw->pw_gid) == -1)
- fatal("setgroups() failed");
- if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
- fatal("setresgid failed");
- if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
- fatal("setresuid() failed");
- endpwent();
-}
-
-void
-addrcpy(struct sockaddr_in *dst, struct sockaddr_in *src)
-{
- dst->sin_addr.s_addr = src->sin_addr.s_addr;
- dst->sin_port = src->sin_port;
- dst->sin_family = src->sin_family;
-}
-
-void
-socketpair_prepare(int fd[2])
-{
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fd) == -1)
- fatal("socketpair_prepare");
- fd_nonblock(fd[0]);
- fd_nonblock(fd[1]);
-}
-