1 /* $OpenBSD: event_tagging.c,v 1.10 2014/10/30 16:45:37 bluhm Exp $ */ 2 3 /* 4 * Copyright (c) 2003, 2004 Niels Provos <provos@citi.umich.edu> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/types.h> 31 #include <sys/ioctl.h> 32 #include <sys/queue.h> 33 #include <sys/time.h> 34 35 #include <errno.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <syslog.h> 40 #include <unistd.h> 41 42 #include "event.h" 43 #include "log.h" 44 45 int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf); 46 int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag); 47 int evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf); 48 49 static struct evbuffer *_buf; /* not thread safe */ 50 51 void 52 evtag_init(void) 53 { 54 if (_buf != NULL) 55 return; 56 57 if ((_buf = evbuffer_new()) == NULL) 58 event_err(1, "%s: malloc", __func__); 59 } 60 61 /* 62 * We encode integer's by nibbles; the first nibble contains the number 63 * of significant nibbles - 1; this allows us to encode up to 64-bit 64 * integers. This function is byte-order independent. 65 */ 66 67 void 68 encode_int(struct evbuffer *evbuf, ev_uint32_t number) 69 { 70 int off = 1, nibbles = 0; 71 ev_uint8_t data[5]; 72 73 memset(data, 0, sizeof(ev_uint32_t)+1); 74 while (number) { 75 if (off & 0x1) 76 data[off/2] = (data[off/2] & 0xf0) | (number & 0x0f); 77 else 78 data[off/2] = (data[off/2] & 0x0f) | 79 ((number & 0x0f) << 4); 80 number >>= 4; 81 off++; 82 } 83 84 if (off > 2) 85 nibbles = off - 2; 86 87 /* Off - 1 is the number of encoded nibbles */ 88 data[0] = (data[0] & 0x0f) | ((nibbles & 0x0f) << 4); 89 90 evbuffer_add(evbuf, data, (off + 1) / 2); 91 } 92 93 /* 94 * Support variable length encoding of tags; we use the high bit in each 95 * octet as a continuation signal. 96 */ 97 98 int 99 evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag) 100 { 101 int bytes = 0; 102 ev_uint8_t data[5]; 103 104 memset(data, 0, sizeof(data)); 105 do { 106 ev_uint8_t lower = tag & 0x7f; 107 tag >>= 7; 108 109 if (tag) 110 lower |= 0x80; 111 112 data[bytes++] = lower; 113 } while (tag); 114 115 if (evbuf != NULL) 116 evbuffer_add(evbuf, data, bytes); 117 118 return (bytes); 119 } 120 121 static int 122 decode_tag_internal(ev_uint32_t *ptag, struct evbuffer *evbuf, int dodrain) 123 { 124 ev_uint32_t number = 0; 125 ev_uint8_t *data = EVBUFFER_DATA(evbuf); 126 int len = EVBUFFER_LENGTH(evbuf); 127 int count = 0, shift = 0, done = 0; 128 129 while (count++ < len) { 130 ev_uint8_t lower = *data++; 131 number |= (lower & 0x7f) << shift; 132 shift += 7; 133 134 if (!(lower & 0x80)) { 135 done = 1; 136 break; 137 } 138 } 139 140 if (!done) 141 return (-1); 142 143 if (dodrain) 144 evbuffer_drain(evbuf, count); 145 146 if (ptag != NULL) 147 *ptag = number; 148 149 return (count); 150 } 151 152 int 153 evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf) 154 { 155 return (decode_tag_internal(ptag, evbuf, 1 /* dodrain */)); 156 } 157 158 /* 159 * Marshal a data type, the general format is as follows: 160 * 161 * tag number: one byte; length: var bytes; payload: var bytes 162 */ 163 164 void 165 evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag, 166 const void *data, ev_uint32_t len) 167 { 168 evtag_encode_tag(evbuf, tag); 169 encode_int(evbuf, len); 170 evbuffer_add(evbuf, data, len); 171 } 172 173 /* Marshaling for integers */ 174 void 175 evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, ev_uint32_t integer) 176 { 177 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 178 encode_int(_buf, integer); 179 180 evtag_encode_tag(evbuf, tag); 181 encode_int(evbuf, EVBUFFER_LENGTH(_buf)); 182 evbuffer_add_buffer(evbuf, _buf); 183 } 184 185 void 186 evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, const char *string) 187 { 188 evtag_marshal(buf, tag, string, strlen(string)); 189 } 190 191 void 192 evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, struct timeval *tv) 193 { 194 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 195 196 encode_int(_buf, tv->tv_sec); /* XXX 2038 */ 197 encode_int(_buf, tv->tv_usec); 198 199 evtag_marshal(evbuf, tag, EVBUFFER_DATA(_buf), 200 EVBUFFER_LENGTH(_buf)); 201 } 202 203 static int 204 decode_int_internal(ev_uint32_t *pnumber, struct evbuffer *evbuf, int dodrain) 205 { 206 ev_uint32_t number = 0; 207 ev_uint8_t *data = EVBUFFER_DATA(evbuf); 208 int len = EVBUFFER_LENGTH(evbuf); 209 int nibbles = 0; 210 211 if (!len) 212 return (-1); 213 214 nibbles = ((data[0] & 0xf0) >> 4) + 1; 215 if (nibbles > 8 || (nibbles >> 1) + 1 > len) 216 return (-1); 217 len = (nibbles >> 1) + 1; 218 219 while (nibbles > 0) { 220 number <<= 4; 221 if (nibbles & 0x1) 222 number |= data[nibbles >> 1] & 0x0f; 223 else 224 number |= (data[nibbles >> 1] & 0xf0) >> 4; 225 nibbles--; 226 } 227 228 if (dodrain) 229 evbuffer_drain(evbuf, len); 230 231 *pnumber = number; 232 233 return (len); 234 } 235 236 int 237 evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf) 238 { 239 return (decode_int_internal(pnumber, evbuf, 1) == -1 ? -1 : 0); 240 } 241 242 int 243 evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag) 244 { 245 return (decode_tag_internal(ptag, evbuf, 0 /* dodrain */)); 246 } 247 248 int 249 evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength) 250 { 251 struct evbuffer tmp; 252 int res, len; 253 254 len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */); 255 if (len == -1) 256 return (-1); 257 258 tmp = *evbuf; 259 tmp.buffer += len; 260 tmp.off -= len; 261 262 res = decode_int_internal(plength, &tmp, 0); 263 if (res == -1) 264 return (-1); 265 266 *plength += res + len; 267 268 return (0); 269 } 270 271 int 272 evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength) 273 { 274 struct evbuffer tmp; 275 int res, len; 276 277 len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */); 278 if (len == -1) 279 return (-1); 280 281 tmp = *evbuf; 282 tmp.buffer += len; 283 tmp.off -= len; 284 285 res = decode_int_internal(plength, &tmp, 0); 286 if (res == -1) 287 return (-1); 288 289 return (0); 290 } 291 292 int 293 evtag_consume(struct evbuffer *evbuf) 294 { 295 ev_uint32_t len; 296 if (decode_tag_internal(NULL, evbuf, 1 /* dodrain */) == -1) 297 return (-1); 298 if (evtag_decode_int(&len, evbuf) == -1) 299 return (-1); 300 evbuffer_drain(evbuf, len); 301 302 return (0); 303 } 304 305 /* Reads the data type from an event buffer */ 306 307 int 308 evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, struct evbuffer *dst) 309 { 310 ev_uint32_t len; 311 ev_uint32_t integer; 312 313 if (decode_tag_internal(ptag, src, 1 /* dodrain */) == -1) 314 return (-1); 315 if (evtag_decode_int(&integer, src) == -1) 316 return (-1); 317 len = integer; 318 319 if (EVBUFFER_LENGTH(src) < len) 320 return (-1); 321 322 if (evbuffer_add(dst, EVBUFFER_DATA(src), len) == -1) 323 return (-1); 324 325 evbuffer_drain(src, len); 326 327 return (len); 328 } 329 330 /* Marshaling for integers */ 331 332 int 333 evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag, 334 ev_uint32_t *pinteger) 335 { 336 ev_uint32_t tag; 337 ev_uint32_t len; 338 ev_uint32_t integer; 339 340 if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1) 341 return (-1); 342 if (need_tag != tag) 343 return (-1); 344 if (evtag_decode_int(&integer, evbuf) == -1) 345 return (-1); 346 len = integer; 347 348 if (EVBUFFER_LENGTH(evbuf) < len) 349 return (-1); 350 351 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 352 if (evbuffer_add(_buf, EVBUFFER_DATA(evbuf), len) == -1) 353 return (-1); 354 355 evbuffer_drain(evbuf, len); 356 357 return (evtag_decode_int(pinteger, _buf)); 358 } 359 360 /* Unmarshal a fixed length tag */ 361 362 int 363 evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, void *data, 364 size_t len) 365 { 366 ev_uint32_t tag; 367 368 /* Initialize this event buffer so that we can read into it */ 369 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 370 371 /* Now unmarshal a tag and check that it matches the tag we want */ 372 if (evtag_unmarshal(src, &tag, _buf) == -1 || tag != need_tag) 373 return (-1); 374 375 if (EVBUFFER_LENGTH(_buf) != len) 376 return (-1); 377 378 memcpy(data, EVBUFFER_DATA(_buf), len); 379 return (0); 380 } 381 382 int 383 evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag, 384 char **pstring) 385 { 386 ev_uint32_t tag; 387 388 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 389 390 if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag) 391 return (-1); 392 393 *pstring = calloc(EVBUFFER_LENGTH(_buf) + 1, 1); 394 if (*pstring == NULL) 395 event_err(1, "%s: calloc", __func__); 396 evbuffer_remove(_buf, *pstring, EVBUFFER_LENGTH(_buf)); 397 398 return (0); 399 } 400 401 int 402 evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag, 403 struct timeval *ptv) 404 { 405 ev_uint32_t tag; 406 ev_uint32_t integer; 407 408 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 409 if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag) 410 return (-1); 411 412 if (evtag_decode_int(&integer, _buf) == -1) 413 return (-1); 414 ptv->tv_sec = integer; 415 if (evtag_decode_int(&integer, _buf) == -1) 416 return (-1); 417 ptv->tv_usec = integer; 418 419 return (0); 420 } 421