2 * misc.c Various miscellaneous functions.
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.
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.
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
20 * Copyright 2000,2006 The FreeRADIUS server project
25 #include <freeradius-devel/libradius.h>
38 * Some versions of Linux don't have closefrom(), but they will
41 * BSD systems will generally have closefrom(), but not proc.
43 * OSX doesn't have closefrom() or /proc/self/fd, but it does
47 #define CLOSEFROM_DIR "/proc/self/fd"
48 #elif defined(__APPLE__)
49 #define CLOSEFROM_DIR "/dev/fd"
56 #define FR_PUT_LE16(a, val)\
58 a[1] = ((uint16_t) (val)) >> 8;\
59 a[0] = ((uint16_t) (val)) & 0xff;\
62 bool fr_dns_lookups = false; /* IP -> hostname lookups? */
63 bool fr_hostname_lookups = true; /* hostname -> IP lookups? */
66 static char const *months[] = {
67 "jan", "feb", "mar", "apr", "may", "jun",
68 "jul", "aug", "sep", "oct", "nov", "dec" };
70 fr_thread_local_setup(char *, fr_inet_ntop_buffer) /* macro */
72 typedef struct fr_talloc_link {
77 /** Sets a signal handler using sigaction if available, else signal
79 * @param sig to set handler for.
80 * @param func handler to set.
82 int fr_set_signal(int sig, sig_t func)
87 memset(&act, 0, sizeof(act));
89 sigemptyset(&act.sa_mask);
90 act.sa_handler = func;
92 if (sigaction(sig, &act, NULL) < 0) {
93 fr_strerror_printf("Failed setting signal %i handler via sigaction(): %s", sig, fr_syserror(errno));
97 if (signal(sig, func) < 0) {
98 fr_strerror_printf("Failed setting signal %i handler via signal(): %s", sig, fr_syserror(errno));
105 /** Uninstall a signal for a specific handler
107 * man sigaction says these are fine to call from a signal handler.
111 int fr_unset_signal(int sig)
113 #ifdef HAVE_SIGACTION
114 struct sigaction act;
116 memset(&act, 0, sizeof(act));
118 sigemptyset(&act.sa_mask);
119 act.sa_handler = SIG_DFL;
121 return sigaction(sig, &act, NULL);
123 return signal(sig, SIG_DFL);
127 static int _fr_trigger_talloc_ctx_free(fr_talloc_link_t *trigger)
129 if (trigger->armed) talloc_free(trigger->child);
134 static int _fr_disarm_talloc_ctx_free(bool **armed)
140 /** Link a parent and a child context, so the child is freed before the parent
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.
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.
149 int fr_link_talloc_ctx_free(TALLOC_CTX *parent, TALLOC_CTX *child)
151 fr_talloc_link_t *trigger;
154 trigger = talloc(parent, fr_talloc_link_t);
155 if (!trigger) return -1;
157 disarm = talloc(child, bool *);
159 talloc_free(trigger);
163 trigger->child = child;
164 trigger->armed = true;
165 *disarm = &trigger->armed;
167 talloc_set_destructor(trigger, _fr_trigger_talloc_ctx_free);
168 talloc_set_destructor(disarm, _fr_disarm_talloc_ctx_free);
174 * Explicitly cleanup the memory allocated to the error inet_ntop
177 static void _fr_inet_ntop_free(void *arg)
182 /** Wrapper around inet_ntop, prints IPv4/IPv6 addresses
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.
188 * So as with lib/log.c use TLS to allocate thread specific buffers, and
189 * write the IP address there instead.
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.
195 char const *fr_inet_ntop(int af, void const *src)
203 buffer = fr_thread_local_init(fr_inet_ntop_buffer, _fr_inet_ntop_free);
208 * malloc is thread safe, talloc is not
210 buffer = malloc(sizeof(char) * INET6_ADDRSTRLEN);
212 fr_perror("Failed allocating memory for inet_ntop buffer");
216 ret = fr_thread_local_set(fr_inet_ntop_buffer, buffer);
218 fr_perror("Failed setting up TLS for inet_ntop buffer: %s", fr_syserror(ret));
225 return inet_ntop(af, src, buffer, INET6_ADDRSTRLEN);
229 * Return an IP address in standard dot notation
233 char const *ip_ntoa(char *buffer, uint32_t ipaddr)
235 ipaddr = ntohl(ipaddr);
237 sprintf(buffer, "%d.%d.%d.%d",
238 (ipaddr >> 24) & 0xff,
239 (ipaddr >> 16) & 0xff,
240 (ipaddr >> 8) & 0xff,
246 * Parse decimal digits until we run out of decimal digits.
248 static int ip_octet_from_str(char const *str, uint32_t *poctet)
253 if ((*p < '0') || (*p > '9')) {
259 while ((*p >= '0') && (*p <= '9')) {
264 if (octet > 255) return -1;
272 static int ip_prefix_from_str(char const *str, uint32_t *paddr)
281 for (shift = 24; shift >= 0; shift -= 8) {
282 length = ip_octet_from_str(p, &octet);
283 if (length <= 0) return -1;
285 addr |= octet << shift;
289 * EOS or / means we're done.
291 if (!*p || (*p == '/')) break;
294 * We require dots between octets.
296 if (*p != '.') return -1;
300 *paddr = htonl(addr);
305 /** Parse an IPv4 address or IPv4 prefix in presentation format (and others)
307 * @param out Where to write the ip address value.
308 * @param value to parse, may be dotted quad [+ prefix], or integer, or octal number, or '*' (INADDR_ANY).
309 * @param inlen Length of value, if value is \0 terminated inlen may be -1.
310 * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
311 * @param fallback to IPv6 resolution if no A records can be found.
312 * @return 0 if ip address was parsed successfully, else -1 on error.
314 int fr_pton4(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, bool fallback)
320 /* Dotted quad + / + [0-9]{1,2} */
321 char buffer[INET_ADDRSTRLEN + 3];
324 * Copy to intermediary buffer if we were given a length
327 if (inlen >= (ssize_t)sizeof(buffer)) {
328 fr_strerror_printf("Invalid IPv4 address string \"%s\"", value);
331 memcpy(buffer, value, inlen);
332 buffer[inlen] = '\0';
336 p = strchr(value, '/');
339 * 192.0.2.2 is parsed as if it was /32
346 * Allow '*' as the wildcard address usually 0.0.0.0
348 if ((value[0] == '*') && (value[1] == '\0')) {
349 out->ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
352 * Convert things which are obviously integers to IP addresses
354 * We assume the number is the bigendian representation of the
357 } else if (is_integer(value) || ((value[0] == '0') && (value[1] == 'x'))) {
358 out->ipaddr.ip4addr.s_addr = htonl(strtoul(value, NULL, 0));
360 } else if (!resolve) {
361 if (inet_pton(AF_INET, value, &out->ipaddr.ip4addr.s_addr) <= 0) {
362 fr_strerror_printf("Failed to parse IPv4 addreess string \"%s\"", value);
365 } else if (ip_hton(out, AF_INET, value, fallback) < 0) return -1;
371 * Copy the IP portion into a temporary buffer if we haven't already.
373 if (inlen < 0) memcpy(buffer, value, p - value);
374 buffer[p - value] = '\0';
376 if (ip_prefix_from_str(buffer, &out->ipaddr.ip4addr.s_addr) <= 0) {
377 fr_strerror_printf("Failed to parse IPv4 address string \"%s\"", value);
381 mask = strtoul(p + 1, &eptr, 10);
383 fr_strerror_printf("Invalid IPv4 mask length \"%s\". Should be between 0-32", p);
387 if (eptr[0] != '\0') {
388 fr_strerror_printf("Failed to parse IPv4 address string \"%s\", "
389 "got garbage after mask length \"%s\"", value, eptr);
394 out->ipaddr.ip4addr = fr_inaddr_mask(&out->ipaddr.ip4addr, mask);
397 out->prefix = (uint8_t) mask;
403 /** Parse an IPv6 address or IPv6 prefix in presentation format (and others)
405 * @param out Where to write the ip address value.
406 * @param value to parse.
407 * @param inlen Length of value, if value is \0 terminated inlen may be -1.
408 * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
409 * @param fallback to IPv4 resolution if no AAAA records can be found.
410 * @return 0 if ip address was parsed successfully, else -1 on error.
412 int fr_pton6(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, bool fallback)
418 /* IPv6 + / + [0-9]{1,3} */
419 char buffer[INET6_ADDRSTRLEN + 4];
422 * Copy to intermediary buffer if we were given a length
425 if (inlen >= (ssize_t)sizeof(buffer)) {
426 fr_strerror_printf("Invalid IPv6 address string \"%s\"", value);
429 memcpy(buffer, value, inlen);
430 buffer[inlen] = '\0';
434 p = strchr(value, '/');
440 * Allow '*' as the wildcard address
442 if ((value[0] == '*') && (value[1] == '\0')) {
443 memset(out->ipaddr.ip6addr.s6_addr, 0, sizeof(out->ipaddr.ip6addr.s6_addr));
444 } else if (!resolve) {
445 if (inet_pton(AF_INET6, value, out->ipaddr.ip6addr.s6_addr) <= 0) {
446 fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
449 } else if (ip_hton(out, AF_INET6, value, fallback) < 0) return -1;
454 if ((p - value) >= INET6_ADDRSTRLEN) {
455 fr_strerror_printf("Invalid IPv6 address string \"%s\"", value);
460 * Copy string to temporary buffer if we didn't do it earlier
462 if (inlen < 0) memcpy(buffer, value, p - value);
463 buffer[p - value] = '\0';
466 if (inet_pton(AF_INET6, buffer, out->ipaddr.ip6addr.s6_addr) <= 0) {
467 fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
470 } else if (ip_hton(out, AF_INET6, buffer, fallback) < 0) return -1;
472 prefix = strtoul(p + 1, &eptr, 10);
474 fr_strerror_printf("Invalid IPv6 mask length \"%s\". Should be between 0-128", p);
477 if (eptr[0] != '\0') {
478 fr_strerror_printf("Failed to parse IPv6 address string \"%s\", "
479 "got garbage after mask length \"%s\"", value, eptr);
484 struct in6_addr addr;
486 addr = fr_in6addr_mask(&out->ipaddr.ip6addr, prefix);
487 memcpy(out->ipaddr.ip6addr.s6_addr, addr.s6_addr, sizeof(out->ipaddr.ip6addr.s6_addr));
490 out->prefix = (uint8_t) prefix;
496 /** Simple wrapper to decide whether an IP value is v4 or v6 and call the appropriate parser.
498 * @param[out] out Where to write the ip address value.
499 * @param[in] value to parse.
500 * @param[in] inlen Length of value, if value is \0 terminated inlen may be -1.
501 * @param[in] resolve If true and value doesn't look like an IP address, try and resolve value as a
503 * @param[in] af If the address type is not obvious from the format, and resolve is true, the DNS
504 * record (A or AAAA) we require. Also controls which parser we pass the address to if
505 * we have no idea what it is.
507 * - 0 if ip address was parsed successfully.
510 int fr_pton(fr_ipaddr_t *out, char const *value, ssize_t inlen, int af, bool resolve)
514 len = (inlen >= 0) ? (size_t)inlen : strlen(value);
515 for (i = 0; i < len; i++) switch (value[i]) {
517 * ':' is illegal in domain names and IPv4 addresses.
518 * Must be v6 and cannot be a domain.
521 return fr_pton6(out, value, inlen, false, false);
524 * Chars which don't really tell us anything
532 * Outside the range of IPv4 chars, must be a domain
533 * Use A record in preference to AAAA record.
535 if ((value[i] < '0') || (value[i] > '9')) {
537 fr_strerror_printf("Not IPv4/6 address, and asked not to resolve");
542 return fr_pton4(out, value, inlen, resolve, true);
545 return fr_pton4(out, value, inlen, resolve, false);
548 return fr_pton6(out, value, inlen, resolve, false);
551 fr_strerror_printf("Invalid address family %i", af);
559 * All chars were in the IPv4 set [0-9/.], must be an IPv4
562 return fr_pton4(out, value, inlen, false, false);
565 /** Parses IPv4/6 address + port, to fr_ipaddr_t and integer
567 * @param[out] out Where to write the ip address value.
568 * @param[out] port_out Where to write the port (0 if no port found).
569 * @param[in] value to parse.
570 * @param[in] inlen Length of value, if value is \0 terminated inlen may be -1.
571 * @param[in] af If the address type is not obvious from the format, and resolve is true, the DNS
572 * record (A or AAAA) we require. Also controls which parser we pass the address to if
573 * we have no idea what it is.
574 * @param[in] resolve If true and value doesn't look like an IP address, try and resolve value as a
577 int fr_pton_port(fr_ipaddr_t *out, uint16_t *port_out, char const *value, ssize_t inlen, int af, bool resolve)
579 char const *p = value, *q;
587 len = (inlen >= 0) ? (size_t)inlen : strlen(value);
590 if (!(q = memchr(p + 1, ']', len - 1))) {
591 fr_strerror_printf("Missing closing ']' for IPv6 address");
596 * inet_pton doesn't like the address being wrapped in []
598 if (fr_pton6(out, p + 1, (q - p) - 1, false, false) < 0) return -1;
609 * Host, IPv4 or IPv6 with no port
611 q = memchr(p, ':', len);
612 if (!q) return fr_pton(out, p, len, af, resolve);
615 * IPv4 or host, with port
617 if (fr_pton(out, p, (q - p), af, resolve) < 0) return -1;
621 * Valid ports are a maximum of 5 digits, so if the
622 * input length indicates there are more than 5 chars
623 * after the ':' then there's an issue.
625 if (inlen > ((q + sizeof(buffer)) - value)) {
627 fr_strerror_printf("IP string contains trailing garbage after port delimiter");
631 p = q + 1; /* Move to first digit */
633 strlcpy(buffer, p, (len - (p - value)) + 1);
634 port = strtoul(buffer, &end, 10);
635 if (*end != '\0') goto error; /* Trailing garbage after integer */
637 if ((port > UINT16_MAX) || (port == 0)) {
638 fr_strerror_printf("Port %lu outside valid port range 1-" STRINGIFY(UINT16_MAX), port);
646 int fr_ntop(char *out, size_t outlen, fr_ipaddr_t *addr)
648 char buffer[INET6_ADDRSTRLEN];
650 if (inet_ntop(addr->af, &(addr->ipaddr), buffer, sizeof(buffer)) == NULL) return -1;
652 return snprintf(out, outlen, "%s/%i", buffer, addr->prefix);
656 * cppcheck apparently can't pick this up from the system headers.
663 * Internal wrapper for locking, to minimize the number of ifdef's
667 int rad_lockfd(int fd, int lock_len)
676 fl.l_whence = SEEK_CUR;
678 return fcntl(fd, F_SETLKW, (void *)&fl);
680 #error "missing definition for F_WRLCK, all file locks will fail"
687 * Internal wrapper for locking, to minimize the number of ifdef's
689 * Lock an fd, prefer lockf() over flock()
690 * Nonblocking version.
692 int rad_lockfd_nonblock(int fd, int lock_len)
701 fl.l_whence = SEEK_CUR;
703 return fcntl(fd, F_SETLK, (void *)&fl);
705 #error "missing definition for F_WRLCK, all file locks will fail"
712 * Internal wrapper for unlocking, to minimize the number of ifdef's
715 * Unlock an fd, prefer lockf() over flock()
717 int rad_unlockfd(int fd, int lock_len)
726 fl.l_whence = SEEK_CUR;
728 return fcntl(fd, F_UNLCK, (void *)&fl);
730 #error "missing definition for F_WRLCK, all file locks will fail"
737 * Return an interface-id in standard colon notation
739 char *ifid_ntoa(char *buffer, size_t size, uint8_t const *ifid)
741 snprintf(buffer, size, "%x:%x:%x:%x",
742 (ifid[0] << 8) + ifid[1], (ifid[2] << 8) + ifid[3],
743 (ifid[4] << 8) + ifid[5], (ifid[6] << 8) + ifid[7]);
749 * Return an interface-id from
750 * one supplied in standard colon notation.
752 uint8_t *ifid_aton(char const *ifid_str, uint8_t *ifid)
754 static char const xdigits[] = "0123456789abcdef";
756 int num_id = 0, val = 0, idx = 0;
758 for (p = ifid_str; ; ++p) {
759 if (*p == ':' || *p == '\0') {
764 * Drop 'val' into the array.
766 ifid[idx] = (val >> 8) & 0xff;
767 ifid[idx + 1] = val & 0xff;
770 * Must have all entries before
781 } else if ((pch = strchr(xdigits, tolower(*p))) != NULL) {
785 * Dumb version of 'scanf'
788 val |= (pch - xdigits);
796 #ifndef HAVE_INET_PTON
797 static int inet_pton4(char const *src, struct in_addr *dst)
803 static char const digits[] = "0123456789";
809 while (*p && ((off = strchr(digits, *p)) != NULL)) {
811 num += (off - digits);
813 if (num > 255) return 0;
820 * Not a digit, MUST be a dot, else we
832 * End of the string. At the fourth
833 * octet is OK, anything else is an
841 memcpy(dst, &tmp, sizeof(tmp));
846 #ifdef HAVE_STRUCT_SOCKADDR_IN6
847 /** Convert presentation level address to network order binary form
849 * @note Does not touch dst unless it's returning 1.
850 * @note :: in a full address is silently ignored.
851 * @note Inspired by Mark Andrews.
852 * @author Paul Vixie, 1996.
854 * @param src presentation level address.
855 * @param dst where to write output address.
856 * @return 1 if `src' is a valid [RFC1884 2.2] address, else 0.
858 static int inet_pton6(char const *src, unsigned char *dst)
860 static char const xdigits_l[] = "0123456789abcdef",
861 xdigits_u[] = "0123456789ABCDEF";
862 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
863 char const *xdigits, *curtok;
867 memset((tp = tmp), 0, IN6ADDRSZ);
868 endp = tp + IN6ADDRSZ;
870 /* Leading :: requires some special handling. */
877 while ((ch = *src++) != '\0') {
880 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
881 pch = strchr((xdigits = xdigits_u), ch);
884 val |= (pch - xdigits);
898 if (tp + INT16SZ > endp)
900 *tp++ = (u_char) (val >> 8) & 0xff;
901 *tp++ = (u_char) val & 0xff;
906 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
907 inet_pton4(curtok, (struct in_addr *) tp) > 0) {
910 break; /* '\0' was seen by inet_pton4(). */
915 if (tp + INT16SZ > endp)
917 *tp++ = (u_char) (val >> 8) & 0xff;
918 *tp++ = (u_char) val & 0xff;
920 if (colonp != NULL) {
922 * Since some memmove()'s erroneously fail to handle
923 * overlapping regions, we'll do the shift by hand.
925 int const n = tp - colonp;
928 for (i = 1; i <= n; i++) {
929 endp[- i] = colonp[n - i];
936 /* bcopy(tmp, dst, IN6ADDRSZ); */
937 memcpy(dst, tmp, IN6ADDRSZ);
943 * Utility function, so that the rest of the server doesn't
944 * have ifdef's around IPv6 support
946 int inet_pton(int af, char const *src, void *dst)
949 return inet_pton4(src, dst);
951 #ifdef HAVE_STRUCT_SOCKADDR_IN6
953 if (af == AF_INET6) {
954 return inet_pton6(src, dst);
962 #ifndef HAVE_INET_NTOP
964 * Utility function, so that the rest of the server doesn't
965 * have ifdef's around IPv6 support
967 char const *inet_ntop(int af, void const *src, char *dst, size_t cnt)
970 uint8_t const *ipaddr = src;
972 if (cnt <= INET_ADDRSTRLEN) return NULL;
974 snprintf(dst, cnt, "%d.%d.%d.%d",
975 ipaddr[0], ipaddr[1],
976 ipaddr[2], ipaddr[3]);
981 * If the system doesn't define this, we define it
984 if (af == AF_INET6) {
985 struct in6_addr const *ipaddr = src;
987 if (cnt <= INET6_ADDRSTRLEN) return NULL;
989 snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x",
990 (ipaddr->s6_addr[0] << 8) | ipaddr->s6_addr[1],
991 (ipaddr->s6_addr[2] << 8) | ipaddr->s6_addr[3],
992 (ipaddr->s6_addr[4] << 8) | ipaddr->s6_addr[5],
993 (ipaddr->s6_addr[6] << 8) | ipaddr->s6_addr[7],
994 (ipaddr->s6_addr[8] << 8) | ipaddr->s6_addr[9],
995 (ipaddr->s6_addr[10] << 8) | ipaddr->s6_addr[11],
996 (ipaddr->s6_addr[12] << 8) | ipaddr->s6_addr[13],
997 (ipaddr->s6_addr[14] << 8) | ipaddr->s6_addr[15]);
1001 return NULL; /* don't support IPv6 */
1005 /** Wrappers for IPv4/IPv6 host to IP address lookup
1007 * This function returns only one IP address, of the specified address family,
1008 * or the first address (of whatever family), if AF_UNSPEC is used.
1010 * If fallback is specified and af is AF_INET, but no AF_INET records were
1011 * found and a record for AF_INET6 exists that record will be returned.
1013 * If fallback is specified and af is AF_INET6, and a record with AF_INET4 exists
1014 * that record will be returned instead.
1016 * @param out Where to write result.
1017 * @param af To search for in preference.
1018 * @param hostname to search for.
1019 * @param fallback to the other adress family, if no records matching af, found.
1020 * @return 0 on success, else -1 on failure.
1022 int ip_hton(fr_ipaddr_t *out, int af, char const *hostname, bool fallback)
1025 struct addrinfo hints, *ai = NULL, *alt = NULL, *res = NULL;
1028 * Avoid malloc for IP addresses. This helps us debug
1029 * memory errors when using talloc.
1034 if (!fr_hostname_lookups) {
1036 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1037 if (af == AF_UNSPEC) {
1040 for (p = hostname; *p != '\0'; p++) {
1051 if (af == AF_UNSPEC) af = AF_INET;
1053 if (!inet_pton(af, hostname, &(out->ipaddr))) return -1;
1059 memset(&hints, 0, sizeof(hints));
1062 * If we're falling back we need both IPv4 and IPv6 records
1065 hints.ai_family = AF_UNSPEC;
1067 hints.ai_family = af;
1070 if ((rcode = getaddrinfo(hostname, NULL, &hints, &res)) != 0) {
1074 fr_strerror_printf("Failed resolving \"%s\" to IP address: %s",
1075 hostname, gai_strerror(rcode));
1079 fr_strerror_printf("Failed resolving \"%s\" to IPv4 address: %s",
1080 hostname, gai_strerror(rcode));
1084 fr_strerror_printf("Failed resolving \"%s\" to IPv6 address: %s",
1085 hostname, gai_strerror(rcode));
1090 for (ai = res; ai; ai = ai->ai_next) {
1091 if ((af == ai->ai_family) || (af == AF_UNSPEC)) break;
1092 if (!alt && fallback && ((ai->ai_family == AF_INET) || (ai->ai_family == AF_INET6))) alt = ai;
1097 fr_strerror_printf("ip_hton failed to find requested information for host %.100s", hostname);
1102 rcode = fr_sockaddr2ipaddr((struct sockaddr_storage *)ai->ai_addr,
1103 ai->ai_addrlen, out, NULL);
1106 fr_strerror_printf("Failed converting sockaddr to ipaddr");
1114 * Look IP addresses up, and print names (depending on DNS config)
1116 char const *ip_ntoh(fr_ipaddr_t const *src, char *dst, size_t cnt)
1118 struct sockaddr_storage ss;
1125 if (!fr_dns_lookups) {
1126 return inet_ntop(src->af, &(src->ipaddr), dst, cnt);
1129 if (!fr_ipaddr2sockaddr(src, 0, &ss, &salen)) {
1133 if ((error = getnameinfo((struct sockaddr *)&ss, salen, dst, cnt, NULL, 0,
1134 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
1135 fr_strerror_printf("ip_ntoh: %s", gai_strerror(error));
1141 /** Mask off a portion of an IPv4 address
1143 * @param ipaddr to mask.
1144 * @param prefix Number of contiguous bits to mask.
1145 * @return an ipv4 address with the host portion zeroed out.
1147 struct in_addr fr_inaddr_mask(struct in_addr const *ipaddr, uint8_t prefix)
1151 if (prefix > 32) prefix = 32;
1154 if (prefix == 32) return *ipaddr;
1156 if (prefix == 0) ret = 0;
1157 else ret = htonl(~((0x00000001UL << (32 - prefix)) - 1)) & ipaddr->s_addr;
1159 return (*(struct in_addr *)&ret);
1162 /** Mask off a portion of an IPv6 address
1164 * @param ipaddr to mask.
1165 * @param prefix Number of contiguous bits to mask.
1166 * @return an ipv6 address with the host portion zeroed out.
1168 struct in6_addr fr_in6addr_mask(struct in6_addr const *ipaddr, uint8_t prefix)
1170 uint64_t const *p = (uint64_t const *) ipaddr;
1171 uint64_t ret[2], *o = ret;
1173 if (prefix > 128) prefix = 128;
1176 if (prefix == 128) return *ipaddr;
1180 *o++ = 0xffffffffffffffffULL & *p++; /* lhs portion masked */
1182 ret[1] = 0; /* rhs portion zeroed */
1185 /* Max left shift is 63 else we get overflow */
1187 *o = htonll(~((uint64_t)(0x0000000000000001ULL << (64 - prefix)) - 1)) & *p;
1192 return *(struct in6_addr *) &ret;
1195 /** Zeroes out the host portion of an fr_ipaddr_t
1197 * @param[in,out] addr to mask
1198 * @param[in] prefix Length of the network portion.
1200 void fr_ipaddr_mask(fr_ipaddr_t *addr, uint8_t prefix)
1205 addr->ipaddr.ip4addr = fr_inaddr_mask(&addr->ipaddr.ip4addr, prefix);
1209 addr->ipaddr.ip6addr = fr_in6addr_mask(&addr->ipaddr.ip6addr, prefix);
1215 addr->prefix = prefix;
1218 static char const hextab[] = "0123456789abcdef";
1220 /** Convert hex strings to binary data
1222 * @param bin Buffer to write output to.
1223 * @param outlen length of output buffer (or length of input string / 2).
1224 * @param hex input string.
1225 * @param inlen length of the input string
1226 * @return length of data written to buffer.
1228 size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen)
1235 * Smartly truncate output, caller should check number of bytes
1239 if (len > outlen) len = outlen;
1241 for (i = 0; i < len; i++) {
1242 if(!(c1 = memchr(hextab, tolower((int) hex[i << 1]), sizeof(hextab))) ||
1243 !(c2 = memchr(hextab, tolower((int) hex[(i << 1) + 1]), sizeof(hextab))))
1245 bin[i] = ((c1-hextab)<<4) + (c2-hextab);
1251 /** Convert binary data to a hex string
1253 * Ascii encoded hex string will not be prefixed with '0x'
1255 * @warning If the output buffer isn't long enough, we have a buffer overflow.
1257 * @param[out] hex Buffer to write hex output.
1258 * @param[in] bin input.
1259 * @param[in] inlen of bin input.
1260 * @return length of data written to buffer.
1262 size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen)
1266 for (i = 0; i < inlen; i++) {
1267 hex[0] = hextab[((*bin) >> 4) & 0x0f];
1268 hex[1] = hextab[*bin & 0x0f];
1277 /** Convert binary data to a hex string
1279 * Ascii encoded hex string will not be prefixed with '0x'
1281 * @param[in] ctx to alloc buffer in.
1282 * @param[in] bin input.
1283 * @param[in] inlen of bin input.
1284 * @return length of data written to buffer.
1286 char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen)
1290 buff = talloc_array(ctx, char, (inlen << 2));
1291 if (!buff) return NULL;
1293 fr_bin2hex(buff, bin, inlen);
1298 /** Consume the integer (or hex) portion of a value string
1300 * @param value string to parse.
1301 * @param end pointer to the first non numeric char.
1302 * @return integer value.
1304 uint32_t fr_strtoul(char const *value, char **end)
1306 if ((value[0] == '0') && (value[1] == 'x')) {
1307 return strtoul(value, end, 16);
1310 return strtoul(value, end, 10);
1313 /** Check whether the string is all whitespace
1315 * @return true if the entirety of the string is whitespace, else false.
1317 bool is_whitespace(char const *value)
1320 if (!isspace(*value)) return false;
1326 /** Check whether the string is made up of printable UTF8 chars
1328 * @param value to check.
1329 * @param len of value.
1332 * - true if the string is printable.
1333 * - false if the string contains non printable chars
1335 bool is_printable(void const *value, size_t len)
1337 uint8_t const *p = value;
1341 for (i = 0; i < len; i++) {
1342 clen = fr_utf8_char(p, len - i);
1343 if (clen == 0) return false;
1350 /** Check whether the string is all numbers
1352 * @return true if the entirety of the string is all numbers, else false.
1354 bool is_integer(char const *value)
1357 if (!isdigit(*value)) return false;
1363 /** Check whether the string is allzeros
1365 * @return true if the entirety of the string is all zeros, else false.
1367 bool is_zero(char const *value)
1370 if (*value != '0') return false;
1377 * So we don't have ifdef's in the rest of the code
1379 #ifndef HAVE_CLOSEFROM
1380 int closefrom(int fd)
1384 #ifdef HAVE_DIRENT_H
1389 if (fcntl(fd, F_CLOSEM) == 0) {
1395 maxfd = fcntl(fd, F_F_MAXFD);
1396 if (maxfd >= 0) goto do_close;
1400 maxfd = sysconf(_SC_OPEN_MAX);
1406 #ifdef HAVE_DIRENT_H
1408 * Use /proc/self/fd directory if it exists.
1410 dir = opendir(CLOSEFROM_DIR);
1416 while ((dp = readdir(dir)) != NULL) {
1417 my_fd = strtol(dp->d_name, &endp, 10);
1418 if (my_fd <= 0) continue;
1420 if ((endp > dp->d_name) && *endp) continue;
1422 if (my_fd == dirfd(dir)) continue;
1424 if ((my_fd >= fd) && (my_fd <= maxfd)) {
1425 (void) close((int) my_fd);
1428 (void) closedir(dir);
1437 if (fd > maxfd) return 0;
1440 * FIXME: return EINTR?
1442 for (i = fd; i < maxfd; i++) {
1450 int fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
1452 if (a->af < b->af) return -1;
1453 if (a->af > b->af) return +1;
1455 if (a->prefix < b->prefix) return -1;
1456 if (a->prefix > b->prefix) return +1;
1460 return memcmp(&a->ipaddr.ip4addr,
1462 sizeof(a->ipaddr.ip4addr));
1464 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1466 if (a->scope < b->scope) return -1;
1467 if (a->scope > b->scope) return +1;
1469 return memcmp(&a->ipaddr.ip6addr,
1471 sizeof(a->ipaddr.ip6addr));
1481 int fr_ipaddr2sockaddr(fr_ipaddr_t const *ipaddr, uint16_t port,
1482 struct sockaddr_storage *sa, socklen_t *salen)
1484 memset(sa, 0, sizeof(*sa));
1486 if (ipaddr->af == AF_INET) {
1487 struct sockaddr_in s4;
1489 *salen = sizeof(s4);
1491 memset(&s4, 0, sizeof(s4));
1492 s4.sin_family = AF_INET;
1493 s4.sin_addr = ipaddr->ipaddr.ip4addr;
1494 s4.sin_port = htons(port);
1495 memset(sa, 0, sizeof(*sa));
1496 memcpy(sa, &s4, sizeof(s4));
1498 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1499 } else if (ipaddr->af == AF_INET6) {
1500 struct sockaddr_in6 s6;
1502 *salen = sizeof(s6);
1504 memset(&s6, 0, sizeof(s6));
1505 s6.sin6_family = AF_INET6;
1506 s6.sin6_addr = ipaddr->ipaddr.ip6addr;
1507 s6.sin6_port = htons(port);
1508 s6.sin6_scope_id = ipaddr->scope;
1509 memset(sa, 0, sizeof(*sa));
1510 memcpy(sa, &s6, sizeof(s6));
1520 int fr_sockaddr2ipaddr(struct sockaddr_storage const *sa, socklen_t salen,
1521 fr_ipaddr_t *ipaddr, uint16_t *port)
1523 memset(ipaddr, 0, sizeof(*ipaddr));
1525 if (sa->ss_family == AF_INET) {
1526 struct sockaddr_in s4;
1528 if (salen < sizeof(s4)) {
1529 fr_strerror_printf("IPv4 address is too small");
1533 memcpy(&s4, sa, sizeof(s4));
1534 ipaddr->af = AF_INET;
1535 ipaddr->prefix = 32;
1536 ipaddr->ipaddr.ip4addr = s4.sin_addr;
1537 if (port) *port = ntohs(s4.sin_port);
1539 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1540 } else if (sa->ss_family == AF_INET6) {
1541 struct sockaddr_in6 s6;
1543 if (salen < sizeof(s6)) {
1544 fr_strerror_printf("IPv6 address is too small");
1548 memcpy(&s6, sa, sizeof(s6));
1549 ipaddr->af = AF_INET6;
1550 ipaddr->prefix = 128;
1551 ipaddr->ipaddr.ip6addr = s6.sin6_addr;
1552 if (port) *port = ntohs(s6.sin6_port);
1553 ipaddr->scope = s6.sin6_scope_id;
1557 fr_strerror_printf("Unsupported address famility %d",
1566 /** Set O_NONBLOCK on a socket
1568 * @note O_NONBLOCK is POSIX.
1570 * @param fd to set nonblocking flag on.
1571 * @return flags set on the socket, or -1 on error.
1573 int fr_nonblock(int fd)
1577 flags = fcntl(fd, F_GETFL, NULL);
1579 fr_strerror_printf("Failure getting socket flags: %s", fr_syserror(errno));
1583 flags |= O_NONBLOCK;
1584 if (fcntl(fd, F_SETFL, flags) < 0) {
1585 fr_strerror_printf("Failure setting socket flags: %s", fr_syserror(errno));
1592 /** Unset O_NONBLOCK on a socket
1594 * @note O_NONBLOCK is POSIX.
1596 * @param fd to set nonblocking flag on.
1597 * @return flags set on the socket, or -1 on error.
1599 int fr_blocking(int fd)
1603 flags = fcntl(fd, F_GETFL, NULL);
1605 fr_strerror_printf("Failure getting socket flags: %s", fr_syserror(errno));
1609 flags ^= O_NONBLOCK;
1610 if (fcntl(fd, F_SETFL, flags) < 0) {
1611 fr_strerror_printf("Failure setting socket flags: %s", fr_syserror(errno));
1618 int fr_nonblock(UNUSED int fd)
1620 fr_strerror_printf("Non blocking sockets are not supported");
1623 int fr_blocking(UNUSED int fd)
1625 fr_strerror_printf("Non blocking sockets are not supported");
1630 /** Write out a vector to a file descriptor
1632 * Wraps writev, calling it as necessary. If timeout is not NULL,
1633 * timeout is applied to each call that returns EAGAIN or EWOULDBLOCK
1635 * @note Should only be used on nonblocking file descriptors.
1636 * @note Socket should likely be closed on timeout.
1637 * @note iovec may be modified in such a way that it's not re-usable.
1638 * @note Leaves errno set to the last error that ocurred.
1640 * @param fd to write to.
1641 * @param vector to write.
1642 * @param iovcnt number of elements in iovec.
1643 * @param timeout how long to wait for fd to become writeable before timing out.
1644 * @return number of bytes written, -1 on error.
1646 ssize_t fr_writev(int fd, struct iovec vector[], int iovcnt, struct timeval *timeout)
1648 struct iovec *vector_p = vector;
1651 while (iovcnt > 0) {
1654 wrote = writev(fd, vector_p, iovcnt);
1659 * An entire vector element was written
1661 if (wrote >= (ssize_t)vector_p->iov_len) {
1663 wrote -= vector_p->iov_len;
1669 * Partial vector element was written
1671 vector_p->iov_len -= wrote;
1672 vector_p->iov_base = ((char *)vector_p->iov_base) + wrote;
1676 } else if (wrote == 0) return total;
1679 /* Write operation would block, use select() to implement a timeout */
1680 #if EWOULDBLOCK != EAGAIN
1690 FD_ZERO(&write_set);
1691 FD_SET(fd, &write_set);
1693 /* Don't let signals mess up the select */
1695 ret = select(fd + 1, NULL, &write_set, NULL, timeout);
1696 } while ((ret == -1) && (errno == EINTR));
1698 /* Select returned 0 which means it reached the timeout */
1700 fr_strerror_printf("Write timed out");
1704 /* Other select error */
1706 fr_strerror_printf("Failed waiting on socket: %s", fr_syserror(errno));
1710 /* select said a file descriptor was ready for writing */
1711 if (!fr_assert(FD_ISSET(fd, &write_set))) return -1;
1724 /** Convert UTF8 string to UCS2 encoding
1726 * @note Borrowed from src/crypto/ms_funcs.c of wpa_supplicant project (http://hostap.epitest.fi/wpa_supplicant/)
1728 * @param[out] out Where to write the ucs2 string.
1729 * @param[in] outlen Size of output buffer.
1730 * @param[in] in UTF8 string to convert.
1731 * @param[in] inlen length of UTF8 string.
1732 * @return the size of the UCS2 string written to the output buffer (in bytes).
1734 ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
1737 uint8_t *start = out;
1739 for (i = 0; i < inlen; i++) {
1743 if ((size_t)(out - start) >= outlen) {
1744 /* input too long */
1748 /* One-byte encoding */
1750 FR_PUT_LE16(out, c);
1753 } else if ((i == (inlen - 1)) || ((size_t)(out - start) >= (outlen - 1))) {
1754 /* Incomplete surrogate */
1759 /* Two-byte encoding */
1760 if ((c & 0xe0) == 0xc0) {
1761 FR_PUT_LE16(out, ((c & 0x1f) << 6) | (c2 & 0x3f));
1765 if ((i == inlen) || ((size_t)(out - start) >= (outlen - 1))) {
1766 /* Incomplete surrogate */
1770 /* Three-byte encoding */
1772 FR_PUT_LE16(out, ((c & 0xf) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));
1779 /** Write 128bit unsigned integer to buffer
1781 * @author Alexey Frunze
1783 * @param out where to write result to.
1784 * @param outlen size of out.
1785 * @param num 128 bit integer.
1787 size_t fr_prints_uint128(char *out, size_t outlen, uint128_t const num)
1789 char buff[128 / 3 + 1 + 1];
1793 #ifdef FR_LITTLE_ENDIAN
1801 memset(buff, '0', sizeof(buff) - 1);
1802 buff[sizeof(buff) - 1] = '\0';
1804 memcpy(n, &num, sizeof(n));
1806 for (i = 0; i < 128; i++) {
1810 carry = (n[h] >= 0x8000000000000000);
1812 // Shift n[] left, doubling it
1813 n[h] = ((n[h] << 1) & 0xffffffffffffffff) + (n[l] >= 0x8000000000000000);
1814 n[l] = ((n[l] << 1) & 0xffffffffffffffff);
1816 // Add s[] to itself in decimal, doubling it
1817 for (j = sizeof(buff) - 2; j >= 0; j--) {
1818 buff[j] += buff[j] - '0' + carry;
1819 carry = (buff[j] > '9');
1826 while ((*p == '0') && (p < &buff[sizeof(buff) - 2])) {
1830 return strlcpy(out, p, outlen);
1834 * Sort of strtok/strsep function.
1836 static char *mystrtok(char **ptr, char const *sep)
1844 while (**ptr && strchr(sep, **ptr)) {
1852 while (**ptr && strchr(sep, **ptr) == NULL) {
1862 /** Convert string in various formats to a time_t
1864 * @param date_str input date string.
1865 * @param date time_t to write result to.
1866 * @return 0 on success or -1 on error.
1868 int fr_get_time(char const *date_str, time_t *date)
1872 struct tm *tm, s_tm;
1879 * Test for unix timestamp date
1881 *date = strtoul(date_str, &tail, 10);
1882 if (*tail == '\0') {
1887 memset(tm, 0, sizeof(*tm));
1888 tm->tm_isdst = -1; /* don't know, and don't care about DST */
1890 strlcpy(buf, date_str, sizeof(buf));
1893 f[0] = mystrtok(&p, " \t");
1894 f[1] = mystrtok(&p, " \t");
1895 f[2] = mystrtok(&p, " \t");
1896 f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */
1897 if (!f[0] || !f[1] || !f[2]) return -1;
1900 * The time has a colon, where nothing else does.
1901 * So if we find it, bubble it to the back of the list.
1904 for (i = 0; i < 3; i++) {
1905 if (strchr(f[i], ':')) {
1915 * The month is text, which allows us to find it easily.
1918 for (i = 0; i < 3; i++) {
1919 if (isalpha( (int) *f[i])) {
1921 * Bubble the month to the front of the list
1927 for (i = 0; i < 12; i++) {
1928 if (strncasecmp(months[i], f[0], 3) == 0) {
1936 /* month not found? */
1937 if (tm->tm_mon == 12) return -1;
1940 * The year may be in f[1], or in f[2]
1942 tm->tm_year = atoi(f[1]);
1943 tm->tm_mday = atoi(f[2]);
1945 if (tm->tm_year >= 1900) {
1946 tm->tm_year -= 1900;
1950 * We can't use 2-digit years any more, they make it
1951 * impossible to tell what's the day, and what's the year.
1953 if (tm->tm_mday < 1900) return -1;
1956 * Swap the year and the day.
1959 tm->tm_year = tm->tm_mday - 1900;
1964 * If the day is out of range, die.
1966 if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {
1971 * There may be %H:%M:%S. Parse it in a hacky way.
1974 f[0] = f[3]; /* HH */
1975 f[1] = strchr(f[0], ':'); /* find : separator */
1976 if (!f[1]) return -1;
1978 *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
1980 f[2] = strchr(f[1], ':'); /* find : separator */
1982 *(f[2]++) = '\0'; /* nuke it, and point to SS */
1983 tm->tm_sec = atoi(f[2]);
1984 } /* else leave it as zero */
1986 tm->tm_hour = atoi(f[0]);
1987 tm->tm_min = atoi(f[1]);
1991 * Returns -1 on error.
1994 if (t == (time_t) -1) return -1;
2001 /** Compares two pointers
2003 * @param a first pointer to compare.
2004 * @param b second pointer to compare.
2005 * @return -1 if a < b, +1 if b > a, or 0 if both equal.
2007 int8_t fr_pointer_cmp(void const *a, void const *b)
2009 if (a < b) return -1;
2010 if (a == b) return 0;
2015 static int _quick_partition(void const *to_sort[], int min, int max, fr_cmp_t cmp) {
2016 void const *pivot = to_sort[min];
2022 do ++i; while((cmp(to_sort[i], pivot) <= 0) && i <= max);
2023 do --j; while(cmp(to_sort[j], pivot) > 0);
2028 to_sort[i] = to_sort[j];
2033 to_sort[min] = to_sort[j];
2039 /** Quick sort an array of pointers using a comparator
2041 * @param to_sort array of pointers to sort.
2042 * @param min_idx the lowest index (usually 0).
2043 * @param max_idx the highest index (usually length of array - 1).
2044 * @param cmp the comparison function to use to sort the array elements.
2046 void fr_quick_sort(void const *to_sort[], int min_idx, int max_idx, fr_cmp_t cmp)
2050 if (min_idx >= max_idx) return;
2052 part = _quick_partition(to_sort, min_idx, max_idx, cmp);
2053 fr_quick_sort(to_sort, min_idx, part - 1, cmp);
2054 fr_quick_sort(to_sort, part + 1, max_idx, cmp);
2058 void fr_talloc_verify_cb(UNUSED const void *ptr, UNUSED int depth,
2059 UNUSED int max_depth, UNUSED int is_ref,
2060 UNUSED void *private_data)