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