12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*- 22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 2003, 2004 David Young. All rights reserved. 32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without 52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that the following conditions 62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * are met: 72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * notice, this list of conditions and the following disclaimer. 92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * documentation and/or other materials provided with the distribution. 122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 3. The name of David Young may not be used to endorse or promote 132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * products derived from this software without specific prior 142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission. 152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY 172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID 202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OF SUCH DAMAGE. 282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H 312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h" 322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdlib.h> 352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h> 362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h> 372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "cpack.h" 392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "extract.h" 402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic u_int8_t * 422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment) 432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project size_t misalignment = (size_t)(p - buf) % alignment; 452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (misalignment == 0) 472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return p; 482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return p + (alignment - misalignment); 502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Advance to the next wordsize boundary. Return NULL if fewer than 532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * wordsize bytes remain in the buffer after the boundary. Otherwise, 542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * return a pointer to the boundary. 552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic u_int8_t * 572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcpack_align_and_reserve(struct cpack_state *cs, size_t wordsize) 582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_int8_t *next; 602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* Ensure alignment. */ 622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project next = cpack_next_boundary(cs->c_buf, cs->c_next, wordsize); 632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* Too little space for wordsize bytes? */ 652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (next - cs->c_buf + wordsize > cs->c_len) 662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return NULL; 672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return next; 692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint 722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcpack_init(struct cpack_state *cs, u_int8_t *buf, size_t buflen) 732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project memset(cs, 0, sizeof(*cs)); 752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project cs->c_buf = buf; 772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project cs->c_len = buflen; 782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project cs->c_next = cs->c_buf; 792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Unpack a 64-bit unsigned integer. */ 842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint 852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcpack_uint64(struct cpack_state *cs, u_int64_t *u) 862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_int8_t *next; 882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) 902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return -1; 912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *u = EXTRACT_LE_64BITS(next); 932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* Move pointer past the u_int64_t. */ 952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project cs->c_next = next + sizeof(*u); 962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Unpack a 32-bit unsigned integer. */ 1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint 1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcpack_uint32(struct cpack_state *cs, u_int32_t *u) 1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_int8_t *next; 1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) 1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return -1; 1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *u = EXTRACT_LE_32BITS(next); 1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* Move pointer past the u_int32_t. */ 1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project cs->c_next = next + sizeof(*u); 1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Unpack a 16-bit unsigned integer. */ 1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint 1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcpack_uint16(struct cpack_state *cs, u_int16_t *u) 1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_int8_t *next; 1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) 1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return -1; 1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *u = EXTRACT_LE_16BITS(next); 1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* Move pointer past the u_int16_t. */ 1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project cs->c_next = next + sizeof(*u); 1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Unpack an 8-bit unsigned integer. */ 1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint 1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcpack_uint8(struct cpack_state *cs, u_int8_t *u) 1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* No space left? */ 1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if ((size_t)(cs->c_next - cs->c_buf) >= cs->c_len) 1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return -1; 1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *u = *cs->c_next; 1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* Move pointer past the u_int8_t. */ 1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project cs->c_next++; 1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 145