Set prefixes in fr_sockaddr2ipaddr
[freeradius.git] / src / lib / misc.c
1 /*
2  * misc.c       Various miscellaneous functions.
3  *
4  * Version:     $Id$
5  *
6  *   This library is free software; you can redistribute it and/or
7  *   modify it under the terms of the GNU Lesser General Public
8  *   License as published by the Free Software Foundation; either
9  *   version 2.1 of the License, or (at your option) any later version.
10  *
11  *   This library is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  *   Lesser General Public License for more details.
15  *
16  *   You should have received a copy of the GNU Lesser General Public
17  *   License along with this library; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2006  The FreeRADIUS server project
21  */
22
23 RCSID("$Id$")
24
25 #include        <freeradius-devel/libradius.h>
26
27 #include        <ctype.h>
28 #include        <sys/file.h>
29 #include        <fcntl.h>
30
31 #define FR_PUT_LE16(a, val)\
32         do {\
33                 a[1] = ((uint16_t) (val)) >> 8;\
34                 a[0] = ((uint16_t) (val)) & 0xff;\
35         } while (0)
36
37 #ifdef HAVE_PTHREAD_H
38 static pthread_mutex_t autofree_context = PTHREAD_MUTEX_INITIALIZER;
39 #  define PTHREAD_MUTEX_LOCK pthread_mutex_lock
40 #  define PTHREAD_MUTEX_UNLOCK pthread_mutex_unlock
41 #else
42 #  define PTHREAD_MUTEX_LOCK(_x)
43 #  define PTHREAD_MUTEX_UNLOCK(_x)
44 #endif
45
46 bool    fr_dns_lookups = false;     /* IP -> hostname lookups? */
47 bool    fr_hostname_lookups = true; /* hostname -> IP lookups? */
48 int     fr_debug_flag = 0;
49
50 static char const *months[] = {
51         "jan", "feb", "mar", "apr", "may", "jun",
52         "jul", "aug", "sep", "oct", "nov", "dec" };
53
54 fr_thread_local_setup(char *, fr_inet_ntop_buffer);     /* macro */
55
56 /** Sets a signal handler using sigaction if available, else signal
57  *
58  * @param sig to set handler for.
59  * @param func handler to set.
60  */
61 int fr_set_signal(int sig, sig_t func)
62 {
63 #ifdef HAVE_SIGACTION
64         struct sigaction act;
65
66         memset(&act, 0, sizeof(act));
67         act.sa_flags = 0;
68         sigemptyset(&act.sa_mask);
69         act.sa_handler = func;
70
71         if (sigaction(sig, &act, NULL) < 0) {
72                 fr_strerror_printf("Failed setting signal %i handler via sigaction(): %s", sig, fr_syserror(errno));
73                 return -1;
74         }
75 #else
76         if (signal(sig, func) < 0) {
77                 fr_strerror_printf("Failed setting signal %i handler via signal(): %s", sig, fr_syserror(errno));
78                 return -1;
79         }
80 #endif
81         return 0;
82 }
83
84 /** Allocates a new talloc context from the root autofree context
85  *
86  * This function is threadsafe, whereas using the NULL context is not.
87  *
88  * @note The returned context must be freed by the caller.
89  * @returns a new talloc context parented by the root autofree context.
90  */
91 TALLOC_CTX *fr_autofree_ctx(void)
92 {
93         static TALLOC_CTX *ctx = NULL, *child;
94         PTHREAD_MUTEX_LOCK(&autofree_context);
95         if (!ctx) {
96                 ctx = talloc_autofree_context();
97         }
98
99         child = talloc_new(ctx);
100         PTHREAD_MUTEX_UNLOCK(&autofree_context);
101
102         return child;
103 }
104
105 /*
106  *      Explicitly cleanup the memory allocated to the error inet_ntop
107  *      buffer.
108  */
109 static void _fr_inet_ntop_free(void *arg)
110 {
111         free(arg);
112 }
113
114 /** Wrapper around inet_ntop, prints IPv4/IPv6 addresses
115  *
116  * inet_ntop requires the caller pass in a buffer for the address.
117  * This would be annoying and cumbersome, seeing as quite often the ASCII
118  * address is only used for logging output.
119  *
120  * So as with lib/log.c use TLS to allocate thread specific buffers, and
121  * write the IP address there instead.
122  *
123  * @param af address family, either AF_INET or AF_INET6.
124  * @param src pointer to network address structure.
125  * @return NULL on error, else pointer to ASCII buffer containing text version of address.
126  */
127 char const *fr_inet_ntop(int af, void const *src)
128 {
129         char *buffer;
130
131         if (!src) {
132                 return NULL;
133         }
134
135         buffer = fr_thread_local_init(fr_inet_ntop_buffer, _fr_inet_ntop_free);
136         if (!buffer) {
137                 int ret;
138
139                 /*
140                  *      malloc is thread safe, talloc is not
141                  */
142                 buffer = malloc(sizeof(char) * INET6_ADDRSTRLEN);
143                 if (!buffer) {
144                         fr_perror("Failed allocating memory for inet_ntop buffer");
145                         return NULL;
146                 }
147
148                 ret = fr_thread_local_set(fr_inet_ntop_buffer, buffer);
149                 if (ret != 0) {
150                         fr_perror("Failed setting up TLS for inet_ntop buffer: %s", fr_syserror(ret));
151                         free(buffer);
152                         return NULL;
153                 }
154         }
155         buffer[0] = '\0';
156
157         return inet_ntop(af, src, buffer, INET6_ADDRSTRLEN);
158 }
159
160 /*
161  *      Return an IP address in standard dot notation
162  *
163  *      FIXME: DELETE THIS
164  */
165 char const *ip_ntoa(char *buffer, uint32_t ipaddr)
166 {
167         ipaddr = ntohl(ipaddr);
168
169         sprintf(buffer, "%d.%d.%d.%d",
170                 (ipaddr >> 24) & 0xff,
171                 (ipaddr >> 16) & 0xff,
172                 (ipaddr >>  8) & 0xff,
173                 (ipaddr      ) & 0xff);
174         return buffer;
175 }
176
177 /** Parse an IPv4 address or IPv4 prefix in presentation format (and others)
178  *
179  * @param out Where to write the ip address value.
180  * @param value to parse, may be dotted quad [+ prefix], or integer, or octal number, or '*' (INADDR_ANY).
181  * @param inlen Length of value, if value is \0 terminated inlen may be 0.
182  * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
183  * @param fallback to IPv4 resolution if no A records can be found.
184  * @return 0 if ip address was parsed successfully, else -1 on error.
185  */
186 int fr_pton4(fr_ipaddr_t *out, char const *value, size_t inlen, bool resolve, bool fallback)
187 {
188         char *p;
189         unsigned int prefix;
190         char *eptr;
191
192         /* Dotted quad + / + [0-9]{1,2} */
193         char buffer[INET_ADDRSTRLEN + 3];
194
195         /*
196          *      Copy to intermediary buffer if we were given a length
197          */
198         if (inlen > 0) {
199                 if (inlen >= sizeof(buffer)) {
200                         fr_strerror_printf("Invalid IPv4 address string \"%s\"", value);
201                         return -1;
202                 }
203                 memcpy(buffer, value, inlen);
204                 buffer[inlen] = '\0';
205         }
206
207         p = strchr(value, '/');
208         /*
209          *      192.0.2.2 is parsed as if it was /32
210          */
211         if (!p) {
212                 /*
213                  *      Allow '*' as the wildcard address usually 0.0.0.0
214                  */
215                 if ((value[0] == '*') && (value[1] == '\0')) {
216                         out->ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
217                 /*
218                  *      Convert things which are obviously integers to IP addresses
219                  *
220                  *      We assume the number is the bigendian representation of the
221                  *      IP address.
222                  */
223                 } else if (is_integer(value)) {
224                         out->ipaddr.ip4addr.s_addr = htonl(strtoul(value, NULL, 0));
225                 } else if (!resolve) {
226                         if (inet_pton(AF_INET, value, &(out->ipaddr.ip4addr.s_addr)) <= 0) {
227                                 fr_strerror_printf("Failed to parse IPv4 address string \"%s\"", value);
228                                 return -1;
229                         }
230                 } else if (ip_hton(out, AF_INET, value, fallback) < 0) return -1;
231
232                 out->prefix = 32;
233                 out->af = AF_INET;
234
235                 return 0;
236         }
237
238         /*
239          *      Otherwise parse the prefix
240          */
241         if ((size_t)(p - value) >= INET_ADDRSTRLEN) {
242                 fr_strerror_printf("Invalid IPv4 address string \"%s\"", value);
243                 return -1;
244         }
245
246         /*
247          *      Copy the IP portion into a temporary buffer if we haven't already.
248          */
249         if (inlen == 0) memcpy(buffer, value, p - value);
250         buffer[p - value] = '\0';
251
252         if (!resolve) {
253                 if (inet_pton(AF_INET, buffer, &(out->ipaddr.ip4addr.s_addr)) <= 0) {
254                         fr_strerror_printf("Failed to parse IPv4 address string \"%s\"", value);
255                         return -1;
256                 }
257         } else if (ip_hton(out, AF_INET, buffer, fallback) < 0) return -1;
258
259         prefix = strtoul(p + 1, &eptr, 10);
260         if (prefix > 32) {
261                 fr_strerror_printf("Invalid IPv4 mask length \"%s\".  Should be between 0-32", p);
262                 return -1;
263         }
264         if (eptr[0] != '\0') {
265                 fr_strerror_printf("Failed to parse IPv4 address string \"%s\", "
266                                    "got garbage after mask length \"%s\"", value, eptr);
267                 return -1;
268         }
269
270         if (prefix < 32) {
271                 out->ipaddr.ip4addr = fr_inaddr_mask(&(out->ipaddr.ip4addr), prefix);
272         }
273
274         out->prefix = (uint8_t) prefix;
275         out->af = AF_INET;
276
277         return 0;
278 }
279
280 /** Parse an IPv6 address or IPv6 prefix in presentation format (and others)
281  *
282  * @param out Where to write the ip address value.
283  * @param value to parse.
284  * @param inlen Length of value, if value is \0 terminated inlen may be 0.
285  * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
286  * @param fallback to IPv4 resolution if no AAAA records can be found.
287  * @return 0 if ip address was parsed successfully, else -1 on error.
288  */
289 int fr_pton6(fr_ipaddr_t *out, char const *value, size_t inlen, bool resolve, bool fallback)
290 {
291         char const *p;
292         unsigned int prefix;
293         char *eptr;
294
295         /* IPv6  + / + [0-9]{1,3} */
296         char buffer[INET6_ADDRSTRLEN + 4];
297
298         /*
299          *      Copy to intermediary buffer if we were given a length
300          */
301         if (inlen > 0) {
302                 if (inlen >= sizeof(buffer)) {
303                         fr_strerror_printf("Invalid IPv6 address string \"%s\"", value);
304                         return -1;
305                 }
306                 memcpy(buffer, value, inlen);
307                 buffer[inlen] = '\0';
308         }
309
310         p = strchr(value, '/');
311         if (!p) {
312                 /*
313                  *      Allow '*' as the wildcard address
314                  */
315                 if ((value[0] == '*') && (value[1] == '\0')) {
316                         memset(&out->ipaddr.ip6addr.s6_addr, 0, sizeof(out->ipaddr.ip6addr.s6_addr));
317                 } else if (!resolve) {
318                         if (inet_pton(AF_INET6, value, &(out->ipaddr.ip6addr.s6_addr)) <= 0) {
319                                 fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
320                                 return -1;
321                         }
322                 } else if (ip_hton(out, AF_INET6, value, fallback) < 0) return -1;
323
324                 out->prefix = 128;
325                 out->af = AF_INET6;
326
327                 return 0;
328         }
329
330         if ((p - value) >= INET6_ADDRSTRLEN) {
331                 fr_strerror_printf("Invalid IPv6 address string \"%s\"", value);
332                 return -1;
333         }
334
335         /*
336          *      Copy string to temporary buffer if we didn't do it earlier
337          */
338         if (inlen == 0) memcpy(buffer, value, p - value);
339         buffer[p - value] = '\0';
340
341         if (!resolve) {
342                 if (inet_pton(AF_INET6, buffer, &(out->ipaddr.ip6addr.s6_addr)) <= 0) {
343                         fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
344                         return -1;
345                 }
346         } else if (ip_hton(out, AF_INET6, buffer, fallback) < 0) return -1;
347
348         prefix = strtoul(p + 1, &eptr, 10);
349         if (prefix > 128) {
350                 fr_strerror_printf("Invalid IPv6 mask length \"%s\".  Should be between 0-128", p);
351                 return -1;
352         }
353         if (eptr[0] != '\0') {
354                 fr_strerror_printf("Failed to parse IPv6 address string \"%s\", "
355                                    "got garbage after mask length \"%s\"", value, eptr);
356                 return -1;
357         }
358
359         if (prefix < 128) {
360                 struct in6_addr addr;
361
362                 addr = fr_in6addr_mask(&(out->ipaddr.ip6addr), prefix);
363                 memcpy(&(out->ipaddr.ip6addr.s6_addr), &addr, sizeof(addr));
364         }
365
366         out->prefix = (uint8_t) prefix;
367         out->af = AF_INET6;
368
369         return 0;
370 }
371
372 /** Simple wrapper to decide whether an IP value is v4 or v6 and call the appropriate parser.
373  *
374  * @param out Where to write the ip address value.
375  * @param value to parse.
376  * @param inlen Length of value, if value is \0 terminated inlen may be 0.
377  * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
378  * @return 0 if ip address was parsed successfully, else -1 on error.
379  */
380 int fr_pton(fr_ipaddr_t *out, char const *value, size_t inlen, bool resolve)
381 {
382         char const *p;
383         int af = AF_INET;
384
385         for (p = value; *p != '\0'; p++) {
386                 if ((*p == ':') ||
387                     (*p == '[') ||
388                     (*p == ']')) {
389                         af = AF_INET6;
390                         break;
391                 }
392         }
393
394         switch (af) {
395         case AF_INET:
396                 return fr_pton4(out, value, inlen, resolve, true);
397
398         /*
399          *      If we found ':' or '[' or ']' in the above string, there's
400          *      no way this can be a hostname, so don't try to resolve.
401          */
402         case AF_INET6:
403                 return fr_pton6(out, value, inlen, false, false);
404
405         default:
406                 return -1;
407         }
408 }
409
410 /** Check if the IP address is equivalent to INADDR_ANY
411  *
412  * @param addr to chec.
413  * @return true if IP address matches INADDR_ANY or INADDR6_ANY (assumed to be 0), else false.
414  */
415 bool is_wildcard(fr_ipaddr_t *addr)
416 {
417         static struct in6_addr in6_addr;
418
419         switch (addr->af) {
420         case AF_INET:
421                 return (addr->ipaddr.ip4addr.s_addr == htons(INADDR_ANY));
422
423         case AF_INET6:
424                 return (memcmp(addr->ipaddr.ip6addr.s6_addr, in6_addr.s6_addr, sizeof(in6_addr.s6_addr)) == 0) ? true :false;
425
426         default:
427                 fr_assert(0);
428                 return false;
429         }
430 }
431
432 int fr_ntop(char *out, size_t outlen, fr_ipaddr_t *addr)
433 {
434         char buffer[INET6_ADDRSTRLEN];
435
436         if (inet_ntop(addr->af, &(addr->ipaddr), buffer, sizeof(buffer)) == NULL) return -1;
437
438         return snprintf(out, outlen, "%s/%i", buffer, addr->prefix);
439 }
440
441 /*
442  *      Internal wrapper for locking, to minimize the number of ifdef's
443  *
444  *      Use fcntl or error
445  */
446 int rad_lockfd(int fd, int lock_len)
447 {
448 #ifdef F_WRLCK
449         struct flock fl;
450
451         fl.l_start = 0;
452         fl.l_len = lock_len;
453         fl.l_pid = getpid();
454         fl.l_type = F_WRLCK;
455         fl.l_whence = SEEK_CUR;
456
457         return fcntl(fd, F_SETLKW, (void *)&fl);
458 #else
459 #error "missing definition for F_WRLCK, all file locks will fail"
460
461         return -1;
462 #endif
463 }
464
465 /*
466  *      Internal wrapper for locking, to minimize the number of ifdef's
467  *
468  *      Lock an fd, prefer lockf() over flock()
469  *      Nonblocking version.
470  */
471 int rad_lockfd_nonblock(int fd, int lock_len)
472 {
473 #ifdef F_WRLCK
474         struct flock fl;
475
476         fl.l_start = 0;
477         fl.l_len = lock_len;
478         fl.l_pid = getpid();
479         fl.l_type = F_WRLCK;
480         fl.l_whence = SEEK_CUR;
481
482         return fcntl(fd, F_SETLK, (void *)&fl);
483 #else
484 #error "missing definition for F_WRLCK, all file locks will fail"
485
486         return -1;
487 #endif
488 }
489
490 /*
491  *      Internal wrapper for unlocking, to minimize the number of ifdef's
492  *      in the source.
493  *
494  *      Unlock an fd, prefer lockf() over flock()
495  */
496 int rad_unlockfd(int fd, int lock_len)
497 {
498 #ifdef F_WRLCK
499         struct flock fl;
500
501         fl.l_start = 0;
502         fl.l_len = lock_len;
503         fl.l_pid = getpid();
504         fl.l_type = F_WRLCK;
505         fl.l_whence = SEEK_CUR;
506
507         return fcntl(fd, F_UNLCK, (void *)&fl);
508 #else
509 #error "missing definition for F_WRLCK, all file locks will fail"
510
511         return -1;
512 #endif
513 }
514
515 /*
516  *      Return an interface-id in standard colon notation
517  */
518 char *ifid_ntoa(char *buffer, size_t size, uint8_t const *ifid)
519 {
520         snprintf(buffer, size, "%x:%x:%x:%x",
521                  (ifid[0] << 8) + ifid[1], (ifid[2] << 8) + ifid[3],
522                  (ifid[4] << 8) + ifid[5], (ifid[6] << 8) + ifid[7]);
523         return buffer;
524 }
525
526
527 /*
528  *      Return an interface-id from
529  *      one supplied in standard colon notation.
530  */
531 uint8_t *ifid_aton(char const *ifid_str, uint8_t *ifid)
532 {
533         static char const xdigits[] = "0123456789abcdef";
534         char const *p, *pch;
535         int num_id = 0, val = 0, idx = 0;
536
537         for (p = ifid_str; ; ++p) {
538                 if (*p == ':' || *p == '\0') {
539                         if (num_id <= 0)
540                                 return NULL;
541
542                         /*
543                          *      Drop 'val' into the array.
544                          */
545                         ifid[idx] = (val >> 8) & 0xff;
546                         ifid[idx + 1] = val & 0xff;
547                         if (*p == '\0') {
548                                 /*
549                                  *      Must have all entries before
550                                  *      end of the string.
551                                  */
552                                 if (idx != 6)
553                                         return NULL;
554                                 break;
555                         }
556                         val = 0;
557                         num_id = 0;
558                         if ((idx += 2) > 6)
559                                 return NULL;
560                 } else if ((pch = strchr(xdigits, tolower(*p))) != NULL) {
561                         if (++num_id > 4)
562                                 return NULL;
563                         /*
564                          *      Dumb version of 'scanf'
565                          */
566                         val <<= 4;
567                         val |= (pch - xdigits);
568                 } else
569                         return NULL;
570         }
571         return ifid;
572 }
573
574
575 #ifndef HAVE_INET_PTON
576 static int inet_pton4(char const *src, struct in_addr *dst)
577 {
578         int octet;
579         unsigned int num;
580         char const *p, *off;
581         uint8_t tmp[4];
582         static char const digits[] = "0123456789";
583
584         octet = 0;
585         p = src;
586         while (1) {
587                 num = 0;
588                 while (*p && ((off = strchr(digits, *p)) != NULL)) {
589                         num *= 10;
590                         num += (off - digits);
591
592                         if (num > 255) return 0;
593
594                         p++;
595                 }
596                 if (!*p) break;
597
598                 /*
599                  *      Not a digit, MUST be a dot, else we
600                  *      die.
601                  */
602                 if (*p != '.') {
603                         return 0;
604                 }
605
606                 tmp[octet++] = num;
607                 p++;
608         }
609
610         /*
611          *      End of the string.  At the fourth
612          *      octet is OK, anything else is an
613          *      error.
614          */
615         if (octet != 3) {
616                 return 0;
617         }
618         tmp[3] = num;
619
620         memcpy(dst, &tmp, sizeof(tmp));
621         return 1;
622 }
623
624
625 #ifdef HAVE_STRUCT_SOCKADDR_IN6
626 /* int
627  * inet_pton6(src, dst)
628  *      convert presentation level address to network order binary form.
629  * return:
630  *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
631  * notice:
632  *      (1) does not touch `dst' unless it's returning 1.
633  *      (2) :: in a full address is silently ignored.
634  * credit:
635  *      inspired by Mark Andrews.
636  * author:
637  *      Paul Vixie, 1996.
638  */
639 static int inet_pton6(char const *src, unsigned char *dst)
640 {
641         static char const xdigits_l[] = "0123456789abcdef",
642                           xdigits_u[] = "0123456789ABCDEF";
643         u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
644         char const *xdigits, *curtok;
645         int ch, saw_xdigit;
646         u_int val;
647
648         memset((tp = tmp), 0, IN6ADDRSZ);
649         endp = tp + IN6ADDRSZ;
650         colonp = NULL;
651         /* Leading :: requires some special handling. */
652         if (*src == ':')
653                 if (*++src != ':')
654                         return (0);
655         curtok = src;
656         saw_xdigit = 0;
657         val = 0;
658         while ((ch = *src++) != '\0') {
659                 char const *pch;
660
661                 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
662                         pch = strchr((xdigits = xdigits_u), ch);
663                 if (pch != NULL) {
664                         val <<= 4;
665                         val |= (pch - xdigits);
666                         if (val > 0xffff)
667                                 return (0);
668                         saw_xdigit = 1;
669                         continue;
670                 }
671                 if (ch == ':') {
672                         curtok = src;
673                         if (!saw_xdigit) {
674                                 if (colonp)
675                                         return (0);
676                                 colonp = tp;
677                                 continue;
678                         }
679                         if (tp + INT16SZ > endp)
680                                 return (0);
681                         *tp++ = (u_char) (val >> 8) & 0xff;
682                         *tp++ = (u_char) val & 0xff;
683                         saw_xdigit = 0;
684                         val = 0;
685                         continue;
686                 }
687                 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
688                     inet_pton4(curtok, (struct in_addr *) tp) > 0) {
689                         tp += INADDRSZ;
690                         saw_xdigit = 0;
691                         break;  /* '\0' was seen by inet_pton4(). */
692                 }
693                 return (0);
694         }
695         if (saw_xdigit) {
696                 if (tp + INT16SZ > endp)
697                         return (0);
698                 *tp++ = (u_char) (val >> 8) & 0xff;
699                 *tp++ = (u_char) val & 0xff;
700         }
701         if (colonp != NULL) {
702                 /*
703                  * Since some memmove()'s erroneously fail to handle
704                  * overlapping regions, we'll do the shift by hand.
705                  */
706                 int const n = tp - colonp;
707                 int i;
708
709                 for (i = 1; i <= n; i++) {
710                         endp[- i] = colonp[n - i];
711                         colonp[n - i] = 0;
712                 }
713                 tp = endp;
714         }
715         if (tp != endp)
716                 return (0);
717         /* bcopy(tmp, dst, IN6ADDRSZ); */
718         memcpy(dst, tmp, IN6ADDRSZ);
719         return (1);
720 }
721 #endif
722
723 /*
724  *      Utility function, so that the rest of the server doesn't
725  *      have ifdef's around IPv6 support
726  */
727 int inet_pton(int af, char const *src, void *dst)
728 {
729         if (af == AF_INET) {
730                 return inet_pton4(src, dst);
731         }
732 #ifdef HAVE_STRUCT_SOCKADDR_IN6
733
734         if (af == AF_INET6) {
735                 return inet_pton6(src, dst);
736         }
737 #endif
738
739         return -1;
740 }
741 #endif
742
743 #ifndef HAVE_INET_NTOP
744 /*
745  *      Utility function, so that the rest of the server doesn't
746  *      have ifdef's around IPv6 support
747  */
748 char const *inet_ntop(int af, void const *src, char *dst, size_t cnt)
749 {
750         if (af == AF_INET) {
751                 uint8_t const *ipaddr = src;
752
753                 if (cnt <= INET_ADDRSTRLEN) return NULL;
754
755                 snprintf(dst, cnt, "%d.%d.%d.%d",
756                          ipaddr[0], ipaddr[1],
757                          ipaddr[2], ipaddr[3]);
758                 return dst;
759         }
760
761         /*
762          *      If the system doesn't define this, we define it
763          *      in missing.h
764          */
765         if (af == AF_INET6) {
766                 struct in6_addr const *ipaddr = src;
767
768                 if (cnt <= INET6_ADDRSTRLEN) return NULL;
769
770                 snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x",
771                          (ipaddr->s6_addr[0] << 8) | ipaddr->s6_addr[1],
772                          (ipaddr->s6_addr[2] << 8) | ipaddr->s6_addr[3],
773                          (ipaddr->s6_addr[4] << 8) | ipaddr->s6_addr[5],
774                          (ipaddr->s6_addr[6] << 8) | ipaddr->s6_addr[7],
775                          (ipaddr->s6_addr[8] << 8) | ipaddr->s6_addr[9],
776                          (ipaddr->s6_addr[10] << 8) | ipaddr->s6_addr[11],
777                          (ipaddr->s6_addr[12] << 8) | ipaddr->s6_addr[13],
778                          (ipaddr->s6_addr[14] << 8) | ipaddr->s6_addr[15]);
779                 return dst;
780         }
781
782         return NULL;            /* don't support IPv6 */
783 }
784 #endif
785
786 /** Wrappers for IPv4/IPv6 host to IP address lookup
787  *
788  * This function returns only one IP address, of the specified address family,
789  * or the first address (of whatever family), if AF_UNSPEC is used.
790  *
791  * If fallback is specified and af is AF_INET, but no AF_INET records were
792  * found and a record for AF_INET6 exists that record will be returned.
793  *
794  * If fallback is specified and af is AF_INET6, and a record with AF_INET4 exists
795  * that record will be returned instead.
796  *
797  * @param out Where to write result.
798  * @param af To search for in preference.
799  * @param hostname to search for.
800  * @param fallback to the other adress family, if no records matching af, found.
801  * @return 0 on success, else -1 on failure.
802  */
803 int ip_hton(fr_ipaddr_t *out, int af, char const *hostname, bool fallback)
804 {
805         int rcode;
806         struct addrinfo hints, *ai = NULL, *alt = NULL, *res = NULL;
807
808         if (!fr_hostname_lookups) {
809 #ifdef HAVE_STRUCT_SOCKADDR_IN6
810                 if (af == AF_UNSPEC) {
811                         char const *p;
812
813                         for (p = hostname; *p != '\0'; p++) {
814                                 if ((*p == ':') ||
815                                     (*p == '[') ||
816                                     (*p == ']')) {
817                                         af = AF_INET6;
818                                         break;
819                                 }
820                         }
821                 }
822 #endif
823
824                 if (af == AF_UNSPEC) af = AF_INET;
825
826                 if (!inet_pton(af, hostname, &(out->ipaddr))) {
827                         return -1;
828                 }
829
830                 out->af = af;
831                 return 0;
832         }
833
834         memset(&hints, 0, sizeof(hints));
835         hints.ai_family = af;
836
837 #ifdef TALLOC_DEBUG
838         /*
839          *      Avoid malloc for IP addresses.  This helps us debug
840          *      memory errors when using talloc.
841          */
842         if (af == AF_INET) {
843                 /*
844                  *      If it's all numeric, avoid getaddrinfo()
845                  */
846                 if (inet_pton(af, hostname, &out->ipaddr.ip4addr) == 1) {
847                         return 0;
848                 }
849         }
850 #endif
851
852         if ((rcode = getaddrinfo(hostname, NULL, &hints, &res)) != 0) {
853                 fr_strerror_printf("ip_hton: %s", gai_strerror(rcode));
854                 return -1;
855         }
856
857         for (ai = res; ai; ai = ai->ai_next) {
858                 if ((af == ai->ai_family) || (af == AF_UNSPEC)) break;
859                 if (!alt && fallback && ((ai->ai_family == AF_INET) || (ai->ai_family == AF_INET6))) alt = ai;
860         }
861
862         if (!ai) ai = alt;
863         if (!ai) {
864                 fr_strerror_printf("ip_hton failed to find requested information for host %.100s", hostname);
865                 freeaddrinfo(ai);
866                 return -1;
867         }
868
869         rcode = fr_sockaddr2ipaddr((struct sockaddr_storage *)ai->ai_addr,
870                                    ai->ai_addrlen, out, NULL);
871         freeaddrinfo(ai);
872         if (!rcode) return -1;
873
874         return 0;
875 }
876
877 /*
878  *      Look IP addresses up, and print names (depending on DNS config)
879  */
880 char const *ip_ntoh(fr_ipaddr_t const *src, char *dst, size_t cnt)
881 {
882         struct sockaddr_storage ss;
883         int error;
884         socklen_t salen;
885
886         /*
887          *      No DNS lookups
888          */
889         if (!fr_dns_lookups) {
890                 return inet_ntop(src->af, &(src->ipaddr), dst, cnt);
891         }
892
893         if (!fr_ipaddr2sockaddr(src, 0, &ss, &salen)) {
894                 return NULL;
895         }
896
897         if ((error = getnameinfo((struct sockaddr *)&ss, salen, dst, cnt, NULL, 0,
898                                  NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
899                 fr_strerror_printf("ip_ntoh: %s", gai_strerror(error));
900                 return NULL;
901         }
902         return dst;
903 }
904
905 /** Mask off a portion of an IPv4 address
906  *
907  * @param ipaddr to mask.
908  * @param prefix Number of contiguous bits to mask.
909  * @return an ipv6 address with the host portion zeroed out.
910  */
911 struct in_addr fr_inaddr_mask(struct in_addr const *ipaddr, uint8_t prefix)
912 {
913         uint32_t ret;
914
915         if (prefix > 32) {
916                 prefix = 32;
917         }
918
919         /* Short circuit */
920         if (prefix == 32) {
921                 return *ipaddr;
922         }
923
924         ret = htonl(~((0x00000001UL << (32 - prefix)) - 1)) & ipaddr->s_addr;
925         return (*(struct in_addr *)&ret);
926 }
927
928 /** Mask off a portion of an IPv6 address
929  *
930  * @param ipaddr to mask.
931  * @param prefix Number of contiguous bits to mask.
932  * @return an ipv6 address with the host portion zeroed out.
933  */
934 struct in6_addr fr_in6addr_mask(struct in6_addr const *ipaddr, uint8_t prefix)
935 {
936         uint64_t const *p = (uint64_t const *) ipaddr;
937         uint64_t ret[2], *o = ret;
938
939         if (prefix > 128) {
940                 prefix = 128;
941         }
942
943         /* Short circuit */
944         if (prefix == 128) {
945                 return *ipaddr;
946         }
947
948         if (prefix >= 64) {
949                 prefix -= 64;
950                 *o++ = 0xffffffffffffffffULL & *p++;
951         } else {
952                 ret[1] = 0;
953         }
954
955         *o = htonll(~((0x0000000000000001ULL << (64 - prefix)) - 1)) & *p;
956
957         return *(struct in6_addr *) &ret;
958 }
959
960 /** Zeroes out the host portion of an fr_ipaddr_t
961  *
962  * @param[in,out] addr to mask
963  * @param[in] prefix Length of the network portion.
964  */
965 void fr_ipaddr_mask(fr_ipaddr_t *addr, uint8_t prefix)
966 {
967
968         switch (addr->af) {
969         case AF_INET:
970                 addr->ipaddr.ip4addr = fr_inaddr_mask(&addr->ipaddr.ip4addr, prefix);
971                 break;
972
973         case AF_INET6:
974                 addr->ipaddr.ip6addr = fr_in6addr_mask(&addr->ipaddr.ip6addr, prefix);
975                 break;
976
977         default:
978                 return;
979         }
980         addr->prefix = prefix;
981 }
982
983 static char const *hextab = "0123456789abcdef";
984
985 /** Convert hex strings to binary data
986  *
987  * @param bin Buffer to write output to.
988  * @param hex input string.
989  * @param outlen length of output buffer (or length of input string / 2).
990  * @return length of data written to buffer.
991  */
992 size_t fr_hex2bin(uint8_t *bin, char const *hex, size_t outlen)
993 {
994         size_t i;
995         char *c1, *c2;
996
997         for (i = 0; i < outlen; i++) {
998                 if(!(c1 = memchr(hextab, tolower((int) hex[i << 1]), 16)) ||
999                    !(c2 = memchr(hextab, tolower((int) hex[(i << 1) + 1]), 16)))
1000                         break;
1001                  bin[i] = ((c1-hextab)<<4) + (c2-hextab);
1002         }
1003
1004         return i;
1005 }
1006
1007
1008 /** Convert binary data to a hex string
1009  *
1010  * Ascii encoded hex string will not be prefixed with '0x'
1011  *
1012  * @warning If the output buffer isn't long enough, we have a buffer overflow.
1013  *
1014  * @param[out] hex Buffer to write hex output.
1015  * @param[in] bin input.
1016  * @param[in] inlen of bin input.
1017  * @return length of data written to buffer.
1018  */
1019 size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen)
1020 {
1021         size_t i;
1022
1023         for (i = 0; i < inlen; i++) {
1024                 hex[0] = hextab[((*bin) >> 4) & 0x0f];
1025                 hex[1] = hextab[*bin & 0x0f];
1026                 hex += 2;
1027                 bin++;
1028         }
1029
1030         *hex = '\0';
1031         return inlen * 2;
1032 }
1033
1034
1035
1036 /** Consume the integer (or hex) portion of a value string
1037  *
1038  * @param value string to parse.
1039  * @param end pointer to the first non numeric char.
1040  * @return integer value.
1041  */
1042 uint32_t fr_strtoul(char const *value, char **end)
1043 {
1044         if ((value[0] == '0') && (value[1] == 'x')) {
1045                 return strtoul(value, end, 16);
1046         }
1047
1048         return strtoul(value, end, 10);
1049 }
1050
1051 /** Check whether the string is all whitespace
1052  *
1053  * @return true if the entirety of the string is whitespace, else false.
1054  */
1055 bool is_whitespace(char const *value)
1056 {
1057         do {
1058                 if (!isspace(*value)) return false;
1059         } while (*++value);
1060
1061         return true;
1062 }
1063
1064 /** Check whether the string is all numbers
1065  *
1066  * @return true if the entirety of the string is are numebrs, else false.
1067  */
1068 bool is_integer(char const *value)
1069 {
1070         do {
1071                 if (!isdigit(*value)) return false;
1072         } while (*++value);
1073
1074         return true;
1075 }
1076
1077 /** Check whether the string is allzeros
1078  *
1079  * @return true if the entirety of the string is are numebrs, else false.
1080  */
1081 bool is_zero(char const *value)
1082 {
1083         do {
1084                 if (*value != '0') return false;
1085         } while (*++value);
1086
1087         return true;
1088 }
1089
1090 /*
1091  *      So we don't have ifdef's in the rest of the code
1092  */
1093 #ifndef HAVE_CLOSEFROM
1094 int closefrom(int fd)
1095 {
1096         int i;
1097         int maxfd = 256;
1098
1099 #ifdef _SC_OPEN_MAX
1100         maxfd = sysconf(_SC_OPEN_MAX);
1101         if (maxfd < 0) {
1102           maxfd = 256;
1103         }
1104 #endif
1105
1106         if (fd > maxfd) return 0;
1107
1108         /*
1109          *      FIXME: return EINTR?
1110          *
1111          *      Use F_CLOSEM?
1112          */
1113         for (i = fd; i < maxfd; i++) {
1114                 close(i);
1115         }
1116
1117         return 0;
1118 }
1119 #endif
1120
1121 int fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
1122 {
1123         if (a->af < b->af) return -1;
1124         if (a->af > b->af) return +1;
1125
1126         switch (a->af) {
1127         case AF_INET:
1128                 return memcmp(&a->ipaddr.ip4addr,
1129                               &b->ipaddr.ip4addr,
1130                               sizeof(a->ipaddr.ip4addr));
1131                 break;
1132
1133 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1134         case AF_INET6:
1135                 if (a->scope < b->scope) return -1;
1136                 if (a->scope > b->scope) return +1;
1137
1138                 return memcmp(&a->ipaddr.ip6addr,
1139                               &b->ipaddr.ip6addr,
1140                               sizeof(a->ipaddr.ip6addr));
1141                 break;
1142 #endif
1143
1144         default:
1145                 break;
1146         }
1147
1148         return -1;
1149 }
1150
1151 int fr_ipaddr2sockaddr(fr_ipaddr_t const *ipaddr, uint16_t port,
1152                        struct sockaddr_storage *sa, socklen_t *salen)
1153 {
1154         if (ipaddr->af == AF_INET) {
1155                 struct sockaddr_in s4;
1156
1157                 *salen = sizeof(s4);
1158
1159                 memset(&s4, 0, sizeof(s4));
1160                 s4.sin_family = AF_INET;
1161                 s4.sin_addr = ipaddr->ipaddr.ip4addr;
1162                 s4.sin_port = htons(port);
1163                 memset(sa, 0, sizeof(*sa));
1164                 memcpy(sa, &s4, sizeof(s4));
1165
1166 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1167         } else if (ipaddr->af == AF_INET6) {
1168                 struct sockaddr_in6 s6;
1169
1170                 *salen = sizeof(s6);
1171
1172                 memset(&s6, 0, sizeof(s6));
1173                 s6.sin6_family = AF_INET6;
1174                 s6.sin6_addr = ipaddr->ipaddr.ip6addr;
1175                 s6.sin6_port = htons(port);
1176                 s6.sin6_scope_id = ipaddr->scope;
1177                 memset(sa, 0, sizeof(*sa));
1178                 memcpy(sa, &s6, sizeof(s6));
1179 #endif
1180         } else {
1181                 return 0;
1182         }
1183
1184         return 1;
1185 }
1186
1187
1188 int fr_sockaddr2ipaddr(struct sockaddr_storage const *sa, socklen_t salen,
1189                        fr_ipaddr_t *ipaddr, uint16_t *port)
1190 {
1191         if (sa->ss_family == AF_INET) {
1192                 struct sockaddr_in      s4;
1193
1194                 if (salen < sizeof(s4)) {
1195                         fr_strerror_printf("IPv4 address is too small");
1196                         return 0;
1197                 }
1198
1199                 memcpy(&s4, sa, sizeof(s4));
1200                 ipaddr->af = AF_INET;
1201                 ipaddr->prefix = 32;
1202                 ipaddr->ipaddr.ip4addr = s4.sin_addr;
1203                 if (port) *port = ntohs(s4.sin_port);
1204
1205 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1206         } else if (sa->ss_family == AF_INET6) {
1207                 struct sockaddr_in6     s6;
1208
1209                 if (salen < sizeof(s6)) {
1210                         fr_strerror_printf("IPv6 address is too small");
1211                         return 0;
1212                 }
1213
1214                 memcpy(&s6, sa, sizeof(s6));
1215                 ipaddr->af = AF_INET6;
1216                 ipaddr->prefix = 128;
1217                 ipaddr->ipaddr.ip6addr = s6.sin6_addr;
1218                 if (port) *port = ntohs(s6.sin6_port);
1219                 ipaddr->scope = s6.sin6_scope_id;
1220 #endif
1221
1222         } else {
1223                 fr_strerror_printf("Unsupported address famility %d",
1224                                    sa->ss_family);
1225                 return 0;
1226         }
1227
1228         return 1;
1229 }
1230
1231 /** Convert UTF8 string to UCS2 encoding
1232  *
1233  * @note Borrowed from src/crypto/ms_funcs.c of wpa_supplicant project (http://hostap.epitest.fi/wpa_supplicant/)
1234  *
1235  * @param[out] out Where to write the ucs2 string.
1236  * @param[in] outlen Size of output buffer.
1237  * @param[in] in UTF8 string to convert.
1238  * @param[in] inlen length of UTF8 string.
1239  * @return the size of the UCS2 string written to the output buffer (in bytes).
1240  */
1241 ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
1242 {
1243         size_t i;
1244         uint8_t *start = out;
1245
1246         for (i = 0; i < inlen; i++) {
1247                 uint8_t c, c2, c3;
1248
1249                 c = in[i];
1250                 if ((size_t)(out - start) >= outlen) {
1251                         /* input too long */
1252                         return -1;
1253                 }
1254
1255                 /* One-byte encoding */
1256                 if (c <= 0x7f) {
1257                         FR_PUT_LE16(out, c);
1258                         out += 2;
1259                         continue;
1260                 } else if ((i == (inlen - 1)) || ((size_t)(out - start) >= (outlen - 1))) {
1261                         /* Incomplete surrogate */
1262                         return -1;
1263                 }
1264
1265                 c2 = in[++i];
1266                 /* Two-byte encoding */
1267                 if ((c & 0xe0) == 0xc0) {
1268                         FR_PUT_LE16(out, ((c & 0x1f) << 6) | (c2 & 0x3f));
1269                         out += 2;
1270                         continue;
1271                 }
1272                 if ((i == inlen) || ((size_t)(out - start) >= (outlen - 1))) {
1273                         /* Incomplete surrogate */
1274                         return -1;
1275                 }
1276
1277                 /* Three-byte encoding */
1278                 c3 = in[++i];
1279                 FR_PUT_LE16(out, ((c & 0xf) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));
1280                 out += 2;
1281         }
1282
1283         return out - start;
1284 }
1285
1286 /** Write 128bit unsigned integer to buffer
1287  *
1288  * @author Alexey Frunze
1289  *
1290  * @param out where to write result to.
1291  * @param outlen size of out.
1292  * @param num 128 bit integer.
1293  */
1294 size_t fr_prints_uint128(char *out, size_t outlen, uint128_t const num)
1295 {
1296         char buff[128 / 3 + 1 + 1];
1297         uint64_t n[2];
1298         char *p = buff;
1299         int i;
1300
1301         memset(buff, '0', sizeof(buff) - 1);
1302         buff[sizeof(buff) - 1] = '\0';
1303
1304         memcpy(n, &num, sizeof(n));
1305
1306         for (i = 0; i < 128; i++) {
1307                 ssize_t j;
1308                 int carry;
1309
1310                 carry = (n[1] >= 0x8000000000000000);
1311
1312                 // Shift n[] left, doubling it
1313                 n[1] = ((n[1] << 1) & 0xffffffffffffffff) + (n[0] >= 0x8000000000000000);
1314                 n[0] = ((n[0] << 1) & 0xffffffffffffffff);
1315
1316                 // Add s[] to itself in decimal, doubling it
1317                 for (j = sizeof(buff) - 2; j >= 0; j--) {
1318                         buff[j] += buff[j] - '0' + carry;
1319                         carry = (buff[j] > '9');
1320                         if (carry) {
1321                                 buff[j] -= 10;
1322                         }
1323                 }
1324         }
1325
1326         while ((*p == '0') && (p < &buff[sizeof(buff) - 2])) {
1327                 p++;
1328         }
1329
1330         return strlcpy(out, p, outlen);
1331 }
1332
1333 /** Calculate powers
1334  *
1335  * @author Orson Peters
1336  * @note Borrowed from the gist here: https://gist.github.com/nightcracker/3551590.
1337  *
1338  * @param base a 32bit signed integer.
1339  * @param exp amount to raise base by.
1340  * @return base ^ pow, or 0 on underflow/overflow.
1341  */
1342 int64_t fr_pow(int32_t base, uint8_t exp) {
1343         static const uint8_t highest_bit_set[] = {
1344                 0, 1, 2, 2, 3, 3, 3, 3,
1345                 4, 4, 4, 4, 4, 4, 4, 4,
1346                 5, 5, 5, 5, 5, 5, 5, 5,
1347                 5, 5, 5, 5, 5, 5, 5, 5,
1348                 6, 6, 6, 6, 6, 6, 6, 6,
1349                 6, 6, 6, 6, 6, 6, 6, 6,
1350                 6, 6, 6, 6, 6, 6, 6, 6,
1351                 6, 6, 6, 6, 6, 6, 6, 255, // anything past 63 is a guaranteed overflow with base > 1
1352                 255, 255, 255, 255, 255, 255, 255, 255,
1353                 255, 255, 255, 255, 255, 255, 255, 255,
1354                 255, 255, 255, 255, 255, 255, 255, 255,
1355                 255, 255, 255, 255, 255, 255, 255, 255,
1356                 255, 255, 255, 255, 255, 255, 255, 255,
1357                 255, 255, 255, 255, 255, 255, 255, 255,
1358                 255, 255, 255, 255, 255, 255, 255, 255,
1359                 255, 255, 255, 255, 255, 255, 255, 255,
1360                 255, 255, 255, 255, 255, 255, 255, 255,
1361                 255, 255, 255, 255, 255, 255, 255, 255,
1362                 255, 255, 255, 255, 255, 255, 255, 255,
1363                 255, 255, 255, 255, 255, 255, 255, 255,
1364                 255, 255, 255, 255, 255, 255, 255, 255,
1365                 255, 255, 255, 255, 255, 255, 255, 255,
1366                 255, 255, 255, 255, 255, 255, 255, 255,
1367                 255, 255, 255, 255, 255, 255, 255, 255,
1368                 255, 255, 255, 255, 255, 255, 255, 255,
1369                 255, 255, 255, 255, 255, 255, 255, 255,
1370                 255, 255, 255, 255, 255, 255, 255, 255,
1371                 255, 255, 255, 255, 255, 255, 255, 255,
1372                 255, 255, 255, 255, 255, 255, 255, 255,
1373                 255, 255, 255, 255, 255, 255, 255, 255,
1374                 255, 255, 255, 255, 255, 255, 255, 255,
1375                 255, 255, 255, 255, 255, 255, 255, 255,
1376         };
1377
1378         uint64_t result = 1;
1379
1380         switch (highest_bit_set[exp]) {
1381         case 255: // we use 255 as an overflow marker and return 0 on overflow/underflow
1382                 if (base == 1) {
1383                         return 1;
1384                 }
1385
1386                 if (base == -1) {
1387                         return 1 - 2 * (exp & 1);
1388                 }
1389                 return 0;
1390         case 6:
1391                 if (exp & 1) result *= base;
1392                 exp >>= 1;
1393                 base *= base;
1394         case 5:
1395                 if (exp & 1) result *= base;
1396                 exp >>= 1;
1397                 base *= base;
1398         case 4:
1399                 if (exp & 1) result *= base;
1400                 exp >>= 1;
1401                 base *= base;
1402         case 3:
1403                 if (exp & 1) result *= base;
1404                 exp >>= 1;
1405                 base *= base;
1406         case 2:
1407                 if (exp & 1) result *= base;
1408                 exp >>= 1;
1409                 base *= base;
1410         case 1:
1411                 if (exp & 1) result *= base;
1412         default:
1413                 return result;
1414         }
1415 }
1416
1417 /*
1418  *      Sort of strtok/strsep function.
1419  */
1420 static char *mystrtok(char **ptr, char const *sep)
1421 {
1422         char    *res;
1423
1424         if (**ptr == 0) {
1425                 return NULL;
1426         }
1427
1428         while (**ptr && strchr(sep, **ptr)) {
1429                 (*ptr)++;
1430         }
1431         if (**ptr == 0) {
1432                 return NULL;
1433         }
1434
1435         res = *ptr;
1436         while (**ptr && strchr(sep, **ptr) == NULL) {
1437                 (*ptr)++;
1438         }
1439
1440         if (**ptr != 0) {
1441                 *(*ptr)++ = 0;
1442         }
1443         return res;
1444 }
1445
1446 /** Convert string in various formats to a time_t
1447  *
1448  * @param date_str input date string.
1449  * @param date time_t to write result to.
1450  * @return 0 on success or -1 on error.
1451  */
1452 int fr_get_time(char const *date_str, time_t *date)
1453 {
1454         int             i;
1455         time_t          t;
1456         struct tm       *tm, s_tm;
1457         char            buf[64];
1458         char            *p;
1459         char            *f[4];
1460         char            *tail = NULL;
1461
1462         /*
1463          * Test for unix timestamp date
1464          */
1465         *date = strtoul(date_str, &tail, 10);
1466         if (*tail == '\0') {
1467                 return 0;
1468         }
1469
1470         tm = &s_tm;
1471         memset(tm, 0, sizeof(*tm));
1472         tm->tm_isdst = -1;      /* don't know, and don't care about DST */
1473
1474         strlcpy(buf, date_str, sizeof(buf));
1475
1476         p = buf;
1477         f[0] = mystrtok(&p, " \t");
1478         f[1] = mystrtok(&p, " \t");
1479         f[2] = mystrtok(&p, " \t");
1480         f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */
1481         if (!f[0] || !f[1] || !f[2]) return -1;
1482
1483         /*
1484          *      The time has a colon, where nothing else does.
1485          *      So if we find it, bubble it to the back of the list.
1486          */
1487         if (f[3]) {
1488                 for (i = 0; i < 3; i++) {
1489                         if (strchr(f[i], ':')) {
1490                                 p = f[3];
1491                                 f[3] = f[i];
1492                                 f[i] = p;
1493                                 break;
1494                         }
1495                 }
1496         }
1497
1498         /*
1499          *  The month is text, which allows us to find it easily.
1500          */
1501         tm->tm_mon = 12;
1502         for (i = 0; i < 3; i++) {
1503                 if (isalpha( (int) *f[i])) {
1504                         /*
1505                          *  Bubble the month to the front of the list
1506                          */
1507                         p = f[0];
1508                         f[0] = f[i];
1509                         f[i] = p;
1510
1511                         for (i = 0; i < 12; i++) {
1512                                 if (strncasecmp(months[i], f[0], 3) == 0) {
1513                                         tm->tm_mon = i;
1514                                         break;
1515                                 }
1516                         }
1517                 }
1518         }
1519
1520         /* month not found? */
1521         if (tm->tm_mon == 12) return -1;
1522
1523         /*
1524          *  The year may be in f[1], or in f[2]
1525          */
1526         tm->tm_year = atoi(f[1]);
1527         tm->tm_mday = atoi(f[2]);
1528
1529         if (tm->tm_year >= 1900) {
1530                 tm->tm_year -= 1900;
1531
1532         } else {
1533                 /*
1534                  *  We can't use 2-digit years any more, they make it
1535                  *  impossible to tell what's the day, and what's the year.
1536                  */
1537                 if (tm->tm_mday < 1900) return -1;
1538
1539                 /*
1540                  *  Swap the year and the day.
1541                  */
1542                 i = tm->tm_year;
1543                 tm->tm_year = tm->tm_mday - 1900;
1544                 tm->tm_mday = i;
1545         }
1546
1547         /*
1548          *  If the day is out of range, die.
1549          */
1550         if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {
1551                 return -1;
1552         }
1553
1554         /*
1555          *      There may be %H:%M:%S.  Parse it in a hacky way.
1556          */
1557         if (f[3]) {
1558                 f[0] = f[3];    /* HH */
1559                 f[1] = strchr(f[0], ':'); /* find : separator */
1560                 if (!f[1]) return -1;
1561
1562                 *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
1563
1564                 f[2] = strchr(f[1], ':'); /* find : separator */
1565                 if (f[2]) {
1566                   *(f[2]++) = '\0';     /* nuke it, and point to SS */
1567                   tm->tm_sec = atoi(f[2]);
1568                 }                       /* else leave it as zero */
1569
1570                 tm->tm_hour = atoi(f[0]);
1571                 tm->tm_min = atoi(f[1]);
1572         }
1573
1574         /*
1575          *  Returns -1 on error.
1576          */
1577         t = mktime(tm);
1578         if (t == (time_t) -1) return -1;
1579
1580         *date = t;
1581
1582         return 0;
1583 }
1584
1585 /** Compares two pointers
1586  *
1587  * @param a first pointer to compare.
1588  * @param b second pointer to compare.
1589  * @return -1 if a < b, +1 if b > a, or 0 if both equal.
1590  */
1591 int8_t fr_pointer_cmp(void const *a, void const *b)
1592 {
1593         if (a < b) return -1;
1594         if (a == b) return 0;
1595
1596         return 1;
1597 }
1598
1599 static int _quick_partition(void const *to_sort[], int min, int max, fr_cmp_t cmp) {
1600         void const *pivot = to_sort[min];
1601         int i = min;
1602         int j = max + 1;
1603         void const *tmp;
1604
1605         for (;;) {
1606                 do ++i; while((cmp(to_sort[i], pivot) <= 0) && i <= max);
1607                 do --j; while(cmp(to_sort[j], pivot) > 0);
1608
1609                 if (i >= j) break;
1610
1611                 tmp = to_sort[i];
1612                 to_sort[i] = to_sort[j];
1613                 to_sort[j] = tmp;
1614         }
1615
1616         tmp = to_sort[min];
1617         to_sort[min] = to_sort[j];
1618         to_sort[j] = tmp;
1619
1620         return j;
1621 }
1622
1623 /** Quick sort an array of pointers using a comparator
1624  *
1625  * @param to_sort array of pointers to sort.
1626  * @param min_idx the lowest index (usually 0).
1627  * @param max_idx the highest index (usually length of array - 1).
1628  * @param cmp the comparison function to use to sort the array elements.
1629  */
1630 void fr_quick_sort(void const *to_sort[], int min_idx, int max_idx, fr_cmp_t cmp)
1631 {
1632         int part;
1633
1634         if (min_idx >= max_idx) return;
1635
1636         part = _quick_partition(to_sort, min_idx, max_idx, cmp);
1637         fr_quick_sort(to_sort, min_idx, part - 1, cmp);
1638         fr_quick_sort(to_sort, part + 1, max_idx, cmp);
1639 }
1640
1641 #ifdef TALLOC_DEBUG
1642 void fr_talloc_verify_cb(UNUSED const void *ptr, UNUSED int depth,
1643                          UNUSED int max_depth, UNUSED int is_ref,
1644                          UNUSED void *private_data)
1645 {
1646         /* do nothing */
1647 }
1648 #endif