]>
Commit | Line | Data |
---|---|---|
552cc11b | 1 | /* |
2a595276 | 2 | * Copyright (C) 2008-2012 Tobias Brunner |
552cc11b MW |
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. | |
552cc11b MW |
15 | */ |
16 | ||
17 | /** | |
bca34c37 TB |
18 | * @defgroup utils_i utils |
19 | * @{ @ingroup utils | |
552cc11b MW |
20 | */ |
21 | ||
22 | #ifndef UTILS_H_ | |
23 | #define UTILS_H_ | |
24 | ||
25 | #include <sys/types.h> | |
26 | #include <stdlib.h> | |
27 | #include <stddef.h> | |
3f310c0d | 28 | #include <sys/time.h> |
0be12e35 MW |
29 | #include <arpa/inet.h> |
30 | #include <string.h> | |
552cc11b | 31 | |
bca34c37 | 32 | #include "enum.h" |
552cc11b | 33 | |
eab241fb AS |
34 | /** |
35 | * strongSwan program return codes | |
36 | */ | |
37 | #define SS_RC_LIBSTRONGSWAN_INTEGRITY 64 | |
38 | #define SS_RC_DAEMON_INTEGRITY 65 | |
3646c8a1 | 39 | #define SS_RC_INITIALIZATION_FAILED 66 |
eab241fb | 40 | |
5d8306de AS |
41 | #define SS_RC_FIRST SS_RC_LIBSTRONGSWAN_INTEGRITY |
42 | #define SS_RC_LAST SS_RC_INITIALIZATION_FAILED | |
43 | ||
552cc11b MW |
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 | /** | |
a2a28d90 | 55 | * General purpose boolean type. |
552cc11b | 56 | */ |
a2a28d90 TB |
57 | #ifdef HAVE_STDBOOL_H |
58 | # include <stdbool.h> | |
59 | #else | |
60 | # ifndef HAVE__BOOL | |
61 | # define _Bool signed char | |
62 | # endif /* HAVE__BOOL */ | |
63 | # define bool _Bool | |
64 | # define false 0 | |
65 | # define true 1 | |
66 | # define __bool_true_false_are_defined 1 | |
67 | #endif /* HAVE_STDBOOL_H */ | |
68 | #ifndef FALSE | |
69 | # define FALSE false | |
70 | #endif /* FALSE */ | |
71 | #ifndef TRUE | |
72 | # define TRUE true | |
73 | #endif /* TRUE */ | |
74 | ||
75 | /** | |
76 | * Helper function that compares two strings for equality | |
77 | */ | |
78 | static inline bool streq(const char *x, const char *y) | |
79 | { | |
80 | return strcmp(x, y) == 0; | |
81 | } | |
552cc11b MW |
82 | |
83 | /** | |
7a3e0a63 | 84 | * Macro compares two strings for equality, length limited |
552cc11b MW |
85 | */ |
86 | #define strneq(x,y,len) (strncmp(x, y, len) == 0) | |
87 | ||
63176bbc | 88 | /** |
a2a28d90 | 89 | * Helper function that compares two strings for equality ignoring case |
63176bbc | 90 | */ |
a2a28d90 TB |
91 | static inline bool strcaseeq(const char *x, const char *y) |
92 | { | |
93 | return strcasecmp(x, y) == 0; | |
94 | } | |
63176bbc | 95 | |
7a3e0a63 MW |
96 | /** |
97 | * Macro compares two strings for equality ignoring case, length limited | |
98 | */ | |
99 | #define strncaseeq(x,y,len) (strncasecmp(x, y, len) == 0) | |
100 | ||
1038d9fe MW |
101 | /** |
102 | * NULL-safe strdup variant | |
103 | */ | |
753ca22f TB |
104 | static inline char *strdupnull(const char *s) |
105 | { | |
106 | return s ? strdup(s) : NULL; | |
107 | } | |
1038d9fe | 108 | |
552cc11b MW |
109 | /** |
110 | * Macro compares two binary blobs for equality | |
111 | */ | |
112 | #define memeq(x,y,len) (memcmp(x, y, len) == 0) | |
113 | ||
114 | /** | |
115 | * Macro gives back larger of two values. | |
116 | */ | |
e822fc57 TB |
117 | #define max(x,y) ({ \ |
118 | typeof(x) _x = (x); \ | |
119 | typeof(y) _y = (y); \ | |
120 | _x > _y ? _x : _y; }) | |
121 | ||
552cc11b MW |
122 | |
123 | /** | |
124 | * Macro gives back smaller of two values. | |
125 | */ | |
e822fc57 TB |
126 | #define min(x,y) ({ \ |
127 | typeof(x) _x = (x); \ | |
128 | typeof(y) _y = (y); \ | |
129 | _x < _y ? _x : _y; }) | |
552cc11b MW |
130 | |
131 | /** | |
132 | * Call destructor of an object, if object != NULL | |
133 | */ | |
134 | #define DESTROY_IF(obj) if (obj) (obj)->destroy(obj) | |
135 | ||
136 | /** | |
137 | * Call offset destructor of an object, if object != NULL | |
138 | */ | |
139 | #define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset); | |
140 | ||
141 | /** | |
142 | * Call function destructor of an object, if object != NULL | |
143 | */ | |
144 | #define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn); | |
145 | ||
146 | /** | |
147 | * Debug macro to follow control flow | |
148 | */ | |
149 | #define POS printf("%s, line %d\n", __FILE__, __LINE__) | |
150 | ||
74eed73a MW |
151 | /** |
152 | * Object allocation/initialization macro, using designated initializer. | |
153 | */ | |
2e1f4a46 MW |
154 | #define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \ |
155 | *(this) = (typeof(*(this))){ __VA_ARGS__ }; } | |
74eed73a | 156 | |
1a1ff9d1 MW |
157 | /** |
158 | * Method declaration/definition macro, providing private and public interface. | |
159 | * | |
160 | * Defines a method name with this as first parameter and a return value ret, | |
161 | * and an alias for this method with a _ prefix, having the this argument | |
162 | * safely casted to the public interface iface. | |
163 | * _name is provided a function pointer, but will get optimized out by GCC. | |
164 | */ | |
165 | #define METHOD(iface, name, ret, this, ...) \ | |
23d2bf84 MW |
166 | static ret name(union {iface *_public; this;} \ |
167 | __attribute__((transparent_union)), ##__VA_ARGS__); \ | |
d185b6ac | 168 | static typeof(name) *_##name = (typeof(name)*)name; \ |
23d2bf84 MW |
169 | static ret name(this, ##__VA_ARGS__) |
170 | ||
171 | /** | |
172 | * Same as METHOD(), but is defined for two public interfaces. | |
173 | */ | |
174 | #define METHOD2(iface1, iface2, name, ret, this, ...) \ | |
175 | static ret name(union {iface1 *_public1; iface2 *_public2; this;} \ | |
176 | __attribute__((transparent_union)), ##__VA_ARGS__); \ | |
d185b6ac | 177 | static typeof(name) *_##name = (typeof(name)*)name; \ |
1a1ff9d1 MW |
178 | static ret name(this, ##__VA_ARGS__) |
179 | ||
7ba89ccd MW |
180 | /** |
181 | * Architecture independent bitfield definition helpers (at least with GCC). | |
182 | * | |
183 | * Defines a bitfield with a type t and a fixed size of bitfield members, e.g.: | |
184 | * BITFIELD2(u_int8_t, | |
185 | * low: 4, | |
186 | * high: 4, | |
187 | * ) flags; | |
188 | * The member defined first placed at bit 0. | |
189 | */ | |
190 | #if BYTE_ORDER == LITTLE_ENDIAN | |
191 | #define BITFIELD2(t, a, b,...) struct { t a; t b; __VA_ARGS__} | |
192 | #define BITFIELD3(t, a, b, c,...) struct { t a; t b; t c; __VA_ARGS__} | |
193 | #define BITFIELD4(t, a, b, c, d,...) struct { t a; t b; t c; t d; __VA_ARGS__} | |
194 | #define BITFIELD5(t, a, b, c, d, e,...) struct { t a; t b; t c; t d; t e; __VA_ARGS__} | |
195 | #elif BYTE_ORDER == BIG_ENDIAN | |
196 | #define BITFIELD2(t, a, b,...) struct { t b; t a; __VA_ARGS__} | |
197 | #define BITFIELD3(t, a, b, c,...) struct { t c; t b; t a; __VA_ARGS__} | |
198 | #define BITFIELD4(t, a, b, c, d,...) struct { t d; t c; t b; t a; __VA_ARGS__} | |
199 | #define BITFIELD5(t, a, b, c, d, e,...) struct { t e; t d; t c; t b; t a; __VA_ARGS__} | |
200 | #endif | |
201 | ||
552cc11b MW |
202 | /** |
203 | * Macro to allocate a sized type. | |
204 | */ | |
205 | #define malloc_thing(thing) ((thing*)malloc(sizeof(thing))) | |
206 | ||
fca4d3ee MW |
207 | /** |
208 | * Get the number of elements in an array | |
209 | */ | |
210 | #define countof(array) (sizeof(array)/sizeof(array[0])) | |
211 | ||
479f2950 MW |
212 | /** |
213 | * Ignore result of functions tagged with warn_unused_result attributes | |
214 | */ | |
d0230850 | 215 | #define ignore_result(call) { if(call){}; } |
479f2950 | 216 | |
552cc11b MW |
217 | /** |
218 | * Assign a function as a class method | |
219 | */ | |
220 | #define ASSIGN(method, function) (method = (typeof(method))function) | |
221 | ||
222 | /** | |
223 | * time_t not defined | |
224 | */ | |
225 | #define UNDEFINED_TIME 0 | |
226 | ||
9f0327e6 AS |
227 | /** |
228 | * Maximum time since epoch causing wrap-around on Jan 19 03:14:07 UTC 2038 | |
229 | */ | |
230 | #define TIME_32_BIT_SIGNED_MAX 0x7fffffff | |
231 | ||
cc396286 TB |
232 | /** |
233 | * define some missing fixed width int types on OpenSolaris. | |
234 | * TODO: since the uintXX_t types are defined by the C99 standard we should | |
235 | * probably use those anyway | |
236 | */ | |
237 | #ifdef __sun | |
238 | #include <stdint.h> | |
239 | typedef uint8_t u_int8_t; | |
240 | typedef uint16_t u_int16_t; | |
241 | typedef uint32_t u_int32_t; | |
242 | typedef uint64_t u_int64_t; | |
243 | #endif | |
244 | ||
552cc11b MW |
245 | typedef enum status_t status_t; |
246 | ||
247 | /** | |
248 | * Return values of function calls. | |
249 | */ | |
250 | enum status_t { | |
251 | /** | |
252 | * Call succeeded. | |
253 | */ | |
254 | SUCCESS, | |
7daf5226 | 255 | |
552cc11b MW |
256 | /** |
257 | * Call failed. | |
258 | */ | |
259 | FAILED, | |
7daf5226 | 260 | |
552cc11b MW |
261 | /** |
262 | * Out of resources. | |
263 | */ | |
264 | OUT_OF_RES, | |
7daf5226 | 265 | |
552cc11b MW |
266 | /** |
267 | * The suggested operation is already done | |
268 | */ | |
269 | ALREADY_DONE, | |
7daf5226 | 270 | |
552cc11b MW |
271 | /** |
272 | * Not supported. | |
273 | */ | |
274 | NOT_SUPPORTED, | |
7daf5226 | 275 | |
552cc11b MW |
276 | /** |
277 | * One of the arguments is invalid. | |
278 | */ | |
279 | INVALID_ARG, | |
7daf5226 | 280 | |
552cc11b MW |
281 | /** |
282 | * Something could not be found. | |
283 | */ | |
284 | NOT_FOUND, | |
7daf5226 | 285 | |
552cc11b MW |
286 | /** |
287 | * Error while parsing. | |
288 | */ | |
289 | PARSE_ERROR, | |
7daf5226 | 290 | |
552cc11b MW |
291 | /** |
292 | * Error while verifying. | |
293 | */ | |
294 | VERIFY_ERROR, | |
7daf5226 | 295 | |
552cc11b MW |
296 | /** |
297 | * Object in invalid state. | |
298 | */ | |
299 | INVALID_STATE, | |
7daf5226 | 300 | |
552cc11b MW |
301 | /** |
302 | * Destroy object which called method belongs to. | |
303 | */ | |
304 | DESTROY_ME, | |
7daf5226 | 305 | |
552cc11b MW |
306 | /** |
307 | * Another call to the method is required. | |
308 | */ | |
309 | NEED_MORE, | |
310 | }; | |
311 | ||
312 | /** | |
313 | * enum_names for type status_t. | |
314 | */ | |
315 | extern enum_name_t *status_names; | |
316 | ||
4d174272 MW |
317 | typedef enum tty_escape_t tty_escape_t; |
318 | ||
319 | /** | |
320 | * Excape codes for tty colors | |
321 | */ | |
322 | enum tty_escape_t { | |
323 | /** text properties */ | |
324 | TTY_RESET, | |
325 | TTY_BOLD, | |
326 | TTY_UNDERLINE, | |
327 | TTY_BLINKING, | |
328 | ||
329 | /** foreground colors */ | |
330 | TTY_FG_BLACK, | |
331 | TTY_FG_RED, | |
332 | TTY_FG_GREEN, | |
333 | TTY_FG_YELLOW, | |
334 | TTY_FG_BLUE, | |
335 | TTY_FG_MAGENTA, | |
336 | TTY_FG_CYAN, | |
337 | TTY_FG_WHITE, | |
338 | TTY_FG_DEF, | |
339 | ||
340 | /** background colors */ | |
341 | TTY_BG_BLACK, | |
342 | TTY_BG_RED, | |
343 | TTY_BG_GREEN, | |
344 | TTY_BG_YELLOW, | |
345 | TTY_BG_BLUE, | |
346 | TTY_BG_MAGENTA, | |
347 | TTY_BG_CYAN, | |
348 | TTY_BG_WHITE, | |
349 | TTY_BG_DEF, | |
350 | }; | |
351 | ||
352 | /** | |
353 | * Get the escape string for a given TTY color, empty string on non-tty fd | |
354 | */ | |
355 | char* tty_escape_get(int fd, tty_escape_t escape); | |
356 | ||
552cc11b MW |
357 | /** |
358 | * deprecated pluto style return value: | |
359 | * error message, NULL for success | |
360 | */ | |
361 | typedef const char *err_t; | |
362 | ||
363 | /** | |
364 | * Handle struct timeval like an own type. | |
365 | */ | |
366 | typedef struct timeval timeval_t; | |
367 | ||
368 | /** | |
369 | * Handle struct timespec like an own type. | |
370 | */ | |
371 | typedef struct timespec timespec_t; | |
372 | ||
373 | /** | |
374 | * Handle struct chunk_t like an own type. | |
375 | */ | |
376 | typedef struct sockaddr sockaddr_t; | |
377 | ||
378 | /** | |
379 | * Clone a data to a newly allocated buffer | |
380 | */ | |
381 | void *clalloc(void *pointer, size_t size); | |
382 | ||
383 | /** | |
384 | * Same as memcpy, but XORs src into dst instead of copy | |
385 | */ | |
386 | void memxor(u_int8_t dest[], u_int8_t src[], size_t n); | |
387 | ||
ed678b52 MW |
388 | /** |
389 | * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant. | |
390 | */ | |
391 | void memwipe_noinline(void *ptr, size_t n); | |
392 | ||
393 | /** | |
394 | * Safely overwrite n bytes of memory at ptr with zero, inlining variant. | |
395 | */ | |
396 | static inline void memwipe_inline(void *ptr, size_t n) | |
397 | { | |
398 | volatile char *c = (volatile char*)ptr; | |
d45b242b | 399 | size_t m, i; |
ed678b52 MW |
400 | |
401 | /* byte wise until long aligned */ | |
d45b242b | 402 | for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++) |
ed678b52 MW |
403 | { |
404 | c[i] = 0; | |
405 | } | |
d45b242b MW |
406 | /* word wise */ |
407 | if (n >= sizeof(long)) | |
ed678b52 | 408 | { |
d45b242b MW |
409 | for (m = n - sizeof(long); i <= m; i += sizeof(long)) |
410 | { | |
411 | *(volatile long*)&c[i] = 0; | |
412 | } | |
ed678b52 MW |
413 | } |
414 | /* byte wise of the rest */ | |
415 | for (; i < n; i++) | |
416 | { | |
417 | c[i] = 0; | |
418 | } | |
419 | } | |
420 | ||
421 | /** | |
422 | * Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant. | |
423 | */ | |
424 | static inline void memwipe(void *ptr, size_t n) | |
425 | { | |
426 | if (__builtin_constant_p(n)) | |
427 | { | |
428 | memwipe_inline(ptr, n); | |
429 | } | |
430 | else | |
431 | { | |
432 | memwipe_noinline(ptr, n); | |
433 | } | |
434 | } | |
435 | ||
81736d7d TB |
436 | /** |
437 | * A variant of strstr with the characteristics of memchr, where haystack is not | |
438 | * a null-terminated string but simply a memory area of length n. | |
439 | */ | |
440 | void *memstr(const void *haystack, const char *needle, size_t n); | |
441 | ||
d543d9ca TB |
442 | /** |
443 | * Translates the characters in the given string, searching for characters | |
444 | * in 'from' and mapping them to characters in 'to'. | |
445 | * The two characters sets 'from' and 'to' must contain the same number of | |
446 | * characters. | |
447 | */ | |
448 | char *translate(char *str, const char *from, const char *to); | |
449 | ||
6c20579a | 450 | /** |
7daf5226 | 451 | * Creates a directory and all required parent directories. |
6c20579a | 452 | * |
3f310c0d | 453 | * @param path path to the new directory |
7daf5226 | 454 | * @param mode permissions of the new directory/directories |
6c20579a TB |
455 | * @return TRUE on success |
456 | */ | |
457 | bool mkdir_p(const char *path, mode_t mode); | |
458 | ||
2a595276 TB |
459 | /** |
460 | * Thread-safe wrapper around strerror and strerror_r. | |
461 | * | |
462 | * This is required because the first is not thread-safe (on some platforms) | |
463 | * and the second uses two different signatures (POSIX/GNU) and is impractical | |
464 | * to use anyway. | |
465 | * | |
466 | * @param errnum error code (i.e. errno) | |
467 | * @return error message | |
468 | */ | |
469 | const char *safe_strerror(int errnum); | |
470 | ||
bbbffac3 TB |
471 | /** |
472 | * Replace usages of strerror(3) with thread-safe variant. | |
473 | */ | |
474 | #define strerror(errnum) safe_strerror(errnum) | |
475 | ||
9a8fdc15 TB |
476 | #ifndef HAVE_CLOSEFROM |
477 | /** | |
478 | * Close open file descriptors greater than or equal to lowfd. | |
479 | * | |
480 | * @param lowfd start closing file descriptoros from here | |
481 | */ | |
482 | void closefrom(int lowfd); | |
483 | #endif | |
484 | ||
3f310c0d MW |
485 | /** |
486 | * Get a timestamp from a monotonic time source. | |
487 | * | |
488 | * While the time()/gettimeofday() functions are affected by leap seconds | |
489 | * and system time changes, this function returns ever increasing monotonic | |
490 | * time stamps. | |
491 | * | |
492 | * @param tv timeval struct receiving monotonic timestamps, or NULL | |
493 | * @return monotonic timestamp in seconds | |
494 | */ | |
495 | time_t time_monotonic(timeval_t *tv); | |
496 | ||
eecd41e3 TB |
497 | /** |
498 | * Add the given number of milliseconds to the given timeval struct | |
499 | * | |
500 | * @param tv timeval struct to modify | |
501 | * @param ms number of milliseconds | |
502 | */ | |
503 | static inline void timeval_add_ms(timeval_t *tv, u_int ms) | |
504 | { | |
505 | tv->tv_usec += ms * 1000; | |
506 | while (tv->tv_usec > 1000000 /* 1s */) | |
507 | { | |
508 | tv->tv_usec -= 1000000; | |
509 | tv->tv_sec++; | |
510 | } | |
511 | } | |
512 | ||
081ae2eb MW |
513 | /** |
514 | * returns null | |
515 | */ | |
516 | void *return_null(); | |
517 | ||
233b853d MW |
518 | /** |
519 | * No-Operation function | |
520 | */ | |
521 | void nop(); | |
522 | ||
da17b016 MW |
523 | /** |
524 | * returns TRUE | |
525 | */ | |
526 | bool return_true(); | |
527 | ||
528 | /** | |
529 | * returns FALSE | |
530 | */ | |
531 | bool return_false(); | |
532 | ||
502edf42 MW |
533 | /** |
534 | * returns FAILED | |
535 | */ | |
536 | status_t return_failed(); | |
537 | ||
4755ab50 MW |
538 | /** |
539 | * returns SUCCESS | |
540 | */ | |
541 | status_t return_success(); | |
542 | ||
0be12e35 MW |
543 | /** |
544 | * Write a 16-bit host order value in network order to an unaligned address. | |
545 | * | |
546 | * @param host host order 16-bit value | |
547 | * @param network unaligned address to write network order value to | |
548 | */ | |
549 | static inline void htoun16(void *network, u_int16_t host) | |
550 | { | |
dbee988e MW |
551 | char *unaligned = (char*)network; |
552 | ||
0be12e35 | 553 | host = htons(host); |
dbee988e | 554 | memcpy(unaligned, &host, sizeof(host)); |
0be12e35 MW |
555 | } |
556 | ||
557 | /** | |
558 | * Write a 32-bit host order value in network order to an unaligned address. | |
559 | * | |
560 | * @param host host order 32-bit value | |
561 | * @param network unaligned address to write network order value to | |
562 | */ | |
563 | static inline void htoun32(void *network, u_int32_t host) | |
564 | { | |
dbee988e MW |
565 | char *unaligned = (char*)network; |
566 | ||
0be12e35 | 567 | host = htonl(host); |
dbee988e | 568 | memcpy((char*)unaligned, &host, sizeof(host)); |
0be12e35 MW |
569 | } |
570 | ||
fbeb9454 AS |
571 | /** |
572 | * Write a 64-bit host order value in network order to an unaligned address. | |
573 | * | |
a91462df | 574 | * @param host host order 64-bit value |
fbeb9454 AS |
575 | * @param network unaligned address to write network order value to |
576 | */ | |
577 | static inline void htoun64(void *network, u_int64_t host) | |
578 | { | |
579 | char *unaligned = (char*)network; | |
f4e25e60 MW |
580 | |
581 | #ifdef be64toh | |
582 | host = htobe64(host); | |
583 | memcpy((char*)unaligned, &host, sizeof(host)); | |
584 | #else | |
fbeb9454 AS |
585 | u_int32_t high_part, low_part; |
586 | ||
587 | high_part = host >> 32; | |
588 | high_part = htonl(high_part); | |
589 | low_part = host & 0xFFFFFFFFLL; | |
590 | low_part = htonl(low_part); | |
591 | ||
592 | memcpy(unaligned, &high_part, sizeof(high_part)); | |
593 | unaligned += sizeof(high_part); | |
594 | memcpy(unaligned, &low_part, sizeof(low_part)); | |
f4e25e60 | 595 | #endif |
fbeb9454 AS |
596 | } |
597 | ||
0be12e35 MW |
598 | /** |
599 | * Read a 16-bit value in network order from an unaligned address to host order. | |
600 | * | |
601 | * @param network unaligned address to read network order value from | |
602 | * @return host order value | |
603 | */ | |
604 | static inline u_int16_t untoh16(void *network) | |
605 | { | |
dbee988e | 606 | char *unaligned = (char*)network; |
0be12e35 MW |
607 | u_int16_t tmp; |
608 | ||
dbee988e | 609 | memcpy(&tmp, unaligned, sizeof(tmp)); |
0be12e35 MW |
610 | return ntohs(tmp); |
611 | } | |
612 | ||
613 | /** | |
614 | * Read a 32-bit value in network order from an unaligned address to host order. | |
615 | * | |
616 | * @param network unaligned address to read network order value from | |
617 | * @return host order value | |
618 | */ | |
619 | static inline u_int32_t untoh32(void *network) | |
620 | { | |
dbee988e | 621 | char *unaligned = (char*)network; |
0be12e35 MW |
622 | u_int32_t tmp; |
623 | ||
dbee988e | 624 | memcpy(&tmp, unaligned, sizeof(tmp)); |
f8f4f31a | 625 | return ntohl(tmp); |
0be12e35 MW |
626 | } |
627 | ||
fbeb9454 AS |
628 | /** |
629 | * Read a 64-bit value in network order from an unaligned address to host order. | |
630 | * | |
631 | * @param network unaligned address to read network order value from | |
632 | * @return host order value | |
633 | */ | |
634 | static inline u_int64_t untoh64(void *network) | |
635 | { | |
636 | char *unaligned = (char*)network; | |
f4e25e60 MW |
637 | |
638 | #ifdef be64toh | |
639 | u_int64_t tmp; | |
640 | ||
641 | memcpy(&tmp, unaligned, sizeof(tmp)); | |
642 | return be64toh(tmp); | |
643 | #else | |
fbeb9454 AS |
644 | u_int32_t high_part, low_part; |
645 | ||
646 | memcpy(&high_part, unaligned, sizeof(high_part)); | |
647 | unaligned += sizeof(high_part); | |
648 | memcpy(&low_part, unaligned, sizeof(low_part)); | |
649 | ||
650 | high_part = ntohl(high_part); | |
651 | low_part = ntohl(low_part); | |
652 | ||
653 | return (((u_int64_t)high_part) << 32) + low_part; | |
f4e25e60 | 654 | #endif |
fbeb9454 AS |
655 | } |
656 | ||
552cc11b MW |
657 | /** |
658 | * Special type to count references | |
659 | */ | |
660 | typedef volatile u_int refcount_t; | |
661 | ||
efd0fe21 MW |
662 | |
663 | #ifdef HAVE_GCC_ATOMIC_OPERATIONS | |
664 | ||
665 | #define ref_get(ref) {__sync_fetch_and_add(ref, 1); } | |
666 | #define ref_put(ref) (!__sync_sub_and_fetch(ref, 1)) | |
667 | ||
5317dd68 TB |
668 | #define cas_bool(ptr, oldval, newval) \ |
669 | (__sync_bool_compare_and_swap(ptr, oldval, newval)) | |
670 | #define cas_ptr(ptr, oldval, newval) \ | |
671 | (__sync_bool_compare_and_swap(ptr, oldval, newval)) | |
672 | ||
efd0fe21 MW |
673 | #else /* !HAVE_GCC_ATOMIC_OPERATIONS */ |
674 | ||
552cc11b MW |
675 | /** |
676 | * Get a new reference. | |
677 | * | |
678 | * Increments the reference counter atomic. | |
679 | * | |
680 | * @param ref pointer to ref counter | |
681 | */ | |
682 | void ref_get(refcount_t *ref); | |
683 | ||
684 | /** | |
685 | * Put back a unused reference. | |
686 | * | |
7daf5226 | 687 | * Decrements the reference counter atomic and |
552cc11b MW |
688 | * says if more references available. |
689 | * | |
690 | * @param ref pointer to ref counter | |
691 | * @return TRUE if no more references counted | |
692 | */ | |
693 | bool ref_put(refcount_t *ref); | |
694 | ||
5317dd68 TB |
695 | /** |
696 | * Atomically replace value of ptr with newval if it currently equals oldval. | |
697 | * | |
698 | * @param ptr pointer to variable | |
699 | * @param oldval old value of the variable | |
700 | * @param newval new value set if possible | |
701 | * @return TRUE if value equaled oldval and newval was written | |
702 | */ | |
703 | bool cas_bool(bool *ptr, bool oldval, bool newval); | |
704 | ||
705 | /** | |
706 | * Atomically replace value of ptr with newval if it currently equals oldval. | |
707 | * | |
708 | * @param ptr pointer to variable | |
709 | * @param oldval old value of the variable | |
710 | * @param newval new value set if possible | |
711 | * @return TRUE if value equaled oldval and newval was written | |
712 | */ | |
713 | bool cas_ptr(void **ptr, void *oldval, void *newval); | |
714 | ||
efd0fe21 MW |
715 | #endif /* HAVE_GCC_ATOMIC_OPERATIONS */ |
716 | ||
552cc11b | 717 | /** |
d25ce370 | 718 | * printf hook for time_t. |
552cc11b | 719 | * |
7daf5226 | 720 | * Arguments are: |
323f9f99 | 721 | * time_t* time, bool utc |
552cc11b | 722 | */ |
1b40b74d | 723 | int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, |
d25ce370 | 724 | const void *const *args); |
552cc11b MW |
725 | |
726 | /** | |
d25ce370 | 727 | * printf hook for time_t deltas. |
552cc11b | 728 | * |
7daf5226 | 729 | * Arguments are: |
323f9f99 | 730 | * time_t* begin, time_t* end |
552cc11b | 731 | */ |
1b40b74d | 732 | int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, |
d25ce370 | 733 | const void *const *args); |
552cc11b MW |
734 | |
735 | /** | |
d25ce370 | 736 | * printf hook for memory areas. |
552cc11b | 737 | * |
7daf5226 | 738 | * Arguments are: |
817ab8a8 | 739 | * u_char *ptr, u_int len |
552cc11b | 740 | */ |
1b40b74d | 741 | int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, |
d25ce370 | 742 | const void *const *args); |
552cc11b | 743 | |
1490ff4d | 744 | #endif /** UTILS_H_ @}*/ |