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>
31 #define FR_PUT_LE16(a, val)\
33 a[1] = ((uint16_t) (val)) >> 8;\
34 a[0] = ((uint16_t) (val)) & 0xff;\
38 # define PTHREAD_MUTEX_LOCK pthread_mutex_lock
39 # define PTHREAD_MUTEX_UNLOCK pthread_mutex_unlock
41 # define PTHREAD_MUTEX_LOCK(_x)
42 # define PTHREAD_MUTEX_UNLOCK(_x)
45 bool fr_dns_lookups = false; /* IP -> hostname lookups? */
46 bool fr_hostname_lookups = true; /* hostname -> IP lookups? */
47 int fr_debug_flag = 0;
49 static char const *months[] = {
50 "jan", "feb", "mar", "apr", "may", "jun",
51 "jul", "aug", "sep", "oct", "nov", "dec" };
53 fr_thread_local_setup(char *, fr_inet_ntop_buffer); /* macro */
55 typedef struct fr_talloc_link {
60 /** Sets a signal handler using sigaction if available, else signal
62 * @param sig to set handler for.
63 * @param func handler to set.
65 int fr_set_signal(int sig, sig_t func)
70 memset(&act, 0, sizeof(act));
72 sigemptyset(&act.sa_mask);
73 act.sa_handler = func;
75 if (sigaction(sig, &act, NULL) < 0) {
76 fr_strerror_printf("Failed setting signal %i handler via sigaction(): %s", sig, fr_syserror(errno));
80 if (signal(sig, func) < 0) {
81 fr_strerror_printf("Failed setting signal %i handler via signal(): %s", sig, fr_syserror(errno));
88 static int _fr_trigger_talloc_ctx_free(fr_talloc_link_t *trigger)
90 if (trigger->armed) talloc_free(trigger->child);
95 static int _fr_disarm_talloc_ctx_free(bool **armed)
101 /** Link a parent and a child context, so the child is freed before the parent
103 * @note This is not thread safe. Do not free parent before threads are joined, do not call from a child thread.
104 * @note It's OK to free the child before threads are joined, but this will leak memory until the parent is freed.
106 * @param parent who's fate the child should share.
107 * @param child bound to parent's lifecycle.
108 * @return 0 on success -1 on failure.
110 int fr_link_talloc_ctx_free(TALLOC_CTX *parent, TALLOC_CTX *child)
112 fr_talloc_link_t *trigger;
115 trigger = talloc(parent, fr_talloc_link_t);
116 if (!trigger) return -1;
118 disarm = talloc(child, bool *);
120 talloc_free(trigger);
124 trigger->child = child;
125 trigger->armed = true;
126 *disarm = &trigger->armed;
128 talloc_set_destructor(trigger, _fr_trigger_talloc_ctx_free);
129 talloc_set_destructor(disarm, _fr_disarm_talloc_ctx_free);
135 * Explicitly cleanup the memory allocated to the error inet_ntop
138 static void _fr_inet_ntop_free(void *arg)
143 /** Wrapper around inet_ntop, prints IPv4/IPv6 addresses
145 * inet_ntop requires the caller pass in a buffer for the address.
146 * This would be annoying and cumbersome, seeing as quite often the ASCII
147 * address is only used for logging output.
149 * So as with lib/log.c use TLS to allocate thread specific buffers, and
150 * write the IP address there instead.
152 * @param af address family, either AF_INET or AF_INET6.
153 * @param src pointer to network address structure.
154 * @return NULL on error, else pointer to ASCII buffer containing text version of address.
156 char const *fr_inet_ntop(int af, void const *src)
164 buffer = fr_thread_local_init(fr_inet_ntop_buffer, _fr_inet_ntop_free);
169 * malloc is thread safe, talloc is not
171 buffer = malloc(sizeof(char) * INET6_ADDRSTRLEN);
173 fr_perror("Failed allocating memory for inet_ntop buffer");
177 ret = fr_thread_local_set(fr_inet_ntop_buffer, buffer);
179 fr_perror("Failed setting up TLS for inet_ntop buffer: %s", fr_syserror(ret));
186 return inet_ntop(af, src, buffer, INET6_ADDRSTRLEN);
190 * Return an IP address in standard dot notation
194 char const *ip_ntoa(char *buffer, uint32_t ipaddr)
196 ipaddr = ntohl(ipaddr);
198 sprintf(buffer, "%d.%d.%d.%d",
199 (ipaddr >> 24) & 0xff,
200 (ipaddr >> 16) & 0xff,
201 (ipaddr >> 8) & 0xff,
206 /** Parse an IPv4 address or IPv4 prefix in presentation format (and others)
208 * @param out Where to write the ip address value.
209 * @param value to parse, may be dotted quad [+ prefix], or integer, or octal number, or '*' (INADDR_ANY).
210 * @param inlen Length of value, if value is \0 terminated inlen may be 0.
211 * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
212 * @param fallback to IPv4 resolution if no A records can be found.
213 * @return 0 if ip address was parsed successfully, else -1 on error.
215 int fr_pton4(fr_ipaddr_t *out, char const *value, size_t inlen, bool resolve, bool fallback)
221 /* Dotted quad + / + [0-9]{1,2} */
222 char buffer[INET_ADDRSTRLEN + 3];
225 * Copy to intermediary buffer if we were given a length
228 if (inlen >= sizeof(buffer)) {
229 fr_strerror_printf("Invalid IPv4 address string \"%s\"", value);
232 memcpy(buffer, value, inlen);
233 buffer[inlen] = '\0';
236 p = strchr(value, '/');
238 * 192.0.2.2 is parsed as if it was /32
242 * Allow '*' as the wildcard address usually 0.0.0.0
244 if ((value[0] == '*') && (value[1] == '\0')) {
245 out->ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
247 * Convert things which are obviously integers to IP addresses
249 * We assume the number is the bigendian representation of the
252 } else if (is_integer(value) || ((value[0] == '0') && (value[1] == 'x'))) {
253 out->ipaddr.ip4addr.s_addr = htonl(strtoul(value, NULL, 0));
254 } else if (!resolve) {
255 if (inet_pton(AF_INET, value, &(out->ipaddr.ip4addr.s_addr)) <= 0) {
256 fr_strerror_printf("Failed to parse IPv4 address string \"%s\"", value);
259 } else if (ip_hton(out, AF_INET, value, fallback) < 0) return -1;
268 * Otherwise parse the prefix
270 if ((size_t)(p - value) >= INET_ADDRSTRLEN) {
271 fr_strerror_printf("Invalid IPv4 address string \"%s\"", value);
276 * Copy the IP portion into a temporary buffer if we haven't already.
278 if (inlen == 0) memcpy(buffer, value, p - value);
279 buffer[p - value] = '\0';
282 if (inet_pton(AF_INET, buffer, &(out->ipaddr.ip4addr.s_addr)) <= 0) {
283 fr_strerror_printf("Failed to parse IPv4 address string \"%s\"", value);
286 } else if (ip_hton(out, AF_INET, buffer, fallback) < 0) return -1;
288 prefix = strtoul(p + 1, &eptr, 10);
290 fr_strerror_printf("Invalid IPv4 mask length \"%s\". Should be between 0-32", p);
293 if (eptr[0] != '\0') {
294 fr_strerror_printf("Failed to parse IPv4 address string \"%s\", "
295 "got garbage after mask length \"%s\"", value, eptr);
300 out->ipaddr.ip4addr = fr_inaddr_mask(&(out->ipaddr.ip4addr), prefix);
303 out->prefix = (uint8_t) prefix;
309 /** Parse an IPv6 address or IPv6 prefix in presentation format (and others)
311 * @param out Where to write the ip address value.
312 * @param value to parse.
313 * @param inlen Length of value, if value is \0 terminated inlen may be 0.
314 * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
315 * @param fallback to IPv4 resolution if no AAAA records can be found.
316 * @return 0 if ip address was parsed successfully, else -1 on error.
318 int fr_pton6(fr_ipaddr_t *out, char const *value, size_t inlen, bool resolve, bool fallback)
324 /* IPv6 + / + [0-9]{1,3} */
325 char buffer[INET6_ADDRSTRLEN + 4];
328 * Copy to intermediary buffer if we were given a length
331 if (inlen >= sizeof(buffer)) {
332 fr_strerror_printf("Invalid IPv6 address string \"%s\"", value);
335 memcpy(buffer, value, inlen);
336 buffer[inlen] = '\0';
339 p = strchr(value, '/');
342 * Allow '*' as the wildcard address
344 if ((value[0] == '*') && (value[1] == '\0')) {
345 memset(&out->ipaddr.ip6addr.s6_addr, 0, sizeof(out->ipaddr.ip6addr.s6_addr));
346 } else if (!resolve) {
347 if (inet_pton(AF_INET6, value, &(out->ipaddr.ip6addr.s6_addr)) <= 0) {
348 fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
351 } else if (ip_hton(out, AF_INET6, value, fallback) < 0) return -1;
359 if ((p - value) >= INET6_ADDRSTRLEN) {
360 fr_strerror_printf("Invalid IPv6 address string \"%s\"", value);
365 * Copy string to temporary buffer if we didn't do it earlier
367 if (inlen == 0) memcpy(buffer, value, p - value);
368 buffer[p - value] = '\0';
371 if (inet_pton(AF_INET6, buffer, &(out->ipaddr.ip6addr.s6_addr)) <= 0) {
372 fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
375 } else if (ip_hton(out, AF_INET6, buffer, fallback) < 0) return -1;
377 prefix = strtoul(p + 1, &eptr, 10);
379 fr_strerror_printf("Invalid IPv6 mask length \"%s\". Should be between 0-128", p);
382 if (eptr[0] != '\0') {
383 fr_strerror_printf("Failed to parse IPv6 address string \"%s\", "
384 "got garbage after mask length \"%s\"", value, eptr);
389 struct in6_addr addr;
391 addr = fr_in6addr_mask(&(out->ipaddr.ip6addr), prefix);
392 memcpy(&(out->ipaddr.ip6addr.s6_addr), &addr, sizeof(addr));
395 out->prefix = (uint8_t) prefix;
401 /** Simple wrapper to decide whether an IP value is v4 or v6 and call the appropriate parser.
403 * @param out Where to write the ip address value.
404 * @param value to parse.
405 * @param inlen Length of value, if value is \0 terminated inlen may be 0.
406 * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
407 * @return 0 if ip address was parsed successfully, else -1 on error.
409 int fr_pton(fr_ipaddr_t *out, char const *value, size_t inlen, bool resolve)
413 len = (inlen == 0) ? strlen(value) : inlen;
414 for (i = 0; i < len; i++) switch (value[i]) {
416 * Chars illegal in domain names and IPv4 addresses.
417 * Must be v6 and cannot be a domain.
422 return fr_pton6(out, value, inlen, false, false);
425 * Chars which don't really tell us anything
433 * Outside the range of IPv4 chars, must be a domain
434 * Use A record in preference to AAAA record.
436 if ((value[i] < '0') || (value[i] > '9')) {
437 if (!resolve) return -1;
438 return fr_pton4(out, value, inlen, true, true);
444 * All chars were in the IPv4 set [0-9/.], must be an IPv4
447 return fr_pton4(out, value, inlen, false, false);
450 /** Check if the IP address is equivalent to INADDR_ANY
452 * @param addr to chec.
453 * @return true if IP address matches INADDR_ANY or INADDR6_ANY (assumed to be 0), else false.
455 bool is_wildcard(fr_ipaddr_t *addr)
457 static struct in6_addr in6_addr;
461 return (addr->ipaddr.ip4addr.s_addr == htons(INADDR_ANY));
464 return (memcmp(addr->ipaddr.ip6addr.s6_addr, in6_addr.s6_addr, sizeof(in6_addr.s6_addr)) == 0) ? true :false;
472 int fr_ntop(char *out, size_t outlen, fr_ipaddr_t *addr)
474 char buffer[INET6_ADDRSTRLEN];
476 if (inet_ntop(addr->af, &(addr->ipaddr), buffer, sizeof(buffer)) == NULL) return -1;
478 return snprintf(out, outlen, "%s/%i", buffer, addr->prefix);
482 * Internal wrapper for locking, to minimize the number of ifdef's
486 int rad_lockfd(int fd, int lock_len)
495 fl.l_whence = SEEK_CUR;
497 return fcntl(fd, F_SETLKW, (void *)&fl);
499 #error "missing definition for F_WRLCK, all file locks will fail"
506 * Internal wrapper for locking, to minimize the number of ifdef's
508 * Lock an fd, prefer lockf() over flock()
509 * Nonblocking version.
511 int rad_lockfd_nonblock(int fd, int lock_len)
520 fl.l_whence = SEEK_CUR;
522 return fcntl(fd, F_SETLK, (void *)&fl);
524 #error "missing definition for F_WRLCK, all file locks will fail"
531 * Internal wrapper for unlocking, to minimize the number of ifdef's
534 * Unlock an fd, prefer lockf() over flock()
536 int rad_unlockfd(int fd, int lock_len)
545 fl.l_whence = SEEK_CUR;
547 return fcntl(fd, F_UNLCK, (void *)&fl);
549 #error "missing definition for F_WRLCK, all file locks will fail"
556 * Return an interface-id in standard colon notation
558 char *ifid_ntoa(char *buffer, size_t size, uint8_t const *ifid)
560 snprintf(buffer, size, "%x:%x:%x:%x",
561 (ifid[0] << 8) + ifid[1], (ifid[2] << 8) + ifid[3],
562 (ifid[4] << 8) + ifid[5], (ifid[6] << 8) + ifid[7]);
568 * Return an interface-id from
569 * one supplied in standard colon notation.
571 uint8_t *ifid_aton(char const *ifid_str, uint8_t *ifid)
573 static char const xdigits[] = "0123456789abcdef";
575 int num_id = 0, val = 0, idx = 0;
577 for (p = ifid_str; ; ++p) {
578 if (*p == ':' || *p == '\0') {
583 * Drop 'val' into the array.
585 ifid[idx] = (val >> 8) & 0xff;
586 ifid[idx + 1] = val & 0xff;
589 * Must have all entries before
600 } else if ((pch = strchr(xdigits, tolower(*p))) != NULL) {
604 * Dumb version of 'scanf'
607 val |= (pch - xdigits);
615 #ifndef HAVE_INET_PTON
616 static int inet_pton4(char const *src, struct in_addr *dst)
622 static char const digits[] = "0123456789";
628 while (*p && ((off = strchr(digits, *p)) != NULL)) {
630 num += (off - digits);
632 if (num > 255) return 0;
639 * Not a digit, MUST be a dot, else we
651 * End of the string. At the fourth
652 * octet is OK, anything else is an
660 memcpy(dst, &tmp, sizeof(tmp));
665 #ifdef HAVE_STRUCT_SOCKADDR_IN6
667 * inet_pton6(src, dst)
668 * convert presentation level address to network order binary form.
670 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
672 * (1) does not touch `dst' unless it's returning 1.
673 * (2) :: in a full address is silently ignored.
675 * inspired by Mark Andrews.
679 static int inet_pton6(char const *src, unsigned char *dst)
681 static char const xdigits_l[] = "0123456789abcdef",
682 xdigits_u[] = "0123456789ABCDEF";
683 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
684 char const *xdigits, *curtok;
688 memset((tp = tmp), 0, IN6ADDRSZ);
689 endp = tp + IN6ADDRSZ;
691 /* Leading :: requires some special handling. */
698 while ((ch = *src++) != '\0') {
701 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
702 pch = strchr((xdigits = xdigits_u), ch);
705 val |= (pch - xdigits);
719 if (tp + INT16SZ > endp)
721 *tp++ = (u_char) (val >> 8) & 0xff;
722 *tp++ = (u_char) val & 0xff;
727 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
728 inet_pton4(curtok, (struct in_addr *) tp) > 0) {
731 break; /* '\0' was seen by inet_pton4(). */
736 if (tp + INT16SZ > endp)
738 *tp++ = (u_char) (val >> 8) & 0xff;
739 *tp++ = (u_char) val & 0xff;
741 if (colonp != NULL) {
743 * Since some memmove()'s erroneously fail to handle
744 * overlapping regions, we'll do the shift by hand.
746 int const n = tp - colonp;
749 for (i = 1; i <= n; i++) {
750 endp[- i] = colonp[n - i];
757 /* bcopy(tmp, dst, IN6ADDRSZ); */
758 memcpy(dst, tmp, IN6ADDRSZ);
764 * Utility function, so that the rest of the server doesn't
765 * have ifdef's around IPv6 support
767 int inet_pton(int af, char const *src, void *dst)
770 return inet_pton4(src, dst);
772 #ifdef HAVE_STRUCT_SOCKADDR_IN6
774 if (af == AF_INET6) {
775 return inet_pton6(src, dst);
783 #ifndef HAVE_INET_NTOP
785 * Utility function, so that the rest of the server doesn't
786 * have ifdef's around IPv6 support
788 char const *inet_ntop(int af, void const *src, char *dst, size_t cnt)
791 uint8_t const *ipaddr = src;
793 if (cnt <= INET_ADDRSTRLEN) return NULL;
795 snprintf(dst, cnt, "%d.%d.%d.%d",
796 ipaddr[0], ipaddr[1],
797 ipaddr[2], ipaddr[3]);
802 * If the system doesn't define this, we define it
805 if (af == AF_INET6) {
806 struct in6_addr const *ipaddr = src;
808 if (cnt <= INET6_ADDRSTRLEN) return NULL;
810 snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x",
811 (ipaddr->s6_addr[0] << 8) | ipaddr->s6_addr[1],
812 (ipaddr->s6_addr[2] << 8) | ipaddr->s6_addr[3],
813 (ipaddr->s6_addr[4] << 8) | ipaddr->s6_addr[5],
814 (ipaddr->s6_addr[6] << 8) | ipaddr->s6_addr[7],
815 (ipaddr->s6_addr[8] << 8) | ipaddr->s6_addr[9],
816 (ipaddr->s6_addr[10] << 8) | ipaddr->s6_addr[11],
817 (ipaddr->s6_addr[12] << 8) | ipaddr->s6_addr[13],
818 (ipaddr->s6_addr[14] << 8) | ipaddr->s6_addr[15]);
822 return NULL; /* don't support IPv6 */
826 /** Wrappers for IPv4/IPv6 host to IP address lookup
828 * This function returns only one IP address, of the specified address family,
829 * or the first address (of whatever family), if AF_UNSPEC is used.
831 * If fallback is specified and af is AF_INET, but no AF_INET records were
832 * found and a record for AF_INET6 exists that record will be returned.
834 * If fallback is specified and af is AF_INET6, and a record with AF_INET4 exists
835 * that record will be returned instead.
837 * @param out Where to write result.
838 * @param af To search for in preference.
839 * @param hostname to search for.
840 * @param fallback to the other adress family, if no records matching af, found.
841 * @return 0 on success, else -1 on failure.
843 int ip_hton(fr_ipaddr_t *out, int af, char const *hostname, bool fallback)
846 struct addrinfo hints, *ai = NULL, *alt = NULL, *res = NULL;
848 if (!fr_hostname_lookups) {
849 #ifdef HAVE_STRUCT_SOCKADDR_IN6
850 if (af == AF_UNSPEC) {
853 for (p = hostname; *p != '\0'; p++) {
864 if (af == AF_UNSPEC) af = AF_INET;
866 if (!inet_pton(af, hostname, &(out->ipaddr))) {
874 memset(&hints, 0, sizeof(hints));
875 hints.ai_family = af;
879 * Avoid malloc for IP addresses. This helps us debug
880 * memory errors when using talloc.
884 * If it's all numeric, avoid getaddrinfo()
886 if (inet_pton(af, hostname, &out->ipaddr.ip4addr) == 1) {
892 if ((rcode = getaddrinfo(hostname, NULL, &hints, &res)) != 0) {
893 fr_strerror_printf("ip_hton: %s", gai_strerror(rcode));
897 for (ai = res; ai; ai = ai->ai_next) {
898 if ((af == ai->ai_family) || (af == AF_UNSPEC)) break;
899 if (!alt && fallback && ((ai->ai_family == AF_INET) || (ai->ai_family == AF_INET6))) alt = ai;
904 fr_strerror_printf("ip_hton failed to find requested information for host %.100s", hostname);
909 rcode = fr_sockaddr2ipaddr((struct sockaddr_storage *)ai->ai_addr,
910 ai->ai_addrlen, out, NULL);
912 if (!rcode) return -1;
918 * Look IP addresses up, and print names (depending on DNS config)
920 char const *ip_ntoh(fr_ipaddr_t const *src, char *dst, size_t cnt)
922 struct sockaddr_storage ss;
929 if (!fr_dns_lookups) {
930 return inet_ntop(src->af, &(src->ipaddr), dst, cnt);
933 if (!fr_ipaddr2sockaddr(src, 0, &ss, &salen)) {
937 if ((error = getnameinfo((struct sockaddr *)&ss, salen, dst, cnt, NULL, 0,
938 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
939 fr_strerror_printf("ip_ntoh: %s", gai_strerror(error));
945 /** Mask off a portion of an IPv4 address
947 * @param ipaddr to mask.
948 * @param prefix Number of contiguous bits to mask.
949 * @return an ipv6 address with the host portion zeroed out.
951 struct in_addr fr_inaddr_mask(struct in_addr const *ipaddr, uint8_t prefix)
964 ret = htonl(~((0x00000001UL << (32 - prefix)) - 1)) & ipaddr->s_addr;
965 return (*(struct in_addr *)&ret);
968 /** Mask off a portion of an IPv6 address
970 * @param ipaddr to mask.
971 * @param prefix Number of contiguous bits to mask.
972 * @return an ipv6 address with the host portion zeroed out.
974 struct in6_addr fr_in6addr_mask(struct in6_addr const *ipaddr, uint8_t prefix)
976 uint64_t const *p = (uint64_t const *) ipaddr;
977 uint64_t ret[2], *o = ret;
990 *o++ = 0xffffffffffffffffULL & *p++;
995 *o = htonll(~((0x0000000000000001ULL << (64 - prefix)) - 1)) & *p;
997 return *(struct in6_addr *) &ret;
1000 /** Zeroes out the host portion of an fr_ipaddr_t
1002 * @param[in,out] addr to mask
1003 * @param[in] prefix Length of the network portion.
1005 void fr_ipaddr_mask(fr_ipaddr_t *addr, uint8_t prefix)
1010 addr->ipaddr.ip4addr = fr_inaddr_mask(&addr->ipaddr.ip4addr, prefix);
1014 addr->ipaddr.ip6addr = fr_in6addr_mask(&addr->ipaddr.ip6addr, prefix);
1020 addr->prefix = prefix;
1023 static char const hextab[] = "0123456789abcdef";
1025 /** Convert hex strings to binary data
1027 * @param bin Buffer to write output to.
1028 * @param outlen length of output buffer (or length of input string / 2).
1029 * @param hex input string.
1030 * @param inlen length of the input string
1031 * @return length of data written to buffer.
1033 size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen)
1040 * Smartly truncate output, caller should check number of bytes
1044 if (len > outlen) len = outlen;
1046 for (i = 0; i < len; i++) {
1047 if(!(c1 = memchr(hextab, tolower((int) hex[i << 1]), sizeof(hextab))) ||
1048 !(c2 = memchr(hextab, tolower((int) hex[(i << 1) + 1]), sizeof(hextab))))
1050 bin[i] = ((c1-hextab)<<4) + (c2-hextab);
1056 /** Convert binary data to a hex string
1058 * Ascii encoded hex string will not be prefixed with '0x'
1060 * @warning If the output buffer isn't long enough, we have a buffer overflow.
1062 * @param[out] hex Buffer to write hex output.
1063 * @param[in] bin input.
1064 * @param[in] inlen of bin input.
1065 * @return length of data written to buffer.
1067 size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen)
1071 for (i = 0; i < inlen; i++) {
1072 hex[0] = hextab[((*bin) >> 4) & 0x0f];
1073 hex[1] = hextab[*bin & 0x0f];
1082 /** Convert binary data to a hex string
1084 * Ascii encoded hex string will not be prefixed with '0x'
1086 * @param[in] ctx to alloc buffer in.
1087 * @param[in] bin input.
1088 * @param[in] inlen of bin input.
1089 * @return length of data written to buffer.
1091 char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen)
1095 buff = talloc_array(ctx, char, (inlen << 2));
1096 if (!buff) return NULL;
1098 fr_bin2hex(buff, bin, inlen);
1103 /** Consume the integer (or hex) portion of a value string
1105 * @param value string to parse.
1106 * @param end pointer to the first non numeric char.
1107 * @return integer value.
1109 uint32_t fr_strtoul(char const *value, char **end)
1111 if ((value[0] == '0') && (value[1] == 'x')) {
1112 return strtoul(value, end, 16);
1115 return strtoul(value, end, 10);
1118 /** Check whether the string is all whitespace
1120 * @return true if the entirety of the string is whitespace, else false.
1122 bool is_whitespace(char const *value)
1125 if (!isspace(*value)) return false;
1131 /** Check whether the string is all numbers
1133 * @return true if the entirety of the string is are numebrs, else false.
1135 bool is_integer(char const *value)
1138 if (!isdigit(*value)) return false;
1144 /** Check whether the string is allzeros
1146 * @return true if the entirety of the string is are numebrs, else false.
1148 bool is_zero(char const *value)
1151 if (*value != '0') return false;
1158 * So we don't have ifdef's in the rest of the code
1160 #ifndef HAVE_CLOSEFROM
1161 int closefrom(int fd)
1167 maxfd = sysconf(_SC_OPEN_MAX);
1173 if (fd > maxfd) return 0;
1176 * FIXME: return EINTR?
1180 for (i = fd; i < maxfd; i++) {
1188 int fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
1190 if (a->af < b->af) return -1;
1191 if (a->af > b->af) return +1;
1195 return memcmp(&a->ipaddr.ip4addr,
1197 sizeof(a->ipaddr.ip4addr));
1200 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1202 if (a->scope < b->scope) return -1;
1203 if (a->scope > b->scope) return +1;
1205 return memcmp(&a->ipaddr.ip6addr,
1207 sizeof(a->ipaddr.ip6addr));
1218 int fr_ipaddr2sockaddr(fr_ipaddr_t const *ipaddr, uint16_t port,
1219 struct sockaddr_storage *sa, socklen_t *salen)
1221 if (ipaddr->af == AF_INET) {
1222 struct sockaddr_in s4;
1224 *salen = sizeof(s4);
1226 memset(&s4, 0, sizeof(s4));
1227 s4.sin_family = AF_INET;
1228 s4.sin_addr = ipaddr->ipaddr.ip4addr;
1229 s4.sin_port = htons(port);
1230 memset(sa, 0, sizeof(*sa));
1231 memcpy(sa, &s4, sizeof(s4));
1233 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1234 } else if (ipaddr->af == AF_INET6) {
1235 struct sockaddr_in6 s6;
1237 *salen = sizeof(s6);
1239 memset(&s6, 0, sizeof(s6));
1240 s6.sin6_family = AF_INET6;
1241 s6.sin6_addr = ipaddr->ipaddr.ip6addr;
1242 s6.sin6_port = htons(port);
1243 s6.sin6_scope_id = ipaddr->scope;
1244 memset(sa, 0, sizeof(*sa));
1245 memcpy(sa, &s6, sizeof(s6));
1255 int fr_sockaddr2ipaddr(struct sockaddr_storage const *sa, socklen_t salen,
1256 fr_ipaddr_t *ipaddr, uint16_t *port)
1258 if (sa->ss_family == AF_INET) {
1259 struct sockaddr_in s4;
1261 if (salen < sizeof(s4)) {
1262 fr_strerror_printf("IPv4 address is too small");
1266 memcpy(&s4, sa, sizeof(s4));
1267 ipaddr->af = AF_INET;
1268 ipaddr->prefix = 32;
1269 ipaddr->ipaddr.ip4addr = s4.sin_addr;
1270 if (port) *port = ntohs(s4.sin_port);
1272 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1273 } else if (sa->ss_family == AF_INET6) {
1274 struct sockaddr_in6 s6;
1276 if (salen < sizeof(s6)) {
1277 fr_strerror_printf("IPv6 address is too small");
1281 memcpy(&s6, sa, sizeof(s6));
1282 ipaddr->af = AF_INET6;
1283 ipaddr->prefix = 128;
1284 ipaddr->ipaddr.ip6addr = s6.sin6_addr;
1285 if (port) *port = ntohs(s6.sin6_port);
1286 ipaddr->scope = s6.sin6_scope_id;
1290 fr_strerror_printf("Unsupported address famility %d",
1298 /** Convert UTF8 string to UCS2 encoding
1300 * @note Borrowed from src/crypto/ms_funcs.c of wpa_supplicant project (http://hostap.epitest.fi/wpa_supplicant/)
1302 * @param[out] out Where to write the ucs2 string.
1303 * @param[in] outlen Size of output buffer.
1304 * @param[in] in UTF8 string to convert.
1305 * @param[in] inlen length of UTF8 string.
1306 * @return the size of the UCS2 string written to the output buffer (in bytes).
1308 ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
1311 uint8_t *start = out;
1313 for (i = 0; i < inlen; i++) {
1317 if ((size_t)(out - start) >= outlen) {
1318 /* input too long */
1322 /* One-byte encoding */
1324 FR_PUT_LE16(out, c);
1327 } else if ((i == (inlen - 1)) || ((size_t)(out - start) >= (outlen - 1))) {
1328 /* Incomplete surrogate */
1333 /* Two-byte encoding */
1334 if ((c & 0xe0) == 0xc0) {
1335 FR_PUT_LE16(out, ((c & 0x1f) << 6) | (c2 & 0x3f));
1339 if ((i == inlen) || ((size_t)(out - start) >= (outlen - 1))) {
1340 /* Incomplete surrogate */
1344 /* Three-byte encoding */
1346 FR_PUT_LE16(out, ((c & 0xf) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));
1353 /** Write 128bit unsigned integer to buffer
1355 * @author Alexey Frunze
1357 * @param out where to write result to.
1358 * @param outlen size of out.
1359 * @param num 128 bit integer.
1361 size_t fr_prints_uint128(char *out, size_t outlen, uint128_t const num)
1363 char buff[128 / 3 + 1 + 1];
1368 memset(buff, '0', sizeof(buff) - 1);
1369 buff[sizeof(buff) - 1] = '\0';
1371 memcpy(n, &num, sizeof(n));
1373 for (i = 0; i < 128; i++) {
1377 carry = (n[1] >= 0x8000000000000000);
1379 // Shift n[] left, doubling it
1380 n[1] = ((n[1] << 1) & 0xffffffffffffffff) + (n[0] >= 0x8000000000000000);
1381 n[0] = ((n[0] << 1) & 0xffffffffffffffff);
1383 // Add s[] to itself in decimal, doubling it
1384 for (j = sizeof(buff) - 2; j >= 0; j--) {
1385 buff[j] += buff[j] - '0' + carry;
1386 carry = (buff[j] > '9');
1393 while ((*p == '0') && (p < &buff[sizeof(buff) - 2])) {
1397 return strlcpy(out, p, outlen);
1400 /** Calculate powers
1402 * @author Orson Peters
1403 * @note Borrowed from the gist here: https://gist.github.com/nightcracker/3551590.
1405 * @param base a 32bit signed integer.
1406 * @param exp amount to raise base by.
1407 * @return base ^ pow, or 0 on underflow/overflow.
1409 int64_t fr_pow(int32_t base, uint8_t exp) {
1410 static const uint8_t highest_bit_set[] = {
1411 0, 1, 2, 2, 3, 3, 3, 3,
1412 4, 4, 4, 4, 4, 4, 4, 4,
1413 5, 5, 5, 5, 5, 5, 5, 5,
1414 5, 5, 5, 5, 5, 5, 5, 5,
1415 6, 6, 6, 6, 6, 6, 6, 6,
1416 6, 6, 6, 6, 6, 6, 6, 6,
1417 6, 6, 6, 6, 6, 6, 6, 6,
1418 6, 6, 6, 6, 6, 6, 6, 255, // anything past 63 is a guaranteed overflow with base > 1
1419 255, 255, 255, 255, 255, 255, 255, 255,
1420 255, 255, 255, 255, 255, 255, 255, 255,
1421 255, 255, 255, 255, 255, 255, 255, 255,
1422 255, 255, 255, 255, 255, 255, 255, 255,
1423 255, 255, 255, 255, 255, 255, 255, 255,
1424 255, 255, 255, 255, 255, 255, 255, 255,
1425 255, 255, 255, 255, 255, 255, 255, 255,
1426 255, 255, 255, 255, 255, 255, 255, 255,
1427 255, 255, 255, 255, 255, 255, 255, 255,
1428 255, 255, 255, 255, 255, 255, 255, 255,
1429 255, 255, 255, 255, 255, 255, 255, 255,
1430 255, 255, 255, 255, 255, 255, 255, 255,
1431 255, 255, 255, 255, 255, 255, 255, 255,
1432 255, 255, 255, 255, 255, 255, 255, 255,
1433 255, 255, 255, 255, 255, 255, 255, 255,
1434 255, 255, 255, 255, 255, 255, 255, 255,
1435 255, 255, 255, 255, 255, 255, 255, 255,
1436 255, 255, 255, 255, 255, 255, 255, 255,
1437 255, 255, 255, 255, 255, 255, 255, 255,
1438 255, 255, 255, 255, 255, 255, 255, 255,
1439 255, 255, 255, 255, 255, 255, 255, 255,
1440 255, 255, 255, 255, 255, 255, 255, 255,
1441 255, 255, 255, 255, 255, 255, 255, 255,
1442 255, 255, 255, 255, 255, 255, 255, 255,
1445 uint64_t result = 1;
1447 switch (highest_bit_set[exp]) {
1448 case 255: // we use 255 as an overflow marker and return 0 on overflow/underflow
1454 return 1 - 2 * (exp & 1);
1458 if (exp & 1) result *= base;
1462 if (exp & 1) result *= base;
1466 if (exp & 1) result *= base;
1470 if (exp & 1) result *= base;
1474 if (exp & 1) result *= base;
1478 if (exp & 1) result *= base;
1485 * Sort of strtok/strsep function.
1487 static char *mystrtok(char **ptr, char const *sep)
1495 while (**ptr && strchr(sep, **ptr)) {
1503 while (**ptr && strchr(sep, **ptr) == NULL) {
1513 /** Convert string in various formats to a time_t
1515 * @param date_str input date string.
1516 * @param date time_t to write result to.
1517 * @return 0 on success or -1 on error.
1519 int fr_get_time(char const *date_str, time_t *date)
1523 struct tm *tm, s_tm;
1530 * Test for unix timestamp date
1532 *date = strtoul(date_str, &tail, 10);
1533 if (*tail == '\0') {
1538 memset(tm, 0, sizeof(*tm));
1539 tm->tm_isdst = -1; /* don't know, and don't care about DST */
1541 strlcpy(buf, date_str, sizeof(buf));
1544 f[0] = mystrtok(&p, " \t");
1545 f[1] = mystrtok(&p, " \t");
1546 f[2] = mystrtok(&p, " \t");
1547 f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */
1548 if (!f[0] || !f[1] || !f[2]) return -1;
1551 * The time has a colon, where nothing else does.
1552 * So if we find it, bubble it to the back of the list.
1555 for (i = 0; i < 3; i++) {
1556 if (strchr(f[i], ':')) {
1566 * The month is text, which allows us to find it easily.
1569 for (i = 0; i < 3; i++) {
1570 if (isalpha( (int) *f[i])) {
1572 * Bubble the month to the front of the list
1578 for (i = 0; i < 12; i++) {
1579 if (strncasecmp(months[i], f[0], 3) == 0) {
1587 /* month not found? */
1588 if (tm->tm_mon == 12) return -1;
1591 * The year may be in f[1], or in f[2]
1593 tm->tm_year = atoi(f[1]);
1594 tm->tm_mday = atoi(f[2]);
1596 if (tm->tm_year >= 1900) {
1597 tm->tm_year -= 1900;
1601 * We can't use 2-digit years any more, they make it
1602 * impossible to tell what's the day, and what's the year.
1604 if (tm->tm_mday < 1900) return -1;
1607 * Swap the year and the day.
1610 tm->tm_year = tm->tm_mday - 1900;
1615 * If the day is out of range, die.
1617 if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {
1622 * There may be %H:%M:%S. Parse it in a hacky way.
1625 f[0] = f[3]; /* HH */
1626 f[1] = strchr(f[0], ':'); /* find : separator */
1627 if (!f[1]) return -1;
1629 *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
1631 f[2] = strchr(f[1], ':'); /* find : separator */
1633 *(f[2]++) = '\0'; /* nuke it, and point to SS */
1634 tm->tm_sec = atoi(f[2]);
1635 } /* else leave it as zero */
1637 tm->tm_hour = atoi(f[0]);
1638 tm->tm_min = atoi(f[1]);
1642 * Returns -1 on error.
1645 if (t == (time_t) -1) return -1;
1652 /** Compares two pointers
1654 * @param a first pointer to compare.
1655 * @param b second pointer to compare.
1656 * @return -1 if a < b, +1 if b > a, or 0 if both equal.
1658 int8_t fr_pointer_cmp(void const *a, void const *b)
1660 if (a < b) return -1;
1661 if (a == b) return 0;
1666 static int _quick_partition(void const *to_sort[], int min, int max, fr_cmp_t cmp) {
1667 void const *pivot = to_sort[min];
1673 do ++i; while((cmp(to_sort[i], pivot) <= 0) && i <= max);
1674 do --j; while(cmp(to_sort[j], pivot) > 0);
1679 to_sort[i] = to_sort[j];
1684 to_sort[min] = to_sort[j];
1690 /** Quick sort an array of pointers using a comparator
1692 * @param to_sort array of pointers to sort.
1693 * @param min_idx the lowest index (usually 0).
1694 * @param max_idx the highest index (usually length of array - 1).
1695 * @param cmp the comparison function to use to sort the array elements.
1697 void fr_quick_sort(void const *to_sort[], int min_idx, int max_idx, fr_cmp_t cmp)
1701 if (min_idx >= max_idx) return;
1703 part = _quick_partition(to_sort, min_idx, max_idx, cmp);
1704 fr_quick_sort(to_sort, min_idx, part - 1, cmp);
1705 fr_quick_sort(to_sort, part + 1, max_idx, cmp);
1709 void fr_talloc_verify_cb(UNUSED const void *ptr, UNUSED int depth,
1710 UNUSED int max_depth, UNUSED int is_ref,
1711 UNUSED void *private_data)