Added a METHOD2() macro that implements a method for two different interfaces
[strongswan.git] / src / libstrongswan / utils.h
1 /*
2 * Copyright (C) 2008-2009 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 /**
18 * @defgroup utils utils
19 * @{ @ingroup libstrongswan
20 */
21
22 #ifndef UTILS_H_
23 #define UTILS_H_
24
25 #include <sys/types.h>
26 #include <stdlib.h>
27 #include <stddef.h>
28 #include <sys/time.h>
29 #include <arpa/inet.h>
30 #include <string.h>
31
32 #include <enum.h>
33
34 /**
35 * strongSwan program return codes
36 */
37 #define SS_RC_LIBSTRONGSWAN_INTEGRITY 64
38 #define SS_RC_DAEMON_INTEGRITY 65
39 #define SS_RC_INITIALIZATION_FAILED 66
40
41 #define SS_RC_FIRST SS_RC_LIBSTRONGSWAN_INTEGRITY
42 #define SS_RC_LAST SS_RC_INITIALIZATION_FAILED
43
44 /**
45 * Number of bits in a byte
46 */
47 #define BITS_PER_BYTE 8
48
49 /**
50 * Default length for various auxiliary text buffers
51 */
52 #define BUF_LEN 512
53
54 /**
55 * Macro compares two strings for equality
56 */
57 #define streq(x,y) (strcmp(x, y) == 0)
58
59 /**
60 * Macro compares two strings for equality
61 */
62 #define strneq(x,y,len) (strncmp(x, y, len) == 0)
63
64 /**
65 * Macro compares two strings for equality ignoring case
66 */
67 #define strcaseeq(x,y) (strcasecmp(x, y) == 0)
68
69 /**
70 * Macro compares two binary blobs for equality
71 */
72 #define memeq(x,y,len) (memcmp(x, y, len) == 0)
73
74 /**
75 * Macro gives back larger of two values.
76 */
77 #define max(x,y) ({ \
78 typeof(x) _x = (x); \
79 typeof(y) _y = (y); \
80 _x > _y ? _x : _y; })
81
82
83 /**
84 * Macro gives back smaller of two values.
85 */
86 #define min(x,y) ({ \
87 typeof(x) _x = (x); \
88 typeof(y) _y = (y); \
89 _x < _y ? _x : _y; })
90
91 /**
92 * Call destructor of an object, if object != NULL
93 */
94 #define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
95
96 /**
97 * Call offset destructor of an object, if object != NULL
98 */
99 #define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
100
101 /**
102 * Call function destructor of an object, if object != NULL
103 */
104 #define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
105
106 /**
107 * Debug macro to follow control flow
108 */
109 #define POS printf("%s, line %d\n", __FILE__, __LINE__)
110
111 /**
112 * Object allocation/initialization macro, using designated initializer.
113 */
114 #define INIT(this, ...) { (this) = malloc(sizeof(*this)); \
115 *(this) = (typeof(*this)){ __VA_ARGS__ }; }
116
117 /**
118 * Method declaration/definition macro, providing private and public interface.
119 *
120 * Defines a method name with this as first parameter and a return value ret,
121 * and an alias for this method with a _ prefix, having the this argument
122 * safely casted to the public interface iface.
123 * _name is provided a function pointer, but will get optimized out by GCC.
124 */
125 #define METHOD(iface, name, ret, this, ...) \
126 static ret name(union {iface *_public; this;} \
127 __attribute__((transparent_union)), ##__VA_ARGS__); \
128 const static typeof(name) *_##name = (const typeof(name)*)name; \
129 static ret name(this, ##__VA_ARGS__)
130
131 /**
132 * Same as METHOD(), but is defined for two public interfaces.
133 */
134 #define METHOD2(iface1, iface2, name, ret, this, ...) \
135 static ret name(union {iface1 *_public1; iface2 *_public2; this;} \
136 __attribute__((transparent_union)), ##__VA_ARGS__); \
137 const static typeof(name) *_##name = (const typeof(name)*)name; \
138 static ret name(this, ##__VA_ARGS__)
139
140 /**
141 * Macro to allocate a sized type.
142 */
143 #define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
144
145 /**
146 * Get the number of elements in an array
147 */
148 #define countof(array) (sizeof(array)/sizeof(array[0]))
149
150 /**
151 * Ignore result of functions tagged with warn_unused_result attributes
152 */
153 #define ignore_result(call) { if(call); }
154
155 /**
156 * Assign a function as a class method
157 */
158 #define ASSIGN(method, function) (method = (typeof(method))function)
159
160 /**
161 * time_t not defined
162 */
163 #define UNDEFINED_TIME 0
164
165 /**
166 * Maximum time since epoch causing wrap-around on Jan 19 03:14:07 UTC 2038
167 */
168 #define TIME_32_BIT_SIGNED_MAX 0x7fffffff
169
170 /**
171 * General purpose boolean type.
172 */
173 #ifdef HAVE_STDBOOL_H
174 # include <stdbool.h>
175 #else
176 # ifndef HAVE__BOOL
177 # define _Bool signed char
178 # endif /* HAVE__BOOL */
179 # define bool _Bool
180 # define false 0
181 # define true 1
182 # define __bool_true_false_are_defined 1
183 #endif /* HAVE_STDBOOL_H */
184 #ifndef FALSE
185 # define FALSE false
186 #endif /* FALSE */
187 #ifndef TRUE
188 # define TRUE true
189 #endif /* TRUE */
190
191 /**
192 * define some missing fixed width int types on OpenSolaris.
193 * TODO: since the uintXX_t types are defined by the C99 standard we should
194 * probably use those anyway
195 */
196 #ifdef __sun
197 #include <stdint.h>
198 typedef uint8_t u_int8_t;
199 typedef uint16_t u_int16_t;
200 typedef uint32_t u_int32_t;
201 typedef uint64_t u_int64_t;
202 #endif
203
204 typedef enum status_t status_t;
205
206 /**
207 * Return values of function calls.
208 */
209 enum status_t {
210 /**
211 * Call succeeded.
212 */
213 SUCCESS,
214
215 /**
216 * Call failed.
217 */
218 FAILED,
219
220 /**
221 * Out of resources.
222 */
223 OUT_OF_RES,
224
225 /**
226 * The suggested operation is already done
227 */
228 ALREADY_DONE,
229
230 /**
231 * Not supported.
232 */
233 NOT_SUPPORTED,
234
235 /**
236 * One of the arguments is invalid.
237 */
238 INVALID_ARG,
239
240 /**
241 * Something could not be found.
242 */
243 NOT_FOUND,
244
245 /**
246 * Error while parsing.
247 */
248 PARSE_ERROR,
249
250 /**
251 * Error while verifying.
252 */
253 VERIFY_ERROR,
254
255 /**
256 * Object in invalid state.
257 */
258 INVALID_STATE,
259
260 /**
261 * Destroy object which called method belongs to.
262 */
263 DESTROY_ME,
264
265 /**
266 * Another call to the method is required.
267 */
268 NEED_MORE,
269 };
270
271 /**
272 * enum_names for type status_t.
273 */
274 extern enum_name_t *status_names;
275
276 /**
277 * deprecated pluto style return value:
278 * error message, NULL for success
279 */
280 typedef const char *err_t;
281
282 /**
283 * Handle struct timeval like an own type.
284 */
285 typedef struct timeval timeval_t;
286
287 /**
288 * Handle struct timespec like an own type.
289 */
290 typedef struct timespec timespec_t;
291
292 /**
293 * Handle struct chunk_t like an own type.
294 */
295 typedef struct sockaddr sockaddr_t;
296
297 /**
298 * Clone a data to a newly allocated buffer
299 */
300 void *clalloc(void *pointer, size_t size);
301
302 /**
303 * Same as memcpy, but XORs src into dst instead of copy
304 */
305 void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
306
307 /**
308 * A variant of strstr with the characteristics of memchr, where haystack is not
309 * a null-terminated string but simply a memory area of length n.
310 */
311 void *memstr(const void *haystack, const char *needle, size_t n);
312
313 /**
314 * Creates a directory and all required parent directories.
315 *
316 * @param path path to the new directory
317 * @param mode permissions of the new directory/directories
318 * @return TRUE on success
319 */
320 bool mkdir_p(const char *path, mode_t mode);
321
322 /**
323 * Get a timestamp from a monotonic time source.
324 *
325 * While the time()/gettimeofday() functions are affected by leap seconds
326 * and system time changes, this function returns ever increasing monotonic
327 * time stamps.
328 *
329 * @param tv timeval struct receiving monotonic timestamps, or NULL
330 * @return monotonic timestamp in seconds
331 */
332 time_t time_monotonic(timeval_t *tv);
333
334 /**
335 * returns null
336 */
337 void *return_null();
338
339 /**
340 * No-Operation function
341 */
342 void nop();
343
344 /**
345 * returns TRUE
346 */
347 bool return_true();
348
349 /**
350 * returns FALSE
351 */
352 bool return_false();
353
354 /**
355 * Write a 16-bit host order value in network order to an unaligned address.
356 *
357 * @param host host order 16-bit value
358 * @param network unaligned address to write network order value to
359 */
360 static inline void htoun16(void *network, u_int16_t host)
361 {
362 char *unaligned = (char*)network;
363
364 host = htons(host);
365 memcpy(unaligned, &host, sizeof(host));
366 }
367
368 /**
369 * Write a 32-bit host order value in network order to an unaligned address.
370 *
371 * @param host host order 32-bit value
372 * @param network unaligned address to write network order value to
373 */
374 static inline void htoun32(void *network, u_int32_t host)
375 {
376 char *unaligned = (char*)network;
377
378 host = htonl(host);
379 memcpy((char*)unaligned, &host, sizeof(host));
380 }
381
382 /**
383 * Read a 16-bit value in network order from an unaligned address to host order.
384 *
385 * @param network unaligned address to read network order value from
386 * @return host order value
387 */
388 static inline u_int16_t untoh16(void *network)
389 {
390 char *unaligned = (char*)network;
391 u_int16_t tmp;
392
393 memcpy(&tmp, unaligned, sizeof(tmp));
394 return ntohs(tmp);
395 }
396
397 /**
398 * Read a 32-bit value in network order from an unaligned address to host order.
399 *
400 * @param network unaligned address to read network order value from
401 * @return host order value
402 */
403 static inline u_int32_t untoh32(void *network)
404 {
405 char *unaligned = (char*)network;
406 u_int32_t tmp;
407
408 memcpy(&tmp, unaligned, sizeof(tmp));
409 return ntohl(tmp);
410 }
411
412 /**
413 * Special type to count references
414 */
415 typedef volatile u_int refcount_t;
416
417
418 #ifdef HAVE_GCC_ATOMIC_OPERATIONS
419
420 #define ref_get(ref) {__sync_fetch_and_add(ref, 1); }
421 #define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
422
423 #else /* !HAVE_GCC_ATOMIC_OPERATIONS */
424
425 /**
426 * Get a new reference.
427 *
428 * Increments the reference counter atomic.
429 *
430 * @param ref pointer to ref counter
431 */
432 void ref_get(refcount_t *ref);
433
434 /**
435 * Put back a unused reference.
436 *
437 * Decrements the reference counter atomic and
438 * says if more references available.
439 *
440 * @param ref pointer to ref counter
441 * @return TRUE if no more references counted
442 */
443 bool ref_put(refcount_t *ref);
444
445 #endif /* HAVE_GCC_ATOMIC_OPERATIONS */
446
447 /**
448 * printf hook for time_t.
449 *
450 * Arguments are:
451 * time_t* time, bool utc
452 */
453 int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
454 const void *const *args);
455
456 /**
457 * printf hook for time_t deltas.
458 *
459 * Arguments are:
460 * time_t* begin, time_t* end
461 */
462 int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
463 const void *const *args);
464
465 /**
466 * printf hook for memory areas.
467 *
468 * Arguments are:
469 * u_char *ptr, int len
470 */
471 int mem_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
472 const void *const *args);
473
474 #endif /** UTILS_H_ @}*/