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