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