1 /* $OpenBSD: event_tagging.c,v 1.3 2010/04/21 20:02:40 nicm 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 #ifdef HAVE_CONFIG_H 31 #include "config.h" 32 #endif 33 34 #ifdef HAVE_SYS_TYPES_H 35 #include <sys/types.h> 36 #endif 37 #ifdef HAVE_SYS_PARAM_H 38 #include <sys/param.h> 39 #endif 40 41 #ifdef WIN32 42 #define WIN32_LEAN_AND_MEAN 43 #include <winsock2.h> 44 #include <windows.h> 45 #undef WIN32_LEAN_AND_MEAN 46 #else 47 #include <sys/ioctl.h> 48 #endif 49 50 #include <sys/queue.h> 51 #ifdef HAVE_SYS_TIME_H 52 #include <sys/time.h> 53 #endif 54 55 #include <errno.h> 56 #include <stdio.h> 57 #include <stdlib.h> 58 #include <string.h> 59 #ifndef WIN32 60 #include <syslog.h> 61 #endif 62 #ifdef HAVE_UNISTD_H 63 #include <unistd.h> 64 #endif 65 66 #include "event.h" 67 #include "evutil.h" 68 #include "log.h" 69 70 int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf); 71 int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag); 72 int evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf); 73 74 static struct evbuffer *_buf; /* not thread safe */ 75 76 void 77 evtag_init(void) 78 { 79 if (_buf != NULL) 80 return; 81 82 if ((_buf = evbuffer_new()) == NULL) 83 event_err(1, "%s: malloc", __func__); 84 } 85 86 /* 87 * We encode integer's by nibbles; the first nibble contains the number 88 * of significant nibbles - 1; this allows us to encode up to 64-bit 89 * integers. This function is byte-order independent. 90 */ 91 92 void 93 encode_int(struct evbuffer *evbuf, ev_uint32_t number) 94 { 95 int off = 1, nibbles = 0; 96 ev_uint8_t data[5]; 97 98 memset(data, 0, sizeof(ev_uint32_t)+1); 99 while (number) { 100 if (off & 0x1) 101 data[off/2] = (data[off/2] & 0xf0) | (number & 0x0f); 102 else 103 data[off/2] = (data[off/2] & 0x0f) | 104 ((number & 0x0f) << 4); 105 number >>= 4; 106 off++; 107 } 108 109 if (off > 2) 110 nibbles = off - 2; 111 112 /* Off - 1 is the number of encoded nibbles */ 113 data[0] = (data[0] & 0x0f) | ((nibbles & 0x0f) << 4); 114 115 evbuffer_add(evbuf, data, (off + 1) / 2); 116 } 117 118 /* 119 * Support variable length encoding of tags; we use the high bit in each 120 * octet as a continuation signal. 121 */ 122 123 int 124 evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag) 125 { 126 int bytes = 0; 127 ev_uint8_t data[5]; 128 129 memset(data, 0, sizeof(data)); 130 do { 131 ev_uint8_t lower = tag & 0x7f; 132 tag >>= 7; 133 134 if (tag) 135 lower |= 0x80; 136 137 data[bytes++] = lower; 138 } while (tag); 139 140 if (evbuf != NULL) 141 evbuffer_add(evbuf, data, bytes); 142 143 return (bytes); 144 } 145 146 static int 147 decode_tag_internal(ev_uint32_t *ptag, struct evbuffer *evbuf, int dodrain) 148 { 149 ev_uint32_t number = 0; 150 ev_uint8_t *data = EVBUFFER_DATA(evbuf); 151 int len = EVBUFFER_LENGTH(evbuf); 152 int count = 0, shift = 0, done = 0; 153 154 while (count++ < len) { 155 ev_uint8_t lower = *data++; 156 number |= (lower & 0x7f) << shift; 157 shift += 7; 158 159 if (!(lower & 0x80)) { 160 done = 1; 161 break; 162 } 163 } 164 165 if (!done) 166 return (-1); 167 168 if (dodrain) 169 evbuffer_drain(evbuf, count); 170 171 if (ptag != NULL) 172 *ptag = number; 173 174 return (count); 175 } 176 177 int 178 evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf) 179 { 180 return (decode_tag_internal(ptag, evbuf, 1 /* dodrain */)); 181 } 182 183 /* 184 * Marshal a data type, the general format is as follows: 185 * 186 * tag number: one byte; length: var bytes; payload: var bytes 187 */ 188 189 void 190 evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag, 191 const void *data, ev_uint32_t len) 192 { 193 evtag_encode_tag(evbuf, tag); 194 encode_int(evbuf, len); 195 evbuffer_add(evbuf, (void *)data, len); 196 } 197 198 /* Marshaling for integers */ 199 void 200 evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, ev_uint32_t integer) 201 { 202 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 203 encode_int(_buf, integer); 204 205 evtag_encode_tag(evbuf, tag); 206 encode_int(evbuf, EVBUFFER_LENGTH(_buf)); 207 evbuffer_add_buffer(evbuf, _buf); 208 } 209 210 void 211 evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, const char *string) 212 { 213 evtag_marshal(buf, tag, string, strlen(string)); 214 } 215 216 void 217 evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, struct timeval *tv) 218 { 219 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 220 221 encode_int(_buf, tv->tv_sec); 222 encode_int(_buf, tv->tv_usec); 223 224 evtag_marshal(evbuf, tag, EVBUFFER_DATA(_buf), 225 EVBUFFER_LENGTH(_buf)); 226 } 227 228 static int 229 decode_int_internal(ev_uint32_t *pnumber, struct evbuffer *evbuf, int dodrain) 230 { 231 ev_uint32_t number = 0; 232 ev_uint8_t *data = EVBUFFER_DATA(evbuf); 233 int len = EVBUFFER_LENGTH(evbuf); 234 int nibbles = 0; 235 236 if (!len) 237 return (-1); 238 239 nibbles = ((data[0] & 0xf0) >> 4) + 1; 240 if (nibbles > 8 || (nibbles >> 1) + 1 > len) 241 return (-1); 242 len = (nibbles >> 1) + 1; 243 244 while (nibbles > 0) { 245 number <<= 4; 246 if (nibbles & 0x1) 247 number |= data[nibbles >> 1] & 0x0f; 248 else 249 number |= (data[nibbles >> 1] & 0xf0) >> 4; 250 nibbles--; 251 } 252 253 if (dodrain) 254 evbuffer_drain(evbuf, len); 255 256 *pnumber = number; 257 258 return (len); 259 } 260 261 int 262 evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf) 263 { 264 return (decode_int_internal(pnumber, evbuf, 1) == -1 ? -1 : 0); 265 } 266 267 int 268 evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag) 269 { 270 return (decode_tag_internal(ptag, evbuf, 0 /* dodrain */)); 271 } 272 273 int 274 evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength) 275 { 276 struct evbuffer tmp; 277 int res, len; 278 279 len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */); 280 if (len == -1) 281 return (-1); 282 283 tmp = *evbuf; 284 tmp.buffer += len; 285 tmp.off -= len; 286 287 res = decode_int_internal(plength, &tmp, 0); 288 if (res == -1) 289 return (-1); 290 291 *plength += res + len; 292 293 return (0); 294 } 295 296 int 297 evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength) 298 { 299 struct evbuffer tmp; 300 int res, len; 301 302 len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */); 303 if (len == -1) 304 return (-1); 305 306 tmp = *evbuf; 307 tmp.buffer += len; 308 tmp.off -= len; 309 310 res = decode_int_internal(plength, &tmp, 0); 311 if (res == -1) 312 return (-1); 313 314 return (0); 315 } 316 317 int 318 evtag_consume(struct evbuffer *evbuf) 319 { 320 ev_uint32_t len; 321 if (decode_tag_internal(NULL, evbuf, 1 /* dodrain */) == -1) 322 return (-1); 323 if (evtag_decode_int(&len, evbuf) == -1) 324 return (-1); 325 evbuffer_drain(evbuf, len); 326 327 return (0); 328 } 329 330 /* Reads the data type from an event buffer */ 331 332 int 333 evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, struct evbuffer *dst) 334 { 335 ev_uint32_t len; 336 ev_uint32_t integer; 337 338 if (decode_tag_internal(ptag, src, 1 /* dodrain */) == -1) 339 return (-1); 340 if (evtag_decode_int(&integer, src) == -1) 341 return (-1); 342 len = integer; 343 344 if (EVBUFFER_LENGTH(src) < len) 345 return (-1); 346 347 if (evbuffer_add(dst, EVBUFFER_DATA(src), len) == -1) 348 return (-1); 349 350 evbuffer_drain(src, len); 351 352 return (len); 353 } 354 355 /* Marshaling for integers */ 356 357 int 358 evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag, 359 ev_uint32_t *pinteger) 360 { 361 ev_uint32_t tag; 362 ev_uint32_t len; 363 ev_uint32_t integer; 364 365 if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1) 366 return (-1); 367 if (need_tag != tag) 368 return (-1); 369 if (evtag_decode_int(&integer, evbuf) == -1) 370 return (-1); 371 len = integer; 372 373 if (EVBUFFER_LENGTH(evbuf) < len) 374 return (-1); 375 376 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 377 if (evbuffer_add(_buf, EVBUFFER_DATA(evbuf), len) == -1) 378 return (-1); 379 380 evbuffer_drain(evbuf, len); 381 382 return (evtag_decode_int(pinteger, _buf)); 383 } 384 385 /* Unmarshal a fixed length tag */ 386 387 int 388 evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, void *data, 389 size_t len) 390 { 391 ev_uint32_t tag; 392 393 /* Initialize this event buffer so that we can read into it */ 394 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 395 396 /* Now unmarshal a tag and check that it matches the tag we want */ 397 if (evtag_unmarshal(src, &tag, _buf) == -1 || tag != need_tag) 398 return (-1); 399 400 if (EVBUFFER_LENGTH(_buf) != len) 401 return (-1); 402 403 memcpy(data, EVBUFFER_DATA(_buf), len); 404 return (0); 405 } 406 407 int 408 evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag, 409 char **pstring) 410 { 411 ev_uint32_t tag; 412 413 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 414 415 if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag) 416 return (-1); 417 418 *pstring = calloc(EVBUFFER_LENGTH(_buf) + 1, 1); 419 if (*pstring == NULL) 420 event_err(1, "%s: calloc", __func__); 421 evbuffer_remove(_buf, *pstring, EVBUFFER_LENGTH(_buf)); 422 423 return (0); 424 } 425 426 int 427 evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag, 428 struct timeval *ptv) 429 { 430 ev_uint32_t tag; 431 ev_uint32_t integer; 432 433 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf)); 434 if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag) 435 return (-1); 436 437 if (evtag_decode_int(&integer, _buf) == -1) 438 return (-1); 439 ptv->tv_sec = integer; 440 if (evtag_decode_int(&integer, _buf) == -1) 441 return (-1); 442 ptv->tv_usec = integer; 443 444 return (0); 445 } 446