diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-10-16 15:53:49 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-10-24 16:00:50 +0200 |
commit | 125b37af6d39e445086b6e80f60b3316a7602b6c (patch) | |
tree | 205c588b7f78a601caa296db8a67f890f2b87841 /src/libstrongswan/utils | |
parent | 05e448c5cc626a4f3b8b799aa89b9a03e2db0547 (diff) | |
download | strongswan-125b37af6d39e445086b6e80f60b3316a7602b6c.tar.bz2 strongswan-125b37af6d39e445086b6e80f60b3316a7602b6c.tar.xz |
Moved chunk_t to utils folder
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r-- | src/libstrongswan/utils/chunk.c | 690 | ||||
-rw-r--r-- | src/libstrongswan/utils/chunk.h | 318 | ||||
-rw-r--r-- | src/libstrongswan/utils/identification.h | 2 |
3 files changed, 1009 insertions, 1 deletions
diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c new file mode 100644 index 000000000..d7f1c31d9 --- /dev/null +++ b/src/libstrongswan/utils/chunk.c @@ -0,0 +1,690 @@ +/* + * Copyright (C) 2008-2009 Tobias Brunner + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include <stdio.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> + +#include "chunk.h" +#include "debug.h" + +/* required for chunk_hash */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) +#define get16bits(d) (*((const u_int16_t*)(d))) +#endif +#if !defined (get16bits) +#define get16bits(d) ((((u_int32_t)(((const u_int8_t*)(d))[1])) << 8)\ + + (u_int32_t)(((const u_int8_t*)(d))[0]) ) +#endif + +/** + * Empty chunk. + */ +chunk_t chunk_empty = { NULL, 0 }; + +/** + * Described in header. + */ +chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk) +{ + chunk_t clone = chunk_empty; + + if (chunk.ptr && chunk.len > 0) + { + clone.ptr = ptr; + clone.len = chunk.len; + memcpy(clone.ptr, chunk.ptr, chunk.len); + } + + return clone; +} + +/** + * Described in header. + */ +size_t chunk_length(const char* mode, ...) +{ + va_list chunks; + size_t length = 0; + + va_start(chunks, mode); + while (TRUE) + { + switch (*mode++) + { + case 'm': + case 'c': + case 's': + { + chunk_t ch = va_arg(chunks, chunk_t); + length += ch.len; + continue; + } + default: + break; + } + break; + } + va_end(chunks); + return length; +} + +/** + * Described in header. + */ +chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...) +{ + va_list chunks; + chunk_t construct = chunk_create(ptr, 0); + + va_start(chunks, mode); + while (TRUE) + { + bool free_chunk = FALSE, clear_chunk = FALSE; + chunk_t ch; + + switch (*mode++) + { + case 's': + clear_chunk = TRUE; + /* FALL */ + case 'm': + free_chunk = TRUE; + /* FALL */ + case 'c': + ch = va_arg(chunks, chunk_t); + memcpy(ptr, ch.ptr, ch.len); + ptr += ch.len; + construct.len += ch.len; + if (clear_chunk) + { + chunk_clear(&ch); + } + else if (free_chunk) + { + free(ch.ptr); + } + continue; + default: + break; + } + break; + } + va_end(chunks); + + return construct; +} + +/** + * Described in header. + */ +void chunk_split(chunk_t chunk, const char *mode, ...) +{ + va_list chunks; + u_int len; + chunk_t *ch; + + va_start(chunks, mode); + while (TRUE) + { + if (*mode == '\0') + { + break; + } + len = va_arg(chunks, u_int); + ch = va_arg(chunks, chunk_t*); + /* a null chunk means skip len bytes */ + if (ch == NULL) + { + chunk = chunk_skip(chunk, len); + continue; + } + switch (*mode++) + { + case 'm': + { + ch->len = min(chunk.len, len); + if (ch->len) + { + ch->ptr = chunk.ptr; + } + else + { + ch->ptr = NULL; + } + chunk = chunk_skip(chunk, ch->len); + continue; + } + case 'a': + { + ch->len = min(chunk.len, len); + if (ch->len) + { + ch->ptr = malloc(ch->len); + memcpy(ch->ptr, chunk.ptr, ch->len); + } + else + { + ch->ptr = NULL; + } + chunk = chunk_skip(chunk, ch->len); + continue; + } + case 'c': + { + ch->len = min(ch->len, chunk.len); + ch->len = min(ch->len, len); + if (ch->len) + { + memcpy(ch->ptr, chunk.ptr, ch->len); + } + else + { + ch->ptr = NULL; + } + chunk = chunk_skip(chunk, ch->len); + continue; + } + default: + break; + } + break; + } + va_end(chunks); +} + +/** + * Described in header. + */ +bool chunk_write(chunk_t chunk, char *path, char *label, mode_t mask, bool force) +{ + mode_t oldmask; + FILE *fd; + bool good = FALSE; + + if (!force && access(path, F_OK) == 0) + { + DBG1(DBG_LIB, " %s file '%s' already exists", label, path); + return FALSE; + } + oldmask = umask(mask); + fd = fopen(path, "w"); + if (fd) + { + if (fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd) == chunk.len) + { + DBG1(DBG_LIB, " written %s file '%s' (%d bytes)", + label, path, chunk.len); + good = TRUE; + } + else + { + DBG1(DBG_LIB, " writing %s file '%s' failed: %s", + label, path, strerror(errno)); + } + fclose(fd); + } + else + { + DBG1(DBG_LIB, " could not open %s file '%s': %s", label, path, + strerror(errno)); + } + umask(oldmask); + return good; +} + + +/** hex conversion digits */ +static char hexdig_upper[] = "0123456789ABCDEF"; +static char hexdig_lower[] = "0123456789abcdef"; + +/** + * Described in header. + */ +chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase) +{ + int i, len; + char *hexdig = hexdig_lower; + + if (uppercase) + { + hexdig = hexdig_upper; + } + + len = chunk.len * 2; + if (!buf) + { + buf = malloc(len + 1); + } + buf[len] = '\0'; + + for (i = 0; i < chunk.len; i++) + { + buf[i*2] = hexdig[(chunk.ptr[i] >> 4) & 0xF]; + buf[i*2+1] = hexdig[(chunk.ptr[i] ) & 0xF]; + } + return chunk_create(buf, len); +} + +/** + * convert a signle hex character to its binary value + */ +static char hex2bin(char hex) +{ + switch (hex) + { + case '0' ... '9': + return hex - '0'; + case 'A' ... 'F': + return hex - 'A' + 10; + case 'a' ... 'f': + return hex - 'a' + 10; + default: + return 0; + } +} + +/** + * Described in header. + */ +chunk_t chunk_from_hex(chunk_t hex, char *buf) +{ + int i, len; + u_char *ptr; + bool odd = FALSE; + + /* subtract the number of optional ':' separation characters */ + len = hex.len; + ptr = hex.ptr; + for (i = 0; i < hex.len; i++) + { + if (*ptr++ == ':') + { + len--; + } + } + + /* compute the number of binary bytes */ + if (len % 2) + { + odd = TRUE; + len++; + } + len /= 2; + + /* allocate buffer memory unless provided by caller */ + if (!buf) + { + buf = malloc(len); + } + + /* buffer is filled from the right */ + memset(buf, 0, len); + hex.ptr += hex.len; + + for (i = len - 1; i >= 0; i--) + { + /* skip separation characters */ + if (*(--hex.ptr) == ':') + { + --hex.ptr; + } + buf[i] = hex2bin(*hex.ptr); + if (i > 0 || !odd) + { + buf[i] |= hex2bin(*(--hex.ptr)) << 4; + } + } + return chunk_create(buf, len); +} + +/** base 64 conversion digits */ +static char b64digits[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * Described in header. + */ +chunk_t chunk_to_base64(chunk_t chunk, char *buf) +{ + int i, len; + char *pos; + + len = chunk.len + ((3 - chunk.len % 3) % 3); + if (!buf) + { + buf = malloc(len * 4 / 3 + 1); + } + pos = buf; + for (i = 0; i < len; i+=3) + { + *pos++ = b64digits[chunk.ptr[i] >> 2]; + if (i+1 >= chunk.len) + { + *pos++ = b64digits[(chunk.ptr[i] & 0x03) << 4]; + *pos++ = '='; + *pos++ = '='; + break; + } + *pos++ = b64digits[((chunk.ptr[i] & 0x03) << 4) | (chunk.ptr[i+1] >> 4)]; + if (i+2 >= chunk.len) + { + *pos++ = b64digits[(chunk.ptr[i+1] & 0x0F) << 2]; + *pos++ = '='; + break; + } + *pos++ = b64digits[((chunk.ptr[i+1] & 0x0F) << 2) | (chunk.ptr[i+2] >> 6)]; + *pos++ = b64digits[chunk.ptr[i+2] & 0x3F]; + } + *pos = '\0'; + return chunk_create(buf, len * 4 / 3); +} + +/** + * convert a base 64 digit to its binary form (inversion of b64digits array) + */ +static int b642bin(char b64) +{ + switch (b64) + { + case 'A' ... 'Z': + return b64 - 'A'; + case 'a' ... 'z': + return ('Z' - 'A' + 1) + b64 - 'a'; + case '0' ... '9': + return ('Z' - 'A' + 1) + ('z' - 'a' + 1) + b64 - '0'; + case '+': + case '-': + return 62; + case '/': + case '_': + return 63; + case '=': + return 0; + default: + return -1; + } +} + +/** + * Described in header. + */ +chunk_t chunk_from_base64(chunk_t base64, char *buf) +{ + u_char *pos, byte[4]; + int i, j, len, outlen; + + len = base64.len / 4 * 3; + if (!buf) + { + buf = malloc(len); + } + pos = base64.ptr; + outlen = 0; + for (i = 0; i < len; i+=3) + { + outlen += 3; + for (j = 0; j < 4; j++) + { + if (*pos == '=') + { + outlen--; + } + byte[j] = b642bin(*pos++); + } + buf[i] = (byte[0] << 2) | (byte[1] >> 4); + buf[i+1] = (byte[1] << 4) | (byte[2] >> 2); + buf[i+2] = (byte[2] << 6) | (byte[3]); + } + return chunk_create(buf, outlen); +} + +/** base 32 conversion digits */ +static char b32digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + +/** + * Described in header. + */ +chunk_t chunk_to_base32(chunk_t chunk, char *buf) +{ + int i, len; + char *pos; + + len = chunk.len + ((5 - chunk.len % 5) % 5); + if (!buf) + { + buf = malloc(len * 8 / 5 + 1); + } + pos = buf; + for (i = 0; i < len; i+=5) + { + *pos++ = b32digits[chunk.ptr[i] >> 3]; + if (i+1 >= chunk.len) + { + *pos++ = b32digits[(chunk.ptr[i] & 0x07) << 2]; + memset(pos, '=', 6); + pos += 6; + break; + } + *pos++ = b32digits[((chunk.ptr[i] & 0x07) << 2) | + (chunk.ptr[i+1] >> 6)]; + *pos++ = b32digits[(chunk.ptr[i+1] & 0x3E) >> 1]; + if (i+2 >= chunk.len) + { + *pos++ = b32digits[(chunk.ptr[i+1] & 0x01) << 4]; + memset(pos, '=', 4); + pos += 4; + break; + } + *pos++ = b32digits[((chunk.ptr[i+1] & 0x01) << 4) | + (chunk.ptr[i+2] >> 4)]; + if (i+3 >= chunk.len) + { + *pos++ = b32digits[(chunk.ptr[i+2] & 0x0F) << 1]; + memset(pos, '=', 3); + pos += 3; + break; + } + *pos++ = b32digits[((chunk.ptr[i+2] & 0x0F) << 1) | + (chunk.ptr[i+3] >> 7)]; + *pos++ = b32digits[(chunk.ptr[i+3] & 0x7F) >> 2]; + if (i+4 >= chunk.len) + { + *pos++ = b32digits[(chunk.ptr[i+3] & 0x03) << 3]; + *pos++ = '='; + break; + } + *pos++ = b32digits[((chunk.ptr[i+3] & 0x03) << 3) | + (chunk.ptr[i+4] >> 5)]; + *pos++ = b32digits[chunk.ptr[i+4] & 0x1F]; + } + *pos = '\0'; + return chunk_create(buf, len * 8 / 5); +} + +/** + * Described in header. + */ +int chunk_compare(chunk_t a, chunk_t b) +{ + int compare_len = a.len - b.len; + int len = (compare_len < 0)? a.len : b.len; + + if (compare_len != 0 || len == 0) + { + return compare_len; + } + return memcmp(a.ptr, b.ptr, len); +}; + + +/** + * Described in header. + */ +bool chunk_increment(chunk_t chunk) +{ + int i; + + for (i = chunk.len - 1; i >= 0; i--) + { + if (++chunk.ptr[i] != 0) + { + return FALSE; + } + } + return TRUE; +} + +/** + * Remove non-printable characters from a chunk. + */ +bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace) +{ + bool printable = TRUE; + int i; + + if (sane) + { + *sane = chunk_clone(chunk); + } + for (i = 0; i < chunk.len; i++) + { + if (!isprint(chunk.ptr[i])) + { + if (sane) + { + sane->ptr[i] = replace; + } + printable = FALSE; + } + } + return printable; +} + +/** + * Described in header. + * + * The implementation is based on Paul Hsieh's SuperFastHash: + * http://www.azillionmonkeys.com/qed/hash.html + */ +u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash) +{ + u_char *data = chunk.ptr; + size_t len = chunk.len; + u_int32_t tmp; + int rem; + + if (!len || data == NULL) + { + return 0; + } + + rem = len & 3; + len >>= 2; + + /* Main loop */ + for (; len > 0; --len) + { + hash += get16bits(data); + tmp = (get16bits(data + 2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2 * sizeof(u_int16_t); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) + { + case 3: + { + hash += get16bits(data); + hash ^= hash << 16; + hash ^= data[sizeof(u_int16_t)] << 18; + hash += hash >> 11; + break; + } + case 2: + { + hash += get16bits(data); + hash ^= hash << 11; + hash += hash >> 17; + break; + } + case 1: + { + hash += *data; + hash ^= hash << 10; + hash += hash >> 1; + break; + } + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} + +/** + * Described in header. + */ +u_int32_t chunk_hash(chunk_t chunk) +{ + return chunk_hash_inc(chunk, chunk.len); +} + +/** + * Described in header. + */ +int chunk_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, + const void *const *args) +{ + chunk_t *chunk = *((chunk_t**)(args[0])); + bool first = TRUE; + chunk_t copy = *chunk; + int written = 0; + + if (!spec->hash) + { + u_int chunk_len = chunk->len; + const void *new_args[] = {&chunk->ptr, &chunk_len}; + return mem_printf_hook(data, spec, new_args); + } + + while (copy.len > 0) + { + if (first) + { + first = FALSE; + } + else + { + written += print_in_hook(data, ":"); + } + written += print_in_hook(data, "%02x", *copy.ptr++); + copy.len--; + } + return written; +} diff --git a/src/libstrongswan/utils/chunk.h b/src/libstrongswan/utils/chunk.h new file mode 100644 index 000000000..865c1b82f --- /dev/null +++ b/src/libstrongswan/utils/chunk.h @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2008-2009 Tobias Brunner + * Copyright (C) 2005-2008 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup chunk chunk + * @{ @ingroup utils + */ + +#ifndef CHUNK_H_ +#define CHUNK_H_ + +#include <string.h> +#include <stdarg.h> +#include <sys/types.h> +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif + +typedef struct chunk_t chunk_t; + +/** + * General purpose pointer/length abstraction. + */ +struct chunk_t { + /** Pointer to start of data */ + u_char *ptr; + /** Length of data in bytes */ + size_t len; +}; + +#include "../utils.h" + +/** + * A { NULL, 0 }-chunk handy for initialization. + */ +extern chunk_t chunk_empty; + +/** + * Create a new chunk pointing to "ptr" with length "len" + */ +static inline chunk_t chunk_create(u_char *ptr, size_t len) +{ + chunk_t chunk = {ptr, len}; + return chunk; +} + +/** + * Create a clone of a chunk pointing to "ptr" + */ +chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk); + +/** + * Calculate length of multiple chunks + */ +size_t chunk_length(const char *mode, ...); + +/** + * Concatenate chunks into a chunk pointing to "ptr". + * + * The mode string specifies the number of chunks, and how to handle each of + * them with a single character: 'c' for copy (allocate new chunk), 'm' for move + * (free given chunk) or 's' for sensitive-move (clear given chunk, then free). + */ +chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...); + +/** + * Split up a chunk into parts, "mode" is a string of "a" (alloc), + * "c" (copy) and "m" (move). Each letter say for the corresponding chunk if + * it should get allocated on heap, copied into existing chunk, or the chunk + * should point into "chunk". The length of each part is an argument before + * each target chunk. E.g.: + * chunk_split(chunk, "mcac", 3, &a, 7, &b, 5, &c, d.len, &d); + */ +void chunk_split(chunk_t chunk, const char *mode, ...); + +/** + * Write the binary contents of a chunk_t to a file + * + * @param chunk contents to write to file + * @param path path where file is written to + * @param label label specifying file type + * @param mask file mode creation mask + * @param force overwrite existing file by force + * @return TRUE if write operation was successful + */ +bool chunk_write(chunk_t chunk, char *path, char *label, mode_t mask, bool force); + +/** + * Convert a chunk of data to hex encoding. + * + * The resulting string is '\\0' terminated, but the chunk does not include + * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 2 + 1). + * + * @param chunk data to convert to hex encoding + * @param buf buffer to write to, NULL to malloc + * @param uppercase TRUE to use uppercase letters + * @return chunk of encoded data + */ +chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase); + +/** + * Convert a hex encoded in a binary chunk. + * + * If buf is supplied, it must hold at least (hex.len / 2) + (hex.len % 2) + * bytes. It is filled by the right to give correct values for short inputs. + * + * @param hex hex encoded input data + * @param buf buffer to write decoded data, NULL to malloc + * @return converted data + */ +chunk_t chunk_from_hex(chunk_t hex, char *buf); + +/** + * Convert a chunk of data to its base64 encoding. + * + * The resulting string is '\\0' terminated, but the chunk does not include + * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 4 / 3 + 1). + * + * @param chunk data to convert + * @param buf buffer to write to, NULL to malloc + * @return chunk of encoded data + */ +chunk_t chunk_to_base64(chunk_t chunk, char *buf); + +/** + * Convert a base64 in a binary chunk. + * + * If buf is supplied, it must hold at least (base64.len / 4 * 3). + * + * @param base64 base64 encoded input data + * @param buf buffer to write decoded data, NULL to malloc + * @return converted data + */ +chunk_t chunk_from_base64(chunk_t base64, char *buf); + +/** + * Convert a chunk of data to its base32 encoding. + * + * The resulting string is '\\0' terminated, but the chunk does not include + * the '\\0'. If buf is supplied, it must hold (chunk.len * 8 / 5 + 1) bytes. + * + * @param chunk data to convert + * @param buf buffer to write to, NULL to malloc + * @return chunk of encoded data + */ +chunk_t chunk_to_base32(chunk_t chunk, char *buf); + +/** + * Free contents of a chunk + */ +static inline void chunk_free(chunk_t *chunk) +{ + free(chunk->ptr); + *chunk = chunk_empty; +} + +/** + * Overwrite the contents of a chunk and free it + */ +static inline void chunk_clear(chunk_t *chunk) +{ + if (chunk->ptr) + { + memwipe(chunk->ptr, chunk->len); + chunk_free(chunk); + } +} + +/** + * Initialize a chunk using a char array + */ +#define chunk_from_chars(...) ((chunk_t){(char[]){__VA_ARGS__}, sizeof((char[]){__VA_ARGS__})}) + +/** + * Initialize a chunk to point to a thing + */ +#define chunk_from_thing(thing) chunk_create((char*)&(thing), sizeof(thing)) + +/** + * Allocate a chunk on the heap + */ +#define chunk_alloc(bytes) ({size_t x = (bytes); chunk_create(x ? malloc(x) : NULL, x);}) + +/** + * Allocate a chunk on the stack + */ +#define chunk_alloca(bytes) ({size_t x = (bytes); chunk_create(x ? alloca(x) : NULL, x);}) + +/** + * Clone a chunk on heap + */ +#define chunk_clone(chunk) ({chunk_t x = (chunk); chunk_create_clone(x.len ? malloc(x.len) : NULL, x);}) + +/** + * Clone a chunk on stack + */ +#define chunk_clonea(chunk) ({chunk_t x = (chunk); chunk_create_clone(x.len ? alloca(x.len) : NULL, x);}) + +/** + * Concatenate chunks into a chunk on heap + */ +#define chunk_cat(mode, ...) chunk_create_cat(malloc(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__) + +/** + * Concatenate chunks into a chunk on stack + */ +#define chunk_cata(mode, ...) chunk_create_cat(alloca(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__) + +/** + * Skip n bytes in chunk (forward pointer, shorten length) + */ +static inline chunk_t chunk_skip(chunk_t chunk, size_t bytes) +{ + if (chunk.len > bytes) + { + chunk.ptr += bytes; + chunk.len -= bytes; + return chunk; + } + return chunk_empty; +} + +/** + * Skip a leading zero-valued byte + */ +static inline chunk_t chunk_skip_zero(chunk_t chunk) +{ + if (chunk.len > 1 && *chunk.ptr == 0x00) + { + chunk.ptr++; + chunk.len--; + } + return chunk; +} + + +/** + * Compare two chunks, returns zero if a equals b + * or negative/positive if a is small/greater than b + */ +int chunk_compare(chunk_t a, chunk_t b); + +/** + * Compare two chunks for equality, + * NULL chunks are never equal. + */ +static inline bool chunk_equals(chunk_t a, chunk_t b) +{ + return a.ptr != NULL && b.ptr != NULL && + a.len == b.len && memeq(a.ptr, b.ptr, a.len); +} + +/** + * Compare two chunks (given as pointers) for equality (useful as callback), + * NULL chunks are never equal. + */ +static inline bool chunk_equals_ptr(chunk_t *a, chunk_t *b) +{ + return a != NULL && b != NULL && chunk_equals(*a, *b); +} + +/** + * Increment a chunk, as it would reprensent a network order integer. + * + * @param chunk chunk to increment + * @return TRUE if an overflow occurred + */ +bool chunk_increment(chunk_t chunk); + +/** + * Check if a chunk has printable characters only. + * + * If sane is given, chunk is cloned into sane and all non printable characters + * get replaced by "replace". + * + * @param chunk chunk to check for printability + * @param sane pointer where sane version is allocated, or NULL + * @param replace character to use for replaceing unprintable characters + * @return TRUE if all characters in chunk are printable + */ +bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace); + +/** + * Computes a 32 bit hash of the given chunk. + * Note: This hash is only intended for hash tables not for cryptographic purposes. + */ +u_int32_t chunk_hash(chunk_t chunk); + +/** + * Incremental version of chunk_hash. Use this to hash two or more chunks. + */ +u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash); + +/** + * printf hook function for chunk_t. + * + * Arguments are: + * chunk_t *chunk + * Use #-modifier to print a compact version + */ +int chunk_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, + const void *const *args); + +#endif /** CHUNK_H_ @}*/ diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index 8b2173afb..cdf229127 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -29,7 +29,7 @@ typedef struct identification_t identification_t; typedef enum id_match_t id_match_t; typedef enum id_part_t id_part_t; -#include <chunk.h> +#include <utils/chunk.h> #include <collections/enumerator.h> /** |