memory: Move memory manipulation related functions to separate files
This commit is contained in:
@@ -40,7 +40,7 @@ settings/settings_parser.c settings/settings_lexer.c utils/cpu_feature.c \
|
||||
utils/utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.c \
|
||||
utils/lexparser.c utils/optionsfrom.c utils/capabilities.c utils/backtrace.c \
|
||||
utils/parser_helper.c utils/test.c utils/process.c utils/utils/strerror.c \
|
||||
utils/utils/atomics.c utils/utils/string.c
|
||||
utils/utils/atomics.c utils/utils/string.c utils/utils/memory.c
|
||||
|
||||
libstrongswan_la_SOURCES += \
|
||||
threading/thread.c \
|
||||
|
||||
@@ -38,7 +38,7 @@ settings/settings_parser.y settings/settings_lexer.l utils/cpu_feature.c \
|
||||
utils/utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.c \
|
||||
utils/lexparser.c utils/optionsfrom.c utils/capabilities.c utils/backtrace.c \
|
||||
utils/parser_helper.c utils/test.c utils/process.c utils/utils/strerror.c \
|
||||
utils/utils/atomics.c utils/utils/string.c
|
||||
utils/utils/atomics.c utils/utils/string.c utils/utils/memory.c
|
||||
|
||||
if !USE_WINDOWS
|
||||
libstrongswan_la_SOURCES += \
|
||||
@@ -109,7 +109,7 @@ utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
|
||||
utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \
|
||||
utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h \
|
||||
utils/utils/atomics.h utils/utils/types.h utils/utils/byteorder.h \
|
||||
utils/utils/string.h
|
||||
utils/utils/string.h utils/utils/memory.h
|
||||
endif
|
||||
|
||||
library.lo : $(top_builddir)/config.status
|
||||
|
||||
@@ -101,120 +101,6 @@ void free_align(void *ptr)
|
||||
free(ptr - pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void memxor(u_int8_t dst[], u_int8_t src[], size_t n)
|
||||
{
|
||||
int m, i;
|
||||
|
||||
/* byte wise XOR until dst aligned */
|
||||
for (i = 0; (uintptr_t)&dst[i] % sizeof(long) && i < n; i++)
|
||||
{
|
||||
dst[i] ^= src[i];
|
||||
}
|
||||
/* try to use words if src shares an aligment with dst */
|
||||
switch (((uintptr_t)&src[i] % sizeof(long)))
|
||||
{
|
||||
case 0:
|
||||
for (m = n - sizeof(long); i <= m; i += sizeof(long))
|
||||
{
|
||||
*(long*)&dst[i] ^= *(long*)&src[i];
|
||||
}
|
||||
break;
|
||||
case sizeof(int):
|
||||
for (m = n - sizeof(int); i <= m; i += sizeof(int))
|
||||
{
|
||||
*(int*)&dst[i] ^= *(int*)&src[i];
|
||||
}
|
||||
break;
|
||||
case sizeof(short):
|
||||
for (m = n - sizeof(short); i <= m; i += sizeof(short))
|
||||
{
|
||||
*(short*)&dst[i] ^= *(short*)&src[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* byte wise XOR of the rest */
|
||||
for (; i < n; i++)
|
||||
{
|
||||
dst[i] ^= src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void memwipe_noinline(void *ptr, size_t n)
|
||||
{
|
||||
memwipe_inline(ptr, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
bool memeq_const(const void *x, const void *y, size_t len)
|
||||
{
|
||||
const u_char *a, *b;
|
||||
u_int bad = 0;
|
||||
size_t i;
|
||||
|
||||
a = (const u_char*)x;
|
||||
b = (const u_char*)y;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
bad |= a[i] != b[i];
|
||||
}
|
||||
return !bad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void *memstr(const void *haystack, const char *needle, size_t n)
|
||||
{
|
||||
const u_char *pos = haystack;
|
||||
size_t l;
|
||||
|
||||
if (!haystack || !needle || (l = strlen(needle)) == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
for (; n >= l; ++pos, --n)
|
||||
{
|
||||
if (memeq(pos, needle, l))
|
||||
{
|
||||
return (void*)pos;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void *utils_memrchr(const void *s, int c, size_t n)
|
||||
{
|
||||
const u_char *pos;
|
||||
|
||||
if (!s || !n)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (pos = s + n - 1; pos >= (u_char*)s; pos--)
|
||||
{
|
||||
if (*pos == (u_char)c)
|
||||
{
|
||||
return (void*)pos;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
/**
|
||||
@@ -649,50 +535,6 @@ void nop()
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HAVE_FMEMOPEN_FALLBACK
|
||||
|
||||
static int fmemread(chunk_t *cookie, char *buf, int size)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = min(size, cookie->len);
|
||||
memcpy(buf, cookie->ptr, len);
|
||||
*cookie = chunk_skip(*cookie, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int fmemwrite(chunk_t *cookie, const char *buf, int size)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = min(size, cookie->len);
|
||||
memcpy(cookie->ptr, buf, len);
|
||||
*cookie = chunk_skip(*cookie, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int fmemclose(void *cookie)
|
||||
{
|
||||
free(cookie);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fmemopen(void *buf, size_t size, const char *mode)
|
||||
{
|
||||
chunk_t *cookie;
|
||||
|
||||
INIT(cookie,
|
||||
.ptr = buf,
|
||||
.len = size,
|
||||
);
|
||||
|
||||
return funopen(cookie, (void*)fmemread, (void*)fmemwrite, NULL, fmemclose);
|
||||
}
|
||||
|
||||
#endif /* FMEMOPEN fallback*/
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
@@ -781,64 +623,3 @@ int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
|
||||
return print_in_hook(data, "%" PRIu64 " %s%s", delta, unit,
|
||||
(delta == 1) ? "" : "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of bytes per line to dump raw data
|
||||
*/
|
||||
#define BYTES_PER_LINE 16
|
||||
|
||||
static char hexdig_upper[] = "0123456789ABCDEF";
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
int mem_printf_hook(printf_hook_data_t *data,
|
||||
printf_hook_spec_t *spec, const void *const *args)
|
||||
{
|
||||
char *bytes = *((void**)(args[0]));
|
||||
u_int len = *((int*)(args[1]));
|
||||
|
||||
char buffer[BYTES_PER_LINE * 3];
|
||||
char ascii_buffer[BYTES_PER_LINE + 1];
|
||||
char *buffer_pos = buffer;
|
||||
char *bytes_pos = bytes;
|
||||
char *bytes_roof = bytes + len;
|
||||
int line_start = 0;
|
||||
int i = 0;
|
||||
int written = 0;
|
||||
|
||||
written += print_in_hook(data, "=> %u bytes @ %p", len, bytes);
|
||||
|
||||
while (bytes_pos < bytes_roof)
|
||||
{
|
||||
*buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
|
||||
*buffer_pos++ = hexdig_upper[ *bytes_pos & 0xF];
|
||||
|
||||
ascii_buffer[i++] =
|
||||
(*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
|
||||
|
||||
if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE)
|
||||
{
|
||||
int padding = 3 * (BYTES_PER_LINE - i);
|
||||
|
||||
while (padding--)
|
||||
{
|
||||
*buffer_pos++ = ' ';
|
||||
}
|
||||
*buffer_pos++ = '\0';
|
||||
ascii_buffer[i] = '\0';
|
||||
|
||||
written += print_in_hook(data, "\n%4d: %s %s",
|
||||
line_start, buffer, ascii_buffer);
|
||||
|
||||
buffer_pos = buffer;
|
||||
line_start += BYTES_PER_LINE;
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*buffer_pos++ = ' ';
|
||||
}
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "utils/atomics.h"
|
||||
#include "utils/byteorder.h"
|
||||
#include "utils/string.h"
|
||||
#include "utils/memory.h"
|
||||
#include "utils/strerror.h"
|
||||
#ifdef __APPLE__
|
||||
# include "compat/apple.h"
|
||||
@@ -103,61 +104,6 @@ void utils_init();
|
||||
*/
|
||||
void utils_deinit();
|
||||
|
||||
/**
|
||||
* Helper function that compares two binary blobs for equality
|
||||
*/
|
||||
static inline bool memeq(const void *x, const void *y, size_t len)
|
||||
{
|
||||
return memcmp(x, y, len) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as memeq(), but with a constant runtime, safe for cryptographic use.
|
||||
*/
|
||||
bool memeq_const(const void *x, const void *y, size_t len);
|
||||
|
||||
/**
|
||||
* Calling memcpy() with NULL pointers, even with n == 0, results in undefined
|
||||
* behavior according to the C standard. This version is guaranteed to not
|
||||
* access the pointers if n is 0.
|
||||
*/
|
||||
static inline void *memcpy_noop(void *dst, const void *src, size_t n)
|
||||
{
|
||||
return n ? memcpy(dst, src, n) : dst;
|
||||
}
|
||||
#ifdef memcpy
|
||||
# undef memcpy
|
||||
#endif
|
||||
#define memcpy(d,s,n) memcpy_noop(d,s,n)
|
||||
|
||||
/**
|
||||
* Calling memmove() with NULL pointers, even with n == 0, results in undefined
|
||||
* behavior according to the C standard. This version is guaranteed to not
|
||||
* access the pointers if n is 0.
|
||||
*/
|
||||
static inline void *memmove_noop(void *dst, const void *src, size_t n)
|
||||
{
|
||||
return n ? memmove(dst, src, n) : dst;
|
||||
}
|
||||
#ifdef memmove
|
||||
# undef memmove
|
||||
#endif
|
||||
#define memmove(d,s,n) memmove_noop(d,s,n)
|
||||
|
||||
/**
|
||||
* Calling memset() with a NULL pointer, even with n == 0, results in undefined
|
||||
* behavior according to the C standard. This version is guaranteed to not
|
||||
* access the pointer if n is 0.
|
||||
*/
|
||||
static inline void *memset_noop(void *s, int c, size_t n)
|
||||
{
|
||||
return n ? memset(s, c, n) : s;
|
||||
}
|
||||
#ifdef memset
|
||||
# undef memset
|
||||
#endif
|
||||
#define memset(s,c,n) memset_noop(s,c,n)
|
||||
|
||||
/**
|
||||
* Macro gives back larger of two values.
|
||||
*/
|
||||
@@ -477,83 +423,6 @@ void* malloc_align(size_t size, u_int8_t align);
|
||||
*/
|
||||
void free_align(void *ptr);
|
||||
|
||||
/**
|
||||
* Same as memcpy, but XORs src into dst instead of copy
|
||||
*/
|
||||
void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
|
||||
|
||||
/**
|
||||
* Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
|
||||
*/
|
||||
void memwipe_noinline(void *ptr, size_t n);
|
||||
|
||||
/**
|
||||
* Safely overwrite n bytes of memory at ptr with zero, inlining variant.
|
||||
*/
|
||||
static inline void memwipe_inline(void *ptr, size_t n)
|
||||
{
|
||||
volatile char *c = (volatile char*)ptr;
|
||||
size_t m, i;
|
||||
|
||||
/* byte wise until long aligned */
|
||||
for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
/* word wise */
|
||||
if (n >= sizeof(long))
|
||||
{
|
||||
for (m = n - sizeof(long); i <= m; i += sizeof(long))
|
||||
{
|
||||
*(volatile long*)&c[i] = 0;
|
||||
}
|
||||
}
|
||||
/* byte wise of the rest */
|
||||
for (; i < n; i++)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
|
||||
*/
|
||||
static inline void memwipe(void *ptr, size_t n)
|
||||
{
|
||||
if (!ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (__builtin_constant_p(n))
|
||||
{
|
||||
memwipe_inline(ptr, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
memwipe_noinline(ptr, n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A variant of strstr with the characteristics of memchr, where haystack is not
|
||||
* a null-terminated string but simply a memory area of length n.
|
||||
*/
|
||||
void *memstr(const void *haystack, const char *needle, size_t n);
|
||||
|
||||
/**
|
||||
* Replacement for memrchr(3) if it is not provided by the C library.
|
||||
*
|
||||
* @param s start of the memory area to search
|
||||
* @param c character to search
|
||||
* @param n length of memory area to search
|
||||
* @return pointer to the found character or NULL
|
||||
*/
|
||||
void *utils_memrchr(const void *s, int c, size_t n);
|
||||
|
||||
#ifndef HAVE_MEMRCHR
|
||||
#define memrchr(s,c,n) utils_memrchr(s,c,n)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Portable function to wait for SIGINT/SIGTERM (or equivalent).
|
||||
*/
|
||||
@@ -696,23 +565,6 @@ static inline size_t round_down(size_t size, size_t alignment)
|
||||
return size - (size % alignment);
|
||||
}
|
||||
|
||||
#ifndef HAVE_FMEMOPEN
|
||||
# ifdef HAVE_FUNOPEN
|
||||
# define HAVE_FMEMOPEN
|
||||
# define HAVE_FMEMOPEN_FALLBACK
|
||||
# include <stdio.h>
|
||||
/**
|
||||
* fmemopen(3) fallback using BSD funopen.
|
||||
*
|
||||
* We could also provide one using fopencookie(), but should we have it we
|
||||
* most likely have fmemopen().
|
||||
*
|
||||
* fseek() is currently not supported.
|
||||
*/
|
||||
FILE *fmemopen(void *buf, size_t size, const char *mode);
|
||||
# endif /* FUNOPEN */
|
||||
#endif /* FMEMOPEN */
|
||||
|
||||
/**
|
||||
* printf hook for time_t.
|
||||
*
|
||||
@@ -731,13 +583,4 @@ int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
|
||||
int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
|
||||
const void *const *args);
|
||||
|
||||
/**
|
||||
* printf hook for memory areas.
|
||||
*
|
||||
* Arguments are:
|
||||
* u_char *ptr, u_int len
|
||||
*/
|
||||
int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
|
||||
const void *const *args);
|
||||
|
||||
#endif /** UTILS_H_ @}*/
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 Tobias Brunner
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* 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 <utils/utils.h>
|
||||
#include <utils/chunk.h>
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void memxor(u_int8_t dst[], u_int8_t src[], size_t n)
|
||||
{
|
||||
int m, i;
|
||||
|
||||
/* byte wise XOR until dst aligned */
|
||||
for (i = 0; (uintptr_t)&dst[i] % sizeof(long) && i < n; i++)
|
||||
{
|
||||
dst[i] ^= src[i];
|
||||
}
|
||||
/* try to use words if src shares an aligment with dst */
|
||||
switch (((uintptr_t)&src[i] % sizeof(long)))
|
||||
{
|
||||
case 0:
|
||||
for (m = n - sizeof(long); i <= m; i += sizeof(long))
|
||||
{
|
||||
*(long*)&dst[i] ^= *(long*)&src[i];
|
||||
}
|
||||
break;
|
||||
case sizeof(int):
|
||||
for (m = n - sizeof(int); i <= m; i += sizeof(int))
|
||||
{
|
||||
*(int*)&dst[i] ^= *(int*)&src[i];
|
||||
}
|
||||
break;
|
||||
case sizeof(short):
|
||||
for (m = n - sizeof(short); i <= m; i += sizeof(short))
|
||||
{
|
||||
*(short*)&dst[i] ^= *(short*)&src[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* byte wise XOR of the rest */
|
||||
for (; i < n; i++)
|
||||
{
|
||||
dst[i] ^= src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void memwipe_noinline(void *ptr, size_t n)
|
||||
{
|
||||
memwipe_inline(ptr, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
bool memeq_const(const void *x, const void *y, size_t len)
|
||||
{
|
||||
const u_char *a, *b;
|
||||
u_int bad = 0;
|
||||
size_t i;
|
||||
|
||||
a = (const u_char*)x;
|
||||
b = (const u_char*)y;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
bad |= a[i] != b[i];
|
||||
}
|
||||
return !bad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void *memstr(const void *haystack, const char *needle, size_t n)
|
||||
{
|
||||
const u_char *pos = haystack;
|
||||
size_t l;
|
||||
|
||||
if (!haystack || !needle || (l = strlen(needle)) == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
for (; n >= l; ++pos, --n)
|
||||
{
|
||||
if (memeq(pos, needle, l))
|
||||
{
|
||||
return (void*)pos;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void *utils_memrchr(const void *s, int c, size_t n)
|
||||
{
|
||||
const u_char *pos;
|
||||
|
||||
if (!s || !n)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (pos = s + n - 1; pos >= (u_char*)s; pos--)
|
||||
{
|
||||
if (*pos == (u_char)c)
|
||||
{
|
||||
return (void*)pos;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FMEMOPEN_FALLBACK
|
||||
|
||||
static int fmemread(chunk_t *cookie, char *buf, int size)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = min(size, cookie->len);
|
||||
memcpy(buf, cookie->ptr, len);
|
||||
*cookie = chunk_skip(*cookie, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int fmemwrite(chunk_t *cookie, const char *buf, int size)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = min(size, cookie->len);
|
||||
memcpy(cookie->ptr, buf, len);
|
||||
*cookie = chunk_skip(*cookie, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int fmemclose(void *cookie)
|
||||
{
|
||||
free(cookie);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fmemopen(void *buf, size_t size, const char *mode)
|
||||
{
|
||||
chunk_t *cookie;
|
||||
|
||||
INIT(cookie,
|
||||
.ptr = buf,
|
||||
.len = size,
|
||||
);
|
||||
|
||||
return funopen(cookie, (void*)fmemread, (void*)fmemwrite, NULL, fmemclose);
|
||||
}
|
||||
|
||||
#endif /* FMEMOPEN fallback*/
|
||||
|
||||
/**
|
||||
* Number of bytes per line to dump raw data
|
||||
*/
|
||||
#define BYTES_PER_LINE 16
|
||||
|
||||
static char hexdig_upper[] = "0123456789ABCDEF";
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
int mem_printf_hook(printf_hook_data_t *data,
|
||||
printf_hook_spec_t *spec, const void *const *args)
|
||||
{
|
||||
char *bytes = *((void**)(args[0]));
|
||||
u_int len = *((int*)(args[1]));
|
||||
|
||||
char buffer[BYTES_PER_LINE * 3];
|
||||
char ascii_buffer[BYTES_PER_LINE + 1];
|
||||
char *buffer_pos = buffer;
|
||||
char *bytes_pos = bytes;
|
||||
char *bytes_roof = bytes + len;
|
||||
int line_start = 0;
|
||||
int i = 0;
|
||||
int written = 0;
|
||||
|
||||
written += print_in_hook(data, "=> %u bytes @ %p", len, bytes);
|
||||
|
||||
while (bytes_pos < bytes_roof)
|
||||
{
|
||||
*buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
|
||||
*buffer_pos++ = hexdig_upper[ *bytes_pos & 0xF];
|
||||
|
||||
ascii_buffer[i++] =
|
||||
(*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
|
||||
|
||||
if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE)
|
||||
{
|
||||
int padding = 3 * (BYTES_PER_LINE - i);
|
||||
|
||||
while (padding--)
|
||||
{
|
||||
*buffer_pos++ = ' ';
|
||||
}
|
||||
*buffer_pos++ = '\0';
|
||||
ascii_buffer[i] = '\0';
|
||||
|
||||
written += print_in_hook(data, "\n%4d: %s %s",
|
||||
line_start, buffer, ascii_buffer);
|
||||
|
||||
buffer_pos = buffer;
|
||||
line_start += BYTES_PER_LINE;
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*buffer_pos++ = ' ';
|
||||
}
|
||||
}
|
||||
return written;
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* 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 memory_i memory
|
||||
* @{ @ingroup utils_i
|
||||
*/
|
||||
|
||||
#ifndef MEMORY_H_
|
||||
#define MEMORY_H_
|
||||
|
||||
/**
|
||||
* Helper function that compares two binary blobs for equality
|
||||
*/
|
||||
static inline bool memeq(const void *x, const void *y, size_t len)
|
||||
{
|
||||
return memcmp(x, y, len) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as memeq(), but with a constant runtime, safe for cryptographic use.
|
||||
*/
|
||||
bool memeq_const(const void *x, const void *y, size_t len);
|
||||
|
||||
/**
|
||||
* Calling memcpy() with NULL pointers, even with n == 0, results in undefined
|
||||
* behavior according to the C standard. This version is guaranteed to not
|
||||
* access the pointers if n is 0.
|
||||
*/
|
||||
static inline void *memcpy_noop(void *dst, const void *src, size_t n)
|
||||
{
|
||||
return n ? memcpy(dst, src, n) : dst;
|
||||
}
|
||||
#ifdef memcpy
|
||||
# undef memcpy
|
||||
#endif
|
||||
#define memcpy(d,s,n) memcpy_noop(d,s,n)
|
||||
|
||||
/**
|
||||
* Calling memmove() with NULL pointers, even with n == 0, results in undefined
|
||||
* behavior according to the C standard. This version is guaranteed to not
|
||||
* access the pointers if n is 0.
|
||||
*/
|
||||
static inline void *memmove_noop(void *dst, const void *src, size_t n)
|
||||
{
|
||||
return n ? memmove(dst, src, n) : dst;
|
||||
}
|
||||
#ifdef memmove
|
||||
# undef memmove
|
||||
#endif
|
||||
#define memmove(d,s,n) memmove_noop(d,s,n)
|
||||
|
||||
/**
|
||||
* Calling memset() with a NULL pointer, even with n == 0, results in undefined
|
||||
* behavior according to the C standard. This version is guaranteed to not
|
||||
* access the pointer if n is 0.
|
||||
*/
|
||||
static inline void *memset_noop(void *s, int c, size_t n)
|
||||
{
|
||||
return n ? memset(s, c, n) : s;
|
||||
}
|
||||
#ifdef memset
|
||||
# undef memset
|
||||
#endif
|
||||
#define memset(s,c,n) memset_noop(s,c,n)
|
||||
|
||||
/**
|
||||
* Same as memcpy, but XORs src into dst instead of copy
|
||||
*/
|
||||
void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
|
||||
|
||||
/**
|
||||
* Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
|
||||
*/
|
||||
void memwipe_noinline(void *ptr, size_t n);
|
||||
|
||||
/**
|
||||
* Safely overwrite n bytes of memory at ptr with zero, inlining variant.
|
||||
*/
|
||||
static inline void memwipe_inline(void *ptr, size_t n)
|
||||
{
|
||||
volatile char *c = (volatile char*)ptr;
|
||||
size_t m, i;
|
||||
|
||||
/* byte wise until long aligned */
|
||||
for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
/* word wise */
|
||||
if (n >= sizeof(long))
|
||||
{
|
||||
for (m = n - sizeof(long); i <= m; i += sizeof(long))
|
||||
{
|
||||
*(volatile long*)&c[i] = 0;
|
||||
}
|
||||
}
|
||||
/* byte wise of the rest */
|
||||
for (; i < n; i++)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
|
||||
*/
|
||||
static inline void memwipe(void *ptr, size_t n)
|
||||
{
|
||||
if (!ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (__builtin_constant_p(n))
|
||||
{
|
||||
memwipe_inline(ptr, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
memwipe_noinline(ptr, n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A variant of strstr with the characteristics of memchr, where haystack is not
|
||||
* a null-terminated string but simply a memory area of length n.
|
||||
*/
|
||||
void *memstr(const void *haystack, const char *needle, size_t n);
|
||||
|
||||
/**
|
||||
* Replacement for memrchr(3) if it is not provided by the C library.
|
||||
*
|
||||
* @param s start of the memory area to search
|
||||
* @param c character to search
|
||||
* @param n length of memory area to search
|
||||
* @return pointer to the found character or NULL
|
||||
*/
|
||||
void *utils_memrchr(const void *s, int c, size_t n);
|
||||
|
||||
#ifndef HAVE_MEMRCHR
|
||||
#define memrchr(s,c,n) utils_memrchr(s,c,n)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FMEMOPEN
|
||||
# ifdef HAVE_FUNOPEN
|
||||
# define HAVE_FMEMOPEN
|
||||
# define HAVE_FMEMOPEN_FALLBACK
|
||||
# include <stdio.h>
|
||||
/**
|
||||
* fmemopen(3) fallback using BSD funopen.
|
||||
*
|
||||
* We could also provide one using fopencookie(), but should we have it we
|
||||
* most likely have fmemopen().
|
||||
*
|
||||
* fseek() is currently not supported.
|
||||
*/
|
||||
FILE *fmemopen(void *buf, size_t size, const char *mode);
|
||||
# endif /* FUNOPEN */
|
||||
#endif /* FMEMOPEN */
|
||||
|
||||
/**
|
||||
* printf hook for memory areas.
|
||||
*
|
||||
* Arguments are:
|
||||
* u_char *ptr, u_int len
|
||||
*/
|
||||
int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
|
||||
const void *const *args);
|
||||
|
||||
#endif /** MEMORY_H_ @} */
|
||||
Reference in New Issue
Block a user