Files
strongswan-ext/src/libstrongswan/utils.h
T
Tobias Brunner fac3bfa5cd Fixing some includes by replacing <> with "".
I changed only the includes needed to fix the build on Android, which has an utils.h system header file, but we should probably change all the local includes in libstrongswan to "" and relative paths.
2010-03-02 10:38:58 +01:00

475 lines
10 KiB
C

/*
* Copyright (C) 2008-2009 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 utils utils
* @{ @ingroup libstrongswan
*/
#ifndef UTILS_H_
#define UTILS_H_
#include <sys/types.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <string.h>
#include "enum.h"
/**
* strongSwan program return codes
*/
#define SS_RC_LIBSTRONGSWAN_INTEGRITY 64
#define SS_RC_DAEMON_INTEGRITY 65
#define SS_RC_INITIALIZATION_FAILED 66
#define SS_RC_FIRST SS_RC_LIBSTRONGSWAN_INTEGRITY
#define SS_RC_LAST SS_RC_INITIALIZATION_FAILED
/**
* Number of bits in a byte
*/
#define BITS_PER_BYTE 8
/**
* Default length for various auxiliary text buffers
*/
#define BUF_LEN 512
/**
* Macro compares two strings for equality
*/
#define streq(x,y) (strcmp(x, y) == 0)
/**
* Macro compares two strings for equality
*/
#define strneq(x,y,len) (strncmp(x, y, len) == 0)
/**
* Macro compares two strings for equality ignoring case
*/
#define strcaseeq(x,y) (strcasecmp(x, y) == 0)
/**
* Macro compares two binary blobs for equality
*/
#define memeq(x,y,len) (memcmp(x, y, len) == 0)
/**
* Macro gives back larger of two values.
*/
#define max(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
_x > _y ? _x : _y; })
/**
* Macro gives back smaller of two values.
*/
#define min(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
_x < _y ? _x : _y; })
/**
* Call destructor of an object, if object != NULL
*/
#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
/**
* Call offset destructor of an object, if object != NULL
*/
#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
/**
* Call function destructor of an object, if object != NULL
*/
#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
/**
* Debug macro to follow control flow
*/
#define POS printf("%s, line %d\n", __FILE__, __LINE__)
/**
* Object allocation/initialization macro, using designated initializer.
*/
#define INIT(this, ...) { (this) = malloc(sizeof(*this)); \
*(this) = (typeof(*this)){ __VA_ARGS__ }; }
/**
* Method declaration/definition macro, providing private and public interface.
*
* Defines a method name with this as first parameter and a return value ret,
* and an alias for this method with a _ prefix, having the this argument
* safely casted to the public interface iface.
* _name is provided a function pointer, but will get optimized out by GCC.
*/
#define METHOD(iface, name, ret, this, ...) \
static ret name(union {iface *_public; this;} \
__attribute__((transparent_union)), ##__VA_ARGS__); \
const static typeof(name) *_##name = (const typeof(name)*)name; \
static ret name(this, ##__VA_ARGS__)
/**
* Same as METHOD(), but is defined for two public interfaces.
*/
#define METHOD2(iface1, iface2, name, ret, this, ...) \
static ret name(union {iface1 *_public1; iface2 *_public2; this;} \
__attribute__((transparent_union)), ##__VA_ARGS__); \
const static typeof(name) *_##name = (const typeof(name)*)name; \
static ret name(this, ##__VA_ARGS__)
/**
* Macro to allocate a sized type.
*/
#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
/**
* Get the number of elements in an array
*/
#define countof(array) (sizeof(array)/sizeof(array[0]))
/**
* Ignore result of functions tagged with warn_unused_result attributes
*/
#define ignore_result(call) { if(call); }
/**
* Assign a function as a class method
*/
#define ASSIGN(method, function) (method = (typeof(method))function)
/**
* time_t not defined
*/
#define UNDEFINED_TIME 0
/**
* Maximum time since epoch causing wrap-around on Jan 19 03:14:07 UTC 2038
*/
#define TIME_32_BIT_SIGNED_MAX 0x7fffffff
/**
* General purpose boolean type.
*/
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#else
# ifndef HAVE__BOOL
# define _Bool signed char
# endif /* HAVE__BOOL */
# define bool _Bool
# define false 0
# define true 1
# define __bool_true_false_are_defined 1
#endif /* HAVE_STDBOOL_H */
#ifndef FALSE
# define FALSE false
#endif /* FALSE */
#ifndef TRUE
# define TRUE true
#endif /* TRUE */
/**
* define some missing fixed width int types on OpenSolaris.
* TODO: since the uintXX_t types are defined by the C99 standard we should
* probably use those anyway
*/
#ifdef __sun
#include <stdint.h>
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
typedef uint64_t u_int64_t;
#endif
typedef enum status_t status_t;
/**
* Return values of function calls.
*/
enum status_t {
/**
* Call succeeded.
*/
SUCCESS,
/**
* Call failed.
*/
FAILED,
/**
* Out of resources.
*/
OUT_OF_RES,
/**
* The suggested operation is already done
*/
ALREADY_DONE,
/**
* Not supported.
*/
NOT_SUPPORTED,
/**
* One of the arguments is invalid.
*/
INVALID_ARG,
/**
* Something could not be found.
*/
NOT_FOUND,
/**
* Error while parsing.
*/
PARSE_ERROR,
/**
* Error while verifying.
*/
VERIFY_ERROR,
/**
* Object in invalid state.
*/
INVALID_STATE,
/**
* Destroy object which called method belongs to.
*/
DESTROY_ME,
/**
* Another call to the method is required.
*/
NEED_MORE,
};
/**
* enum_names for type status_t.
*/
extern enum_name_t *status_names;
/**
* deprecated pluto style return value:
* error message, NULL for success
*/
typedef const char *err_t;
/**
* Handle struct timeval like an own type.
*/
typedef struct timeval timeval_t;
/**
* Handle struct timespec like an own type.
*/
typedef struct timespec timespec_t;
/**
* Handle struct chunk_t like an own type.
*/
typedef struct sockaddr sockaddr_t;
/**
* Clone a data to a newly allocated buffer
*/
void *clalloc(void *pointer, size_t size);
/**
* Same as memcpy, but XORs src into dst instead of copy
*/
void memxor(u_int8_t dest[], u_int8_t src[], size_t 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);
/**
* Creates a directory and all required parent directories.
*
* @param path path to the new directory
* @param mode permissions of the new directory/directories
* @return TRUE on success
*/
bool mkdir_p(const char *path, mode_t mode);
/**
* Get a timestamp from a monotonic time source.
*
* While the time()/gettimeofday() functions are affected by leap seconds
* and system time changes, this function returns ever increasing monotonic
* time stamps.
*
* @param tv timeval struct receiving monotonic timestamps, or NULL
* @return monotonic timestamp in seconds
*/
time_t time_monotonic(timeval_t *tv);
/**
* returns null
*/
void *return_null();
/**
* No-Operation function
*/
void nop();
/**
* returns TRUE
*/
bool return_true();
/**
* returns FALSE
*/
bool return_false();
/**
* Write a 16-bit host order value in network order to an unaligned address.
*
* @param host host order 16-bit value
* @param network unaligned address to write network order value to
*/
static inline void htoun16(void *network, u_int16_t host)
{
char *unaligned = (char*)network;
host = htons(host);
memcpy(unaligned, &host, sizeof(host));
}
/**
* Write a 32-bit host order value in network order to an unaligned address.
*
* @param host host order 32-bit value
* @param network unaligned address to write network order value to
*/
static inline void htoun32(void *network, u_int32_t host)
{
char *unaligned = (char*)network;
host = htonl(host);
memcpy((char*)unaligned, &host, sizeof(host));
}
/**
* Read a 16-bit value in network order from an unaligned address to host order.
*
* @param network unaligned address to read network order value from
* @return host order value
*/
static inline u_int16_t untoh16(void *network)
{
char *unaligned = (char*)network;
u_int16_t tmp;
memcpy(&tmp, unaligned, sizeof(tmp));
return ntohs(tmp);
}
/**
* Read a 32-bit value in network order from an unaligned address to host order.
*
* @param network unaligned address to read network order value from
* @return host order value
*/
static inline u_int32_t untoh32(void *network)
{
char *unaligned = (char*)network;
u_int32_t tmp;
memcpy(&tmp, unaligned, sizeof(tmp));
return ntohl(tmp);
}
/**
* Special type to count references
*/
typedef volatile u_int refcount_t;
#ifdef HAVE_GCC_ATOMIC_OPERATIONS
#define ref_get(ref) {__sync_fetch_and_add(ref, 1); }
#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
#else /* !HAVE_GCC_ATOMIC_OPERATIONS */
/**
* Get a new reference.
*
* Increments the reference counter atomic.
*
* @param ref pointer to ref counter
*/
void ref_get(refcount_t *ref);
/**
* Put back a unused reference.
*
* Decrements the reference counter atomic and
* says if more references available.
*
* @param ref pointer to ref counter
* @return TRUE if no more references counted
*/
bool ref_put(refcount_t *ref);
#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
/**
* printf hook for time_t.
*
* Arguments are:
* time_t* time, bool utc
*/
int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
const void *const *args);
/**
* printf hook for time_t deltas.
*
* Arguments are:
* time_t* begin, time_t* end
*/
int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
const void *const *args);
/**
* printf hook for memory areas.
*
* Arguments are:
* u_char *ptr, int len
*/
int mem_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
const void *const *args);
#endif /** UTILS_H_ @}*/