15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2003, 2004 Niels Provos <provos@citi.umich.edu>
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that the following conditions
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3. The name of the author may not be used to endorse or promote products
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    derived from this software without specific prior written permission.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CONFIG_H
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TYPES_H
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_PARAM_H
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/param.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WIN32_LEAN_AND_MEAN
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock2.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef WIN32_LEAN_AND_MEAN
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/ioctl.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/queue.h>
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TIME_H
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h>
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h>
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WIN32
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <syslog.h>
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_UNISTD_H
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "event.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "evutil.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "log.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct evbuffer *_buf;	/* not thread safe */
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_init(void)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (_buf != NULL)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((_buf = evbuffer_new()) == NULL)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		event_err(1, "%s: malloc", __func__);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We encode integer's by nibbles; the first nibble contains the number
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of significant nibbles - 1;  this allows us to encode up to 64-bit
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * integers.  This function is byte-order independent.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)encode_int(struct evbuffer *evbuf, ev_uint32_t number)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int off = 1, nibbles = 0;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint8_t data[5];
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memset(data, 0, sizeof(ev_uint32_t)+1);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (number) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (off & 0x1)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			data[off/2] = (data[off/2] & 0xf0) | (number & 0x0f);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			data[off/2] = (data[off/2] & 0x0f) |
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    ((number & 0x0f) << 4);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		number >>= 4;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		off++;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (off > 2)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		nibbles = off - 2;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Off - 1 is the number of encoded nibbles */
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	data[0] = (data[0] & 0x0f) | ((nibbles & 0x0f) << 4);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_add(evbuf, data, (off + 1) / 2);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Support variable length encoding of tags; we use the high bit in each
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * octet as a continuation signal.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int bytes = 0;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint8_t data[5];
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memset(data, 0, sizeof(data));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	do {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ev_uint8_t lower = tag & 0x7f;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tag >>= 7;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tag)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			lower |= 0x80;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		data[bytes++] = lower;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} while (tag);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evbuf != NULL)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		evbuffer_add(evbuf, data, bytes);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (bytes);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decode_tag_internal(ev_uint32_t *ptag, struct evbuffer *evbuf, int dodrain)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t number = 0;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint8_t *data = EVBUFFER_DATA(evbuf);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int len = EVBUFFER_LENGTH(evbuf);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int count = 0, shift = 0, done = 0;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (count++ < len) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ev_uint8_t lower = *data++;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		number |= (lower & 0x7f) << shift;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		shift += 7;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!(lower & 0x80)) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			done = 1;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!done)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (dodrain)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		evbuffer_drain(evbuf, count);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ptag != NULL)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*ptag = number;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (count);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (decode_tag_internal(ptag, evbuf, 1 /* dodrain */));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Marshal a data type, the general format is as follows:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tag number: one byte; length: var bytes; payload: var bytes
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void *data, ev_uint32_t len)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evtag_encode_tag(evbuf, tag);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	encode_int(evbuf, len);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_add(evbuf, (void *)data, len);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Marshaling for integers */
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, ev_uint32_t integer)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	encode_int(_buf, integer);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evtag_encode_tag(evbuf, tag);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	encode_int(evbuf, EVBUFFER_LENGTH(_buf));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_add_buffer(evbuf, _buf);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, const char *string)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evtag_marshal(buf, tag, string, strlen(string));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, struct timeval *tv)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	encode_int(_buf, tv->tv_sec);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	encode_int(_buf, tv->tv_usec);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evtag_marshal(evbuf, tag, EVBUFFER_DATA(_buf),
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    EVBUFFER_LENGTH(_buf));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decode_int_internal(ev_uint32_t *pnumber, struct evbuffer *evbuf, int dodrain)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t number = 0;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint8_t *data = EVBUFFER_DATA(evbuf);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int len = EVBUFFER_LENGTH(evbuf);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int nibbles = 0;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!len)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nibbles = ((data[0] & 0xf0) >> 4) + 1;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (nibbles > 8 || (nibbles >> 1) + 1 > len)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = (nibbles >> 1) + 1;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (nibbles > 0) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		number <<= 4;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (nibbles & 0x1)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			number |= data[nibbles >> 1] & 0x0f;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			number |= (data[nibbles >> 1] & 0xf0) >> 4;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		nibbles--;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (dodrain)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		evbuffer_drain(evbuf, len);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*pnumber = number;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (len);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (decode_int_internal(pnumber, evbuf, 1) == -1 ? -1 : 0);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (decode_tag_internal(ptag, evbuf, 0 /* dodrain */));
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct evbuffer tmp;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int res, len;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (len == -1)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = *evbuf;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp.buffer += len;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp.off -= len;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	res = decode_int_internal(plength, &tmp, 0);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (res == -1)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*plength += res + len;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (0);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct evbuffer tmp;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int res, len;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (len == -1)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = *evbuf;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp.buffer += len;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp.off -= len;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	res = decode_int_internal(plength, &tmp, 0);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (res == -1)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (0);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_consume(struct evbuffer *evbuf)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t len;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (decode_tag_internal(NULL, evbuf, 1 /* dodrain */) == -1)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evtag_decode_int(&len, evbuf) == -1)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(evbuf, len);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (0);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Reads the data type from an event buffer */
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, struct evbuffer *dst)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t len;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t integer;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (decode_tag_internal(ptag, src, 1 /* dodrain */) == -1)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evtag_decode_int(&integer, src) == -1)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = integer;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (EVBUFFER_LENGTH(src) < len)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evbuffer_add(dst, EVBUFFER_DATA(src), len) == -1)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(src, len);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (len);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Marshaling for integers */
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ev_uint32_t *pinteger)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t tag;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t len;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t integer;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (need_tag != tag)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evtag_decode_int(&integer, evbuf) == -1)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = integer;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (EVBUFFER_LENGTH(evbuf) < len)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evbuffer_add(_buf, EVBUFFER_DATA(evbuf), len) == -1)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(evbuf, len);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (evtag_decode_int(pinteger, _buf));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Unmarshal a fixed length tag */
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, void *data,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t len)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t tag;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Initialize this event buffer so that we can read into it */
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Now unmarshal a tag and check that it matches the tag we want */
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evtag_unmarshal(src, &tag, _buf) == -1 || tag != need_tag)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (EVBUFFER_LENGTH(_buf) != len)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(data, EVBUFFER_DATA(_buf), len);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (0);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char **pstring)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t tag;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*pstring = calloc(EVBUFFER_LENGTH(_buf) + 1, 1);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (*pstring == NULL)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		event_err(1, "%s: calloc", __func__);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_remove(_buf, *pstring, EVBUFFER_LENGTH(_buf));
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (0);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct timeval *ptv)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t tag;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev_uint32_t integer;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evtag_decode_int(&integer, _buf) == -1)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ptv->tv_sec = integer;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evtag_decode_int(&integer, _buf) == -1)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return (-1);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ptv->tv_usec = integer;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (0);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
444