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