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