xref: /freebsd/contrib/ntp/ntpd/ntp_io.c (revision 9a14aa017b21c292740c00ee098195cd46642730)
1 /*
2  * ntp_io.c - input/output routines for ntpd.	The socket-opening code
3  *		   was shamelessly stolen from ntpd.
4  */
5 
6 #ifdef HAVE_CONFIG_H
7 # include <config.h>
8 #endif
9 
10 #include "ntp_machine.h"
11 #include "ntpd.h"
12 #include "ntp_io.h"
13 #include "iosignal.h"
14 #include "ntp_refclock.h"
15 #include "ntp_stdlib.h"
16 #include "ntp_request.h"
17 #include "ntp.h"
18 #include "ntp_unixtime.h"
19 
20 /* Don't include ISC's version of IPv6 variables and structures */
21 #define ISC_IPV6_H 1
22 #include <isc/interfaceiter.h>
23 #include <isc/list.h>
24 #include <isc/result.h>
25 
26 #ifdef SIM
27 #include "ntpsim.h"
28 #endif
29 
30 #include <stdio.h>
31 #include <signal.h>
32 #ifdef HAVE_SYS_PARAM_H
33 # include <sys/param.h>
34 #endif /* HAVE_SYS_PARAM_H */
35 #ifdef HAVE_SYS_IOCTL_H
36 # include <sys/ioctl.h>
37 #endif
38 #ifdef HAVE_SYS_SOCKIO_H	/* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
39 # include <sys/sockio.h>
40 #endif
41 #ifdef HAVE_SYS_UIO_H
42 # include <sys/uio.h>
43 #endif
44 
45 /*
46  * setsockopt does not always have the same arg declaration
47  * across all platforms. If it's not defined we make it empty
48  */
49 
50 #ifndef SETSOCKOPT_ARG_CAST
51 #define SETSOCKOPT_ARG_CAST
52 #endif
53 
54 /*
55  * Set up some macros to look for IPv6 and IPv6 multicast
56  */
57 
58 #if defined(ISC_PLATFORM_HAVEIPV6) && !defined(DISABLE_IPV6)
59 
60 #define INCLUDE_IPV6_SUPPORT
61 
62 #if defined(INCLUDE_IPV6_SUPPORT) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
63 #define INCLUDE_IPV6_MULTICAST_SUPPORT
64 
65 #endif	/* IPV6 Multicast Support */
66 #endif  /* IPv6 Support */
67 
68 #ifdef INCLUDE_IPV6_SUPPORT
69 #include <netinet/in.h>
70 #include <net/if_var.h>
71 #include <netinet/in_var.h>
72 #endif /* !INCLUDE_IPV6_SUPPORT */
73 
74 extern int listen_to_virtual_ips;
75 extern const char *specific_interface;
76 
77 #if defined(SO_TIMESTAMP) && defined(SCM_TIMESTAMP)
78 #if defined(CMSG_FIRSTHDR)
79 #define HAVE_TIMESTAMP
80 #define USE_TIMESTAMP_CMSG
81 #ifndef TIMESTAMP_CTLMSGBUF_SIZE
82 #define TIMESTAMP_CTLMSGBUF_SIZE 1536 /* moderate default */
83 #endif
84 #else
85 /* fill in for old/other timestamp interfaces */
86 #endif
87 #endif
88 
89 #if defined(SYS_WINNT)
90 #include <transmitbuff.h>
91 #include <isc/win32os.h>
92 /*
93  * Define this macro to control the behavior of connection
94  * resets on UDP sockets.  See Microsoft KnowledgeBase Article Q263823
95  * for details.
96  * NOTE: This requires that Windows 2000 systems install Service Pack 2
97  * or later.
98  */
99 #ifndef SIO_UDP_CONNRESET
100 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
101 #endif
102 
103 /*
104  * Windows C runtime ioctl() can't deal properly with sockets,
105  * map to ioctlsocket for this source file.
106  */
107 #define ioctl(fd, opt, val)  ioctlsocket((fd), (opt), (u_long *)(val))
108 #endif  /* SYS_WINNT */
109 
110 /*
111  * We do asynchronous input using the SIGIO facility.  A number of
112  * recvbuf buffers are preallocated for input.	In the signal
113  * handler we poll to see which sockets are ready and read the
114  * packets from them into the recvbuf's along with a time stamp and
115  * an indication of the source host and the interface it was received
116  * through.  This allows us to get as accurate receive time stamps
117  * as possible independent of other processing going on.
118  *
119  * We watch the number of recvbufs available to the signal handler
120  * and allocate more when this number drops below the low water
121  * mark.  If the signal handler should run out of buffers in the
122  * interim it will drop incoming frames, the idea being that it is
123  * better to drop a packet than to be inaccurate.
124  */
125 
126 
127 /*
128  * Other statistics of possible interest
129  */
130 volatile u_long packets_dropped;	/* total number of packets dropped on reception */
131 volatile u_long packets_ignored;	/* packets received on wild card interface */
132 volatile u_long packets_received;	/* total number of packets received */
133 u_long packets_sent;	/* total number of packets sent */
134 u_long packets_notsent; /* total number of packets which couldn't be sent */
135 
136 volatile u_long handler_calls;	/* number of calls to interrupt handler */
137 volatile u_long handler_pkts;	/* number of pkts received by handler */
138 u_long io_timereset;		/* time counters were reset */
139 
140 /*
141  * Interface stuff
142  */
143 struct interface *any_interface;	/* default ipv4 interface */
144 struct interface *any6_interface;	/* default ipv6 interface */
145 struct interface *loopback_interface;	/* loopback ipv4 interface */
146 
147 int ninterfaces;			/* Total number of interfaces */
148 
149 volatile int disable_dynamic_updates;   /* when set to != 0 dynamic updates won't happen */
150 
151 #ifdef REFCLOCK
152 /*
153  * Refclock stuff.	We keep a chain of structures with data concerning
154  * the guys we are doing I/O for.
155  */
156 static	struct refclockio *refio;
157 #endif /* REFCLOCK */
158 
159 
160 /*
161  * Define what the possible "soft" errors can be.  These are non-fatal returns
162  * of various network related functions, like recv() and so on.
163  *
164  * For some reason, BSDI (and perhaps others) will sometimes return <0
165  * from recv() but will have errno==0.  This is broken, but we have to
166  * work around it here.
167  */
168 #define SOFT_ERROR(e)	((e) == EAGAIN || \
169 			 (e) == EWOULDBLOCK || \
170 			 (e) == EINTR || \
171 			 (e) == 0)
172 
173 /*
174  * File descriptor masks etc. for call to select
175  * Not needed for I/O Completion Ports
176  */
177 fd_set activefds;
178 int maxactivefd;
179 /*
180  * bit alternating value to detect verified interfaces during an update cycle
181  */
182 static  u_char          sys_interphase = 0;
183 
184 static  struct interface *new_interface P((struct interface *));
185 static  void add_interface P((struct interface *));
186 static  int update_interfaces P((u_short, interface_receiver_t, void *));
187 static  void remove_interface P((struct interface *));
188 static  struct interface *create_interface P((u_short, struct interface *));
189 
190 static int	move_fd		P((SOCKET));
191 
192 /*
193  * Multicast functions
194  */
195 static	isc_boolean_t	addr_ismulticast	 P((struct sockaddr_storage *));
196 /*
197  * Not all platforms support multicast
198  */
199 #ifdef MCAST
200 static	isc_boolean_t	socket_multicast_enable	 P((struct interface *, int, struct sockaddr_storage *));
201 static	isc_boolean_t	socket_multicast_disable P((struct interface *, struct sockaddr_storage *));
202 #endif
203 
204 #ifdef DEBUG
205 static void print_interface	P((struct interface *, char *, char *));
206 #define DPRINT_INTERFACE(_LVL_, _ARGS_) do { if (debug >= (_LVL_)) { print_interface _ARGS_; } } while (0)
207 #else
208 #define DPRINT_INTERFACE(_LVL_, _ARGS_) do {} while (0)
209 #endif
210 
211 typedef struct vsock vsock_t;
212 enum desc_type { FD_TYPE_SOCKET, FD_TYPE_FILE };
213 
214 struct vsock {
215 	SOCKET				fd;
216 	enum desc_type                  type;
217 	ISC_LINK(vsock_t)		link;
218 };
219 
220 #if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
221 /*
222  * async notification processing (e. g. routing sockets)
223  */
224 /*
225  * support for receiving data on fd that is not a refclock or a socket
226  * like e. g. routing sockets
227  */
228 struct asyncio_reader {
229 	SOCKET fd;		                    /* fd to be read */
230 	void  *data;		                    /* possibly local data */
231 	void (*receiver)(struct asyncio_reader *);  /* input handler */
232 	ISC_LINK(struct asyncio_reader) link;       /* the list this is being kept in */
233 };
234 
235 ISC_LIST(struct asyncio_reader) asyncio_reader_list;
236 
237 static void delete_asyncio_reader P((struct asyncio_reader *));
238 static struct asyncio_reader *new_asyncio_reader P((void));
239 static void add_asyncio_reader P((struct asyncio_reader *, enum desc_type));
240 static void remove_asyncio_reader P((struct asyncio_reader *));
241 
242 #endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
243 
244 static void init_async_notifications P((void));
245 
246 static	int create_sockets	P((u_short));
247 static	SOCKET	open_socket	P((struct sockaddr_storage *, int, int, struct interface *));
248 static	char *	fdbits		P((int, fd_set *));
249 static	void	set_reuseaddr	P((int));
250 static	isc_boolean_t	socket_broadcast_enable	 P((struct interface *, SOCKET, struct sockaddr_storage *));
251 static	isc_boolean_t	socket_broadcast_disable P((struct interface *, struct sockaddr_storage *));
252 
253 ISC_LIST(vsock_t)	fd_list;
254 
255 typedef struct remaddr remaddr_t;
256 
257 struct remaddr {
258       struct sockaddr_storage	 addr;
259       struct interface               *interface;
260       ISC_LINK(remaddr_t)	 link;
261 };
262 
263 ISC_LIST(remaddr_t)       remoteaddr_list;
264 
265 ISC_LIST(struct interface)     inter_list;
266 
267 static struct interface *wildipv4 = NULL;
268 static struct interface *wildipv6 = NULL;
269 
270 static void	add_fd_to_list	P((SOCKET, enum desc_type));
271 static void	close_and_delete_fd_from_list	P((SOCKET));
272 static void	add_addr_to_list	P((struct sockaddr_storage *, struct interface *));
273 static void	delete_addr_from_list	P((struct sockaddr_storage *));
274 static struct interface *find_addr_in_list	P((struct sockaddr_storage *));
275 static struct interface *find_flagged_addr_in_list P((struct sockaddr_storage *, int));
276 static void	create_wildcards	P((u_short));
277 static isc_boolean_t	address_okay	P((struct interface *));
278 static void		convert_isc_if		P((isc_interface_t *, struct interface *, u_short));
279 static void	delete_interface_from_list	P((struct interface *));
280 static struct interface *getinterface	P((struct sockaddr_storage *, int));
281 static struct interface *findlocalinterface	P((struct sockaddr_storage *, int));
282 static struct interface *findlocalcastinterface	P((struct sockaddr_storage *, int));
283 
284 /*
285  * Routines to read the ntp packets
286  */
287 #if !defined(HAVE_IO_COMPLETION_PORT)
288 static inline int     read_network_packet	P((SOCKET, struct interface *, l_fp));
289 static inline int     read_refclock_packet	P((SOCKET, struct refclockio *, l_fp));
290 #endif
291 
292 #ifdef SYS_WINNT
293 /*
294  * Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom
295  * to not work correctly, returning a WSACONNRESET error when a WSASendTo
296  * fails with an "ICMP port unreachable" response and preventing the
297  * socket from using the WSARecvFrom in subsequent operations.
298  * The function below fixes this, but requires that Windows 2000
299  * Service Pack 2 or later be installed on the system.  NT 4.0
300  * systems are not affected by this and work correctly.
301  * See Microsoft Knowledge Base Article Q263823 for details of this.
302  */
303 void
304 connection_reset_fix(
305 	SOCKET fd,
306 	struct sockaddr_storage *addr
307 	)
308 {
309 	DWORD dwBytesReturned = 0;
310 	BOOL  bNewBehavior = FALSE;
311 	DWORD status;
312 
313 	/*
314 	 * disable bad behavior using IOCTL: SIO_UDP_CONNRESET
315 	 * NT 4.0 has no problem
316 	 */
317 	if (isc_win32os_majorversion() >= 5) {
318 		status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,
319 				  sizeof(bNewBehavior), NULL, 0,
320 				  &dwBytesReturned, NULL, NULL);
321 		if (SOCKET_ERROR == status)
322 			netsyslog(LOG_ERR, "connection_reset_fix() "
323 					   "failed for address %s: %m",
324 					   stoa(addr));
325 	}
326 }
327 #endif
328 
329 /*
330  * on Unix systems the stdio library typically
331  * makes use of file descriptors in the lower
332  * integer range. stdio usually will make use
333  * of the file descriptor in the range of
334  * [0..FOPEN_MAX)
335  * in order to keep this range clean for socket
336  * file descriptors we attempt to move them above
337  * FOPEM_MAX. This is not as easy as it sounds as
338  * FOPEN_MAX changes from implementation to implementation
339  * and may exceed to current file decriptor limits.
340  * We are using following strategy:
341  * - keep a current socket fd boundary initialized with
342  *   max(0, min(getdtablesize() - FD_CHUNK, FOPEN_MAX))
343  * - attempt to move the descriptor to the boundary or
344  *   above.
345  *   - if that fails and boundary > 0 set boundary
346  *     to min(0, socket_fd_boundary - FD_CHUNK)
347  *     -> retry
348  *     if failure and boundary == 0 return old fd
349  *   - on success close old fd return new fd
350  *
351  * effects:
352  *   - fds will be moved above the socket fd boundary
353  *     if at all possible.
354  *   - the socket boundary will be reduced until
355  *     allocation is possible or 0 is reached - at this
356  *     point the algrithm will be disabled
357  */
358 static int move_fd(SOCKET fd)
359 {
360 #if !defined(SYS_WINNT) && defined(F_DUPFD)
361 #ifndef FD_CHUNK
362 #define FD_CHUNK	10
363 #endif
364 /*
365  * number of fds we would like to have for
366  * stdio FILE* available.
367  * we can pick a "low" number as our use of
368  * FILE* is limited to log files and temporarily
369  * to data and config files. Except for log files
370  * we don't keep the other FILE* open beyond the
371  * scope of the function that opened it.
372  */
373 #ifndef FD_PREFERRED_SOCKBOUNDARY
374 #define FD_PREFERRED_SOCKBOUNDARY 48
375 #endif
376 
377 #ifndef HAVE_GETDTABLESIZE
378 /*
379  * if we have no idea about the max fd value set up things
380  * so we will start at FOPEN_MAX
381  */
382 #define getdtablesize() (FOPEN_MAX+FD_CHUNK)
383 #endif
384 
385 #ifndef FOPEN_MAX
386 #define FOPEN_MAX	20	/* assume that for the lack of anything better */
387 #endif
388 	static SOCKET socket_boundary = -1;
389 	SOCKET newfd;
390 
391 	/*
392 	 * check whether boundary has be set up
393 	 * already
394 	 */
395 	if (socket_boundary == -1) {
396 		socket_boundary = max(0, min(getdtablesize() - FD_CHUNK,
397 					     min(FOPEN_MAX, FD_PREFERRED_SOCKBOUNDARY)));
398 #ifdef DEBUG
399 		msyslog(LOG_DEBUG, "ntp_io: estimated max descriptors: %d, initial socket boundary: %d",
400 			getdtablesize(), socket_boundary);
401 #endif
402 	}
403 
404 	/*
405 	 * Leave a space for stdio to work in. potentially moving the
406 	 * socket_boundary lower until allocation succeeds.
407 	 */
408 	do {
409 		if (fd >= 0 && fd < socket_boundary) {
410 			/* inside reserved range: attempt to move fd */
411 			newfd = fcntl(fd, F_DUPFD, socket_boundary);
412 
413 			if (newfd != -1) {
414 				/* success: drop the old one - return the new one */
415 				(void)close(fd);
416 				return (newfd);
417 			}
418 		} else {
419 			/* outside reserved range: no work - return the original one */
420 			return (fd);
421 		}
422 		socket_boundary = max(0, socket_boundary - FD_CHUNK);
423 #ifdef DEBUG
424 		msyslog(LOG_DEBUG, "ntp_io: selecting new socket boundary: %d",
425 			socket_boundary);
426 #endif
427 	} while (socket_boundary > 0);
428 #endif /* !defined(SYS_WINNT) && defined(F_DUPFD) */
429 	return (fd);
430 }
431 
432 #ifdef DEBUG_TIMING
433 /*
434  * collect timing information for various processing
435  * paths. currently we only pass then on to the file
436  * for later processing. this could also do histogram
437  * based analysis in other to reduce the load (and skew)
438  * dur to the file output
439  */
440 void
441 collect_timing(struct recvbuf *rb, const char *tag, int count, l_fp *dts)
442 {
443 	char buf[2048];
444 
445 	snprintf(buf, sizeof(buf), "%s %d %s %s",
446 		 (rb != NULL) ?
447 		 ((rb->dstadr) ? stoa(&rb->recv_srcadr) : "-REFCLOCK-") : "-",
448 		 count, lfptoa(dts, 9), tag);
449 	record_timing_stats(buf);
450 }
451 #endif
452 
453 /*
454  * About dynamic interfaces, sockets, reception and more...
455  *
456  * the code solves following tasks:
457  *
458  *   - keep a current list of active interfaces in order
459  *     to bind to to the interface address on NTP_PORT so that
460  *     all wild and specific bindings for NTP_PORT are taken by ntpd
461  *     to avoid other daemons messing with the time or sockets.
462  *   - all interfaces keep a list of peers that are referencing
463  *     the interface in order to quickly re-assign the peers to
464  *     new interface in case an interface is deleted (=> gone from system or
465  *     down)
466  *   - have a preconfigured socket ready with the right local address
467  *     for transmission and reception
468  *   - have an address list for all destination addresses used within ntpd
469  *     to find the "right" preconfigured socket.
470  *   - facilitate updating the internal interface list with respect to
471  *     the current kernel state
472  *
473  * special issues:
474  *
475  *   - mapping of multicast addresses to the interface affected is not always
476  *     one to one - especially on hosts with multiple interfaces
477  *     the code here currently allocates a separate interface entry for those
478  *     multicast addresses
479  *     iff it is able to bind to a *new* socket with the multicast address (flags |= MCASTIF)
480  *     in case of failure the multicast address is bound to an existing interface.
481  *   - on some systems it is perfectly legal to assign the same address to
482  *     multiple interfaces. Therefore this code does not keep a list of interfaces
483  *     but a list of interfaces that represent a unique address as determined by the kernel
484  *     by the procedure in findlocalinterface. Thus it is perfectly legal to see only
485  *     one representative of a group of real interfaces if they share the same address.
486  *
487  * Frank Kardel 20050910
488  */
489 
490 /*
491  * init_io - initialize I/O data structures and call socket creation routine
492  */
493 void
494 init_io(void)
495 {
496 #ifdef SYS_WINNT
497 	init_io_completion_port();
498 
499 	if (!Win32InitSockets())
500 	{
501 		netsyslog(LOG_ERR, "No useable winsock.dll: %m");
502 		exit(1);
503 	}
504 	init_transmitbuff();
505 #endif /* SYS_WINNT */
506 
507 	/*
508 	 * Init buffer free list and stat counters
509 	 */
510 	init_recvbuff(RECV_INIT);
511 
512 	packets_dropped = packets_received = 0;
513 	packets_ignored = 0;
514 	packets_sent = packets_notsent = 0;
515 	handler_calls = handler_pkts = 0;
516 	io_timereset = 0;
517 	loopback_interface = NULL;
518 	any_interface = NULL;
519 	any6_interface = NULL;
520 
521 #ifdef REFCLOCK
522 	refio = NULL;
523 #endif
524 
525 #if defined(HAVE_SIGNALED_IO)
526 	(void) set_signal();
527 #endif
528 
529 	ISC_LIST_INIT(fd_list);
530 
531 #if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
532 	ISC_LIST_INIT(asyncio_reader_list);
533 #endif
534 
535         ISC_LIST_INIT(remoteaddr_list);
536 
537 	ISC_LIST_INIT(inter_list);
538 
539 	/*
540 	 * Create the sockets
541 	 */
542 	BLOCKIO();
543 	(void) create_sockets(htons(NTP_PORT));
544 	UNBLOCKIO();
545 
546 	init_async_notifications();
547 
548 	DPRINTF(3, ("init_io: maxactivefd %d\n", maxactivefd));
549 }
550 
551 #ifdef DEBUG
552 /*
553  * function to dump the contents of the interface structure
554  * for debugging use only.
555  */
556 void
557 interface_dump(struct interface *itf)
558 {
559 	u_char* cp;
560 	int i;
561 	/* Limit the size of the sockaddr_storage hex dump */
562 	int maxsize = min(32, sizeof(struct sockaddr_storage));
563 
564 	printf("Dumping interface: %p\n", itf);
565 	printf("fd = %d\n", itf->fd);
566 	printf("bfd = %d\n", itf->bfd);
567 	printf("sin = %s,\n", stoa(&(itf->sin)));
568 	cp = (u_char*) &(itf->sin);
569 	for(i = 0; i < maxsize; i++)
570 	{
571 		printf("%02x", *cp++);
572 		if((i+1)%4 == 0)
573 			printf(" ");
574 	}
575 	printf("\n");
576 	printf("bcast = %s,\n", stoa(&(itf->bcast)));
577 	cp = (u_char*) &(itf->bcast);
578 	for(i = 0; i < maxsize; i++)
579 	{
580 		printf("%02x", *cp++);
581 		if((i+1)%4 == 0)
582 			printf(" ");
583 	}
584 	printf("\n");
585 	printf("mask = %s,\n", stoa(&(itf->mask)));
586 	cp = (u_char*) &(itf->mask);
587 	for(i = 0; i < maxsize; i++)
588 	{
589 		printf("%02x", *cp++);
590 		if((i+1)%4 == 0)
591 			printf(" ");
592 	}
593 	printf("\n");
594 	printf("name = %s\n", itf->name);
595 	printf("flags = 0x%08x\n", itf->flags);
596 	printf("last_ttl = %d\n", itf->last_ttl);
597 	printf("addr_refid = %08x\n", itf->addr_refid);
598 	printf("num_mcast = %d\n", itf->num_mcast);
599 	printf("received = %ld\n", itf->received);
600 	printf("sent = %ld\n", itf->sent);
601 	printf("notsent = %ld\n", itf->notsent);
602 	printf("ifindex = %u\n", itf->ifindex);
603 	printf("scopeid = %u\n", itf->scopeid);
604 	printf("peercnt = %u\n", itf->peercnt);
605 	printf("phase = %u\n", itf->phase);
606 }
607 
608 /*
609  * print_interface - helper to output debug information
610  */
611 static void
612 print_interface(struct interface *iface, char *pfx, char *sfx)
613 {
614 	printf("%sinterface #%d: fd=%d, bfd=%d, name=%s, flags=0x%x, scope=%d, ifindex=%d",
615 	       pfx,
616 	       iface->ifnum,
617 	       iface->fd,
618 	       iface->bfd,
619 	       iface->name,
620 	       iface->flags,
621 	       iface->scopeid,
622 	       iface->ifindex);
623 	/* Leave these as three printf calls. */
624 	printf(", sin=%s",
625 	       stoa((&iface->sin)));
626 	if (iface->flags & INT_BROADCAST)
627 		printf(", bcast=%s,",
628 		       stoa((&iface->bcast)));
629 	if (iface->family == AF_INET)
630 	  printf(", mask=%s",
631 		 stoa((&iface->mask)));
632 	printf(", %s:%s", iface->ignore_packets == ISC_FALSE ? "Enabled" : "Disabled", sfx);
633 	if (debug > 4)	/* in-depth debugging only */
634 		interface_dump(iface);
635 }
636 
637 #endif
638 
639 #if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
640 /*
641  * create an asyncio_reader structure
642  */
643 static struct asyncio_reader *
644 new_asyncio_reader()
645 {
646 	struct asyncio_reader *reader;
647 
648 	reader = (struct asyncio_reader *)emalloc(sizeof(struct asyncio_reader));
649 
650 	memset((char *)reader, 0, sizeof(*reader));
651 	ISC_LINK_INIT(reader, link);
652 	reader->fd = INVALID_SOCKET;
653 	return reader;
654 }
655 
656 /*
657  * delete a reader
658  */
659 static void
660 delete_asyncio_reader(struct asyncio_reader *reader)
661 {
662 	free(reader);
663 }
664 
665 /*
666  * add asynchio_reader
667  */
668 static void
669 add_asyncio_reader(struct asyncio_reader *reader, enum desc_type type)
670 {
671 	ISC_LIST_APPEND(asyncio_reader_list, reader, link);
672 	add_fd_to_list(reader->fd, type);
673 }
674 
675 /*
676  * remove asynchio_reader
677  */
678 static void
679 remove_asyncio_reader(struct asyncio_reader *reader)
680 {
681 	ISC_LIST_UNLINK_TYPE(asyncio_reader_list, reader, link, struct asyncio_reader);
682 
683 	if (reader->fd != INVALID_SOCKET)
684 		close_and_delete_fd_from_list(reader->fd);
685 
686 	reader->fd = INVALID_SOCKET;
687 }
688 #endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
689 
690 /*
691  * interface list enumerator - visitor pattern
692  */
693 void
694 interface_enumerate(interface_receiver_t receiver, void *data)
695 {
696 	interface_info_t ifi;
697         struct interface *interf;
698 
699 	ifi.action = IFS_EXISTS;
700 
701 	for (interf = ISC_LIST_HEAD(inter_list);
702 	     interf != NULL;
703 	     interf = ISC_LIST_NEXT(interf, link)) {
704 		ifi.interface = interf;
705 		receiver(data, &ifi);
706 	}
707 }
708 
709 /*
710  * do standard initialization of interface structure
711  */
712 static void
713 init_interface(struct interface *interface)
714 {
715 	memset((char *)interface, 0, sizeof(struct interface));
716 	ISC_LINK_INIT(interface, link);
717 	ISC_LIST_INIT(interface->peers);
718 	interface->fd = INVALID_SOCKET;
719 	interface->bfd = INVALID_SOCKET;
720 	interface->num_mcast = 0;
721 	interface->received = 0;
722 	interface->sent = 0;
723 	interface->notsent = 0;
724 	interface->peercnt = 0;
725 	interface->phase = sys_interphase;
726 }
727 
728 /*
729  * create new interface structure initialize from
730  * template structure or via standard initialization
731  * function
732  */
733 static struct interface *
734 new_interface(struct interface *interface)
735 {
736 	static u_int sys_ifnum = 0;
737 
738 	struct interface *iface = (struct interface *)emalloc(sizeof(struct interface));
739 
740 	if (interface != NULL)
741 	{
742 		memcpy((char*)iface, (char*)interface, sizeof(*interface));
743 	}
744 	else
745 	{
746 		init_interface(iface);
747 	}
748 
749 	iface->ifnum = sys_ifnum++;  /* count every new instance of an interface in the system */
750 	iface->starttime = current_time;
751 
752 	return iface;
753 }
754 
755 /*
756  * return interface storage into free memory pool
757  */
758 static void
759 delete_interface(struct interface *interface)
760 {
761 	free(interface);
762 }
763 
764 /*
765  * link interface into list of known interfaces
766  */
767 static void
768 add_interface(struct interface *interface)
769 {
770 	static struct interface *listhead = NULL;
771 
772 	/*
773 	 * For ntpd, the first few interfaces (wildcard, localhost)
774 	 * will never be removed.  This means inter_list.head is
775 	 * unchanging once initialized.  Take advantage of that to
776 	 * watch for changes and catch corruption earlier.  This
777 	 * helped track down corruption caused by using FD_SET with
778 	 * a descriptor numerically larger than FD_SETSIZE.
779 	 */
780 	if (NULL == listhead)
781 		listhead = inter_list.head;
782 
783 	if (listhead != inter_list.head) {
784 		msyslog(LOG_ERR, "add_interface inter_list.head corrupted: was %p now %p",
785 			listhead, inter_list.head);
786 		exit(1);
787 	}
788 	/*
789 	 * Calculate the address hash
790 	 */
791 	interface->addr_refid = addr2refid(&interface->sin);
792 
793 	ISC_LIST_APPEND(inter_list, interface, link);
794 	ninterfaces++;
795 }
796 
797 /*
798  * remove interface from known interface list and clean up
799  * associated resources
800  */
801 static void
802 remove_interface(struct interface *interface)
803 {
804 	struct sockaddr_storage resmask;
805 
806 	ISC_LIST_UNLINK_TYPE(inter_list, interface, link, struct interface);
807 
808 	delete_interface_from_list(interface);
809 
810 	if (interface->fd != INVALID_SOCKET)
811 	{
812 		msyslog(LOG_INFO, "Deleting interface #%d %s, %s#%d, interface stats: received=%ld, sent=%ld, dropped=%ld, active_time=%ld secs",
813 			interface->ifnum,
814 			interface->name,
815 			stoa((&interface->sin)),
816 			NTP_PORT,  /* XXX should extract port from sin structure */
817 			interface->received,
818 			interface->sent,
819 			interface->notsent,
820 			current_time - interface->starttime);
821 
822 		close_and_delete_fd_from_list(interface->fd);
823 	}
824 
825 	if (interface->bfd != INVALID_SOCKET)
826 	{
827 		msyslog(LOG_INFO, "Deleting interface #%d %s, broadcast address %s#%d",
828 			interface->ifnum,
829 			interface->name,
830 			stoa((&interface->bcast)),
831 			(u_short) NTP_PORT);  /* XXX extract port from sin structure */
832 		close_and_delete_fd_from_list(interface->bfd);
833 	}
834 
835 	ninterfaces--;
836 	ntp_monclearinterface(interface);
837 
838 	/* remove restrict interface entry */
839 
840 	/*
841 	 * Blacklist bound interface address
842 	 */
843 	SET_HOSTMASK(&resmask, interface->sin.ss_family);
844 	hack_restrict(RESTRICT_REMOVEIF, &interface->sin, &resmask,
845 		      RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
846 }
847 
848 static void
849 list_if_listening(struct interface *interface, u_short port)
850 {
851 	msyslog(LOG_INFO, "Listening on interface #%d %s, %s#%d %s",
852 		interface->ifnum,
853 		interface->name,
854 		stoa((&interface->sin)),
855 		ntohs( (u_short) port),
856 		(interface->ignore_packets == ISC_FALSE) ?
857 		"Enabled": "Disabled");
858 }
859 
860 static void
861 create_wildcards(u_short port) {
862 	isc_boolean_t okipv4 = ISC_TRUE;
863 	/*
864 	 * create pseudo-interface with wildcard IPv4 address
865 	 */
866 #ifdef IPV6_V6ONLY
867 	if(isc_net_probeipv4() != ISC_R_SUCCESS)
868 		okipv4 = ISC_FALSE;
869 #endif
870 
871 	if(okipv4 == ISC_TRUE) {
872 	        struct interface *interface = new_interface(NULL);
873 
874 		interface->family = AF_INET;
875 		interface->sin.ss_family = AF_INET;
876 		((struct sockaddr_in*)&interface->sin)->sin_addr.s_addr = htonl(INADDR_ANY);
877 		((struct sockaddr_in*)&interface->sin)->sin_port = port;
878 		(void) strncpy(interface->name, "wildcard", sizeof(interface->name));
879 		interface->mask.ss_family = AF_INET;
880 		((struct sockaddr_in*)&interface->mask)->sin_addr.s_addr = htonl(~(u_int32)0);
881 		interface->flags = INT_BROADCAST | INT_UP | INT_WILDCARD;
882 		interface->ignore_packets = ISC_TRUE;
883 #if defined(MCAST)
884 		/*
885 		 * enable possible multicast reception on the broadcast socket
886 		 */
887 		interface->bcast.ss_family = AF_INET;
888 		((struct sockaddr_in*)&interface->bcast)->sin_port = port;
889 		((struct sockaddr_in*)&interface->bcast)->sin_addr.s_addr = htonl(INADDR_ANY);
890 #endif /* MCAST */
891 		interface->fd = open_socket(&interface->sin,
892 				 interface->flags, 1, interface);
893 
894 		if (interface->fd != INVALID_SOCKET) {
895 			wildipv4 = interface;
896 			any_interface = interface;
897 
898 			add_addr_to_list(&interface->sin, interface);
899 			add_interface(interface);
900 			list_if_listening(interface, port);
901 		} else {
902 			msyslog(LOG_ERR, "unable to bind to wildcard socket address %s - another process may be running - EXITING",
903 				stoa((&interface->sin)));
904 			exit(1);
905 		}
906 	}
907 
908 #ifdef INCLUDE_IPV6_SUPPORT
909 	/*
910 	 * create pseudo-interface with wildcard IPv6 address
911 	 */
912 	if (isc_net_probeipv6() == ISC_R_SUCCESS) {
913 	        struct interface *interface = new_interface(NULL);
914 
915 		interface->family = AF_INET6;
916 		interface->sin.ss_family = AF_INET6;
917 		((struct sockaddr_in6*)&interface->sin)->sin6_addr = in6addr_any;
918  		((struct sockaddr_in6*)&interface->sin)->sin6_port = port;
919 # ifdef ISC_PLATFORM_HAVESCOPEID
920  		((struct sockaddr_in6*)&interface->sin)->sin6_scope_id = 0;
921 # endif
922 		(void) strncpy(interface->name, "wildcard", sizeof(interface->name));
923 		interface->mask.ss_family = AF_INET6;
924 		memset(&((struct sockaddr_in6*)&interface->mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));
925 		interface->flags = INT_UP | INT_WILDCARD;
926 		interface->ignore_packets = ISC_TRUE;
927 
928 		interface->fd = open_socket(&interface->sin,
929 				 interface->flags, 1, interface);
930 
931 		if (interface->fd != INVALID_SOCKET) {
932 			wildipv6 = interface;
933 			any6_interface = interface;
934 			add_addr_to_list(&interface->sin, interface);
935 			add_interface(interface);
936 			list_if_listening(interface, port);
937 		} else {
938 			msyslog(LOG_ERR, "unable to bind to wildcard socket address %s - another process may be running - EXITING",
939 				stoa((&interface->sin)));
940 			exit(1);
941 		}
942 	}
943 #endif
944 }
945 
946 
947 static isc_boolean_t
948 address_okay(struct interface *iface) {
949 
950 	DPRINTF(4, ("address_okay: listen Virtual: %d, IF name: %s\n",
951 		    listen_to_virtual_ips, iface->name));
952 
953 	/*
954 	 * Always allow the loopback
955 	 */
956 	if((iface->flags & INT_LOOPBACK) != 0) {
957 		DPRINTF(4, ("address_okay: loopback - OK\n"));
958 		return (ISC_TRUE);
959 	}
960 
961 	/*
962 	 * Check if the interface is specified
963 	 */
964 	if (specific_interface != NULL) {
965 		if (strcasecmp(iface->name, specific_interface) == 0) {
966 			DPRINTF(4, ("address_okay: specific interface name matched - OK\n"));
967 			return (ISC_TRUE);
968 		} else {
969 			DPRINTF(4, ("address_okay: specific interface name NOT matched - FAIL\n"));
970 			return (ISC_FALSE);
971 		}
972 	}
973 	else {
974 		if (listen_to_virtual_ips == 0  &&
975 		    (strchr(iface->name, (int)':') != NULL)) {
976 			DPRINTF(4, ("address_okay: virtual ip/alias - FAIL\n"));
977 			return (ISC_FALSE);
978 		}
979 	}
980 
981 	DPRINTF(4, ("address_okay: OK\n"));
982 	return (ISC_TRUE);
983 }
984 
985 static void
986 convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port)
987 {
988 	itf->scopeid = 0;
989 	itf->family = (short) isc_if->af;
990 	strcpy(itf->name, isc_if->name);
991 
992 	if(isc_if->af == AF_INET) {
993 		itf->sin.ss_family = (u_short) isc_if->af;
994 		memcpy(&(((struct sockaddr_in*)&itf->sin)->sin_addr),
995 		       &(isc_if->address.type.in),
996 		       sizeof(struct in_addr));
997 		((struct sockaddr_in*)&itf->sin)->sin_port = port;
998 
999 		if((isc_if->flags & INTERFACE_F_BROADCAST) != 0) {
1000 			itf->flags |= INT_BROADCAST;
1001 			itf->bcast.ss_family = itf->sin.ss_family;
1002 			memcpy(&(((struct sockaddr_in*)&itf->bcast)->sin_addr),
1003 			       &(isc_if->broadcast.type.in),
1004 				 sizeof(struct in_addr));
1005 			((struct sockaddr_in*)&itf->bcast)->sin_port = port;
1006 		}
1007 
1008 		itf->mask.ss_family = itf->sin.ss_family;
1009 		memcpy(&(((struct sockaddr_in*)&itf->mask)->sin_addr),
1010 		       &(isc_if->netmask.type.in),
1011 		       sizeof(struct in_addr));
1012 		((struct sockaddr_in*)&itf->mask)->sin_port = port;
1013 	}
1014 #ifdef INCLUDE_IPV6_SUPPORT
1015 	else if (isc_if->af == AF_INET6) {
1016 		itf->sin.ss_family = (u_short) isc_if->af;
1017 		memcpy(&(((struct sockaddr_in6 *)&itf->sin)->sin6_addr),
1018 		       &(isc_if->address.type.in6),
1019 		       sizeof(((struct sockaddr_in6 *)&itf->sin)->sin6_addr));
1020 		((struct sockaddr_in6 *)&itf->sin)->sin6_port = port;
1021 
1022 #ifdef ISC_PLATFORM_HAVESCOPEID
1023 		((struct sockaddr_in6 *)&itf->sin)->sin6_scope_id = isc_netaddr_getzone(&isc_if->address);
1024 		itf->scopeid = isc_netaddr_getzone(&isc_if->address);
1025 #endif
1026 		itf->mask.ss_family = itf->sin.ss_family;
1027 		memcpy(&(((struct sockaddr_in6 *)&itf->mask)->sin6_addr),
1028 		       &(isc_if->netmask.type.in6),
1029 		       sizeof(struct in6_addr));
1030 		((struct sockaddr_in6 *)&itf->mask)->sin6_port = port;
1031 		/* Copy the interface index */
1032 		itf->ifindex = isc_if->ifindex;
1033 	}
1034 #endif /* INCLUDE_IPV6_SUPPORT */
1035 
1036 
1037 	/* Process the rest of the flags */
1038 
1039 	if((isc_if->flags & INTERFACE_F_UP) != 0)
1040 		itf->flags |= INT_UP;
1041 	if((isc_if->flags & INTERFACE_F_LOOPBACK) != 0)
1042 		itf->flags |= INT_LOOPBACK;
1043 	if((isc_if->flags & INTERFACE_F_POINTTOPOINT) != 0)
1044 		itf->flags |= INT_PPP;
1045 	if((isc_if->flags & INTERFACE_F_MULTICAST) != 0)
1046 		itf->flags |= INT_MULTICAST;
1047 
1048 }
1049 
1050 /*
1051  * refresh_interface
1052  *
1053  * some OSes have been observed to keep
1054  * cached routes even when more specific routes
1055  * become available.
1056  * this can be mitigated by re-binding
1057  * the socket.
1058  */
1059 static int
1060 refresh_interface(struct interface * interface)
1061 {
1062 #ifdef  OS_MISSES_SPECIFIC_ROUTE_UPDATES
1063 	if (interface->fd != INVALID_SOCKET)
1064 	{
1065 		close_and_delete_fd_from_list(interface->fd);
1066 		interface->fd = open_socket(&interface->sin,
1067 					    interface->flags, 0, interface);
1068 		 /*
1069 		  * reset TTL indication so TTL is is set again
1070 		  * next time around
1071 		  */
1072 		interface->last_ttl = 0;
1073 		return interface->fd != INVALID_SOCKET;
1074 	}
1075 	else
1076 	{
1077 		return 0;	/* invalid sockets are not refreshable */
1078 	}
1079 #else /* !OS_MISSES_SPECIFIC_ROUTE_UPDATES */
1080 	return interface->fd != INVALID_SOCKET;
1081 #endif /* !OS_MISSES_SPECIFIC_ROUTE_UPDATES */
1082 }
1083 
1084 /*
1085  * interface_update - externally callable update function
1086  */
1087 void
1088 interface_update(interface_receiver_t receiver, void *data)
1089 {
1090 	if (!disable_dynamic_updates) {
1091 		int new_interface_found;
1092 
1093 		BLOCKIO();
1094 		new_interface_found = update_interfaces(htons(NTP_PORT), receiver, data);
1095 		UNBLOCKIO();
1096 
1097 		if (new_interface_found) {
1098 #ifdef DEBUG
1099 			msyslog(LOG_DEBUG, "new interface(s) found: waking up resolver");
1100 #endif
1101 #ifdef SYS_WINNT
1102 			/* wake up the resolver thread */
1103 			if (ResolverEventHandle != NULL)
1104 				SetEvent(ResolverEventHandle);
1105 #else
1106 			/* write any single byte to the pipe to wake up the resolver process */
1107 			write( resolver_pipe_fd[1], &new_interface_found, 1 );
1108 #endif
1109 		}
1110 	}
1111 }
1112 
1113 /*
1114  * find out if a given interface structure contains
1115  * a wildcard address
1116  */
1117 static int
1118 is_wildcard_addr(struct sockaddr_storage *sas)
1119 {
1120 	if (sas->ss_family == AF_INET &&
1121 	    ((struct sockaddr_in*)sas)->sin_addr.s_addr == htonl(INADDR_ANY))
1122 		return 1;
1123 
1124 #ifdef INCLUDE_IPV6_SUPPORT
1125 	if (sas->ss_family == AF_INET6 &&
1126 	    memcmp(&((struct sockaddr_in6*)sas)->sin6_addr, &in6addr_any,
1127 		   sizeof(in6addr_any) == 0))
1128 		return 1;
1129 #endif
1130 
1131 	return 0;
1132 }
1133 
1134 #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
1135 /*
1136  * enable/disable re-use of wildcard address socket
1137  */
1138 static void
1139 set_wildcard_reuse(int family, int on)
1140 {
1141 	int onvalue = 1;
1142 	int offvalue = 0;
1143 	int *onoff;
1144 	SOCKET fd = INVALID_SOCKET;
1145 
1146 	onoff = on ? &onvalue : &offvalue;
1147 
1148 	switch (family) {
1149 	case AF_INET:
1150 		if (any_interface) {
1151 			fd = any_interface->fd;
1152 		}
1153 		break;
1154 
1155 #ifdef INCLUDE_IPV6_SUPPORT
1156 	case AF_INET6:
1157 		if (any6_interface) {
1158 			fd = any6_interface->fd;
1159 		}
1160 		break;
1161 #endif /* !INCLUDE_IPV6_SUPPORT */
1162 	}
1163 
1164 	if (fd != INVALID_SOCKET) {
1165 		if (setsockopt(fd, SOL_SOCKET,
1166 			       SO_REUSEADDR, (char *)onoff,
1167 			       sizeof(*onoff))) {
1168 			netsyslog(LOG_ERR, "set_wildcard_reuse: setsockopt(SO_REUSEADDR, %s) failed: %m", *onoff ? "on" : "off");
1169 		}
1170 		DPRINTF(4, ("set SO_REUSEADDR to %s on %s\n", *onoff ? "ON" : "OFF",
1171 			    stoa((family == AF_INET) ?
1172 				  &any_interface->sin : &any6_interface->sin)));
1173 	}
1174 }
1175 #endif /* OS_NEEDS_REUSEADDR_FOR_IFADDRBIND */
1176 
1177 #ifdef INCLUDE_IPV6_SUPPORT
1178 static isc_boolean_t
1179 is_anycast(struct sockaddr *sa, char *name)
1180 {
1181 #if defined(SIOCGIFAFLAG_IN6) && defined(IN6_IFF_ANYCAST)
1182 	struct in6_ifreq ifr6;
1183 	int fd;
1184 	u_int32_t flags6;
1185 
1186 	if (sa->sa_family != AF_INET6)
1187 		return ISC_FALSE;
1188 	if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
1189 		return ISC_FALSE;
1190 	memset(&ifr6, 0, sizeof(ifr6));
1191 	memcpy(&ifr6.ifr_addr, (struct sockaddr_in6 *)sa,
1192 	    sizeof(struct sockaddr_in6));
1193 	strlcpy(ifr6.ifr_name, name, IF_NAMESIZE);
1194 	if (ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
1195 		close(fd);
1196 		return ISC_FALSE;
1197 	}
1198 	close(fd);
1199 	flags6 = ifr6.ifr_ifru.ifru_flags6;
1200 	if ((flags6 & IN6_IFF_ANYCAST) != 0)
1201 		return ISC_TRUE;
1202 #endif /* !SIOCGIFAFLAG_IN6 || !IN6_IFF_ANYCAST */
1203 	return ISC_FALSE;
1204 }
1205 #endif /* !INCLUDE_IPV6_SUPPORT */
1206 
1207 /*
1208  * update_interface strategy
1209  *
1210  * toggle configuration phase
1211  *
1212  * Phase 1:
1213  * forall currently existing interfaces
1214  *   if address is known:
1215  *       drop socket - rebind again
1216  *
1217  *   if address is NOT known:
1218  *     attempt to create a new interface entry
1219  *
1220  * Phase 2:
1221  * forall currently known non MCAST and WILDCARD interfaces
1222  *   if interface does not match configuration phase (not seen in phase 1):
1223  *     remove interface from known interface list
1224  *     forall peers associated with this interface
1225  *       disconnect peer from this interface
1226  *
1227  * Phase 3:
1228  *   attempt to re-assign interfaces to peers
1229  *
1230  */
1231 
1232 static int
1233 update_interfaces(
1234 	u_short port,
1235 	interface_receiver_t receiver,
1236 	void *data
1237 	)
1238 {
1239 	interface_info_t ifi;
1240 	isc_mem_t *mctx = NULL;
1241 	isc_interfaceiter_t *iter = NULL;
1242 	isc_boolean_t scan_ipv4 = ISC_FALSE;
1243 	isc_boolean_t scan_ipv6 = ISC_FALSE;
1244 	isc_result_t result;
1245 	int new_interface_found = 0;
1246 
1247 	DPRINTF(3, ("update_interfaces(%d)\n", ntohs( (u_short) port)));
1248 
1249 #ifdef INCLUDE_IPV6_SUPPORT
1250 	if (isc_net_probeipv6() == ISC_R_SUCCESS)
1251 		scan_ipv6 = ISC_TRUE;
1252 #if defined(DEBUG)
1253 	else
1254 		if (debug)
1255 			netsyslog(LOG_ERR, "no IPv6 interfaces found");
1256 #endif
1257 #endif
1258 	if (isc_net_probeipv6() == ISC_R_SUCCESS)
1259 		scan_ipv6 = ISC_TRUE;
1260 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(DEBUG)
1261 	else
1262 		if (debug)
1263 			netsyslog(LOG_ERR, "no IPv6 interfaces found");
1264 #endif
1265 
1266 	if (isc_net_probeipv4() == ISC_R_SUCCESS)
1267 		scan_ipv4 = ISC_TRUE;
1268 #ifdef DEBUG
1269 	else
1270 		if(debug)
1271 			netsyslog(LOG_ERR, "no IPv4 interfaces found");
1272 #endif
1273 	/*
1274 	 * phase one - scan interfaces
1275 	 * - create those that are not found
1276 	 * - update those that are found
1277 	 */
1278 
1279 	result = isc_interfaceiter_create(mctx, &iter);
1280 
1281 	if (result != ISC_R_SUCCESS)
1282 		return 0;
1283 
1284 	sys_interphase ^= 0x1;	/* toggle system phase for finding untouched (to be deleted) interfaces */
1285 
1286 	for (result = isc_interfaceiter_first(iter);
1287 	     result == ISC_R_SUCCESS;
1288 	     result = isc_interfaceiter_next(iter))
1289 	{
1290 		isc_interface_t isc_if;
1291 		unsigned int family;
1292 		struct interface interface;
1293 		struct interface *iface;
1294 
1295 		result = isc_interfaceiter_current(iter, &isc_if);
1296 
1297 		if (result != ISC_R_SUCCESS)
1298 			break;
1299 
1300 		/* See if we have a valid family to use */
1301 		family = isc_if.address.family;
1302 		if (family != AF_INET && family != AF_INET6)
1303 			continue;
1304 		if (scan_ipv4 == ISC_FALSE && family == AF_INET)
1305 			continue;
1306 		if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
1307 			continue;
1308 
1309 		/*
1310 		 * create prototype
1311 		 */
1312 		init_interface(&interface);
1313 
1314 		convert_isc_if(&isc_if, &interface, port);
1315 
1316 		/*
1317 		 * Check to see if we are going to use the interface
1318 		 * If we don't use it we mark it to drop any packet
1319 		 * received but we still must create the socket and
1320 		 * bind to it. This prevents other apps binding to it
1321 		 * and potentially causing problems with more than one
1322 		 * process fiddling with the clock
1323 		 */
1324 		if (address_okay(&interface) == ISC_TRUE) {
1325 			interface.ignore_packets = ISC_FALSE;
1326 		}
1327 		else {
1328 			interface.ignore_packets = ISC_TRUE;
1329 		}
1330 
1331 		DPRINT_INTERFACE(4, (&interface, "examining ", "\n"));
1332 
1333 		if (!(interface.flags & INT_UP))  { /* interfaces must be UP to be usable */
1334 			DPRINTF(4, ("skipping interface %s (%s) - DOWN\n", interface.name, stoa(&interface.sin)));
1335 			continue;
1336 		}
1337 
1338 		/*
1339 		 * skip any interfaces UP and bound to a wildcard
1340 		 * address - some dhcp clients produce that in the
1341 		 * wild
1342 		 */
1343 		if (is_wildcard_addr(&interface.sin))
1344 			continue;
1345 
1346 #ifdef INCLUDE_IPV6_SUPPORT
1347 		if (is_anycast((struct sockaddr *)&interface.sin, isc_if.name))
1348 			continue;
1349 #endif /* !INCLUDE_IPV6_SUPPORT */
1350 
1351 		/*
1352 		 * map to local *address* in order
1353 		 * to map all duplicate interfaces to an interface structure
1354 		 * with the appropriate socket (our name space is
1355 		 * (ip-address) - NOT (interface name, ip-address))
1356 		 */
1357 		iface = getinterface(&interface.sin, INT_WILDCARD);
1358 
1359 		if (iface && refresh_interface(iface))
1360 		{
1361 			/*
1362 			 * found existing and up to date interface - mark present
1363 			 */
1364 
1365 			iface->phase = sys_interphase;
1366 			DPRINT_INTERFACE(4, (iface, "updating ", " present\n"));
1367 			ifi.action = IFS_EXISTS;
1368 			ifi.interface = iface;
1369 			if (receiver)
1370 				receiver(data, &ifi);
1371 		}
1372 		else
1373 		{
1374 			/*
1375 			 * this is new or refreshing failed - add to our interface list
1376 			 * if refreshing failed we will delete the interface structure in
1377 			 * phase 2 as the interface was not marked current. We can bind to
1378 			 * the address as the refresh code already closed the offending socket
1379 			 */
1380 
1381 			iface = create_interface(port, &interface);
1382 
1383 			if (iface)
1384 			{
1385 				ifi.action = IFS_CREATED;
1386 				ifi.interface = iface;
1387 				if (receiver)
1388 					receiver(data, &ifi);
1389 
1390 				new_interface_found = 1;
1391 
1392 				DPRINT_INTERFACE(3, (iface, "updating ", " new - created\n"));
1393 			}
1394 			else
1395 			{
1396 				DPRINT_INTERFACE(3, (&interface, "updating ", " new - creation FAILED"));
1397 
1398 				msyslog(LOG_INFO, "failed to initialize interface for address %s", stoa(&interface.sin));
1399 				continue;
1400 			}
1401 		}
1402 	}
1403 
1404 	isc_interfaceiter_destroy(&iter);
1405 
1406 	/*
1407 	 * phase 2 - delete gone interfaces - reassigning peers to other interfaces
1408 	 */
1409 	{
1410 		struct interface *interf = ISC_LIST_HEAD(inter_list);
1411 
1412 		while (interf != NULL)
1413 		{
1414 			struct interface *next = ISC_LIST_NEXT(interf, link);
1415 
1416 			if (!(interf->flags & (INT_WILDCARD|INT_MCASTIF))) {
1417 				/*
1418 				 * if phase does not match sys_phase this interface was not
1419 				 * enumerated during interface scan - so it is gone and
1420 				 * will be deleted here unless it is solely an MCAST/WILDCARD interface
1421 				 */
1422 				if (interf->phase != sys_interphase) {
1423 					struct peer *peer;
1424 					DPRINT_INTERFACE(3, (interf, "updating ", "GONE - deleting\n"));
1425 					remove_interface(interf);
1426 
1427 					ifi.action = IFS_DELETED;
1428 					ifi.interface = interf;
1429 					if (receiver)
1430 						receiver(data, &ifi);
1431 
1432 					peer = ISC_LIST_HEAD(interf->peers);
1433 					/*
1434 					 * disconnect peer from deleted interface
1435 					 */
1436 					while (peer != NULL) {
1437 						struct peer *npeer = ISC_LIST_NEXT(peer, ilink);
1438 
1439 						/*
1440 						 * this one just lost it's interface
1441 						 */
1442 						set_peerdstadr(peer, NULL);
1443 
1444 						peer = npeer;
1445 					}
1446 
1447 					/*
1448 					 * update globals in case we lose
1449 					 * a loopback interface
1450 					 */
1451 					if (interf == loopback_interface)
1452 						loopback_interface = NULL;
1453 
1454 					delete_interface(interf);
1455 				}
1456 			}
1457 			interf = next;
1458 		}
1459 	}
1460 
1461 	/*
1462 	 * phase 3 - re-configure as the world has changed if necessary
1463 	 */
1464 	refresh_all_peerinterfaces();
1465 	return new_interface_found;
1466 }
1467 
1468 
1469 /*
1470  * create_sockets - create a socket for each interface plus a default
1471  *			socket for when we don't know where to send
1472  */
1473 static int
1474 create_sockets(
1475 	u_short port
1476 	)
1477 {
1478 #ifndef HAVE_IO_COMPLETION_PORT
1479 	/*
1480 	 * I/O Completion Ports don't care about the select and FD_SET
1481 	 */
1482 	maxactivefd = 0;
1483 	FD_ZERO(&activefds);
1484 #endif
1485 
1486 	DPRINTF(2, ("create_sockets(%d)\n", ntohs( (u_short) port)));
1487 
1488 	create_wildcards(port);
1489 
1490 	update_interfaces(port, NULL, NULL);
1491 
1492 	/*
1493 	 * Now that we have opened all the sockets, turn off the reuse
1494 	 * flag for security.
1495 	 */
1496 	set_reuseaddr(0);
1497 
1498 	DPRINTF(2, ("create_sockets: Total interfaces = %d\n", ninterfaces));
1499 
1500 	return ninterfaces;
1501 }
1502 
1503 /*
1504  * create_interface - create a new interface for a given prototype
1505  *		      binding the socket.
1506  */
1507 static struct interface *
1508 create_interface(
1509 		 u_short port,
1510 		 struct interface *iface
1511 		 )
1512 {
1513 	struct sockaddr_storage resmask;
1514 	struct interface *interface;
1515 
1516 	DPRINTF(2, ("create_interface(%s#%d)\n", stoa(&iface->sin), ntohs( (u_short) port)));
1517 
1518 	/* build an interface */
1519 	interface = new_interface(iface);
1520 
1521 	/*
1522 	 * create socket
1523 	 */
1524 	interface->fd = open_socket(&interface->sin,
1525 				 interface->flags, 0, interface);
1526 
1527 	if (interface->fd != INVALID_SOCKET)
1528 		list_if_listening(interface, port);
1529 
1530 	if ((interface->flags & INT_BROADCAST) &&
1531 	    interface->bfd != INVALID_SOCKET)
1532 	  msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
1533 		  stoa((&interface->bcast)),
1534 		  ntohs( (u_short) port));
1535 
1536 	if (interface->fd == INVALID_SOCKET &&
1537 	    interface->bfd == INVALID_SOCKET) {
1538 		msyslog(LOG_ERR, "unable to create socket on %s (%d) for %s#%d",
1539 			interface->name,
1540 			interface->ifnum,
1541 			stoa((&interface->sin)),
1542 			ntohs( (u_short) port));
1543 		delete_interface(interface);
1544 		return NULL;
1545 	}
1546 
1547         /*
1548 	 * Blacklist bound interface address
1549 	 */
1550 
1551 	SET_HOSTMASK(&resmask, interface->sin.ss_family);
1552 	hack_restrict(RESTRICT_FLAGS, &interface->sin, &resmask,
1553 		      RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
1554 
1555 	/*
1556 	 * set globals with the first found
1557 	 * loopback interface of the appropriate class
1558 	 */
1559 	if ((loopback_interface == NULL) &&
1560 	    (interface->family == AF_INET) &&
1561 	    ((interface->flags & INT_LOOPBACK) != 0))
1562 	{
1563 		loopback_interface = interface;
1564 	}
1565 
1566 	/*
1567 	 * put into our interface list
1568 	 */
1569 	add_addr_to_list(&interface->sin, interface);
1570 	add_interface(interface);
1571 
1572 	DPRINT_INTERFACE(2, (interface, "created ", "\n"));
1573 	return interface;
1574 }
1575 
1576 
1577 #ifdef SO_EXCLUSIVEADDRUSE
1578 static void
1579 set_excladdruse(int fd)
1580 {
1581 	int one = 1;
1582 	int failed;
1583 
1584 	failed = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
1585 			    (char *)&one, sizeof(one));
1586 
1587 	if (failed)
1588 		netsyslog(LOG_ERR,
1589 			  "setsockopt(%d, SO_EXCLUSIVEADDRUSE, on): %m", fd);
1590 }
1591 #endif  /* SO_EXCLUSIVEADDRUSE */
1592 
1593 
1594 /*
1595  * set_reuseaddr() - set/clear REUSEADDR on all sockets
1596  *			NB possible hole - should we be doing this on broadcast
1597  *			fd's also?
1598  */
1599 static void
1600 set_reuseaddr(int flag) {
1601 	struct interface *interf;
1602 
1603 #ifndef SO_EXCLUSIVEADDRUSE
1604 
1605 	for (interf = ISC_LIST_HEAD(inter_list);
1606 	     interf != NULL;
1607 	     interf = ISC_LIST_NEXT(interf, link)) {
1608 
1609 		if (interf->flags & INT_WILDCARD)
1610 			continue;
1611 
1612 		/*
1613 		 * if interf->fd  is INVALID_SOCKET, we might have a adapter
1614 		 * configured but not present
1615 		 */
1616 		DPRINTF(4, ("setting SO_REUSEADDR on %.16s@%s to %s\n", interf->name, stoa(&interf->sin), flag ? "on" : "off"));
1617 
1618 		if (interf->fd != INVALID_SOCKET) {
1619 			if (setsockopt(interf->fd, SOL_SOCKET,
1620 					SO_REUSEADDR, (char *)&flag,
1621 					sizeof(flag))) {
1622 				netsyslog(LOG_ERR, "set_reuseaddr: setsockopt(SO_REUSEADDR, %s) failed: %m", flag ? "on" : "off");
1623 			}
1624 		}
1625 	}
1626 #endif /* ! SO_EXCLUSIVEADDRUSE */
1627 }
1628 
1629 /*
1630  * This is just a wrapper around an internal function so we can
1631  * make other changes as necessary later on
1632  */
1633 void
1634 enable_broadcast(struct interface *iface, struct sockaddr_storage *baddr)
1635 {
1636 #ifdef SO_BROADCAST
1637 	socket_broadcast_enable(iface, iface->fd, baddr);
1638 #endif
1639 }
1640 
1641 #ifdef OPEN_BCAST_SOCKET
1642 /*
1643  * Enable a broadcast address to a given socket
1644  * The socket is in the inter_list all we need to do is enable
1645  * broadcasting. It is not this function's job to select the socket
1646  */
1647 static isc_boolean_t
1648 socket_broadcast_enable(struct interface *iface, SOCKET fd, struct sockaddr_storage *maddr)
1649 {
1650 #ifdef SO_BROADCAST
1651 	int on = 1;
1652 
1653 	if (maddr->ss_family == AF_INET)
1654 	{
1655 		/* if this interface can support broadcast, set SO_BROADCAST */
1656 		if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1657 			       (char *)&on, sizeof(on)))
1658 		{
1659 			netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) enable failure on address %s: %m",
1660 				stoa(maddr));
1661 		}
1662 #ifdef DEBUG
1663 		else if (debug > 1) {
1664 			printf("Broadcast enabled on socket %d for address %s\n",
1665 				fd, stoa(maddr));
1666 		}
1667 #endif
1668 	}
1669 	iface->flags |= INT_BCASTOPEN;
1670 	return ISC_TRUE;
1671 #else
1672 	return ISC_FALSE;
1673 #endif /* SO_BROADCAST */
1674 }
1675 
1676 /*
1677  * Remove a broadcast address from a given socket
1678  * The socket is in the inter_list all we need to do is disable
1679  * broadcasting. It is not this function's job to select the socket
1680  */
1681 static isc_boolean_t
1682 socket_broadcast_disable(struct interface *iface, struct sockaddr_storage *maddr)
1683 {
1684 #ifdef SO_BROADCAST
1685 	int off = 0;	/* This seems to be OK as an int */
1686 
1687 	if (maddr->ss_family == AF_INET)
1688 	{
1689 		if (setsockopt(iface->fd, SOL_SOCKET, SO_BROADCAST,
1690 			       (char *)&off, sizeof(off)))
1691 		{
1692 			netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) disable failure on address %s: %m",
1693 				stoa(maddr));
1694 		}
1695 	}
1696 	iface->flags &= ~INT_BCASTOPEN;
1697 	return ISC_TRUE;
1698 #else
1699 	return ISC_FALSE;
1700 #endif /* SO_BROADCAST */
1701 }
1702 
1703 #endif /* OPEN_BCAST_SOCKET */
1704 /*
1705  * Check to see if the address is a multicast address
1706  */
1707 static isc_boolean_t
1708 addr_ismulticast(struct sockaddr_storage *maddr)
1709 {
1710 	switch (maddr->ss_family)
1711 	{
1712 	case AF_INET :
1713 		if (!IN_CLASSD(ntohl(((struct sockaddr_in*)maddr)->sin_addr.s_addr))) {
1714 			DPRINTF(4, ("multicast address %s not class D\n", stoa(maddr)));
1715 			return (ISC_FALSE);
1716 		}
1717 		else
1718 		{
1719 			return (ISC_TRUE);
1720 		}
1721 
1722 	case AF_INET6 :
1723 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1724 		if (!IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)maddr)->sin6_addr)) {
1725 			DPRINTF(4, ("address %s not IPv6 multicast address\n", stoa(maddr)));
1726 			return (ISC_FALSE);
1727 		}
1728 		else
1729 		{
1730 			return (ISC_TRUE);
1731 		}
1732 
1733 /*
1734  * If we don't have IPV6 support any IPV6 address is not multicast
1735  */
1736 #else
1737 		return (ISC_FALSE);
1738 #endif
1739 	/*
1740 	 * Never valid
1741 	 */
1742 	default:
1743 		return (ISC_FALSE);
1744 	}
1745 }
1746 
1747 /*
1748  * Multicast servers need to set the appropriate Multicast interface
1749  * socket option in order for it to know which interface to use for
1750  * send the multicast packet.
1751  */
1752 void
1753 enable_multicast_if(struct interface *iface, struct sockaddr_storage *maddr)
1754 {
1755 #ifdef MCAST
1756 #ifdef IP_MULTICAST_LOOP
1757 	/*u_char*/ TYPEOF_IP_MULTICAST_LOOP off = 0;
1758 #endif
1759 #ifdef IPV6_MULTICAST_LOOP
1760 	u_int off6 = 0;		/* RFC 3493, 5.2. defines type unsigned int */
1761 #endif
1762 
1763 	switch (maddr->ss_family)
1764 	{
1765 	case AF_INET:
1766 		if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_IF,
1767 		   (char *)&(((struct sockaddr_in*)&iface->sin)->sin_addr.s_addr),
1768 		    sizeof(struct in_addr)) == -1) {
1769 			netsyslog(LOG_ERR,
1770 			"setsockopt IP_MULTICAST_IF failure: %m on socket %d, addr %s for multicast address %s",
1771 			iface->fd, stoa(&iface->sin), stoa(maddr));
1772 			return;
1773 		}
1774 #ifdef IP_MULTICAST_LOOP
1775 		/*
1776 		 * Don't send back to itself, but allow it to fail to set it
1777 		 */
1778 		if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_LOOP,
1779 		       SETSOCKOPT_ARG_CAST &off, sizeof(off)) == -1) {
1780 			netsyslog(LOG_ERR,
1781 			"setsockopt IP_MULTICAST_LOOP failure: %m on socket %d, addr %s for multicast address %s",
1782 			iface->fd, stoa(&iface->sin), stoa(maddr));
1783 		}
1784 #endif
1785 	DPRINTF(4, ("Added IPv4 multicast interface on socket %d, addr %s for multicast address %s\n",
1786 			    iface->fd, stoa(&iface->sin),
1787 			    stoa(maddr)));
1788 		break;
1789 
1790 	case AF_INET6:
1791 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1792 		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
1793 		    (char *) &iface->scopeid, sizeof(iface->scopeid)) == -1) {
1794 			netsyslog(LOG_ERR,
1795 			"setsockopt IPV6_MULTICAST_IF failure: %m on socket %d, addr %s, scope %d for multicast address %s",
1796 			iface->fd, stoa(&iface->sin), iface->scopeid,
1797 			stoa(maddr));
1798 			return;
1799 		}
1800 #ifdef IPV6_MULTICAST_LOOP
1801 		/*
1802 		 * Don't send back to itself, but allow it to fail to set it
1803 		 */
1804 		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1805 		       (char *) &off6, sizeof(off6)) == -1) {
1806 			netsyslog(LOG_ERR,
1807 			"setsockopt IPV6_MULTICAST_LOOP failure: %m on socket %d, addr %s for multicast address %s",
1808 			iface->fd, stoa(&iface->sin), stoa(maddr));
1809 		}
1810 #endif
1811 		DPRINTF(4, ("Added IPv6 multicast interface on socket %d, addr %s, scope %d for multicast address %s\n",
1812 			    iface->fd,  stoa(&iface->sin), iface->scopeid,
1813 			    stoa(maddr)));
1814 		break;
1815 #else
1816 		return;
1817 #endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */
1818 	}
1819 	return;
1820 #endif
1821 }
1822 
1823 /*
1824  * Add a multicast address to a given socket
1825  * The socket is in the inter_list all we need to do is enable
1826  * multicasting. It is not this function's job to select the socket
1827  */
1828 static isc_boolean_t
1829 socket_multicast_enable(struct interface *iface, int lscope, struct sockaddr_storage *maddr)
1830 {
1831 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1832 	struct ipv6_mreq mreq6;
1833 	struct in6_addr iaddr6;
1834 #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
1835 
1836 	struct ip_mreq mreq;
1837 
1838 	if (find_addr_in_list(maddr)) {
1839 		DPRINTF(4, ("socket_multicast_enable(%s): already enabled\n", stoa(maddr)));
1840 		return ISC_TRUE;
1841 	}
1842 
1843 	switch (maddr->ss_family)
1844 	{
1845 	case AF_INET:
1846 		memset((char *)&mreq, 0, sizeof(mreq));
1847 		mreq.imr_multiaddr = (((struct sockaddr_in*)maddr)->sin_addr);
1848 		mreq.imr_interface.s_addr = htonl(INADDR_ANY);
1849 		if (setsockopt(iface->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1850 			(char *)&mreq, sizeof(mreq)) == -1) {
1851 			netsyslog(LOG_ERR,
1852 			"setsockopt IP_ADD_MEMBERSHIP failure: %m on socket %d, addr %s for %x / %x (%s)",
1853 			iface->fd, stoa(&iface->sin),
1854 			mreq.imr_multiaddr.s_addr,
1855 			mreq.imr_interface.s_addr, stoa(maddr));
1856 			return ISC_FALSE;
1857 		}
1858 		DPRINTF(4, ("Added IPv4 multicast membership on socket %d, addr %s for %x / %x (%s)\n",
1859 			    iface->fd, stoa(&iface->sin),
1860 			    mreq.imr_multiaddr.s_addr,
1861 			    mreq.imr_interface.s_addr, stoa(maddr)));
1862 		break;
1863 
1864 	case AF_INET6:
1865 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1866 		/*
1867 		 * Enable reception of multicast packets
1868 		 * If the address is link-local we can get the interface index
1869 		 * from the scope id. Don't do this for other types of multicast
1870 		 * addresses. For now let the kernel figure it out.
1871 		 */
1872 		memset((char *)&mreq6, 0, sizeof(mreq6));
1873 		iaddr6 = ((struct sockaddr_in6*)maddr)->sin6_addr;
1874 		mreq6.ipv6mr_multiaddr = iaddr6;
1875 		mreq6.ipv6mr_interface = lscope;
1876 
1877 		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1878 			(char *)&mreq6, sizeof(mreq6)) == -1) {
1879 			netsyslog(LOG_ERR,
1880 			 "setsockopt IPV6_JOIN_GROUP failure: %m on socket %d, addr %s for interface %d(%s)",
1881 			iface->fd, stoa(&iface->sin),
1882 			mreq6.ipv6mr_interface, stoa(maddr));
1883 			return ISC_FALSE;
1884 		}
1885 		DPRINTF(4, ("Added IPv6 multicast group on socket %d, addr %s for interface %d(%s)\n",
1886 			    iface->fd, stoa(&iface->sin),
1887 			    mreq6.ipv6mr_interface, stoa(maddr)));
1888 		break;
1889 #else
1890 		return ISC_FALSE;
1891 #endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */
1892 	}
1893 	iface->flags |= INT_MCASTOPEN;
1894 	iface->num_mcast++;
1895 	add_addr_to_list(maddr, iface);
1896 	return ISC_TRUE;
1897 }
1898 
1899 /*
1900  * Remove a multicast address from a given socket
1901  * The socket is in the inter_list all we need to do is disable
1902  * multicasting. It is not this function's job to select the socket
1903  */
1904 static isc_boolean_t
1905 socket_multicast_disable(struct interface *iface, struct sockaddr_storage *maddr)
1906 {
1907 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1908 	struct ipv6_mreq mreq6;
1909 	struct in6_addr iaddr6;
1910 #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
1911 
1912 	struct ip_mreq mreq;
1913 	memset((char *)&mreq, 0, sizeof(mreq));
1914 
1915 	if (find_addr_in_list(maddr) == NULL) {
1916 		DPRINTF(4, ("socket_multicast_disable(%s): not enabled\n", stoa(maddr)));
1917 		return ISC_TRUE;
1918 	}
1919 
1920 	switch (maddr->ss_family)
1921 	{
1922 	case AF_INET:
1923 		mreq.imr_multiaddr = (((struct sockaddr_in*)&maddr)->sin_addr);
1924 		mreq.imr_interface.s_addr = ((struct sockaddr_in*)&iface->sin)->sin_addr.s_addr;
1925 		if (setsockopt(iface->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
1926 			(char *)&mreq, sizeof(mreq)) == -1) {
1927 			netsyslog(LOG_ERR,
1928 			"setsockopt IP_DROP_MEMBERSHIP failure: %m on socket %d, addr %s for %x / %x (%s)",
1929 			iface->fd, stoa(&iface->sin),
1930 			mreq.imr_multiaddr.s_addr,
1931 			mreq.imr_interface.s_addr, stoa(maddr));
1932 			return ISC_FALSE;
1933 		}
1934 		break;
1935 	case AF_INET6:
1936 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1937 		/*
1938 		 * Disable reception of multicast packets
1939 		 * If the address is link-local we can get the interface index
1940 		 * from the scope id. Don't do this for other types of multicast
1941 		 * addresses. For now let the kernel figure it out.
1942 		 */
1943 		iaddr6 = ((struct sockaddr_in6*)&maddr)->sin6_addr;
1944 		mreq6.ipv6mr_multiaddr = iaddr6;
1945 		mreq6.ipv6mr_interface = iface->scopeid;
1946 
1947 		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
1948 			(char *)&mreq6, sizeof(mreq6)) == -1) {
1949 			netsyslog(LOG_ERR,
1950 			"setsockopt IPV6_LEAVE_GROUP failure: %m on socket %d, addr %s for %d(%s)",
1951 			iface->fd, stoa(&iface->sin),
1952 			mreq6.ipv6mr_interface, stoa(maddr));
1953 			return ISC_FALSE;
1954 		}
1955 		break;
1956 #else
1957 		return ISC_FALSE;
1958 #endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */
1959 
1960 	}
1961 	iface->num_mcast--;
1962 	if (iface->num_mcast <= 0) {
1963                 iface->num_mcast = 0;
1964 		iface->flags &= ~INT_MCASTOPEN;
1965 	}
1966 	return ISC_TRUE;
1967 }
1968 
1969 /*
1970  * io_setbclient - open the broadcast client sockets
1971  */
1972 void
1973 io_setbclient(void)
1974 {
1975 #ifdef OPEN_BCAST_SOCKET
1976         struct interface *interf;
1977 	int nif = 0;
1978 	isc_boolean_t jstatus;
1979 	SOCKET fd;
1980 
1981 	set_reuseaddr(1);
1982 
1983 	for (interf = ISC_LIST_HEAD(inter_list);
1984 	     interf != NULL;
1985 	     interf = ISC_LIST_NEXT(interf, link)) {
1986 	        if (interf->flags & INT_WILDCARD)
1987 		        continue;
1988 
1989 		/* use only allowed addresses */
1990 		if (interf->ignore_packets == ISC_TRUE)
1991 			continue;
1992 		/* Only IPv4 addresses are valid for broadcast */
1993 		if (interf->sin.ss_family != AF_INET)
1994 			continue;
1995 
1996 		/* Is this a broadcast address? */
1997 		if (!(interf->flags & INT_BROADCAST))
1998 			continue;
1999 
2000 		/* Skip the loopback addresses */
2001 		if (interf->flags & INT_LOOPBACK)
2002 			continue;
2003 
2004 		/* Do we already have the broadcast address open? */
2005 		if (interf->flags & INT_BCASTOPEN) {
2006 		/* account for already open interfaces to aviod misleading warning below */
2007 			nif++;
2008 			continue;
2009 		}
2010 
2011 		/*
2012 		 * Try to open the broadcast address
2013 		 */
2014 		interf->family = AF_INET;
2015 		interf->bfd = open_socket(&interf->bcast,
2016 				    INT_BROADCAST, 0, interf);
2017 
2018 		 /*
2019 		 * If we succeeded then we use it otherwise
2020 		 * enable the underlying address
2021 		 */
2022 		if (interf->bfd == INVALID_SOCKET) {
2023 			fd = interf->fd;
2024 		}
2025 		else {
2026 			fd = interf->bfd;
2027 		}
2028 
2029 		/* Enable Broadcast on socket */
2030 		jstatus = socket_broadcast_enable(interf, fd, &interf->sin);
2031 		if (jstatus == ISC_TRUE)
2032 		{
2033 			nif++;
2034 			netsyslog(LOG_INFO,"io_setbclient: Opened broadcast client on interface #%d %s, socket: %d",
2035 				  interf->ifnum, interf->name, fd);
2036 			interf->addr_refid = addr2refid(&interf->sin);
2037 		}
2038 	}
2039 	set_reuseaddr(0);
2040 #ifdef DEBUG
2041 	if (debug)
2042 		if (nif > 0)
2043 			printf("io_setbclient: Opened broadcast clients\n");
2044 #endif
2045 	if (nif == 0)
2046 		netsyslog(LOG_ERR, "Unable to listen for broadcasts, no broadcast interfaces available");
2047 #else
2048 	netsyslog(LOG_ERR, "io_setbclient: Broadcast Client disabled by build");
2049 #endif
2050 }
2051 
2052 /*
2053  * io_unsetbclient - close the broadcast client sockets
2054  */
2055 void
2056 io_unsetbclient(void)
2057 {
2058         struct interface *interf;
2059 	isc_boolean_t lstatus;
2060 
2061 	for (interf = ISC_LIST_HEAD(inter_list);
2062 	     interf != NULL;
2063 	     interf = ISC_LIST_NEXT(interf, link))
2064 	{
2065 	        if (interf->flags & INT_WILDCARD)
2066 		    continue;
2067 
2068 		if (!(interf->flags & INT_BCASTOPEN))
2069 		    continue;
2070 		lstatus = socket_broadcast_disable(interf, &interf->sin);
2071 	}
2072 }
2073 
2074 /*
2075  * io_multicast_add() - add multicast group address
2076  */
2077 void
2078 io_multicast_add(
2079 	struct sockaddr_storage addr
2080 	)
2081 {
2082 #ifdef MCAST
2083 	struct interface *interface;
2084 #ifndef MULTICAST_NONEWSOCKET
2085 	struct interface *iface;
2086 #endif
2087 	int lscope = 0;
2088 
2089 	/*
2090 	 * Check to see if this is a multicast address
2091 	 */
2092 	if (addr_ismulticast(&addr) == ISC_FALSE)
2093 		return;
2094 
2095 	/* If we already have it we can just return */
2096 	if (find_flagged_addr_in_list(&addr, INT_MCASTOPEN|INT_MCASTIF) != NULL)
2097 	{
2098 		netsyslog(LOG_INFO, "Duplicate request found for multicast address %s",
2099 			stoa(&addr));
2100 		return;
2101 	}
2102 
2103 #ifndef MULTICAST_NONEWSOCKET
2104 	interface = new_interface(NULL);
2105 
2106 	/*
2107 	 * Open a new socket for the multicast address
2108 	 */
2109 	interface->sin.ss_family = addr.ss_family;
2110 	interface->family = addr.ss_family;
2111 
2112 	switch(addr.ss_family) {
2113 	case AF_INET:
2114 		memcpy(&(((struct sockaddr_in *)&interface->sin)->sin_addr),
2115 		       &(((struct sockaddr_in*)&addr)->sin_addr),
2116 		       sizeof(struct in_addr));
2117 		((struct sockaddr_in*)&interface->sin)->sin_port = htons(NTP_PORT);
2118 		memset(&((struct sockaddr_in*)&interface->mask)->sin_addr.s_addr, 0xff, sizeof(struct in_addr));
2119 		break;
2120 	case AF_INET6:
2121 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2122 		memcpy(&(((struct sockaddr_in6 *)&interface->sin)->sin6_addr),
2123 		       &((struct sockaddr_in6*)&addr)->sin6_addr,
2124 		       sizeof(struct in6_addr));
2125 		((struct sockaddr_in6*)&interface->sin)->sin6_port = htons(NTP_PORT);
2126 #ifdef ISC_PLATFORM_HAVESCOPEID
2127 		((struct sockaddr_in6*)&interface->sin)->sin6_scope_id = ((struct sockaddr_in6*)&addr)->sin6_scope_id;
2128 #endif
2129 		memset(&((struct sockaddr_in6*)&interface->mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));
2130 #endif
2131 		iface = findlocalcastinterface(&addr, INT_MULTICAST);
2132 		if (iface) {
2133 # ifdef ISC_PLATFORM_HAVESCOPEID
2134 			lscope = ((struct sockaddr_in6*)&iface->sin)->sin6_scope_id;
2135 # endif
2136 			DPRINTF(4, ("Found interface #%d %s, scope: %d for address %s\n", iface->ifnum, iface->name, lscope, stoa(&addr)));
2137 		}
2138 		break;
2139 	}
2140 
2141 	set_reuseaddr(1);
2142 	interface->bfd = INVALID_SOCKET;
2143 	interface->fd = open_socket(&interface->sin,
2144 			    INT_MULTICAST, 0, interface);
2145 
2146 	if (interface->fd != INVALID_SOCKET)
2147 	{
2148 		interface->bfd = INVALID_SOCKET;
2149 		interface->ignore_packets = ISC_FALSE;
2150 		interface->flags |= INT_MCASTIF;
2151 
2152 		(void) strncpy(interface->name, "multicast",
2153 			sizeof(interface->name));
2154 		((struct sockaddr_in*)&interface->mask)->sin_addr.s_addr =
2155 						htonl(~(u_int32)0);
2156 		DPRINT_INTERFACE(2, (interface, "multicast add ", "\n"));
2157 		/* socket_multicast_enable() will add this address to the addresslist */
2158 		add_interface(interface);
2159 		list_if_listening(interface, htons(NTP_PORT));
2160 	}
2161 	else
2162 	{
2163 		delete_interface(interface);  /* re-use existing interface */
2164 		interface = NULL;
2165 		if (addr.ss_family == AF_INET)
2166 			interface = wildipv4;
2167 		else if (addr.ss_family == AF_INET6)
2168 			interface = wildipv6;
2169 
2170 		if (interface != NULL) {
2171 			/* HACK ! -- stuff in an address */
2172 			interface->bcast = addr;
2173 			netsyslog(LOG_ERR,
2174 			 "...multicast address %s using wildcard interface #%d %s",
2175 				  stoa(&addr), interface->ifnum, interface->name);
2176 		} else {
2177 			netsyslog(LOG_ERR,
2178 			"No multicast socket available to use for address %s",
2179 			stoa(&addr));
2180 			return;
2181 		}
2182 	}
2183 #else
2184 	/*
2185 	 * For the case where we can't use a separate socket
2186 	 */
2187 	interface = findlocalcastinterface(&addr, INT_MULTICAST);
2188 	/*
2189 	 * If we don't have a valid socket, just return
2190 	 */
2191 	if (!interface)
2192 	{
2193 		netsyslog(LOG_ERR,
2194 		"Cannot add multicast address %s: Cannot find slot",
2195 		stoa(&addr));
2196 		return;
2197 	}
2198 
2199 #endif
2200 	{
2201 		isc_boolean_t jstatus;
2202 		jstatus = socket_multicast_enable(interface, lscope, &addr);
2203 
2204 		if (jstatus == ISC_TRUE)
2205 			netsyslog(LOG_INFO, "Added Multicast Listener %s on interface #%d %s\n", stoa(&addr), interface->ifnum, interface->name);
2206 		else
2207 			netsyslog(LOG_ERR, "Failed to add Multicast Listener %s\n", stoa(&addr));
2208 	}
2209 #else /* MCAST */
2210 	netsyslog(LOG_ERR,
2211 		  "Cannot add multicast address %s: no Multicast support",
2212 		  stoa(&addr));
2213 #endif /* MCAST */
2214 	return;
2215 }
2216 
2217 /*
2218  * io_multicast_del() - delete multicast group address
2219  */
2220 void
2221 io_multicast_del(
2222 	struct sockaddr_storage addr
2223 	)
2224 {
2225 #ifdef MCAST
2226         struct interface *interface;
2227 	isc_boolean_t lstatus;
2228 
2229 	/*
2230 	 * Check to see if this is a multicast address
2231 	 */
2232 	if (addr_ismulticast(&addr) == ISC_FALSE)
2233 	{
2234 		netsyslog(LOG_ERR,
2235 			 "invalid multicast address %s", stoa(&addr));
2236 		return;
2237 	}
2238 
2239 	switch (addr.ss_family)
2240 	{
2241 	case AF_INET :
2242 		/*
2243 		 * Disable reception of multicast packets
2244 		 */
2245 		interface = find_flagged_addr_in_list(&addr, INT_MCASTOPEN);
2246 		while ( interface != NULL) {
2247 			lstatus = socket_multicast_disable(interface, &addr);
2248 			interface = find_flagged_addr_in_list(&addr, INT_MCASTOPEN);
2249 		}
2250 		break;
2251 
2252 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2253 	case AF_INET6 :
2254 		/*
2255 		 * Disable reception of multicast packets
2256 		 */
2257 		for (interface = ISC_LIST_HEAD(inter_list);
2258 		     interface != NULL;
2259 		     interface = ISC_LIST_NEXT(interface, link))
2260 		{
2261                         if (interface->flags & INT_WILDCARD)
2262 			        continue;
2263 
2264 			/* Be sure it's the correct family */
2265 			if (interface->sin.ss_family != AF_INET6)
2266 				continue;
2267 			if (!(interface->flags & INT_MCASTOPEN))
2268 				continue;
2269 			if (!(interface->fd < 0))
2270 				continue;
2271 			if (!SOCKCMP(&addr, &interface->sin))
2272 				continue;
2273 			lstatus = socket_multicast_disable(interface, &addr);
2274 		}
2275 		break;
2276 #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
2277 
2278 	}/* switch */
2279 
2280         delete_addr_from_list(&addr);
2281 
2282 #else /* not MCAST */
2283 	netsyslog(LOG_ERR, "this function requires multicast kernel");
2284 #endif /* not MCAST */
2285 }
2286 
2287 /*
2288  * init_nonblocking_io() - set up descriptor to be non blocking
2289  */
2290 static void init_nonblocking_io(SOCKET fd)
2291 {
2292 	/*
2293 	 * set non-blocking,
2294 	 */
2295 
2296 #ifdef USE_FIONBIO
2297 	/* in vxWorks we use FIONBIO, but the others are defined for old systems, so
2298 	 * all hell breaks loose if we leave them defined
2299 	 */
2300 #undef O_NONBLOCK
2301 #undef FNDELAY
2302 #undef O_NDELAY
2303 #endif
2304 
2305 #if defined(O_NONBLOCK) /* POSIX */
2306 	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
2307 	{
2308 		netsyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails on fd #%d: %m",
2309 			fd);
2310 		exit(1);
2311 		/*NOTREACHED*/
2312 	}
2313 #elif defined(FNDELAY)
2314 	if (fcntl(fd, F_SETFL, FNDELAY) < 0)
2315 	{
2316 		netsyslog(LOG_ERR, "fcntl(FNDELAY) fails on fd #%d: %m",
2317 			fd);
2318 		exit(1);
2319 		/*NOTREACHED*/
2320 	}
2321 #elif defined(O_NDELAY) /* generally the same as FNDELAY */
2322 	if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
2323 	{
2324 		netsyslog(LOG_ERR, "fcntl(O_NDELAY) fails on fd #%d: %m",
2325 			fd);
2326 		exit(1);
2327 		/*NOTREACHED*/
2328 	}
2329 #elif defined(FIONBIO)
2330 	{
2331 		int on = 1;
2332 		if (ioctl(fd,FIONBIO,&on) < 0)
2333 		{
2334 			netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on fd #%d: %m",
2335 				fd);
2336 			exit(1);
2337 			/*NOTREACHED*/
2338 		}
2339 	}
2340 #elif defined(FIOSNBIO)
2341 	if (ioctl(fd,FIOSNBIO,&on) < 0)
2342 	{
2343 		netsyslog(LOG_ERR, "ioctl(FIOSNBIO) fails on fd #%d: %m",
2344 			fd);
2345 		exit(1);
2346 		/*NOTREACHED*/
2347 	}
2348 #else
2349 # include "Bletch: Need non-blocking I/O!"
2350 #endif
2351 }
2352 
2353 /*
2354  * open_socket - open a socket, returning the file descriptor
2355  */
2356 
2357 static SOCKET
2358 open_socket(
2359 	struct sockaddr_storage *addr,
2360 	int flags,
2361 	int turn_off_reuse,
2362 	struct interface *interf
2363 	)
2364 {
2365 	int errval;
2366 	SOCKET fd;
2367 	/*
2368 	 * int is OK for REUSEADR per
2369 	 * http://www.kohala.com/start/mcast.api.txt
2370 	 */
2371 	int on = 1;
2372 	int off = 0;
2373 
2374 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
2375 	int tos;
2376 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
2377 
2378 	if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS))
2379 		return (INVALID_SOCKET);
2380 
2381 	/* create a datagram (UDP) socket */
2382 	fd = socket(addr->ss_family, SOCK_DGRAM, 0);
2383 	if (INVALID_SOCKET == fd) {
2384 #ifndef SYS_WINNT
2385 		errval = errno;
2386 #else
2387 		errval = WSAGetLastError();
2388 #endif
2389 		netsyslog(LOG_ERR,
2390 			  "socket(AF_INET%s, SOCK_DGRAM, 0) failed on address %s: %m",
2391 			  (addr->ss_family == AF_INET6) ? "6" : "",
2392 			  stoa(addr));
2393 
2394 		if (errval == EPROTONOSUPPORT ||
2395 		    errval == EAFNOSUPPORT ||
2396 		    errval == EPFNOSUPPORT)
2397 			return (INVALID_SOCKET);
2398 		msyslog(LOG_ERR, "unexpected error code %d (not PROTONOSUPPORT|AFNOSUPPORT|FPNOSUPPORT) - exiting", errval);
2399 		exit(1);
2400 		/*NOTREACHED*/
2401 	}
2402 
2403 #ifdef SYS_WINNT
2404 	connection_reset_fix(fd, addr);
2405 #endif
2406 	/*
2407 	 * Fixup the file descriptor for some systems
2408 	 * See bug #530 for details of the issue.
2409 	 */
2410 	fd = move_fd(fd);
2411 
2412 	/*
2413 	 * set SO_REUSEADDR since we will be binding the same port
2414 	 * number on each interface according to turn_off_reuse.
2415 	 * This is undesirable on Windows versions starting with
2416 	 * Windows XP (numeric version 5.1).
2417 	 */
2418 #ifdef SYS_WINNT
2419 	if (isc_win32os_versioncheck(5, 1, 0, 0) < 0)  /* before 5.1 */
2420 #endif
2421 		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
2422 			       (char *)(turn_off_reuse
2423 					? &off
2424 					: &on),
2425 			       sizeof(on))) {
2426 
2427 			netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR %s"
2428 					   " fails for address %s: %m",
2429 					   turn_off_reuse
2430 						? "off"
2431 						: "on",
2432 					   stoa(addr));
2433 			closesocket(fd);
2434 			return INVALID_SOCKET;
2435 		}
2436 #ifdef SO_EXCLUSIVEADDRUSE
2437 	/*
2438 	 * setting SO_EXCLUSIVEADDRUSE on the wildcard we open
2439 	 * first will cause more specific binds to fail.
2440 	 */
2441 	if (!(interf->flags & INT_WILDCARD))
2442 		set_excladdruse(fd);
2443 #endif
2444 
2445 	/*
2446 	 * IPv4 specific options go here
2447 	 */
2448 	if (addr->ss_family == AF_INET) {
2449 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
2450 	/* set IP_TOS to minimize packet delay */
2451 		tos = IPTOS_LOWDELAY;
2452 		if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)
2453 		{
2454 			netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m",
2455 				stoa(addr));
2456 		}
2457 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
2458 	}
2459 
2460 	/*
2461 	 * IPv6 specific options go here
2462 	 */
2463         if (addr->ss_family == AF_INET6) {
2464 #if defined(IPV6_V6ONLY)
2465                 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
2466                 	(char*)&on, sizeof(on)))
2467                 {
2468                 	netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m",
2469 				stoa(addr));
2470 		}
2471 #endif /* IPV6_V6ONLY */
2472 #if defined(IPV6_BINDV6ONLY)
2473                 if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
2474                 	(char*)&on, sizeof(on)))
2475                 {
2476                 	netsyslog(LOG_ERR,
2477 			    "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
2478 			    stoa(addr));
2479 		}
2480 #endif /* IPV6_BINDV6ONLY */
2481 	}
2482 
2483 #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
2484 	/*
2485 	 * some OSes don't allow binding to more specific
2486 	 * addresses if a wildcard address already bound
2487 	 * to the port and SO_REUSEADDR is not set
2488 	 */
2489 	if (!is_wildcard_addr(addr)) {
2490 		set_wildcard_reuse(addr->ss_family, 1);
2491 	}
2492 #endif
2493 
2494 	/*
2495 	 * bind the local address.
2496 	 */
2497 	errval = bind(fd, (struct sockaddr *)addr, SOCKLEN(addr));
2498 
2499 #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
2500 	/*
2501 	 * some OSes don't allow binding to more specific
2502 	 * addresses if a wildcard address already bound
2503 	 * to the port and REUSE_ADDR is not set
2504 	 */
2505 	if (!is_wildcard_addr(addr)) {
2506 		set_wildcard_reuse(addr->ss_family, 0);
2507 	}
2508 #endif
2509 
2510 	if (errval < 0) {
2511 		/*
2512 		 * Don't log this under all conditions
2513 		 */
2514 		if (turn_off_reuse == 0
2515 #ifdef DEBUG
2516 		    || debug > 1
2517 #endif
2518 			) {
2519 			if (addr->ss_family == AF_INET)
2520 				netsyslog(LOG_ERR,
2521 					  "bind() fd %d, family AF_INET, port %d, addr %s, in_classd=%d flags=0x%x fails: %m",
2522 					  fd, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
2523 					  stoa(addr),
2524 					  IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)),
2525 					  flags);
2526 #ifdef INCLUDE_IPV6_SUPPORT
2527 			else if (addr->ss_family == AF_INET6)
2528 				netsyslog(LOG_ERR,
2529 					  "bind() fd %d, family AF_INET6, port %d, scope %d, addr %s, mcast=%d flags=0x%x fails: %m",
2530 					  fd, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port),
2531 # ifdef ISC_PLATFORM_HAVESCOPEID
2532 					  ((struct sockaddr_in6*)addr)->sin6_scope_id
2533 # else
2534 					  -1
2535 # endif
2536 					  , stoa(addr),
2537 					  IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr),
2538 					  flags);
2539 #endif
2540 		}
2541 
2542 		closesocket(fd);
2543 
2544 		return INVALID_SOCKET;
2545 	}
2546 
2547 #ifdef HAVE_TIMESTAMP
2548 	{
2549 		if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP,
2550 			       (char*)&on, sizeof(on)))
2551 		{
2552 			netsyslog(LOG_DEBUG,
2553 				  "setsockopt SO_TIMESTAMP on fails on address %s: %m",
2554 				  stoa(addr));
2555 		}
2556 #ifdef DEBUG
2557 		else
2558 		{
2559 			DPRINTF(4, ("setsockopt SO_TIMESTAMP enabled on fd %d address %s\n", fd, stoa(addr)));
2560 		}
2561 #endif
2562 	}
2563 #endif
2564 	DPRINTF(4, ("bind() fd %d, family %d, port %d, addr %s, flags=0x%x\n",
2565 		   fd,
2566 		   addr->ss_family,
2567 		   (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
2568 		   stoa(addr),
2569 		   interf->flags));
2570 
2571 	init_nonblocking_io(fd);
2572 
2573 #ifdef HAVE_SIGNALED_IO
2574 	init_socket_sig(fd);
2575 #endif /* not HAVE_SIGNALED_IO */
2576 
2577 	add_fd_to_list(fd, FD_TYPE_SOCKET);
2578 
2579 #if !defined(SYS_WINNT) && !defined(VMS)
2580 	DPRINTF(4, ("flags for fd %d: 0x%x\n", fd,
2581 		    fcntl(fd, F_GETFL, 0)));
2582 #endif /* SYS_WINNT || VMS */
2583 
2584 #if defined (HAVE_IO_COMPLETION_PORT)
2585 /*
2586  * Add the socket to the completion port
2587  */
2588 	if (io_completion_port_add_socket(fd, interf))
2589 	{
2590 		msyslog(LOG_ERR, "unable to set up io completion port - EXITING");
2591 		exit(1);
2592 	}
2593 #endif
2594 	return fd;
2595 }
2596 
2597 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
2598 /*
2599  * sendpkt - send a packet to the specified destination. Maintain a
2600  * send error cache so that only the first consecutive error for a
2601  * destination is logged.
2602  */
2603 void
2604 sendpkt(
2605 	struct sockaddr_storage *dest,
2606 	struct interface *inter,
2607 	int ttl,
2608 	struct pkt *pkt,
2609 	int len
2610 	)
2611 {
2612 	int cc, slot;
2613 
2614 	/*
2615 	 * Send error caches. Empty slots have port == 0
2616 	 * Set ERRORCACHESIZE to 0 to disable
2617 	 */
2618 	struct cache {
2619 		u_short port;
2620 		struct	in_addr addr;
2621 	};
2622 
2623 #ifdef INCLUDE_IPV6_SUPPORT
2624 	struct cache6 {
2625 		u_short port;
2626 		struct in6_addr addr;
2627 	};
2628 #endif /* INCLUDE_IPV6_SUPPORT */
2629 
2630 
2631 #ifndef ERRORCACHESIZE
2632 #define ERRORCACHESIZE 8
2633 #endif
2634 #if ERRORCACHESIZE > 0
2635 	static struct cache badaddrs[ERRORCACHESIZE];
2636 #ifdef INCLUDE_IPV6_SUPPORT
2637 	static struct cache6 badaddrs6[ERRORCACHESIZE];
2638 #endif /* INCLUDE_IPV6_SUPPORT */
2639 #else
2640 #define badaddrs ((struct cache *)0)		/* Only used in empty loops! */
2641 #ifdef INCLUDE_IPV6_SUPPORT
2642 #define badaddrs6 ((struct cache6 *)0)		/* Only used in empty loops! */
2643 #endif /* INCLUDE_IPV6_SUPPORT */
2644 #endif
2645 #ifdef DEBUG
2646 	if (debug > 1)
2647 	  {
2648 	    if (inter != NULL)
2649 	      {
2650 		printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n",
2651 		       (ttl > 0) ? "\tMCAST\t***** " : "",
2652 		       inter->fd, stoa(dest),
2653 		       stoa(&inter->sin), ttl, len);
2654 	      }
2655 	    else
2656 	      {
2657 		printf("%ssendpkt(dst=%s, ttl=%d, len=%d): no interface - IGNORED\n",
2658 		       (ttl > 0) ? "\tMCAST\t***** " : "",
2659 		       stoa(dest),
2660 		       ttl, len);
2661 	      }
2662 	  }
2663 #endif
2664 
2665 	if (inter == NULL)	/* unbound peer - drop request and wait for better network conditions */
2666 	  return;
2667 
2668 #ifdef MCAST
2669 
2670 	/*
2671 	 * for the moment we use the bcast option to set multicast ttl
2672 	 */
2673 	if (ttl > 0 && ttl != inter->last_ttl) {
2674 
2675 		/*
2676 		 * set the multicast ttl for outgoing packets
2677 		 */
2678 		int rtc;
2679 
2680 		switch (inter->sin.ss_family) {
2681 
2682 		case AF_INET :
2683 		{
2684 			u_char mttl = (u_char) ttl;
2685 
2686 			rtc = setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,
2687 					 (const void *) &mttl, sizeof(mttl));
2688 			break;
2689 		}
2690 
2691 #ifdef INCLUDE_IPV6_SUPPORT
2692 		case AF_INET6 :
2693 		{
2694 			u_int ittl = (u_char) ttl;
2695 
2696 			rtc = setsockopt(inter->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
2697 					 (const void *) &ittl, sizeof(ittl));
2698 			break;
2699 		}
2700 
2701 #endif /* INCLUDE_IPV6_SUPPORT */
2702 		default:	/* just NOP if not supported */
2703 			rtc = 0;
2704 			break;
2705 		}
2706 
2707 		if (rtc != 0) {
2708 			netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL/IPV6_MULTICAST_HOPS fails on address %s: %m",
2709 				  stoa(&inter->sin));
2710 		}
2711 		else
2712 			inter->last_ttl = ttl;
2713 	}
2714 
2715 #endif /* MCAST */
2716 
2717 	for (slot = ERRORCACHESIZE; --slot >= 0; )
2718 		if(dest->ss_family == AF_INET) {
2719 			if (badaddrs[slot].port == SRCPORT(dest) &&
2720 				badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr)
2721 			break;
2722 		}
2723 #ifdef INCLUDE_IPV6_SUPPORT
2724 		else if (dest->ss_family == AF_INET6) {
2725 			if (badaddrs6[slot].port == SRCPORT(dest) &&
2726 				!memcmp(&badaddrs6[slot].addr, &((struct sockaddr_in6*)dest)->sin6_addr, sizeof(struct in6_addr)))
2727 			break;
2728 		}
2729 #endif /* INCLUDE_IPV6_SUPPORT */
2730 
2731 #if defined(HAVE_IO_COMPLETION_PORT)
2732         cc = io_completion_port_sendto(inter, pkt, len, dest);
2733 	if (cc != ERROR_SUCCESS)
2734 #else
2735 #ifdef SIM
2736         cc = srvr_rply(&ntp_node,  dest, inter, pkt);
2737 #else /* SIM */
2738 	cc = sendto(inter->fd, (char *)pkt, (unsigned int)len, 0, (struct sockaddr *)dest,
2739 		    SOCKLEN(dest));
2740 #endif /* SIM */
2741 	if (cc == -1)
2742 #endif
2743 	{
2744 		inter->notsent++;
2745 		packets_notsent++;
2746 
2747 #if defined(HAVE_IO_COMPLETION_PORT)
2748 		if (cc != WSAEWOULDBLOCK && cc != WSAENOBUFS && slot < 0)
2749 #else
2750 		if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
2751 #endif
2752 		{
2753 			/*
2754 			 * Remember this, if there's an empty slot
2755 			 */
2756 			switch (dest->ss_family) {
2757 
2758 			case AF_INET :
2759 
2760 				for (slot = ERRORCACHESIZE; --slot >= 0; )
2761 					if (badaddrs[slot].port == 0)
2762 					{
2763 						badaddrs[slot].port = SRCPORT(dest);
2764 						badaddrs[slot].addr = ((struct sockaddr_in*)dest)->sin_addr;
2765 						break;
2766 					}
2767 				break;
2768 
2769 #ifdef INCLUDE_IPV6_SUPPORT
2770 			case AF_INET6 :
2771 
2772 				for (slot = ERRORCACHESIZE; --slot >= 0; )
2773 					if (badaddrs6[slot].port == 0)
2774 					{
2775 						badaddrs6[slot].port = SRCPORT(dest);
2776 						badaddrs6[slot].addr = ((struct sockaddr_in6*)dest)->sin6_addr;
2777 						break;
2778 					}
2779 				break;
2780 #endif /* INCLUDE_IPV6_SUPPORT */
2781 			default:  /* don't care if not supported */
2782 				break;
2783 			}
2784 
2785 			netsyslog(LOG_ERR, "sendto(%s) (fd=%d): %m",
2786 				  stoa(dest), inter->fd);
2787 		}
2788 	}
2789 	else
2790 	{
2791 		inter->sent++;
2792 		packets_sent++;
2793 		/*
2794 		 * He's not bad any more
2795 		 */
2796 		if (slot >= 0)
2797 		{
2798 			netsyslog(LOG_INFO, "Connection re-established to %s", stoa(dest));
2799 			switch (dest->ss_family) {
2800 			case AF_INET :
2801 				badaddrs[slot].port = 0;
2802 				break;
2803 #ifdef INCLUDE_IPV6_SUPPORT
2804 			case AF_INET6 :
2805 				badaddrs6[slot].port = 0;
2806 				break;
2807 #endif /* INCLUDE_IPV6_SUPPORT */
2808 			default:  /* don't care if not supported */
2809 				break;
2810 			}
2811 		}
2812 	}
2813 }
2814 
2815 #if !defined(HAVE_IO_COMPLETION_PORT)
2816 /*
2817  * fdbits - generate ascii representation of fd_set (FAU debug support)
2818  * HFDF format - highest fd first.
2819  */
2820 static char *
2821 fdbits(
2822 	int count,
2823 	fd_set *set
2824 	)
2825 {
2826 	static char buffer[256];
2827 	char * buf = buffer;
2828 
2829 	count = (count < 256) ? count : 255;
2830 
2831 	while (count >= 0)
2832 	{
2833 		*buf++ = FD_ISSET(count, set) ? '#' : '-';
2834 		count--;
2835 	}
2836 	*buf = '\0';
2837 
2838 	return buffer;
2839 }
2840 
2841 /*
2842  * Routine to read the refclock packets for a specific interface
2843  * Return the number of bytes read. That way we know if we should
2844  * read it again or go on to the next one if no bytes returned
2845  */
2846 static inline int
2847 read_refclock_packet(SOCKET fd, struct refclockio *rp, l_fp ts)
2848 {
2849 	int i;
2850 	int buflen;
2851 	register struct recvbuf *rb;
2852 
2853 	rb = get_free_recv_buffer();
2854 
2855 	if (rb == NULL)
2856 	{
2857 		/*
2858 		 * No buffer space available - just drop the packet
2859 		 */
2860 		char buf[RX_BUFF_SIZE];
2861 
2862 		buflen = read(fd, buf, sizeof buf);
2863 		packets_dropped++;
2864 		return (buflen);
2865 	}
2866 
2867 	i = (rp->datalen == 0
2868 	    || rp->datalen > sizeof(rb->recv_space))
2869 	    ? sizeof(rb->recv_space) : rp->datalen;
2870 	buflen = read(fd, (char *)&rb->recv_space, (unsigned)i);
2871 
2872 	if (buflen < 0)
2873 	{
2874 		if (errno != EINTR && errno != EAGAIN) {
2875 			netsyslog(LOG_ERR, "clock read fd %d: %m", fd);
2876 		}
2877 		freerecvbuf(rb);
2878 		return (buflen);
2879 	}
2880 
2881 	/*
2882 	 * Got one. Mark how and when it got here,
2883 	 * put it on the full list and do bookkeeping.
2884 	 */
2885 	rb->recv_length = buflen;
2886 	rb->recv_srcclock = rp->srcclock;
2887 	rb->dstadr = 0;
2888 	rb->fd = fd;
2889 	rb->recv_time = ts;
2890 	rb->receiver = rp->clock_recv;
2891 
2892 	if (rp->io_input)
2893 	{
2894 		/*
2895 		 * have direct input routine for refclocks
2896 		 */
2897 		if (rp->io_input(rb) == 0)
2898 		{
2899 			/*
2900 			 * data was consumed - nothing to pass up
2901 			 * into block input machine
2902 			 */
2903 			freerecvbuf(rb);
2904 			return (buflen);
2905 		}
2906 	}
2907 
2908 	add_full_recv_buffer(rb);
2909 
2910 	rp->recvcount++;
2911 	packets_received++;
2912 	return (buflen);
2913 }
2914 
2915 #ifdef HAVE_TIMESTAMP
2916 /*
2917  * extract timestamps from control message buffer
2918  */
2919 static l_fp
2920 	fetch_timestamp(struct recvbuf *rb, struct msghdr *msghdr, l_fp ts)
2921 {
2922 #ifdef USE_TIMESTAMP_CMSG
2923 	struct cmsghdr *cmsghdr;
2924 
2925 	cmsghdr = CMSG_FIRSTHDR(msghdr);
2926 	while (cmsghdr != NULL) {
2927 		switch (cmsghdr->cmsg_type)
2928 		{
2929 		case SCM_TIMESTAMP:
2930 		{
2931 			struct timeval *tvp = (struct timeval *)CMSG_DATA(cmsghdr);
2932 			double dtemp;
2933 			l_fp nts;
2934 			DPRINTF(4, ("fetch_timestamp: system network time stamp: %ld.%06ld\n", tvp->tv_sec, tvp->tv_usec));
2935 			nts.l_i = tvp->tv_sec + JAN_1970;
2936 			dtemp = tvp->tv_usec / 1e6;
2937 
2938  			/* fuzz lower bits not covered by precision */
2939  			if (sys_precision != 0)
2940  				dtemp += (ntp_random() / FRAC - .5) / (1 <<
2941  								       -sys_precision);
2942 
2943 			nts.l_uf = (u_int32)(dtemp*FRAC);
2944 #ifdef DEBUG_TIMING
2945 			{
2946 				l_fp dts = ts;
2947 				L_SUB(&dts, &nts);
2948 				collect_timing(rb, "input processing delay", 1, &dts);
2949 				DPRINTF(4, ("fetch_timestamp: timestamp delta: %s (incl. prec fuzz)\n", lfptoa(&dts, 9)));
2950 			}
2951 #endif
2952 			ts = nts;  /* network time stamp */
2953 			break;
2954 		}
2955 		default:
2956 			DPRINTF(4, ("fetch_timestamp: skipping control message 0x%x\n", cmsghdr->cmsg_type));
2957 			break;
2958 		}
2959 		cmsghdr = CMSG_NXTHDR(msghdr, cmsghdr);
2960 	}
2961 #endif
2962 	return ts;
2963 }
2964 #endif
2965 
2966 /*
2967  * Routine to read the network NTP packets for a specific interface
2968  * Return the number of bytes read. That way we know if we should
2969  * read it again or go on to the next one if no bytes returned
2970  */
2971 static inline int
2972 read_network_packet(SOCKET fd, struct interface *itf, l_fp ts)
2973 {
2974 	GETSOCKNAME_SOCKLEN_TYPE fromlen;
2975 	int buflen;
2976 	register struct recvbuf *rb;
2977 #ifdef HAVE_TIMESTAMP
2978 	struct msghdr msghdr;
2979 	struct iovec iovec;
2980 	char control[TIMESTAMP_CTLMSGBUF_SIZE];	/* pick up control messages */
2981 #endif
2982 
2983 	/*
2984 	 * Get a buffer and read the frame.  If we
2985 	 * haven't got a buffer, or this is received
2986 	 * on a disallowed socket, just dump the
2987 	 * packet.
2988 	 */
2989 
2990 	rb = get_free_recv_buffer();
2991 
2992 	if (rb == NULL || itf->ignore_packets == ISC_TRUE)
2993 	{
2994 		char buf[RX_BUFF_SIZE];
2995 		struct sockaddr_storage from;
2996 		if (rb != NULL)
2997 			freerecvbuf(rb);
2998 
2999 		fromlen = sizeof(from);
3000 		buflen = recvfrom(fd, buf, sizeof(buf), 0,
3001 				(struct sockaddr*)&from, &fromlen);
3002 		DPRINTF(4, ("%s on (%lu) fd=%d from %s\n",
3003 			(itf->ignore_packets == ISC_TRUE) ? "ignore" : "drop",
3004 			free_recvbuffs(), fd,
3005 			stoa(&from)));
3006 		if (itf->ignore_packets == ISC_TRUE)
3007 			packets_ignored++;
3008 		else
3009 			packets_dropped++;
3010 		return (buflen);
3011 	}
3012 
3013 	fromlen = sizeof(struct sockaddr_storage);
3014 
3015 #ifndef HAVE_TIMESTAMP
3016 	rb->recv_length = recvfrom(fd,
3017 			  (char *)&rb->recv_space,
3018 			   sizeof(rb->recv_space), 0,
3019 			   (struct sockaddr *)&rb->recv_srcadr,
3020 			   &fromlen);
3021 #else
3022 	iovec.iov_base        = (void *)&rb->recv_space;
3023 	iovec.iov_len         = sizeof(rb->recv_space);
3024 	msghdr.msg_name       = (void *)&rb->recv_srcadr;
3025 	msghdr.msg_namelen    = sizeof(rb->recv_srcadr);
3026 	msghdr.msg_iov        = &iovec;
3027 	msghdr.msg_iovlen     = 1;
3028 	msghdr.msg_control    = (void *)&control;
3029 	msghdr.msg_controllen = sizeof(control);
3030 	msghdr.msg_flags      = 0;
3031 	rb->recv_length       = recvmsg(fd, &msghdr, 0);
3032 #endif
3033 
3034 	buflen = rb->recv_length;
3035 
3036 	if (buflen == 0 || (buflen == -1 &&
3037 	    (errno==EWOULDBLOCK
3038 #ifdef EAGAIN
3039 	   || errno==EAGAIN
3040 #endif
3041 	 ))) {
3042 		freerecvbuf(rb);
3043 		return (buflen);
3044 	}
3045 	else if (buflen < 0)
3046 	{
3047 		netsyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
3048 		stoa(&rb->recv_srcadr), fd);
3049 		DPRINTF(5, ("read_network_packet: fd=%d dropped (bad recvfrom)\n", fd));
3050 		freerecvbuf(rb);
3051 		return (buflen);
3052 	}
3053 
3054 #ifdef DEBUG
3055 	if (debug > 2) {
3056 		if(rb->recv_srcadr.ss_family == AF_INET)
3057 			printf("read_network_packet: fd=%d length %d from %08lx %s\n",
3058 				fd, buflen,
3059 				(u_long)ntohl(((struct sockaddr_in*)&rb->recv_srcadr)->sin_addr.s_addr) &
3060 				0x00000000ffffffff,
3061 				stoa(&rb->recv_srcadr));
3062 		else
3063 			printf("read_network_packet: fd=%d length %d from %s\n",
3064 				fd, buflen,
3065 				stoa(&rb->recv_srcadr));
3066 	}
3067 #endif
3068 
3069 	/*
3070 	 * Got one.  Mark how and when it got here,
3071 	 * put it on the full list and do bookkeeping.
3072 	 */
3073 	rb->dstadr = itf;
3074 	rb->fd = fd;
3075 #ifdef HAVE_TIMESTAMP
3076 	ts = fetch_timestamp(rb, &msghdr, ts);  /* pick up a network time stamp if possible */
3077 #endif
3078 	rb->recv_time = ts;
3079 	rb->receiver = receive;
3080 
3081 	add_full_recv_buffer(rb);
3082 
3083 	itf->received++;
3084 	packets_received++;
3085 	return (buflen);
3086 }
3087 
3088 /*
3089  * input_handler - receive packets asynchronously
3090  */
3091 void
3092 input_handler(
3093 	l_fp *cts
3094 	)
3095 {
3096 
3097 	int buflen;
3098 	int n;
3099 	int doing;
3100 	SOCKET fd;
3101 	struct timeval tvzero;
3102 	l_fp ts;			/* Timestamp at BOselect() gob */
3103 #ifdef DEBUG_TIMING
3104 	l_fp ts_e;			/* Timestamp at EOselect() gob */
3105 #endif
3106 	fd_set fds;
3107 	int select_count = 0;
3108 	struct interface *interface;
3109 #if defined(HAS_ROUTING_SOCKET)
3110 	struct asyncio_reader *asyncio_reader;
3111 #endif
3112 
3113 	handler_calls++;
3114 
3115 	/*
3116 	 * If we have something to do, freeze a timestamp.
3117 	 * See below for the other cases (nothing (left) to do or error)
3118 	 */
3119 	ts = *cts;
3120 
3121 	/*
3122 	 * Do a poll to see who has data
3123 	 */
3124 
3125 	fds = activefds;
3126 	tvzero.tv_sec = tvzero.tv_usec = 0;
3127 
3128 	n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero);
3129 
3130 	/*
3131 	 * If there are no packets waiting just return
3132 	 */
3133 	if (n < 0)
3134 	{
3135 		int err = errno;
3136 		/*
3137 		 * extended FAU debugging output
3138 		 */
3139 		if (err != EINTR)
3140 		    netsyslog(LOG_ERR,
3141 			      "select(%d, %s, 0L, 0L, &0.0) error: %m",
3142 			      maxactivefd+1,
3143 			      fdbits(maxactivefd, &activefds));
3144 		if (err == EBADF) {
3145 			int j, b;
3146 			fds = activefds;
3147 			for (j = 0; j <= maxactivefd; j++)
3148 			    if ((FD_ISSET(j, &fds) && (read(j, &b, 0) == -1)))
3149 				netsyslog(LOG_ERR, "Bad file descriptor %d", j);
3150 		}
3151 		return;
3152 	}
3153 	else if (n == 0)
3154 		return;
3155 
3156 	++handler_pkts;
3157 
3158 #ifdef REFCLOCK
3159 	/*
3160 	 * Check out the reference clocks first, if any
3161 	 */
3162 
3163 	if (refio != NULL)
3164 	{
3165 		register struct refclockio *rp;
3166 
3167 		for (rp = refio; rp != NULL; rp = rp->next)
3168 		{
3169 			fd = rp->fd;
3170 
3171 			if (FD_ISSET(fd, &fds))
3172 			{
3173 				do {
3174 					++select_count;
3175 					buflen = read_refclock_packet(fd, rp, ts);
3176 				} while (buflen > 0);
3177 
3178 			} /* End if (FD_ISSET(fd, &fds)) */
3179 		} /* End for (rp = refio; rp != 0 && n > 0; rp = rp->next) */
3180 	} /* End if (refio != 0) */
3181 
3182 #endif /* REFCLOCK */
3183 
3184 	/*
3185 	 * Loop through the interfaces looking for data to read.
3186 	 */
3187 	for (interface = ISC_LIST_TAIL(inter_list);
3188 	     interface != NULL;
3189 	     interface = ISC_LIST_PREV(interface, link))
3190 	{
3191 		for (doing = 0; (doing < 2); doing++)
3192 		{
3193 			if (doing == 0)
3194 			{
3195 				fd = interface->fd;
3196 			}
3197 			else
3198 			{
3199 				if (!(interface->flags & INT_BCASTOPEN))
3200 				    break;
3201 				fd = interface->bfd;
3202 			}
3203 			if (fd < 0) continue;
3204 			if (FD_ISSET(fd, &fds))
3205 			{
3206 				do {
3207 					++select_count;
3208 					buflen = read_network_packet(fd, interface, ts);
3209 				} while (buflen > 0);
3210 			}
3211 		/* Check more interfaces */
3212 		}
3213 	}
3214 
3215 #ifdef HAS_ROUTING_SOCKET
3216 	/*
3217 	 * scan list of asyncio readers - currently only used for routing sockets
3218 	 */
3219 	asyncio_reader = ISC_LIST_TAIL(asyncio_reader_list);
3220 
3221 	while (asyncio_reader != NULL)
3222 	{
3223 	        struct asyncio_reader *next = ISC_LIST_PREV(asyncio_reader, link);
3224 		if (FD_ISSET(asyncio_reader->fd, &fds)) {
3225 			++select_count;
3226 			asyncio_reader->receiver(asyncio_reader);
3227 		}
3228 		asyncio_reader = next;
3229 	}
3230 #endif /* HAS_ROUTING_SOCKET */
3231 
3232 	/*
3233 	 * Done everything from that select.
3234 	 */
3235 
3236 	/*
3237 	 * If nothing to do, just return.
3238 	 * If an error occurred, complain and return.
3239 	 */
3240 	if (select_count == 0) /* We really had nothing to do */
3241 	{
3242 #ifdef DEBUG
3243 		if (debug)
3244 		    netsyslog(LOG_DEBUG, "input_handler: select() returned 0");
3245 #endif
3246 		return;
3247 	}
3248 		/* We've done our work */
3249 #ifdef DEBUG_TIMING
3250 	get_systime(&ts_e);
3251 	/*
3252 	 * (ts_e - ts) is the amount of time we spent
3253 	 * processing this gob of file descriptors.  Log
3254 	 * it.
3255 	 */
3256 	L_SUB(&ts_e, &ts);
3257 	collect_timing(NULL, "input handler", 1, &ts_e);
3258 	if (debug > 3)
3259 	    netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
3260 #endif
3261 	/* just bail. */
3262 	return;
3263 }
3264 
3265 #endif
3266 
3267 /*
3268  * findinterface - find local interface corresponding to address
3269  */
3270 struct interface *
3271 findinterface(
3272 	struct sockaddr_storage *addr
3273 	)
3274 {
3275 	struct interface *interface;
3276 
3277 	interface = findlocalinterface(addr, INT_WILDCARD);
3278 
3279 	if (interface == NULL)
3280 	{
3281 		DPRINTF(4, ("Found no interface for address %s - returning wildcard\n",
3282 			    stoa(addr)));
3283 
3284 		return (ANY_INTERFACE_CHOOSE(addr));
3285 	}
3286 	else
3287 	{
3288 		DPRINTF(4, ("Found interface #%d %s for address %s\n",
3289 			    interface->ifnum, interface->name, stoa(addr)));
3290 
3291 		return (interface);
3292 	}
3293 }
3294 
3295 /*
3296  * findlocalinterface - find local interface index corresponding to address
3297  *
3298  * This code attempts to find the local sending address for an outgoing
3299  * address by connecting a new socket to destinationaddress:NTP_PORT
3300  * and reading the sockname of the resulting connect.
3301  * the complicated sequence simulates the routing table lookup
3302  * for to first hop without duplicating any of the routing logic into
3303  * ntpd. preferably we would have used an API call - but its not there -
3304  * so this is the best we can do here short of duplicating to entire routing
3305  * logic in ntpd which would be a silly and really unportable thing to do.
3306  *
3307  */
3308 static struct interface *
3309 findlocalinterface(
3310 	struct sockaddr_storage *addr,
3311 	int flags
3312 	)
3313 {
3314 	SOCKET s;
3315 	int rtn;
3316 	struct sockaddr_storage saddr;
3317 	GETSOCKNAME_SOCKLEN_TYPE saddrlen = SOCKLEN(addr);
3318 	struct interface *iface;
3319 
3320 	DPRINTF(4, ("Finding interface for addr %s in list of addresses\n",
3321 		    stoa(addr)));
3322 
3323 	memset(&saddr, 0, sizeof(saddr));
3324 	saddr.ss_family = addr->ss_family;
3325 	if(addr->ss_family == AF_INET) {
3326 		memcpy(&((struct sockaddr_in*)&saddr)->sin_addr, &((struct sockaddr_in*)addr)->sin_addr, sizeof(struct in_addr));
3327 		((struct sockaddr_in*)&saddr)->sin_port = htons(NTP_PORT);
3328 	}
3329 #ifdef INCLUDE_IPV6_SUPPORT
3330 	else if(addr->ss_family == AF_INET6) {
3331  		memcpy(&((struct sockaddr_in6*)&saddr)->sin6_addr, &((struct sockaddr_in6*)addr)->sin6_addr, sizeof(struct in6_addr));
3332 		((struct sockaddr_in6*)&saddr)->sin6_port = htons(NTP_PORT);
3333 # ifdef ISC_PLATFORM_HAVESCOPEID
3334 		((struct sockaddr_in6*)&saddr)->sin6_scope_id = ((struct sockaddr_in6*)addr)->sin6_scope_id;
3335 # endif
3336 	}
3337 #endif
3338 
3339 	s = socket(addr->ss_family, SOCK_DGRAM, 0);
3340 	if (s == INVALID_SOCKET)
3341 		return NULL;
3342 
3343 	rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr));
3344 #ifndef SYS_WINNT
3345 	if (rtn < 0)
3346 #else
3347 	if (rtn == SOCKET_ERROR)
3348 #endif
3349 	{
3350 		closesocket(s);
3351 		return NULL;
3352 	}
3353 
3354 	rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen);
3355 	closesocket(s);
3356 #ifndef SYS_WINNT
3357 	if (rtn < 0)
3358 #else
3359 	if (rtn == SOCKET_ERROR)
3360 #endif
3361 		return NULL;
3362 
3363 	DPRINTF(4, ("findlocalinterface: kernel maps %s to %s\n", stoa(addr), stoa(&saddr)));
3364 
3365 	iface = getinterface(&saddr, flags);
3366 
3367 	/* Don't both with ignore interfaces */
3368 	if (iface != NULL && iface->ignore_packets == ISC_TRUE)
3369 	{
3370 		return NULL;
3371 	}
3372 	else
3373 	{
3374 		return iface;
3375 	}
3376 }
3377 
3378 /*
3379  * fetch an interface structure the matches the
3380  * address is has the given flags not set
3381  */
3382 static struct interface *
3383 getinterface(struct sockaddr_storage *addr, int flags)
3384 {
3385 	struct interface *interface = find_addr_in_list(addr);
3386 
3387 	if (interface != NULL && interface->flags & flags)
3388 	{
3389 		return NULL;
3390 	}
3391 	else
3392 	{
3393 		return interface;
3394 	}
3395 }
3396 
3397 /*
3398  * findlocalcastinterface - find local *cast interface index corresponding to address
3399  * depending on the flags passed
3400  */
3401 static struct interface *
3402 findlocalcastinterface(
3403 	struct sockaddr_storage *addr, int flags
3404 	)
3405 {
3406 	struct interface *interface;
3407 	struct interface *nif = NULL;
3408 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
3409 	isc_boolean_t want_linklocal;
3410 #endif
3411 
3412 	/*
3413 	 * see how kernel maps the mcast address
3414 	 */
3415         nif = findlocalinterface(addr, 0);
3416 
3417 	if (nif) {
3418 		DPRINTF(2, ("findlocalcastinterface: kernel recommends interface #%d %s\n", nif->ifnum, nif->name));
3419 		return nif;
3420 	}
3421 
3422 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
3423 	want_linklocal = ISC_FALSE;
3424 	if (addr_ismulticast(addr) && flags == INT_MULTICAST)
3425 	{
3426 		if (IN6_IS_ADDR_MC_LINKLOCAL(&((struct sockaddr_in6*)addr)->sin6_addr))
3427 		{
3428 			want_linklocal = ISC_TRUE;
3429 		}
3430 		else if (IN6_IS_ADDR_MC_SITELOCAL(&((struct sockaddr_in6*)addr)->sin6_addr))
3431 		{
3432 			want_linklocal = ISC_TRUE;
3433 		}
3434 	}
3435 #endif
3436 
3437 	for (interface = ISC_LIST_HEAD(inter_list);
3438 	     interface != NULL;
3439 	     interface = ISC_LIST_NEXT(interface, link))
3440 	  {
3441 		/* use only allowed addresses */
3442 		if (interface->ignore_packets == ISC_TRUE)
3443 			continue;
3444 
3445 		/* Skip the loopback and wildcard addresses */
3446 		if (interface->flags & (INT_LOOPBACK|INT_WILDCARD))
3447 			continue;
3448 
3449 		/* Skip if different family */
3450 		if(interface->sin.ss_family != addr->ss_family)
3451 			continue;
3452 
3453 		/* Is this it one of these based on flags? */
3454 		if (!(interface->flags & flags))
3455 			continue;
3456 
3457 		/* for IPv6 multicast check the address for linklocal */
3458 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
3459 		if (flags == INT_MULTICAST && interface->sin.ss_family == AF_INET6 &&
3460 		   (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&interface->sin)->sin6_addr))
3461 		   && want_linklocal == ISC_TRUE)
3462 		{
3463 			nif = interface;
3464 			break;
3465 		}
3466 		/* If we want a linklocal address and this isn't it, skip */\
3467 		if (want_linklocal == ISC_TRUE)
3468 			continue;
3469 #endif
3470 		/* Otherwise just look for the flag */
3471 		if((interface->flags & flags))
3472 		{
3473 			nif = interface;
3474 			break;
3475 		}
3476 	}
3477 #ifdef DEBUG
3478 	if (debug > 2)
3479 	{
3480 		if (nif)
3481 			printf("findlocalcastinterface: found interface #%d %s\n", nif->ifnum, nif->name);
3482 		else
3483 			printf("findlocalcastinterface: no interface found for %s flags 0x%x\n", stoa(addr), flags);
3484 	}
3485 #endif
3486 	return (nif);
3487 }
3488 
3489 /*
3490  * findbcastinter - find broadcast interface corresponding to address
3491  */
3492 struct interface *
3493 findbcastinter(
3494 	struct sockaddr_storage *addr
3495 	)
3496 {
3497 #if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
3498         struct interface *interface;
3499 
3500 
3501 	DPRINTF(4, ("Finding broadcast/multicast interface for addr %s in list of addresses\n",
3502 		    stoa(addr)));
3503 
3504 	interface = findlocalinterface(addr, INT_LOOPBACK|INT_WILDCARD);
3505 
3506 	if (interface != NULL)
3507 	{
3508 		DPRINTF(4, ("Found bcast-/mcast- interface index #%d %s\n", interface->ifnum, interface->name));
3509 		return interface;
3510 	}
3511 
3512 	/* plan B - try to find something reasonable in our lists in case kernel lookup doesn't help */
3513 
3514 	for (interface = ISC_LIST_HEAD(inter_list);
3515 	     interface != NULL;
3516 	     interface = ISC_LIST_NEXT(interface, link))
3517 	{
3518 	        if (interface->flags & INT_WILDCARD)
3519 		        continue;
3520 
3521 		/* Don't bother with ignored interfaces */
3522 		if (interface->ignore_packets == ISC_TRUE)
3523 			continue;
3524 
3525 		/*
3526 		 * First look if this is the correct family
3527 		 */
3528 		if(interface->sin.ss_family != addr->ss_family)
3529 	  		continue;
3530 
3531 		/* Skip the loopback addresses */
3532 		if (interface->flags & INT_LOOPBACK)
3533 			continue;
3534 
3535 		/*
3536 		 * If we are looking to match a multicast address grab it.
3537 		 */
3538 		if (addr_ismulticast(addr) == ISC_TRUE && interface->flags & INT_MULTICAST)
3539 		{
3540 #ifdef INCLUDE_IPV6_SUPPORT
3541 			if(addr->ss_family == AF_INET6) {
3542 				/* Only use link-local address for link-scope mcast */
3543 				if(IN6_IS_ADDR_MC_LINKLOCAL(&((struct sockaddr_in6*)addr)->sin6_addr) &&
3544 				  !IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&interface->sin)->sin6_addr)) {
3545 					continue;
3546 				}
3547 			}
3548 #endif
3549 			break;
3550 		}
3551 
3552 		/*
3553 		 * We match only those interfaces marked as
3554 		 * broadcastable and either the explicit broadcast
3555 		 * address or the network portion of the IP address.
3556 		 * Sloppy.
3557 		 */
3558 		if(addr->ss_family == AF_INET) {
3559 			if (SOCKCMP(&interface->bcast, addr)) {
3560 				break;
3561 			}
3562 			if ((NSRCADR(&interface->sin) &
3563 			     NSRCADR(&interface->mask)) == (NSRCADR(addr) &
3564 							    NSRCADR(&interface->mask)))
3565 				break;
3566 		}
3567 #ifdef INCLUDE_IPV6_SUPPORT
3568 		else if(addr->ss_family == AF_INET6) {
3569 			if (SOCKCMP(&interface->bcast, addr)) {
3570 				break;
3571 			}
3572 			if (SOCKCMP(netof(&interface->sin), netof(addr))) {
3573 				break;
3574 			}
3575 		}
3576 #endif
3577 	}
3578 #endif /* SIOCGIFCONF */
3579 	if (interface == NULL) {
3580 		DPRINTF(4, ("No bcast interface found for %s\n", stoa(addr)));
3581 		return ANY_INTERFACE_CHOOSE(addr);
3582 	} else {
3583 		DPRINTF(4, ("Found bcast-/mcast- interface index #%d %s\n", interface->ifnum, interface->name));
3584 		return interface;
3585 	}
3586 }
3587 
3588 
3589 /*
3590  * io_clr_stats - clear I/O module statistics
3591  */
3592 void
3593 io_clr_stats(void)
3594 {
3595 	packets_dropped = 0;
3596 	packets_ignored = 0;
3597 	packets_received = 0;
3598 	packets_sent = 0;
3599 	packets_notsent = 0;
3600 
3601 	handler_calls = 0;
3602 	handler_pkts = 0;
3603 	io_timereset = current_time;
3604 }
3605 
3606 
3607 #ifdef REFCLOCK
3608 /*
3609  * io_addclock - add a reference clock to the list and arrange that we
3610  *				 get SIGIO interrupts from it.
3611  */
3612 int
3613 io_addclock(
3614 	struct refclockio *rio
3615 	)
3616 {
3617 	BLOCKIO();
3618 	/*
3619 	 * Stuff the I/O structure in the list and mark the descriptor
3620 	 * in use.	There is a harmless (I hope) race condition here.
3621 	 */
3622 	rio->next = refio;
3623 
3624 # ifdef HAVE_SIGNALED_IO
3625 	if (init_clock_sig(rio))
3626 	{
3627 		UNBLOCKIO();
3628 		return 0;
3629 	}
3630 # elif defined(HAVE_IO_COMPLETION_PORT)
3631 	if (io_completion_port_add_clock_io(rio))
3632 	{
3633 		UNBLOCKIO();
3634 		return 0;
3635 	}
3636 # endif
3637 
3638 	/*
3639 	 * enqueue
3640 	 */
3641 	refio = rio;
3642 
3643         /*
3644 	 * register fd
3645 	 */
3646 	add_fd_to_list(rio->fd, FD_TYPE_FILE);
3647 
3648 	UNBLOCKIO();
3649 	return 1;
3650 }
3651 
3652 /*
3653  * io_closeclock - close the clock in the I/O structure given
3654  */
3655 void
3656 io_closeclock(
3657 	struct refclockio *rio
3658 	)
3659 {
3660 	BLOCKIO();
3661 	/*
3662 	 * Remove structure from the list
3663 	 */
3664 	if (refio == rio)
3665 	{
3666 		refio = rio->next;
3667 	}
3668 	else
3669 	{
3670 		register struct refclockio *rp;
3671 
3672 		for (rp = refio; rp != NULL; rp = rp->next)
3673 		    if (rp->next == rio)
3674 		    {
3675 			    rp->next = rio->next;
3676 			    break;
3677 		    }
3678 
3679 		if (rp == NULL) {
3680 			UNBLOCKIO();
3681 			return;
3682 		}
3683 	}
3684 
3685 	/*
3686 	 * Close the descriptor.
3687 	 */
3688 	close_and_delete_fd_from_list(rio->fd);
3689 	UNBLOCKIO();
3690 }
3691 #endif	/* REFCLOCK */
3692 
3693 /*
3694  * On NT a SOCKET is an unsigned int so we cannot possibly keep it in
3695  * an array. So we use one of the ISC_LIST functions to hold the
3696  * socket value and use that when we want to enumerate it.
3697  */
3698 void
3699 kill_asyncio(int startfd)
3700 {
3701 	vsock_t *lsock;
3702 	vsock_t *next;
3703 
3704 	BLOCKIO();
3705 
3706 	lsock = ISC_LIST_HEAD(fd_list);
3707 	while (lsock != NULL) {
3708 		/*
3709 		 * careful here - list is being dismantled while
3710 		 * we scan it - setting next here insures that
3711 		 * we are able to correctly scan the list
3712 		 */
3713 		next = ISC_LIST_NEXT(lsock, link);
3714 		/*
3715 		 * will remove socket from list
3716 		 */
3717 		close_and_delete_fd_from_list(lsock->fd);
3718 		lsock = next;
3719 	}
3720 
3721 	UNBLOCKIO();
3722 }
3723 
3724 /*
3725  * Add and delete functions for the list of open sockets
3726  */
3727 static void
3728 add_fd_to_list(SOCKET fd, enum desc_type type) {
3729 	vsock_t *lsock = (vsock_t *)emalloc(sizeof(vsock_t));
3730 	lsock->fd = fd;
3731 	lsock->type = type;
3732 
3733 	ISC_LIST_APPEND(fd_list, lsock, link);
3734 	/*
3735 	 * I/O Completion Ports don't care about the select and FD_SET
3736 	 */
3737 #ifndef HAVE_IO_COMPLETION_PORT
3738 	if (fd < 0 || fd >= FD_SETSIZE) {
3739 		msyslog(LOG_ERR, "Too many sockets in use, FD_SETSIZE %d exceeded",
3740 			FD_SETSIZE);
3741 		exit(1);
3742 	}
3743 	/*
3744 	 * keep activefds in sync
3745 	 */
3746 	if (fd > maxactivefd)
3747 	    maxactivefd = fd;
3748 	FD_SET( (u_int)fd, &activefds);
3749 #endif
3750 }
3751 
3752 static void
3753 close_and_delete_fd_from_list(SOCKET fd) {
3754 
3755 	vsock_t *next;
3756 	vsock_t *lsock = ISC_LIST_HEAD(fd_list);
3757 
3758 	while(lsock != NULL) {
3759 		next = ISC_LIST_NEXT(lsock, link);
3760 		if(lsock->fd == fd) {
3761 			ISC_LIST_DEQUEUE_TYPE(fd_list, lsock, link, vsock_t);
3762 
3763 			switch (lsock->type) {
3764 			case FD_TYPE_SOCKET:
3765 #ifdef SYS_WINNT
3766 				closesocket(lsock->fd);
3767 				break;
3768 #endif
3769 			case FD_TYPE_FILE:
3770 				(void) close(lsock->fd);
3771 				break;
3772 			default:
3773 				msyslog(LOG_ERR, "internal error - illegal descriptor type %d - EXITING", (int)lsock->type);
3774 				exit(1);
3775 			}
3776 
3777 			free(lsock);
3778 			/*
3779 			 * I/O Completion Ports don't care about select and fd_set
3780 			 */
3781 #ifndef HAVE_IO_COMPLETION_PORT
3782 			/*
3783 			 * remove from activefds
3784 			 */
3785 			FD_CLR( (u_int) fd, &activefds);
3786 
3787 			if (fd == maxactivefd) {
3788 				int i, newmax = 0;
3789 				for (i = 0; i < maxactivefd; i++)
3790 					if (FD_ISSET(i, &activefds))
3791 						newmax = i;
3792 				maxactivefd = newmax;
3793 			}
3794 #endif
3795 			break;
3796 		}
3797 		lsock = next;
3798 	}
3799 }
3800 
3801 static void
3802 add_addr_to_list(struct sockaddr_storage *addr, struct interface *interface){
3803 #ifdef DEBUG
3804 	if (find_addr_in_list(addr) == NULL) {
3805 #endif
3806 		/* not there yet - add to list */
3807 		remaddr_t *laddr = (remaddr_t *)emalloc(sizeof(remaddr_t));
3808 		memcpy(&laddr->addr, addr, sizeof(struct sockaddr_storage));
3809 		laddr->interface = interface;
3810 
3811 		ISC_LIST_APPEND(remoteaddr_list, laddr, link);
3812 
3813 		DPRINTF(4, ("Added addr %s to list of addresses\n",
3814 			    stoa(addr)));
3815 #ifdef DEBUG
3816 	} else {
3817 		DPRINTF(4, ("WARNING: Attempt to add duplicate addr %s to address list\n",
3818 			    stoa(addr)));
3819 	}
3820 #endif
3821 }
3822 
3823 static void
3824 delete_addr_from_list(struct sockaddr_storage *addr) {
3825 
3826 	remaddr_t *next;
3827 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
3828 
3829 	while(laddr != NULL) {
3830 		next = ISC_LIST_NEXT(laddr, link);
3831 		if(SOCKCMP(&laddr->addr, addr)) {
3832 			ISC_LIST_DEQUEUE_TYPE(remoteaddr_list, laddr, link, remaddr_t);
3833 			DPRINTF(4, ("Deleted addr %s from list of addresses\n",
3834 				    stoa(addr)));
3835 			free(laddr);
3836 			break;
3837 		}
3838 		laddr = next;
3839 	}
3840 }
3841 
3842 static void
3843 delete_interface_from_list(struct interface *iface) {
3844 	remaddr_t *next;
3845 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
3846 
3847 	while(laddr != NULL) {
3848 		next = ISC_LIST_NEXT(laddr, link);
3849 		if (laddr->interface == iface) {
3850 			ISC_LIST_DEQUEUE_TYPE(remoteaddr_list, laddr, link, remaddr_t);
3851 			DPRINTF(4, ("Deleted addr %s for interface #%d %s from list of addresses\n",
3852 				    stoa(&laddr->addr), iface->ifnum, iface->name));
3853 			free(laddr);
3854 		}
3855 		laddr = next;
3856 	}
3857 }
3858 
3859 static struct interface *
3860 find_addr_in_list(struct sockaddr_storage *addr) {
3861 
3862 	remaddr_t *next;
3863 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
3864 	DPRINTF(4, ("Searching for addr %s in list of addresses - ",
3865 		    stoa(addr)));
3866 
3867 	while(laddr != NULL) {
3868 		next = ISC_LIST_NEXT(laddr, link);
3869 		if(SOCKCMP(&laddr->addr, addr)) {
3870 			DPRINTF(4, ("FOUND\n"));
3871 			return laddr->interface;
3872 		}
3873 		else
3874 			laddr = next;
3875 	}
3876 	DPRINTF(4, ("NOT FOUND\n"));
3877 	return NULL; /* Not found */
3878 }
3879 
3880 /*
3881  * Find the given address with the associated flag in the list
3882  */
3883 static struct interface *
3884 find_flagged_addr_in_list(struct sockaddr_storage *addr, int flag) {
3885 
3886 	remaddr_t *next;
3887 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
3888 	DPRINTF(4, ("Finding addr %s in list of addresses\n",
3889 		    stoa(addr)));
3890 
3891 	while(laddr != NULL) {
3892 		next = ISC_LIST_NEXT(laddr, link);
3893 		if(SOCKCMP(&laddr->addr, addr) && (laddr->interface->flags & flag)) {
3894 			return laddr->interface;
3895 			break;
3896 		}
3897 		else
3898 			laddr = next;
3899 	}
3900 	return NULL; /* Not found */
3901 }
3902 
3903 #ifdef HAS_ROUTING_SOCKET
3904 #include <net/route.h>
3905 
3906 #ifndef UPDATE_GRACE
3907 #define UPDATE_GRACE	2	/* wait UPDATE_GRACE seconds before scanning */
3908 #endif
3909 
3910 static void
3911 process_routing_msgs(struct asyncio_reader *reader)
3912 {
3913 	char buffer[5120];
3914 	char *p = buffer;
3915 
3916 	int cnt;
3917 
3918 	if (disable_dynamic_updates) {
3919 		/*
3920 		 * discard ourselves if we are not need any more
3921 		 * usually happens when running unprivileged
3922 		 */
3923 		remove_asyncio_reader(reader);
3924 		delete_asyncio_reader(reader);
3925 		return;
3926 	}
3927 
3928 	cnt = read(reader->fd, buffer, sizeof(buffer));
3929 
3930 	if (cnt < 0) {
3931 		msyslog(LOG_ERR, "i/o error on routing socket %m - disabling");
3932 		remove_asyncio_reader(reader);
3933 		delete_asyncio_reader(reader);
3934 		return;
3935 	}
3936 
3937 	/*
3938 	 * process routing message
3939 	 */
3940 	while ((p + sizeof(struct rt_msghdr)) <= (buffer + cnt))
3941 	{
3942 		struct rt_msghdr *rtm;
3943 
3944 		rtm = (struct rt_msghdr *)p;
3945 		if (rtm->rtm_version != RTM_VERSION) {
3946 			msyslog(LOG_ERR, "version mismatch on routing socket %m - disabling");
3947 			remove_asyncio_reader(reader);
3948 			delete_asyncio_reader(reader);
3949 			return;
3950 		}
3951 
3952 		switch (rtm->rtm_type) {
3953 #ifdef RTM_NEWADDR
3954 		case RTM_NEWADDR:
3955 #endif
3956 #ifdef RTM_DELADDR
3957 		case RTM_DELADDR:
3958 #endif
3959 #ifdef RTM_ADD
3960 		case RTM_ADD:
3961 #endif
3962 #ifdef RTM_DELETE
3963 		case RTM_DELETE:
3964 #endif
3965 #ifdef RTM_REDIRECT
3966 		case RTM_REDIRECT:
3967 #endif
3968 #ifdef RTM_CHANGE
3969 		case RTM_CHANGE:
3970 #endif
3971 #ifdef RTM_LOSING
3972 		case RTM_LOSING:
3973 #endif
3974 #ifdef RTM_IFINFO
3975 		case RTM_IFINFO:
3976 #endif
3977 #ifdef RTM_IFANNOUNCE
3978 		case RTM_IFANNOUNCE:
3979 #endif
3980 			/*
3981 			 * we are keen on new and deleted addresses and if an interface goes up and down or routing changes
3982 			 */
3983 			DPRINTF(3, ("routing message op = %d: scheduling interface update\n", rtm->rtm_type));
3984 			timer_interfacetimeout(current_time + UPDATE_GRACE);
3985 			break;
3986 		default:
3987 			/*
3988 			 * the rest doesn't bother us.
3989 			 */
3990 			DPRINTF(4, ("routing message op = %d: ignored\n", rtm->rtm_type));
3991 			break;
3992 		}
3993 		p += rtm->rtm_msglen;
3994 	}
3995 }
3996 
3997 /*
3998  * set up routing notifications
3999  */
4000 static void
4001 init_async_notifications()
4002 {
4003 	struct asyncio_reader *reader;
4004 	int fd = socket(PF_ROUTE, SOCK_RAW, 0);
4005 
4006 	if (fd >= 0) {
4007 		fd = move_fd(fd);
4008 		init_nonblocking_io(fd);
4009 #if defined(HAVE_SIGNALED_IO)
4010 		init_socket_sig(fd);
4011 #endif /* HAVE_SIGNALED_IO */
4012 
4013 		reader = new_asyncio_reader();
4014 
4015 		reader->fd = fd;
4016 		reader->receiver = process_routing_msgs;
4017 
4018 		add_asyncio_reader(reader, FD_TYPE_SOCKET);
4019 		msyslog(LOG_INFO, "Listening on routing socket on fd #%d for interface updates", fd);
4020 	} else {
4021 		msyslog(LOG_ERR, "unable to open routing socket (%m) - using polled interface update");
4022 	}
4023 }
4024 #else
4025 static void
4026 init_async_notifications()
4027 {
4028 }
4029 #endif
4030