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