]> git.ipfire.org Git - people/ms/strongswan.git/blame - src/libstrongswan/utils/utils.h
pki: Also check for MAX_COMMANDS when building getopt_long arguments
[people/ms/strongswan.git] / src / libstrongswan / utils / utils.h
CommitLineData
552cc11b 1/*
766141bc 2 * Copyright (C) 2008-2014 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 29#include <string.h>
552cc11b 30
922ee2c5
MW
31#ifdef WIN32
32# include "windows.h"
33#else
34# define _GNU_SOURCE
35# include <arpa/inet.h>
36# include <sys/socket.h>
37# include <netdb.h>
38# include <netinet/in.h>
266ee0a1 39# include <sched.h>
922ee2c5
MW
40#endif
41
eab241fb
AS
42/**
43 * strongSwan program return codes
44 */
45#define SS_RC_LIBSTRONGSWAN_INTEGRITY 64
46#define SS_RC_DAEMON_INTEGRITY 65
3646c8a1 47#define SS_RC_INITIALIZATION_FAILED 66
eab241fb 48
5d8306de
AS
49#define SS_RC_FIRST SS_RC_LIBSTRONGSWAN_INTEGRITY
50#define SS_RC_LAST SS_RC_INITIALIZATION_FAILED
51
552cc11b
MW
52/**
53 * Number of bits in a byte
54 */
55#define BITS_PER_BYTE 8
56
57/**
58 * Default length for various auxiliary text buffers
59 */
60#define BUF_LEN 512
61
62/**
a2a28d90 63 * General purpose boolean type.
552cc11b 64 */
a2a28d90
TB
65#ifdef HAVE_STDBOOL_H
66# include <stdbool.h>
67#else
68# ifndef HAVE__BOOL
69# define _Bool signed char
70# endif /* HAVE__BOOL */
71# define bool _Bool
72# define false 0
73# define true 1
74# define __bool_true_false_are_defined 1
75#endif /* HAVE_STDBOOL_H */
76#ifndef FALSE
77# define FALSE false
78#endif /* FALSE */
79#ifndef TRUE
80# define TRUE true
81#endif /* TRUE */
82
9ee8b3b4
MW
83#include "enum.h"
84#include "utils/strerror.h"
85
a43f1e56
MW
86/**
87 * Directory separator character in paths on this platform
88 */
89#ifdef WIN32
90# define DIRECTORY_SEPARATOR "\\"
91#else
92# define DIRECTORY_SEPARATOR "/"
93#endif
94
87a79e6a
MW
95/**
96 * Initialize utility functions
97 */
98void utils_init();
99
100/**
101 * Deinitialize utility functions
102 */
103void utils_deinit();
104
a2a28d90
TB
105/**
106 * Helper function that compares two strings for equality
107 */
108static inline bool streq(const char *x, const char *y)
109{
110 return strcmp(x, y) == 0;
111}
552cc11b
MW
112
113/**
985dcab1 114 * Helper function that compares two strings for equality, length limited
552cc11b 115 */
985dcab1
TB
116static inline bool strneq(const char *x, const char *y, size_t len)
117{
118 return strncmp(x, y, len) == 0;
119}
552cc11b 120
f460facd
TB
121/**
122 * Helper function that checks if a string starts with a given prefix
123 */
124static inline bool strpfx(const char *x, const char *prefix)
125{
126 return strneq(x, prefix, strlen(prefix));
127}
128
63176bbc 129/**
a2a28d90 130 * Helper function that compares two strings for equality ignoring case
63176bbc 131 */
a2a28d90
TB
132static inline bool strcaseeq(const char *x, const char *y)
133{
134 return strcasecmp(x, y) == 0;
135}
63176bbc 136
7a3e0a63 137/**
985dcab1 138 * Helper function that compares two strings for equality ignoring case, length limited
7a3e0a63 139 */
985dcab1
TB
140static inline bool strncaseeq(const char *x, const char *y, size_t len)
141{
142 return strncasecmp(x, y, len) == 0;
143}
7a3e0a63 144
32a145fd
TB
145/**
146 * Helper function that checks if a string starts with a given prefix
147 */
148static inline bool strcasepfx(const char *x, const char *prefix)
149{
150 return strncaseeq(x, prefix, strlen(prefix));
151}
152
1038d9fe
MW
153/**
154 * NULL-safe strdup variant
155 */
753ca22f
TB
156static inline char *strdupnull(const char *s)
157{
158 return s ? strdup(s) : NULL;
159}
1038d9fe 160
552cc11b 161/**
985dcab1 162 * Helper function that compares two binary blobs for equality
552cc11b 163 */
985dcab1
TB
164static inline bool memeq(const void *x, const void *y, size_t len)
165{
166 return memcmp(x, y, len) == 0;
167}
552cc11b
MW
168
169/**
170 * Macro gives back larger of two values.
171 */
e822fc57
TB
172#define max(x,y) ({ \
173 typeof(x) _x = (x); \
174 typeof(y) _y = (y); \
175 _x > _y ? _x : _y; })
176
552cc11b
MW
177
178/**
179 * Macro gives back smaller of two values.
180 */
e822fc57
TB
181#define min(x,y) ({ \
182 typeof(x) _x = (x); \
183 typeof(y) _y = (y); \
184 _x < _y ? _x : _y; })
552cc11b
MW
185
186/**
187 * Call destructor of an object, if object != NULL
188 */
189#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
190
191/**
192 * Call offset destructor of an object, if object != NULL
193 */
194#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
195
196/**
197 * Call function destructor of an object, if object != NULL
198 */
199#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
200
201/**
202 * Debug macro to follow control flow
203 */
204#define POS printf("%s, line %d\n", __FILE__, __LINE__)
205
74eed73a
MW
206/**
207 * Object allocation/initialization macro, using designated initializer.
208 */
2e1f4a46
MW
209#define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \
210 *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
74eed73a 211
1a1ff9d1
MW
212/**
213 * Method declaration/definition macro, providing private and public interface.
214 *
215 * Defines a method name with this as first parameter and a return value ret,
216 * and an alias for this method with a _ prefix, having the this argument
217 * safely casted to the public interface iface.
218 * _name is provided a function pointer, but will get optimized out by GCC.
219 */
220#define METHOD(iface, name, ret, this, ...) \
23d2bf84
MW
221 static ret name(union {iface *_public; this;} \
222 __attribute__((transparent_union)), ##__VA_ARGS__); \
d185b6ac 223 static typeof(name) *_##name = (typeof(name)*)name; \
23d2bf84
MW
224 static ret name(this, ##__VA_ARGS__)
225
226/**
227 * Same as METHOD(), but is defined for two public interfaces.
228 */
229#define METHOD2(iface1, iface2, name, ret, this, ...) \
230 static ret name(union {iface1 *_public1; iface2 *_public2; this;} \
231 __attribute__((transparent_union)), ##__VA_ARGS__); \
d185b6ac 232 static typeof(name) *_##name = (typeof(name)*)name; \
1a1ff9d1
MW
233 static ret name(this, ##__VA_ARGS__)
234
9e932513
MW
235/**
236 * Callback declaration/definition macro, allowing casted first parameter.
237 *
238 * This is very similar to METHOD, but instead of casting the first parameter
239 * to a public interface, it uses a void*. This allows type safe definition
240 * of a callback function, while using the real type for the first parameter.
241 */
242#define CALLBACK(name, ret, param1, ...) \
243 static ret _cb_##name(union {void *_generic; param1;} \
244 __attribute__((transparent_union)), ##__VA_ARGS__); \
245 static typeof(_cb_##name) *name = (typeof(_cb_##name)*)_cb_##name; \
246 static ret _cb_##name(param1, ##__VA_ARGS__)
247
7ba89ccd
MW
248/**
249 * Architecture independent bitfield definition helpers (at least with GCC).
250 *
251 * Defines a bitfield with a type t and a fixed size of bitfield members, e.g.:
252 * BITFIELD2(u_int8_t,
253 * low: 4,
254 * high: 4,
255 * ) flags;
256 * The member defined first placed at bit 0.
257 */
258#if BYTE_ORDER == LITTLE_ENDIAN
259#define BITFIELD2(t, a, b,...) struct { t a; t b; __VA_ARGS__}
260#define BITFIELD3(t, a, b, c,...) struct { t a; t b; t c; __VA_ARGS__}
261#define BITFIELD4(t, a, b, c, d,...) struct { t a; t b; t c; t d; __VA_ARGS__}
262#define BITFIELD5(t, a, b, c, d, e,...) struct { t a; t b; t c; t d; t e; __VA_ARGS__}
263#elif BYTE_ORDER == BIG_ENDIAN
264#define BITFIELD2(t, a, b,...) struct { t b; t a; __VA_ARGS__}
265#define BITFIELD3(t, a, b, c,...) struct { t c; t b; t a; __VA_ARGS__}
266#define BITFIELD4(t, a, b, c, d,...) struct { t d; t c; t b; t a; __VA_ARGS__}
267#define BITFIELD5(t, a, b, c, d, e,...) struct { t e; t d; t c; t b; t a; __VA_ARGS__}
268#endif
269
552cc11b
MW
270/**
271 * Macro to allocate a sized type.
272 */
273#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
274
fca4d3ee
MW
275/**
276 * Get the number of elements in an array
277 */
278#define countof(array) (sizeof(array)/sizeof(array[0]))
279
479f2950
MW
280/**
281 * Ignore result of functions tagged with warn_unused_result attributes
282 */
d0230850 283#define ignore_result(call) { if(call){}; }
479f2950 284
552cc11b
MW
285/**
286 * Assign a function as a class method
287 */
288#define ASSIGN(method, function) (method = (typeof(method))function)
289
290/**
291 * time_t not defined
292 */
293#define UNDEFINED_TIME 0
294
9f0327e6
AS
295/**
296 * Maximum time since epoch causing wrap-around on Jan 19 03:14:07 UTC 2038
297 */
298#define TIME_32_BIT_SIGNED_MAX 0x7fffffff
299
cc396286
TB
300/**
301 * define some missing fixed width int types on OpenSolaris.
302 * TODO: since the uintXX_t types are defined by the C99 standard we should
303 * probably use those anyway
304 */
922ee2c5 305#if defined __sun || defined WIN32
cc396286
TB
306 #include <stdint.h>
307 typedef uint8_t u_int8_t;
308 typedef uint16_t u_int16_t;
309 typedef uint32_t u_int32_t;
310 typedef uint64_t u_int64_t;
311#endif
312
552cc11b
MW
313typedef enum status_t status_t;
314
315/**
316 * Return values of function calls.
317 */
318enum status_t {
319 /**
320 * Call succeeded.
321 */
322 SUCCESS,
7daf5226 323
552cc11b
MW
324 /**
325 * Call failed.
326 */
327 FAILED,
7daf5226 328
552cc11b
MW
329 /**
330 * Out of resources.
331 */
332 OUT_OF_RES,
7daf5226 333
552cc11b
MW
334 /**
335 * The suggested operation is already done
336 */
337 ALREADY_DONE,
7daf5226 338
552cc11b
MW
339 /**
340 * Not supported.
341 */
342 NOT_SUPPORTED,
7daf5226 343
552cc11b
MW
344 /**
345 * One of the arguments is invalid.
346 */
347 INVALID_ARG,
7daf5226 348
552cc11b
MW
349 /**
350 * Something could not be found.
351 */
352 NOT_FOUND,
7daf5226 353
552cc11b
MW
354 /**
355 * Error while parsing.
356 */
357 PARSE_ERROR,
7daf5226 358
552cc11b
MW
359 /**
360 * Error while verifying.
361 */
362 VERIFY_ERROR,
7daf5226 363
552cc11b
MW
364 /**
365 * Object in invalid state.
366 */
367 INVALID_STATE,
7daf5226 368
552cc11b
MW
369 /**
370 * Destroy object which called method belongs to.
371 */
372 DESTROY_ME,
7daf5226 373
552cc11b
MW
374 /**
375 * Another call to the method is required.
376 */
377 NEED_MORE,
378};
379
380/**
381 * enum_names for type status_t.
382 */
383extern enum_name_t *status_names;
384
4d174272
MW
385typedef enum tty_escape_t tty_escape_t;
386
387/**
388 * Excape codes for tty colors
389 */
390enum tty_escape_t {
391 /** text properties */
392 TTY_RESET,
393 TTY_BOLD,
394 TTY_UNDERLINE,
395 TTY_BLINKING,
396
397 /** foreground colors */
398 TTY_FG_BLACK,
399 TTY_FG_RED,
400 TTY_FG_GREEN,
401 TTY_FG_YELLOW,
402 TTY_FG_BLUE,
403 TTY_FG_MAGENTA,
404 TTY_FG_CYAN,
405 TTY_FG_WHITE,
406 TTY_FG_DEF,
407
408 /** background colors */
409 TTY_BG_BLACK,
410 TTY_BG_RED,
411 TTY_BG_GREEN,
412 TTY_BG_YELLOW,
413 TTY_BG_BLUE,
414 TTY_BG_MAGENTA,
415 TTY_BG_CYAN,
416 TTY_BG_WHITE,
417 TTY_BG_DEF,
418};
419
420/**
421 * Get the escape string for a given TTY color, empty string on non-tty fd
422 */
423char* tty_escape_get(int fd, tty_escape_t escape);
424
552cc11b
MW
425/**
426 * deprecated pluto style return value:
427 * error message, NULL for success
428 */
429typedef const char *err_t;
430
431/**
432 * Handle struct timeval like an own type.
433 */
434typedef struct timeval timeval_t;
435
436/**
437 * Handle struct timespec like an own type.
438 */
439typedef struct timespec timespec_t;
440
441/**
442 * Handle struct chunk_t like an own type.
443 */
444typedef struct sockaddr sockaddr_t;
445
552cc11b
MW
446/**
447 * Same as memcpy, but XORs src into dst instead of copy
448 */
449void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
450
ed678b52
MW
451/**
452 * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
453 */
454void memwipe_noinline(void *ptr, size_t n);
455
456/**
457 * Safely overwrite n bytes of memory at ptr with zero, inlining variant.
458 */
459static inline void memwipe_inline(void *ptr, size_t n)
460{
461 volatile char *c = (volatile char*)ptr;
d45b242b 462 size_t m, i;
ed678b52
MW
463
464 /* byte wise until long aligned */
d45b242b 465 for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
ed678b52
MW
466 {
467 c[i] = 0;
468 }
d45b242b
MW
469 /* word wise */
470 if (n >= sizeof(long))
ed678b52 471 {
d45b242b
MW
472 for (m = n - sizeof(long); i <= m; i += sizeof(long))
473 {
474 *(volatile long*)&c[i] = 0;
475 }
ed678b52
MW
476 }
477 /* byte wise of the rest */
478 for (; i < n; i++)
479 {
480 c[i] = 0;
481 }
482}
483
484/**
485 * Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
486 */
487static inline void memwipe(void *ptr, size_t n)
488{
c480b5f4
TB
489 if (!ptr)
490 {
491 return;
492 }
ed678b52
MW
493 if (__builtin_constant_p(n))
494 {
495 memwipe_inline(ptr, n);
496 }
497 else
498 {
499 memwipe_noinline(ptr, n);
500 }
501}
502
81736d7d
TB
503/**
504 * A variant of strstr with the characteristics of memchr, where haystack is not
505 * a null-terminated string but simply a memory area of length n.
506 */
507void *memstr(const void *haystack, const char *needle, size_t n);
508
2ed241ae
TB
509/**
510 * Replacement for memrchr(3) if it is not provided by the C library.
511 *
512 * @param s start of the memory area to search
513 * @param c character to search
514 * @param n length of memory area to search
515 * @return pointer to the found character or NULL
516 */
517void *utils_memrchr(const void *s, int c, size_t n);
518
519#ifndef HAVE_MEMRCHR
520#define memrchr(s,c,n) utils_memrchr(s,c,n)
521#endif
522
d543d9ca
TB
523/**
524 * Translates the characters in the given string, searching for characters
525 * in 'from' and mapping them to characters in 'to'.
526 * The two characters sets 'from' and 'to' must contain the same number of
527 * characters.
528 */
529char *translate(char *str, const char *from, const char *to);
530
ccb6758e 531/**
4ab38d98 532 * Replaces all occurrences of search in the given string with replace.
ccb6758e
TB
533 *
534 * Allocates memory only if anything is replaced in the string. The original
535 * string is also returned if any of the arguments are invalid (e.g. if search
536 * is empty or any of them are NULL).
537 *
538 * @param str original string
539 * @param search string to search for and replace
4ab38d98 540 * @param replace string to replace found occurrences with
ccb6758e
TB
541 * @return allocated string, if anything got replaced, str otherwise
542 */
543char *strreplace(const char *str, const char *search, const char *replace);
544
66c0801d
MW
545/**
546 * Portable function to wait for SIGINT/SIGTERM (or equivalent).
547 */
548void wait_sigint();
549
766141bc
TB
550/**
551 * Like dirname(3) returns the directory part of the given null-terminated
552 * pathname, up to but not including the final '/' (or '.' if no '/' is found).
553 * Trailing '/' are not counted as part of the pathname.
554 *
555 * The difference is that it does this in a thread-safe manner (i.e. it does not
556 * use static buffers) and does not modify the original path.
557 *
558 * @param path original pathname
559 * @return allocated directory component
560 */
561char *path_dirname(const char *path);
562
563/**
564 * Like basename(3) returns the filename part of the given null-terminated path,
565 * i.e. the part following the final '/' (or '.' if path is empty or NULL).
566 * Trailing '/' are not counted as part of the pathname.
567 *
568 * The difference is that it does this in a thread-safe manner (i.e. it does not
569 * use static buffers) and does not modify the original path.
570 *
571 * @param path original pathname
572 * @return allocated filename component
573 */
574char *path_basename(const char *path);
575
67b3bcd1
MW
576/**
577 * Check if a given path is absolute.
578 *
579 * @param path path to check
580 * @return TRUE if absolute, FALSE if relative
581 */
582bool path_absolute(const char *path);
583
6c20579a 584/**
7daf5226 585 * Creates a directory and all required parent directories.
6c20579a 586 *
3f310c0d 587 * @param path path to the new directory
7daf5226 588 * @param mode permissions of the new directory/directories
6c20579a
TB
589 * @return TRUE on success
590 */
591bool mkdir_p(const char *path, mode_t mode);
592
9a8fdc15
TB
593#ifndef HAVE_CLOSEFROM
594/**
595 * Close open file descriptors greater than or equal to lowfd.
596 *
4ab38d98 597 * @param lowfd start closing file descriptors from here
9a8fdc15
TB
598 */
599void closefrom(int lowfd);
600#endif
601
3f310c0d
MW
602/**
603 * Get a timestamp from a monotonic time source.
604 *
605 * While the time()/gettimeofday() functions are affected by leap seconds
606 * and system time changes, this function returns ever increasing monotonic
607 * time stamps.
608 *
609 * @param tv timeval struct receiving monotonic timestamps, or NULL
610 * @return monotonic timestamp in seconds
611 */
612time_t time_monotonic(timeval_t *tv);
613
eecd41e3
TB
614/**
615 * Add the given number of milliseconds to the given timeval struct
616 *
617 * @param tv timeval struct to modify
618 * @param ms number of milliseconds
619 */
620static inline void timeval_add_ms(timeval_t *tv, u_int ms)
621{
622 tv->tv_usec += ms * 1000;
819c02db 623 while (tv->tv_usec >= 1000000 /* 1s */)
eecd41e3
TB
624 {
625 tv->tv_usec -= 1000000;
626 tv->tv_sec++;
627 }
628}
629
081ae2eb
MW
630/**
631 * returns null
632 */
633void *return_null();
634
233b853d
MW
635/**
636 * No-Operation function
637 */
638void nop();
639
da17b016
MW
640/**
641 * returns TRUE
642 */
643bool return_true();
644
645/**
646 * returns FALSE
647 */
648bool return_false();
649
502edf42
MW
650/**
651 * returns FAILED
652 */
653status_t return_failed();
654
4755ab50
MW
655/**
656 * returns SUCCESS
657 */
658status_t return_success();
659
0be12e35
MW
660/**
661 * Write a 16-bit host order value in network order to an unaligned address.
662 *
663 * @param host host order 16-bit value
664 * @param network unaligned address to write network order value to
665 */
666static inline void htoun16(void *network, u_int16_t host)
667{
dbee988e
MW
668 char *unaligned = (char*)network;
669
0be12e35 670 host = htons(host);
dbee988e 671 memcpy(unaligned, &host, sizeof(host));
0be12e35
MW
672}
673
674/**
675 * Write a 32-bit host order value in network order to an unaligned address.
676 *
677 * @param host host order 32-bit value
678 * @param network unaligned address to write network order value to
679 */
680static inline void htoun32(void *network, u_int32_t host)
681{
dbee988e
MW
682 char *unaligned = (char*)network;
683
0be12e35 684 host = htonl(host);
dbee988e 685 memcpy((char*)unaligned, &host, sizeof(host));
0be12e35
MW
686}
687
fbeb9454
AS
688/**
689 * Write a 64-bit host order value in network order to an unaligned address.
690 *
a91462df 691 * @param host host order 64-bit value
fbeb9454
AS
692 * @param network unaligned address to write network order value to
693 */
694static inline void htoun64(void *network, u_int64_t host)
695{
696 char *unaligned = (char*)network;
f4e25e60
MW
697
698#ifdef be64toh
699 host = htobe64(host);
700 memcpy((char*)unaligned, &host, sizeof(host));
701#else
fbeb9454
AS
702 u_int32_t high_part, low_part;
703
704 high_part = host >> 32;
705 high_part = htonl(high_part);
706 low_part = host & 0xFFFFFFFFLL;
707 low_part = htonl(low_part);
708
709 memcpy(unaligned, &high_part, sizeof(high_part));
710 unaligned += sizeof(high_part);
711 memcpy(unaligned, &low_part, sizeof(low_part));
f4e25e60 712#endif
fbeb9454
AS
713}
714
0be12e35
MW
715/**
716 * Read a 16-bit value in network order from an unaligned address to host order.
717 *
718 * @param network unaligned address to read network order value from
719 * @return host order value
720 */
721static inline u_int16_t untoh16(void *network)
722{
dbee988e 723 char *unaligned = (char*)network;
0be12e35
MW
724 u_int16_t tmp;
725
dbee988e 726 memcpy(&tmp, unaligned, sizeof(tmp));
0be12e35
MW
727 return ntohs(tmp);
728}
729
730/**
731 * Read a 32-bit value in network order from an unaligned address to host order.
732 *
733 * @param network unaligned address to read network order value from
734 * @return host order value
735 */
736static inline u_int32_t untoh32(void *network)
737{
dbee988e 738 char *unaligned = (char*)network;
0be12e35
MW
739 u_int32_t tmp;
740
dbee988e 741 memcpy(&tmp, unaligned, sizeof(tmp));
f8f4f31a 742 return ntohl(tmp);
0be12e35
MW
743}
744
fbeb9454
AS
745/**
746 * Read a 64-bit value in network order from an unaligned address to host order.
747 *
748 * @param network unaligned address to read network order value from
749 * @return host order value
750 */
751static inline u_int64_t untoh64(void *network)
752{
753 char *unaligned = (char*)network;
f4e25e60
MW
754
755#ifdef be64toh
756 u_int64_t tmp;
757
758 memcpy(&tmp, unaligned, sizeof(tmp));
759 return be64toh(tmp);
760#else
fbeb9454
AS
761 u_int32_t high_part, low_part;
762
763 memcpy(&high_part, unaligned, sizeof(high_part));
764 unaligned += sizeof(high_part);
765 memcpy(&low_part, unaligned, sizeof(low_part));
766
767 high_part = ntohl(high_part);
768 low_part = ntohl(low_part);
769
770 return (((u_int64_t)high_part) << 32) + low_part;
f4e25e60 771#endif
fbeb9454
AS
772}
773
84044f9c 774/**
812ae898 775 * Get the padding required to make size a multiple of alignment
84044f9c 776 */
812ae898 777static inline size_t pad_len(size_t size, size_t alignment)
84044f9c 778{
812ae898 779 size_t remainder;
84044f9c 780
812ae898
TB
781 remainder = size % alignment;
782 return remainder ? alignment - remainder : 0;
783}
784
785/**
786 * Round up size to be multiple of alignment
787 */
788static inline size_t round_up(size_t size, size_t alignment)
789{
790 return size + pad_len(size, alignment);
84044f9c
MW
791}
792
793/**
812ae898 794 * Round down size to be a multiple of alignment
84044f9c 795 */
812ae898 796static inline size_t round_down(size_t size, size_t alignment)
84044f9c 797{
812ae898 798 return size - (size % alignment);
84044f9c
MW
799}
800
552cc11b
MW
801/**
802 * Special type to count references
803 */
4d04e2c6 804typedef u_int refcount_t;
efd0fe21 805
a0c2370e
TB
806/* use __atomic* built-ins with GCC 4.7 and newer */
807#ifdef __GNUC__
808# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
809# define HAVE_GCC_ATOMIC_OPERATIONS
810# endif
811#endif
812
efd0fe21
MW
813#ifdef HAVE_GCC_ATOMIC_OPERATIONS
814
0f603d42
TB
815#define ref_get(ref) __atomic_add_fetch(ref, 1, __ATOMIC_RELAXED)
816/* The relaxed memory model works fine for increments as these (usually) don't
817 * change the state of refcounted objects. But here we have to ensure that we
818 * free the right stuff if ref counted objects are mutable. So we have to sync
819 * with other threads that call ref_put(). It would be sufficient to use
820 * __ATOMIC_RELEASE here and then call __atomic_thread_fence() with
821 * __ATOMIC_ACQUIRE if we reach 0, but since we don't have control over the use
822 * of ref_put() we have to make sure. */
823#define ref_put(ref) (!__atomic_sub_fetch(ref, 1, __ATOMIC_ACQ_REL))
824#define ref_cur(ref) __atomic_load_n(ref, __ATOMIC_RELAXED)
825
826#define _cas_impl(ptr, oldval, newval) ({ typeof(oldval) _old = oldval; \
827 __atomic_compare_exchange_n(ptr, &_old, newval, FALSE, \
828 __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); })
829#define cas_bool(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
830#define cas_ptr(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
831
832#elif defined(HAVE_GCC_SYNC_OPERATIONS)
833
3160b92a 834#define ref_get(ref) __sync_add_and_fetch(ref, 1)
efd0fe21 835#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
efedd0d2 836#define ref_cur(ref) __sync_fetch_and_add(ref, 0)
efd0fe21 837
5317dd68
TB
838#define cas_bool(ptr, oldval, newval) \
839 (__sync_bool_compare_and_swap(ptr, oldval, newval))
840#define cas_ptr(ptr, oldval, newval) \
841 (__sync_bool_compare_and_swap(ptr, oldval, newval))
842
0f603d42 843#else /* !HAVE_GCC_ATOMIC_OPERATIONS && !HAVE_GCC_SYNC_OPERATIONS */
efd0fe21 844
552cc11b
MW
845/**
846 * Get a new reference.
847 *
efedd0d2 848 * Increments the reference counter atomically.
552cc11b
MW
849 *
850 * @param ref pointer to ref counter
3160b92a 851 * @return new value of ref
552cc11b 852 */
3160b92a 853refcount_t ref_get(refcount_t *ref);
552cc11b
MW
854
855/**
856 * Put back a unused reference.
857 *
efedd0d2 858 * Decrements the reference counter atomically and
552cc11b
MW
859 * says if more references available.
860 *
861 * @param ref pointer to ref counter
862 * @return TRUE if no more references counted
863 */
864bool ref_put(refcount_t *ref);
865
efedd0d2
TB
866/**
867 * Get the current value of the reference counter.
868 *
869 * @param ref pointer to ref counter
870 * @return current value of ref
871 */
872refcount_t ref_cur(refcount_t *ref);
873
5317dd68
TB
874/**
875 * Atomically replace value of ptr with newval if it currently equals oldval.
876 *
877 * @param ptr pointer to variable
878 * @param oldval old value of the variable
879 * @param newval new value set if possible
880 * @return TRUE if value equaled oldval and newval was written
881 */
882bool cas_bool(bool *ptr, bool oldval, bool newval);
883
884/**
885 * Atomically replace value of ptr with newval if it currently equals oldval.
886 *
887 * @param ptr pointer to variable
888 * @param oldval old value of the variable
889 * @param newval new value set if possible
890 * @return TRUE if value equaled oldval and newval was written
891 */
892bool cas_ptr(void **ptr, void *oldval, void *newval);
893
efd0fe21
MW
894#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
895
2077d996
MW
896#ifndef HAVE_FMEMOPEN
897# ifdef HAVE_FUNOPEN
9df621d2
MW
898# define HAVE_FMEMOPEN
899# define HAVE_FMEMOPEN_FALLBACK
5ac29360 900# include <stdio.h>
2077d996
MW
901/**
902 * fmemopen(3) fallback using BSD funopen.
903 *
904 * We could also provide one using fopencookie(), but should we have it we
905 * most likely have fmemopen().
906 *
907 * fseek() is currently not supported.
908 */
909FILE *fmemopen(void *buf, size_t size, const char *mode);
910# endif /* FUNOPEN */
911#endif /* FMEMOPEN */
912
552cc11b 913/**
d25ce370 914 * printf hook for time_t.
552cc11b 915 *
7daf5226 916 * Arguments are:
323f9f99 917 * time_t* time, bool utc
552cc11b 918 */
1b40b74d 919int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
d25ce370 920 const void *const *args);
552cc11b
MW
921
922/**
d25ce370 923 * printf hook for time_t deltas.
552cc11b 924 *
7daf5226 925 * Arguments are:
323f9f99 926 * time_t* begin, time_t* end
552cc11b 927 */
1b40b74d 928int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
d25ce370 929 const void *const *args);
552cc11b
MW
930
931/**
d25ce370 932 * printf hook for memory areas.
552cc11b 933 *
7daf5226 934 * Arguments are:
817ab8a8 935 * u_char *ptr, u_int len
552cc11b 936 */
1b40b74d 937int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
d25ce370 938 const void *const *args);
552cc11b 939
1490ff4d 940#endif /** UTILS_H_ @}*/