1/*	$NetBSD: evt.c,v 1.5 2006/09/09 16:22:09 manu Exp $	*/
2
3/* Id: evt.c,v 1.5 2006/06/22 20:11:35 manubsd Exp */
4
5/*
6 * Copyright (C) 2004 Emmanuel Dreyfus
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <errno.h>
37#include <string.h>
38#include <stdio.h>
39#include <time.h>
40#include <unistd.h>
41#include <stdlib.h>
42#include <sys/queue.h>
43#include <sys/socket.h>
44
45#include "vmbuf.h"
46#include "plog.h"
47#include "misc.h"
48#include "admin.h"
49#include "gcmalloc.h"
50#include "evt.h"
51
52#ifdef ENABLE_ADMINPORT
53struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist);
54int evtlist_len = 0;
55
56void
57evt_push(src, dst, type, optdata)
58	struct sockaddr *src;
59	struct sockaddr *dst;
60	int type;
61	vchar_t *optdata;
62{
63	struct evtdump *evtdump;
64	struct evt *evt;
65	size_t len;
66
67	/* If admin socket is disabled, silently discard anything */
68	if (adminsock_path == NULL)
69		return;
70
71	/* If we are above the limit, don't record anything */
72	if (evtlist_len > EVTLIST_MAX) {
73		plog(LLV_DEBUG, LOCATION, NULL,
74		    "Cannot record event: event queue overflowed\n");
75		return;
76	}
77
78	/* If we hit the limit, record an overflow event instead */
79	if (evtlist_len == EVTLIST_MAX) {
80		plog(LLV_ERROR, LOCATION, NULL,
81		    "Cannot record event: event queue overflow\n");
82		src = NULL;
83		dst = NULL;
84		type = EVTT_OVERFLOW;
85		optdata = NULL;
86	}
87
88	len = sizeof(*evtdump);
89	if (optdata)
90		len += optdata->l;
91
92	if ((evtdump = racoon_malloc(len)) == NULL) {
93		plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n",
94		    strerror(errno));
95		return;
96	}
97
98	if ((evt = racoon_malloc(sizeof(*evt))) == NULL) {
99		plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n",
100		    strerror(errno));
101		racoon_free(evtdump);
102		return;
103	}
104
105	if (src)
106		memcpy(&evtdump->src, src, sysdep_sa_len(src));
107	if (dst)
108		memcpy(&evtdump->dst, dst, sysdep_sa_len(dst));
109	evtdump->len = len;
110	evtdump->type = type;
111	time(&evtdump->timestamp);
112
113	if (optdata)
114		memcpy(evtdump + 1, optdata->v, optdata->l);
115
116	evt->dump = evtdump;
117	TAILQ_INSERT_TAIL(&evtlist, evt, next);
118
119	evtlist_len++;
120
121	return;
122}
123
124struct evtdump *
125evt_pop(void) {
126	struct evtdump *evtdump;
127	struct evt *evt;
128
129	if ((evt = TAILQ_FIRST(&evtlist)) == NULL)
130		return NULL;
131
132	evtdump = evt->dump;
133	TAILQ_REMOVE(&evtlist, evt, next);
134	racoon_free(evt);
135	evtlist_len--;
136
137	return evtdump;
138}
139
140vchar_t *
141evt_dump(void) {
142	struct evtdump *evtdump;
143	vchar_t *buf = NULL;
144
145	if ((evtdump = evt_pop()) != NULL) {
146		if ((buf = vmalloc(evtdump->len)) == NULL) {
147			plog(LLV_ERROR, LOCATION, NULL,
148			    "evt_dump failed: %s\n", strerror(errno));
149			return NULL;
150		}
151		memcpy(buf->v, evtdump, evtdump->len);
152		racoon_free(evtdump);
153	}
154
155	return buf;
156}
157
158#endif /* ENABLE_ADMINPORT */
159