xref: /freebsd/contrib/ntp/ntpd/ntp_io.c (revision 7aa383846770374466b1dcb2cefd71bde9acf463)
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 	/*u_char*/ TYPEOF_IP_MULTICAST_LOOP off = 0;
1757 
1758 	switch (maddr->ss_family)
1759 	{
1760 	case AF_INET:
1761 		if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_IF,
1762 		   (char *)&(((struct sockaddr_in*)&iface->sin)->sin_addr.s_addr),
1763 		    sizeof(struct in_addr)) == -1) {
1764 			netsyslog(LOG_ERR,
1765 			"setsockopt IP_MULTICAST_IF failure: %m on socket %d, addr %s for multicast address %s",
1766 			iface->fd, stoa(&iface->sin), stoa(maddr));
1767 			return;
1768 		}
1769 #ifdef IP_MULTICAST_LOOP
1770 		/*
1771 		 * Don't send back to itself, but allow it to fail to set it
1772 		 */
1773 		if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_LOOP,
1774 		       SETSOCKOPT_ARG_CAST &off, sizeof(off)) == -1) {
1775 			netsyslog(LOG_ERR,
1776 			"setsockopt IP_MULTICAST_LOOP failure: %m on socket %d, addr %s for multicast address %s",
1777 			iface->fd, stoa(&iface->sin), stoa(maddr));
1778 		}
1779 #endif
1780 	DPRINTF(4, ("Added IPv4 multicast interface on socket %d, addr %s for multicast address %s\n",
1781 			    iface->fd, stoa(&iface->sin),
1782 			    stoa(maddr)));
1783 		break;
1784 
1785 	case AF_INET6:
1786 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1787 		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
1788 		    (char *) &iface->scopeid, sizeof(iface->scopeid)) == -1) {
1789 			netsyslog(LOG_ERR,
1790 			"setsockopt IPV6_MULTICAST_IF failure: %m on socket %d, addr %s, scope %d for multicast address %s",
1791 			iface->fd, stoa(&iface->sin), iface->scopeid,
1792 			stoa(maddr));
1793 			return;
1794 		}
1795 #ifdef IPV6_MULTICAST_LOOP
1796 		/*
1797 		 * Don't send back to itself, but allow it to fail to set it
1798 		 */
1799 		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1800 		       (char *) &off, sizeof(off)) == -1) {
1801 			netsyslog(LOG_ERR,
1802 			"setsockopt IP_MULTICAST_LOOP failure: %m on socket %d, addr %s for multicast address %s",
1803 			iface->fd, stoa(&iface->sin), stoa(maddr));
1804 		}
1805 #endif
1806 		DPRINTF(4, ("Added IPv6 multicast interface on socket %d, addr %s, scope %d for multicast address %s\n",
1807 			    iface->fd,  stoa(&iface->sin), iface->scopeid,
1808 			    stoa(maddr)));
1809 		break;
1810 #else
1811 		return;
1812 #endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */
1813 	}
1814 	return;
1815 #endif
1816 }
1817 
1818 /*
1819  * Add a multicast address to a given socket
1820  * The socket is in the inter_list all we need to do is enable
1821  * multicasting. It is not this function's job to select the socket
1822  */
1823 static isc_boolean_t
1824 socket_multicast_enable(struct interface *iface, int lscope, struct sockaddr_storage *maddr)
1825 {
1826 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1827 	struct ipv6_mreq mreq6;
1828 	struct in6_addr iaddr6;
1829 #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
1830 
1831 	struct ip_mreq mreq;
1832 
1833 	if (find_addr_in_list(maddr)) {
1834 		DPRINTF(4, ("socket_multicast_enable(%s): already enabled\n", stoa(maddr)));
1835 		return ISC_TRUE;
1836 	}
1837 
1838 	switch (maddr->ss_family)
1839 	{
1840 	case AF_INET:
1841 		memset((char *)&mreq, 0, sizeof(mreq));
1842 		mreq.imr_multiaddr = (((struct sockaddr_in*)maddr)->sin_addr);
1843 		mreq.imr_interface.s_addr = htonl(INADDR_ANY);
1844 		if (setsockopt(iface->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1845 			(char *)&mreq, sizeof(mreq)) == -1) {
1846 			netsyslog(LOG_ERR,
1847 			"setsockopt IP_ADD_MEMBERSHIP failure: %m on socket %d, addr %s for %x / %x (%s)",
1848 			iface->fd, stoa(&iface->sin),
1849 			mreq.imr_multiaddr.s_addr,
1850 			mreq.imr_interface.s_addr, stoa(maddr));
1851 			return ISC_FALSE;
1852 		}
1853 		DPRINTF(4, ("Added IPv4 multicast membership on socket %d, addr %s for %x / %x (%s)\n",
1854 			    iface->fd, stoa(&iface->sin),
1855 			    mreq.imr_multiaddr.s_addr,
1856 			    mreq.imr_interface.s_addr, stoa(maddr)));
1857 		break;
1858 
1859 	case AF_INET6:
1860 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1861 		/*
1862 		 * Enable reception of multicast packets
1863 		 * If the address is link-local we can get the interface index
1864 		 * from the scope id. Don't do this for other types of multicast
1865 		 * addresses. For now let the kernel figure it out.
1866 		 */
1867 		memset((char *)&mreq6, 0, sizeof(mreq6));
1868 		iaddr6 = ((struct sockaddr_in6*)maddr)->sin6_addr;
1869 		mreq6.ipv6mr_multiaddr = iaddr6;
1870 		mreq6.ipv6mr_interface = lscope;
1871 
1872 		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1873 			(char *)&mreq6, sizeof(mreq6)) == -1) {
1874 			netsyslog(LOG_ERR,
1875 			 "setsockopt IPV6_JOIN_GROUP failure: %m on socket %d, addr %s for interface %d(%s)",
1876 			iface->fd, stoa(&iface->sin),
1877 			mreq6.ipv6mr_interface, stoa(maddr));
1878 			return ISC_FALSE;
1879 		}
1880 		DPRINTF(4, ("Added IPv6 multicast group on socket %d, addr %s for interface %d(%s)\n",
1881 			    iface->fd, stoa(&iface->sin),
1882 			    mreq6.ipv6mr_interface, stoa(maddr)));
1883 		break;
1884 #else
1885 		return ISC_FALSE;
1886 #endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */
1887 	}
1888 	iface->flags |= INT_MCASTOPEN;
1889 	iface->num_mcast++;
1890 	add_addr_to_list(maddr, iface);
1891 	return ISC_TRUE;
1892 }
1893 
1894 /*
1895  * Remove a multicast address from a given socket
1896  * The socket is in the inter_list all we need to do is disable
1897  * multicasting. It is not this function's job to select the socket
1898  */
1899 static isc_boolean_t
1900 socket_multicast_disable(struct interface *iface, struct sockaddr_storage *maddr)
1901 {
1902 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1903 	struct ipv6_mreq mreq6;
1904 	struct in6_addr iaddr6;
1905 #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
1906 
1907 	struct ip_mreq mreq;
1908 	memset((char *)&mreq, 0, sizeof(mreq));
1909 
1910 	if (find_addr_in_list(maddr) == NULL) {
1911 		DPRINTF(4, ("socket_multicast_disable(%s): not enabled\n", stoa(maddr)));
1912 		return ISC_TRUE;
1913 	}
1914 
1915 	switch (maddr->ss_family)
1916 	{
1917 	case AF_INET:
1918 		mreq.imr_multiaddr = (((struct sockaddr_in*)&maddr)->sin_addr);
1919 		mreq.imr_interface.s_addr = ((struct sockaddr_in*)&iface->sin)->sin_addr.s_addr;
1920 		if (setsockopt(iface->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
1921 			(char *)&mreq, sizeof(mreq)) == -1) {
1922 			netsyslog(LOG_ERR,
1923 			"setsockopt IP_DROP_MEMBERSHIP failure: %m on socket %d, addr %s for %x / %x (%s)",
1924 			iface->fd, stoa(&iface->sin),
1925 			mreq.imr_multiaddr.s_addr,
1926 			mreq.imr_interface.s_addr, stoa(maddr));
1927 			return ISC_FALSE;
1928 		}
1929 		break;
1930 	case AF_INET6:
1931 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1932 		/*
1933 		 * Disable reception of multicast packets
1934 		 * If the address is link-local we can get the interface index
1935 		 * from the scope id. Don't do this for other types of multicast
1936 		 * addresses. For now let the kernel figure it out.
1937 		 */
1938 		iaddr6 = ((struct sockaddr_in6*)&maddr)->sin6_addr;
1939 		mreq6.ipv6mr_multiaddr = iaddr6;
1940 		mreq6.ipv6mr_interface = iface->scopeid;
1941 
1942 		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
1943 			(char *)&mreq6, sizeof(mreq6)) == -1) {
1944 			netsyslog(LOG_ERR,
1945 			"setsockopt IPV6_LEAVE_GROUP failure: %m on socket %d, addr %s for %d(%s)",
1946 			iface->fd, stoa(&iface->sin),
1947 			mreq6.ipv6mr_interface, stoa(maddr));
1948 			return ISC_FALSE;
1949 		}
1950 		break;
1951 #else
1952 		return ISC_FALSE;
1953 #endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */
1954 
1955 	}
1956 	iface->num_mcast--;
1957 	if (iface->num_mcast <= 0) {
1958                 iface->num_mcast = 0;
1959 		iface->flags &= ~INT_MCASTOPEN;
1960 	}
1961 	return ISC_TRUE;
1962 }
1963 
1964 /*
1965  * io_setbclient - open the broadcast client sockets
1966  */
1967 void
1968 io_setbclient(void)
1969 {
1970 #ifdef OPEN_BCAST_SOCKET
1971         struct interface *interf;
1972 	int nif = 0;
1973 	isc_boolean_t jstatus;
1974 	SOCKET fd;
1975 
1976 	set_reuseaddr(1);
1977 
1978 	for (interf = ISC_LIST_HEAD(inter_list);
1979 	     interf != NULL;
1980 	     interf = ISC_LIST_NEXT(interf, link)) {
1981 	        if (interf->flags & INT_WILDCARD)
1982 		        continue;
1983 
1984 		/* use only allowed addresses */
1985 		if (interf->ignore_packets == ISC_TRUE)
1986 			continue;
1987 		/* Only IPv4 addresses are valid for broadcast */
1988 		if (interf->sin.ss_family != AF_INET)
1989 			continue;
1990 
1991 		/* Is this a broadcast address? */
1992 		if (!(interf->flags & INT_BROADCAST))
1993 			continue;
1994 
1995 		/* Skip the loopback addresses */
1996 		if (interf->flags & INT_LOOPBACK)
1997 			continue;
1998 
1999 		/* Do we already have the broadcast address open? */
2000 		if (interf->flags & INT_BCASTOPEN) {
2001 		/* account for already open interfaces to aviod misleading warning below */
2002 			nif++;
2003 			continue;
2004 		}
2005 
2006 		/*
2007 		 * Try to open the broadcast address
2008 		 */
2009 		interf->family = AF_INET;
2010 		interf->bfd = open_socket(&interf->bcast,
2011 				    INT_BROADCAST, 0, interf);
2012 
2013 		 /*
2014 		 * If we succeeded then we use it otherwise
2015 		 * enable the underlying address
2016 		 */
2017 		if (interf->bfd == INVALID_SOCKET) {
2018 			fd = interf->fd;
2019 		}
2020 		else {
2021 			fd = interf->bfd;
2022 		}
2023 
2024 		/* Enable Broadcast on socket */
2025 		jstatus = socket_broadcast_enable(interf, fd, &interf->sin);
2026 		if (jstatus == ISC_TRUE)
2027 		{
2028 			nif++;
2029 			netsyslog(LOG_INFO,"io_setbclient: Opened broadcast client on interface #%d %s, socket: %d",
2030 				  interf->ifnum, interf->name, fd);
2031 			interf->addr_refid = addr2refid(&interf->sin);
2032 		}
2033 	}
2034 	set_reuseaddr(0);
2035 #ifdef DEBUG
2036 	if (debug)
2037 		if (nif > 0)
2038 			printf("io_setbclient: Opened broadcast clients\n");
2039 #endif
2040 	if (nif == 0)
2041 		netsyslog(LOG_ERR, "Unable to listen for broadcasts, no broadcast interfaces available");
2042 #else
2043 	netsyslog(LOG_ERR, "io_setbclient: Broadcast Client disabled by build");
2044 #endif
2045 }
2046 
2047 /*
2048  * io_unsetbclient - close the broadcast client sockets
2049  */
2050 void
2051 io_unsetbclient(void)
2052 {
2053         struct interface *interf;
2054 	isc_boolean_t lstatus;
2055 
2056 	for (interf = ISC_LIST_HEAD(inter_list);
2057 	     interf != NULL;
2058 	     interf = ISC_LIST_NEXT(interf, link))
2059 	{
2060 	        if (interf->flags & INT_WILDCARD)
2061 		    continue;
2062 
2063 		if (!(interf->flags & INT_BCASTOPEN))
2064 		    continue;
2065 		lstatus = socket_broadcast_disable(interf, &interf->sin);
2066 	}
2067 }
2068 
2069 /*
2070  * io_multicast_add() - add multicast group address
2071  */
2072 void
2073 io_multicast_add(
2074 	struct sockaddr_storage addr
2075 	)
2076 {
2077 #ifdef MCAST
2078 	struct interface *interface;
2079 #ifndef MULTICAST_NONEWSOCKET
2080 	struct interface *iface;
2081 #endif
2082 	int lscope = 0;
2083 
2084 	/*
2085 	 * Check to see if this is a multicast address
2086 	 */
2087 	if (addr_ismulticast(&addr) == ISC_FALSE)
2088 		return;
2089 
2090 	/* If we already have it we can just return */
2091 	if (find_flagged_addr_in_list(&addr, INT_MCASTOPEN|INT_MCASTIF) != NULL)
2092 	{
2093 		netsyslog(LOG_INFO, "Duplicate request found for multicast address %s",
2094 			stoa(&addr));
2095 		return;
2096 	}
2097 
2098 #ifndef MULTICAST_NONEWSOCKET
2099 	interface = new_interface(NULL);
2100 
2101 	/*
2102 	 * Open a new socket for the multicast address
2103 	 */
2104 	interface->sin.ss_family = addr.ss_family;
2105 	interface->family = addr.ss_family;
2106 
2107 	switch(addr.ss_family) {
2108 	case AF_INET:
2109 		memcpy(&(((struct sockaddr_in *)&interface->sin)->sin_addr),
2110 		       &(((struct sockaddr_in*)&addr)->sin_addr),
2111 		       sizeof(struct in_addr));
2112 		((struct sockaddr_in*)&interface->sin)->sin_port = htons(NTP_PORT);
2113 		memset(&((struct sockaddr_in*)&interface->mask)->sin_addr.s_addr, 0xff, sizeof(struct in_addr));
2114 		break;
2115 	case AF_INET6:
2116 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2117 		memcpy(&(((struct sockaddr_in6 *)&interface->sin)->sin6_addr),
2118 		       &((struct sockaddr_in6*)&addr)->sin6_addr,
2119 		       sizeof(struct in6_addr));
2120 		((struct sockaddr_in6*)&interface->sin)->sin6_port = htons(NTP_PORT);
2121 #ifdef ISC_PLATFORM_HAVESCOPEID
2122 		((struct sockaddr_in6*)&interface->sin)->sin6_scope_id = ((struct sockaddr_in6*)&addr)->sin6_scope_id;
2123 #endif
2124 		memset(&((struct sockaddr_in6*)&interface->mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));
2125 #endif
2126 		iface = findlocalcastinterface(&addr, INT_MULTICAST);
2127 		if (iface) {
2128 # ifdef ISC_PLATFORM_HAVESCOPEID
2129 			lscope = ((struct sockaddr_in6*)&iface->sin)->sin6_scope_id;
2130 # endif
2131 			DPRINTF(4, ("Found interface #%d %s, scope: %d for address %s\n", iface->ifnum, iface->name, lscope, stoa(&addr)));
2132 		}
2133 		break;
2134 	}
2135 
2136 	set_reuseaddr(1);
2137 	interface->bfd = INVALID_SOCKET;
2138 	interface->fd = open_socket(&interface->sin,
2139 			    INT_MULTICAST, 0, interface);
2140 
2141 	if (interface->fd != INVALID_SOCKET)
2142 	{
2143 		interface->bfd = INVALID_SOCKET;
2144 		interface->ignore_packets = ISC_FALSE;
2145 		interface->flags |= INT_MCASTIF;
2146 
2147 		(void) strncpy(interface->name, "multicast",
2148 			sizeof(interface->name));
2149 		((struct sockaddr_in*)&interface->mask)->sin_addr.s_addr =
2150 						htonl(~(u_int32)0);
2151 		DPRINT_INTERFACE(2, (interface, "multicast add ", "\n"));
2152 		/* socket_multicast_enable() will add this address to the addresslist */
2153 		add_interface(interface);
2154 		list_if_listening(interface, htons(NTP_PORT));
2155 	}
2156 	else
2157 	{
2158 		delete_interface(interface);  /* re-use existing interface */
2159 		interface = NULL;
2160 		if (addr.ss_family == AF_INET)
2161 			interface = wildipv4;
2162 		else if (addr.ss_family == AF_INET6)
2163 			interface = wildipv6;
2164 
2165 		if (interface != NULL) {
2166 			/* HACK ! -- stuff in an address */
2167 			interface->bcast = addr;
2168 			netsyslog(LOG_ERR,
2169 			 "...multicast address %s using wildcard interface #%d %s",
2170 				  stoa(&addr), interface->ifnum, interface->name);
2171 		} else {
2172 			netsyslog(LOG_ERR,
2173 			"No multicast socket available to use for address %s",
2174 			stoa(&addr));
2175 			return;
2176 		}
2177 	}
2178 #else
2179 	/*
2180 	 * For the case where we can't use a separate socket
2181 	 */
2182 	interface = findlocalcastinterface(&addr, INT_MULTICAST);
2183 	/*
2184 	 * If we don't have a valid socket, just return
2185 	 */
2186 	if (!interface)
2187 	{
2188 		netsyslog(LOG_ERR,
2189 		"Cannot add multicast address %s: Cannot find slot",
2190 		stoa(&addr));
2191 		return;
2192 	}
2193 
2194 #endif
2195 	{
2196 		isc_boolean_t jstatus;
2197 		jstatus = socket_multicast_enable(interface, lscope, &addr);
2198 
2199 		if (jstatus == ISC_TRUE)
2200 			netsyslog(LOG_INFO, "Added Multicast Listener %s on interface #%d %s\n", stoa(&addr), interface->ifnum, interface->name);
2201 		else
2202 			netsyslog(LOG_ERR, "Failed to add Multicast Listener %s\n", stoa(&addr));
2203 	}
2204 #else /* MCAST */
2205 	netsyslog(LOG_ERR,
2206 		  "Cannot add multicast address %s: no Multicast support",
2207 		  stoa(&addr));
2208 #endif /* MCAST */
2209 	return;
2210 }
2211 
2212 /*
2213  * io_multicast_del() - delete multicast group address
2214  */
2215 void
2216 io_multicast_del(
2217 	struct sockaddr_storage addr
2218 	)
2219 {
2220 #ifdef MCAST
2221         struct interface *interface;
2222 	isc_boolean_t lstatus;
2223 
2224 	/*
2225 	 * Check to see if this is a multicast address
2226 	 */
2227 	if (addr_ismulticast(&addr) == ISC_FALSE)
2228 	{
2229 		netsyslog(LOG_ERR,
2230 			 "invalid multicast address %s", stoa(&addr));
2231 		return;
2232 	}
2233 
2234 	switch (addr.ss_family)
2235 	{
2236 	case AF_INET :
2237 		/*
2238 		 * Disable reception of multicast packets
2239 		 */
2240 		interface = find_flagged_addr_in_list(&addr, INT_MCASTOPEN);
2241 		while ( interface != NULL) {
2242 			lstatus = socket_multicast_disable(interface, &addr);
2243 			interface = find_flagged_addr_in_list(&addr, INT_MCASTOPEN);
2244 		}
2245 		break;
2246 
2247 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2248 	case AF_INET6 :
2249 		/*
2250 		 * Disable reception of multicast packets
2251 		 */
2252 		for (interface = ISC_LIST_HEAD(inter_list);
2253 		     interface != NULL;
2254 		     interface = ISC_LIST_NEXT(interface, link))
2255 		{
2256                         if (interface->flags & INT_WILDCARD)
2257 			        continue;
2258 
2259 			/* Be sure it's the correct family */
2260 			if (interface->sin.ss_family != AF_INET6)
2261 				continue;
2262 			if (!(interface->flags & INT_MCASTOPEN))
2263 				continue;
2264 			if (!(interface->fd < 0))
2265 				continue;
2266 			if (!SOCKCMP(&addr, &interface->sin))
2267 				continue;
2268 			lstatus = socket_multicast_disable(interface, &addr);
2269 		}
2270 		break;
2271 #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
2272 
2273 	}/* switch */
2274 
2275         delete_addr_from_list(&addr);
2276 
2277 #else /* not MCAST */
2278 	netsyslog(LOG_ERR, "this function requires multicast kernel");
2279 #endif /* not MCAST */
2280 }
2281 
2282 /*
2283  * init_nonblocking_io() - set up descriptor to be non blocking
2284  */
2285 static void init_nonblocking_io(SOCKET fd)
2286 {
2287 	/*
2288 	 * set non-blocking,
2289 	 */
2290 
2291 #ifdef USE_FIONBIO
2292 	/* in vxWorks we use FIONBIO, but the others are defined for old systems, so
2293 	 * all hell breaks loose if we leave them defined
2294 	 */
2295 #undef O_NONBLOCK
2296 #undef FNDELAY
2297 #undef O_NDELAY
2298 #endif
2299 
2300 #if defined(O_NONBLOCK) /* POSIX */
2301 	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
2302 	{
2303 		netsyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails on fd #%d: %m",
2304 			fd);
2305 		exit(1);
2306 		/*NOTREACHED*/
2307 	}
2308 #elif defined(FNDELAY)
2309 	if (fcntl(fd, F_SETFL, FNDELAY) < 0)
2310 	{
2311 		netsyslog(LOG_ERR, "fcntl(FNDELAY) fails on fd #%d: %m",
2312 			fd);
2313 		exit(1);
2314 		/*NOTREACHED*/
2315 	}
2316 #elif defined(O_NDELAY) /* generally the same as FNDELAY */
2317 	if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
2318 	{
2319 		netsyslog(LOG_ERR, "fcntl(O_NDELAY) fails on fd #%d: %m",
2320 			fd);
2321 		exit(1);
2322 		/*NOTREACHED*/
2323 	}
2324 #elif defined(FIONBIO)
2325 	{
2326 		int on = 1;
2327 		if (ioctl(fd,FIONBIO,&on) < 0)
2328 		{
2329 			netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on fd #%d: %m",
2330 				fd);
2331 			exit(1);
2332 			/*NOTREACHED*/
2333 		}
2334 	}
2335 #elif defined(FIOSNBIO)
2336 	if (ioctl(fd,FIOSNBIO,&on) < 0)
2337 	{
2338 		netsyslog(LOG_ERR, "ioctl(FIOSNBIO) fails on fd #%d: %m",
2339 			fd);
2340 		exit(1);
2341 		/*NOTREACHED*/
2342 	}
2343 #else
2344 # include "Bletch: Need non-blocking I/O!"
2345 #endif
2346 }
2347 
2348 /*
2349  * open_socket - open a socket, returning the file descriptor
2350  */
2351 
2352 static SOCKET
2353 open_socket(
2354 	struct sockaddr_storage *addr,
2355 	int flags,
2356 	int turn_off_reuse,
2357 	struct interface *interf
2358 	)
2359 {
2360 	int errval;
2361 	SOCKET fd;
2362 	/*
2363 	 * int is OK for REUSEADR per
2364 	 * http://www.kohala.com/start/mcast.api.txt
2365 	 */
2366 	int on = 1;
2367 	int off = 0;
2368 
2369 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
2370 	int tos;
2371 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
2372 
2373 	if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS))
2374 		return (INVALID_SOCKET);
2375 
2376 	/* create a datagram (UDP) socket */
2377 	fd = socket(addr->ss_family, SOCK_DGRAM, 0);
2378 	if (INVALID_SOCKET == fd) {
2379 #ifndef SYS_WINNT
2380 		errval = errno;
2381 #else
2382 		errval = WSAGetLastError();
2383 #endif
2384 		netsyslog(LOG_ERR,
2385 			  "socket(AF_INET%s, SOCK_DGRAM, 0) failed on address %s: %m",
2386 			  (addr->ss_family == AF_INET6) ? "6" : "",
2387 			  stoa(addr));
2388 
2389 		if (errval == EPROTONOSUPPORT ||
2390 		    errval == EAFNOSUPPORT ||
2391 		    errval == EPFNOSUPPORT)
2392 			return (INVALID_SOCKET);
2393 		msyslog(LOG_ERR, "unexpected error code %d (not PROTONOSUPPORT|AFNOSUPPORT|FPNOSUPPORT) - exiting", errval);
2394 		exit(1);
2395 		/*NOTREACHED*/
2396 	}
2397 
2398 #ifdef SYS_WINNT
2399 	connection_reset_fix(fd, addr);
2400 #endif
2401 	/*
2402 	 * Fixup the file descriptor for some systems
2403 	 * See bug #530 for details of the issue.
2404 	 */
2405 	fd = move_fd(fd);
2406 
2407 	/*
2408 	 * set SO_REUSEADDR since we will be binding the same port
2409 	 * number on each interface according to turn_off_reuse.
2410 	 * This is undesirable on Windows versions starting with
2411 	 * Windows XP (numeric version 5.1).
2412 	 */
2413 #ifdef SYS_WINNT
2414 	if (isc_win32os_versioncheck(5, 1, 0, 0) < 0)  /* before 5.1 */
2415 #endif
2416 		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
2417 			       (char *)(turn_off_reuse
2418 					? &off
2419 					: &on),
2420 			       sizeof(on))) {
2421 
2422 			netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR %s"
2423 					   " fails for address %s: %m",
2424 					   turn_off_reuse
2425 						? "off"
2426 						: "on",
2427 					   stoa(addr));
2428 			closesocket(fd);
2429 			return INVALID_SOCKET;
2430 		}
2431 #ifdef SO_EXCLUSIVEADDRUSE
2432 	/*
2433 	 * setting SO_EXCLUSIVEADDRUSE on the wildcard we open
2434 	 * first will cause more specific binds to fail.
2435 	 */
2436 	if (!(interf->flags & INT_WILDCARD))
2437 		set_excladdruse(fd);
2438 #endif
2439 
2440 	/*
2441 	 * IPv4 specific options go here
2442 	 */
2443 	if (addr->ss_family == AF_INET) {
2444 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
2445 	/* set IP_TOS to minimize packet delay */
2446 		tos = IPTOS_LOWDELAY;
2447 		if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)
2448 		{
2449 			netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m",
2450 				stoa(addr));
2451 		}
2452 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
2453 	}
2454 
2455 	/*
2456 	 * IPv6 specific options go here
2457 	 */
2458         if (addr->ss_family == AF_INET6) {
2459 #if defined(IPV6_V6ONLY)
2460                 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
2461                 	(char*)&on, sizeof(on)))
2462                 {
2463                 	netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m",
2464 				stoa(addr));
2465 		}
2466 #endif /* IPV6_V6ONLY */
2467 #if defined(IPV6_BINDV6ONLY)
2468                 if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
2469                 	(char*)&on, sizeof(on)))
2470                 {
2471                 	netsyslog(LOG_ERR,
2472 			    "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
2473 			    stoa(addr));
2474 		}
2475 #endif /* IPV6_BINDV6ONLY */
2476 	}
2477 
2478 #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
2479 	/*
2480 	 * some OSes don't allow binding to more specific
2481 	 * addresses if a wildcard address already bound
2482 	 * to the port and SO_REUSEADDR is not set
2483 	 */
2484 	if (!is_wildcard_addr(addr)) {
2485 		set_wildcard_reuse(addr->ss_family, 1);
2486 	}
2487 #endif
2488 
2489 	/*
2490 	 * bind the local address.
2491 	 */
2492 	errval = bind(fd, (struct sockaddr *)addr, SOCKLEN(addr));
2493 
2494 #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
2495 	/*
2496 	 * some OSes don't allow binding to more specific
2497 	 * addresses if a wildcard address already bound
2498 	 * to the port and REUSE_ADDR is not set
2499 	 */
2500 	if (!is_wildcard_addr(addr)) {
2501 		set_wildcard_reuse(addr->ss_family, 0);
2502 	}
2503 #endif
2504 
2505 	if (errval < 0) {
2506 		/*
2507 		 * Don't log this under all conditions
2508 		 */
2509 		if (turn_off_reuse == 0
2510 #ifdef DEBUG
2511 		    || debug > 1
2512 #endif
2513 			) {
2514 			if (addr->ss_family == AF_INET)
2515 				netsyslog(LOG_ERR,
2516 					  "bind() fd %d, family AF_INET, port %d, addr %s, in_classd=%d flags=0x%x fails: %m",
2517 					  fd, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
2518 					  stoa(addr),
2519 					  IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)),
2520 					  flags);
2521 #ifdef INCLUDE_IPV6_SUPPORT
2522 			else if (addr->ss_family == AF_INET6)
2523 				netsyslog(LOG_ERR,
2524 					  "bind() fd %d, family AF_INET6, port %d, scope %d, addr %s, mcast=%d flags=0x%x fails: %m",
2525 					  fd, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port),
2526 # ifdef ISC_PLATFORM_HAVESCOPEID
2527 					  ((struct sockaddr_in6*)addr)->sin6_scope_id
2528 # else
2529 					  -1
2530 # endif
2531 					  , stoa(addr),
2532 					  IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr),
2533 					  flags);
2534 #endif
2535 		}
2536 
2537 		closesocket(fd);
2538 
2539 		return INVALID_SOCKET;
2540 	}
2541 
2542 #ifdef HAVE_TIMESTAMP
2543 	{
2544 		if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP,
2545 			       (char*)&on, sizeof(on)))
2546 		{
2547 			netsyslog(LOG_DEBUG,
2548 				  "setsockopt SO_TIMESTAMP on fails on address %s: %m",
2549 				  stoa(addr));
2550 		}
2551 #ifdef DEBUG
2552 		else
2553 		{
2554 			DPRINTF(4, ("setsockopt SO_TIMESTAMP enabled on fd %d address %s\n", fd, stoa(addr)));
2555 		}
2556 #endif
2557 	}
2558 #endif
2559 	DPRINTF(4, ("bind() fd %d, family %d, port %d, addr %s, flags=0x%x\n",
2560 		   fd,
2561 		   addr->ss_family,
2562 		   (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
2563 		   stoa(addr),
2564 		   interf->flags));
2565 
2566 	init_nonblocking_io(fd);
2567 
2568 #ifdef HAVE_SIGNALED_IO
2569 	init_socket_sig(fd);
2570 #endif /* not HAVE_SIGNALED_IO */
2571 
2572 	add_fd_to_list(fd, FD_TYPE_SOCKET);
2573 
2574 #if !defined(SYS_WINNT) && !defined(VMS)
2575 	DPRINTF(4, ("flags for fd %d: 0x%x\n", fd,
2576 		    fcntl(fd, F_GETFL, 0)));
2577 #endif /* SYS_WINNT || VMS */
2578 
2579 #if defined (HAVE_IO_COMPLETION_PORT)
2580 /*
2581  * Add the socket to the completion port
2582  */
2583 	if (io_completion_port_add_socket(fd, interf))
2584 	{
2585 		msyslog(LOG_ERR, "unable to set up io completion port - EXITING");
2586 		exit(1);
2587 	}
2588 #endif
2589 	return fd;
2590 }
2591 
2592 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
2593 /*
2594  * sendpkt - send a packet to the specified destination. Maintain a
2595  * send error cache so that only the first consecutive error for a
2596  * destination is logged.
2597  */
2598 void
2599 sendpkt(
2600 	struct sockaddr_storage *dest,
2601 	struct interface *inter,
2602 	int ttl,
2603 	struct pkt *pkt,
2604 	int len
2605 	)
2606 {
2607 	int cc, slot;
2608 
2609 	/*
2610 	 * Send error caches. Empty slots have port == 0
2611 	 * Set ERRORCACHESIZE to 0 to disable
2612 	 */
2613 	struct cache {
2614 		u_short port;
2615 		struct	in_addr addr;
2616 	};
2617 
2618 #ifdef INCLUDE_IPV6_SUPPORT
2619 	struct cache6 {
2620 		u_short port;
2621 		struct in6_addr addr;
2622 	};
2623 #endif /* INCLUDE_IPV6_SUPPORT */
2624 
2625 
2626 #ifndef ERRORCACHESIZE
2627 #define ERRORCACHESIZE 8
2628 #endif
2629 #if ERRORCACHESIZE > 0
2630 	static struct cache badaddrs[ERRORCACHESIZE];
2631 #ifdef INCLUDE_IPV6_SUPPORT
2632 	static struct cache6 badaddrs6[ERRORCACHESIZE];
2633 #endif /* INCLUDE_IPV6_SUPPORT */
2634 #else
2635 #define badaddrs ((struct cache *)0)		/* Only used in empty loops! */
2636 #ifdef INCLUDE_IPV6_SUPPORT
2637 #define badaddrs6 ((struct cache6 *)0)		/* Only used in empty loops! */
2638 #endif /* INCLUDE_IPV6_SUPPORT */
2639 #endif
2640 #ifdef DEBUG
2641 	if (debug > 1)
2642 	  {
2643 	    if (inter != NULL)
2644 	      {
2645 		printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n",
2646 		       (ttl > 0) ? "\tMCAST\t***** " : "",
2647 		       inter->fd, stoa(dest),
2648 		       stoa(&inter->sin), ttl, len);
2649 	      }
2650 	    else
2651 	      {
2652 		printf("%ssendpkt(dst=%s, ttl=%d, len=%d): no interface - IGNORED\n",
2653 		       (ttl > 0) ? "\tMCAST\t***** " : "",
2654 		       stoa(dest),
2655 		       ttl, len);
2656 	      }
2657 	  }
2658 #endif
2659 
2660 	if (inter == NULL)	/* unbound peer - drop request and wait for better network conditions */
2661 	  return;
2662 
2663 #ifdef MCAST
2664 
2665 	/*
2666 	 * for the moment we use the bcast option to set multicast ttl
2667 	 */
2668 	if (ttl > 0 && ttl != inter->last_ttl) {
2669 
2670 		/*
2671 		 * set the multicast ttl for outgoing packets
2672 		 */
2673 		int rtc;
2674 
2675 		switch (inter->sin.ss_family) {
2676 
2677 		case AF_INET :
2678 		{
2679 			u_char mttl = (u_char) ttl;
2680 
2681 			rtc = setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,
2682 					 (const void *) &mttl, sizeof(mttl));
2683 			break;
2684 		}
2685 
2686 #ifdef INCLUDE_IPV6_SUPPORT
2687 		case AF_INET6 :
2688 		{
2689 			u_int ittl = (u_char) ttl;
2690 
2691 			rtc = setsockopt(inter->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
2692 					 (const void *) &ittl, sizeof(ittl));
2693 			break;
2694 		}
2695 
2696 #endif /* INCLUDE_IPV6_SUPPORT */
2697 		default:	/* just NOP if not supported */
2698 			rtc = 0;
2699 			break;
2700 		}
2701 
2702 		if (rtc != 0) {
2703 			netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL/IPV6_MULTICAST_HOPS fails on address %s: %m",
2704 				  stoa(&inter->sin));
2705 		}
2706 		else
2707 			inter->last_ttl = ttl;
2708 	}
2709 
2710 #endif /* MCAST */
2711 
2712 	for (slot = ERRORCACHESIZE; --slot >= 0; )
2713 		if(dest->ss_family == AF_INET) {
2714 			if (badaddrs[slot].port == ((struct sockaddr_in*)dest)->sin_port &&
2715 				badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr)
2716 			break;
2717 		}
2718 #ifdef INCLUDE_IPV6_SUPPORT
2719 		else if (dest->ss_family == AF_INET6) {
2720 			if (badaddrs6[slot].port == ((struct sockaddr_in6*)dest)->sin6_port &&
2721 				badaddrs6[slot].addr.s6_addr == ((struct sockaddr_in6*)dest)->sin6_addr.s6_addr)
2722 			break;
2723 		}
2724 #endif /* INCLUDE_IPV6_SUPPORT */
2725 
2726 #if defined(HAVE_IO_COMPLETION_PORT)
2727         cc = io_completion_port_sendto(inter, pkt, len, dest);
2728 	if (cc != ERROR_SUCCESS)
2729 #else
2730 #ifdef SIM
2731         cc = srvr_rply(&ntp_node,  dest, inter, pkt);
2732 #else /* SIM */
2733 	cc = sendto(inter->fd, (char *)pkt, (unsigned int)len, 0, (struct sockaddr *)dest,
2734 		    SOCKLEN(dest));
2735 #endif /* SIM */
2736 	if (cc == -1)
2737 #endif
2738 	{
2739 		inter->notsent++;
2740 		packets_notsent++;
2741 
2742 #if defined(HAVE_IO_COMPLETION_PORT)
2743 		if (cc != WSAEWOULDBLOCK && cc != WSAENOBUFS && slot < 0)
2744 #else
2745 		if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
2746 #endif
2747 		{
2748 			/*
2749 			 * Remember this, if there's an empty slot
2750 			 */
2751 			switch (dest->ss_family) {
2752 
2753 			case AF_INET :
2754 
2755 				for (slot = ERRORCACHESIZE; --slot >= 0; )
2756 					if (badaddrs[slot].port == 0)
2757 					{
2758 						badaddrs[slot].port = SRCPORT(dest);
2759 						badaddrs[slot].addr = ((struct sockaddr_in*)dest)->sin_addr;
2760 						break;
2761 					}
2762 				break;
2763 
2764 #ifdef INCLUDE_IPV6_SUPPORT
2765 			case AF_INET6 :
2766 
2767 				for (slot = ERRORCACHESIZE; --slot >= 0; )
2768 					if (badaddrs6[slot].port == 0)
2769 					{
2770 						badaddrs6[slot].port = SRCPORT(dest);
2771 						badaddrs6[slot].addr = ((struct sockaddr_in6*)dest)->sin6_addr;
2772 						break;
2773 					}
2774 				break;
2775 #endif /* INCLUDE_IPV6_SUPPORT */
2776 			default:  /* don't care if not supported */
2777 				break;
2778 			}
2779 
2780 			netsyslog(LOG_ERR, "sendto(%s) (fd=%d): %m",
2781 				  stoa(dest), inter->fd);
2782 		}
2783 	}
2784 	else
2785 	{
2786 		inter->sent++;
2787 		packets_sent++;
2788 		/*
2789 		 * He's not bad any more
2790 		 */
2791 		if (slot >= 0)
2792 		{
2793 			netsyslog(LOG_INFO, "Connection re-established to %s", stoa(dest));
2794 			switch (dest->ss_family) {
2795 			case AF_INET :
2796 				badaddrs[slot].port = 0;
2797 				break;
2798 #ifdef INCLUDE_IPV6_SUPPORT
2799 			case AF_INET6 :
2800 				badaddrs6[slot].port = 0;
2801 				break;
2802 #endif /* INCLUDE_IPV6_SUPPORT */
2803 			default:  /* don't care if not supported */
2804 				break;
2805 			}
2806 		}
2807 	}
2808 }
2809 
2810 #if !defined(HAVE_IO_COMPLETION_PORT)
2811 /*
2812  * fdbits - generate ascii representation of fd_set (FAU debug support)
2813  * HFDF format - highest fd first.
2814  */
2815 static char *
2816 fdbits(
2817 	int count,
2818 	fd_set *set
2819 	)
2820 {
2821 	static char buffer[256];
2822 	char * buf = buffer;
2823 
2824 	count = (count < 256) ? count : 255;
2825 
2826 	while (count >= 0)
2827 	{
2828 		*buf++ = FD_ISSET(count, set) ? '#' : '-';
2829 		count--;
2830 	}
2831 	*buf = '\0';
2832 
2833 	return buffer;
2834 }
2835 
2836 /*
2837  * Routine to read the refclock packets for a specific interface
2838  * Return the number of bytes read. That way we know if we should
2839  * read it again or go on to the next one if no bytes returned
2840  */
2841 static inline int
2842 read_refclock_packet(SOCKET fd, struct refclockio *rp, l_fp ts)
2843 {
2844 	int i;
2845 	int buflen;
2846 	register struct recvbuf *rb;
2847 
2848 	rb = get_free_recv_buffer();
2849 
2850 	if (rb == NULL)
2851 	{
2852 		/*
2853 		 * No buffer space available - just drop the packet
2854 		 */
2855 		char buf[RX_BUFF_SIZE];
2856 
2857 		buflen = read(fd, buf, sizeof buf);
2858 		packets_dropped++;
2859 		return (buflen);
2860 	}
2861 
2862 	i = (rp->datalen == 0
2863 	    || rp->datalen > sizeof(rb->recv_space))
2864 	    ? sizeof(rb->recv_space) : rp->datalen;
2865 	buflen = read(fd, (char *)&rb->recv_space, (unsigned)i);
2866 
2867 	if (buflen < 0)
2868 	{
2869 		if (errno != EINTR && errno != EAGAIN) {
2870 			netsyslog(LOG_ERR, "clock read fd %d: %m", fd);
2871 		}
2872 		freerecvbuf(rb);
2873 		return (buflen);
2874 	}
2875 
2876 	/*
2877 	 * Got one. Mark how and when it got here,
2878 	 * put it on the full list and do bookkeeping.
2879 	 */
2880 	rb->recv_length = buflen;
2881 	rb->recv_srcclock = rp->srcclock;
2882 	rb->dstadr = 0;
2883 	rb->fd = fd;
2884 	rb->recv_time = ts;
2885 	rb->receiver = rp->clock_recv;
2886 
2887 	if (rp->io_input)
2888 	{
2889 		/*
2890 		 * have direct input routine for refclocks
2891 		 */
2892 		if (rp->io_input(rb) == 0)
2893 		{
2894 			/*
2895 			 * data was consumed - nothing to pass up
2896 			 * into block input machine
2897 			 */
2898 			freerecvbuf(rb);
2899 			return (buflen);
2900 		}
2901 	}
2902 
2903 	add_full_recv_buffer(rb);
2904 
2905 	rp->recvcount++;
2906 	packets_received++;
2907 	return (buflen);
2908 }
2909 
2910 #ifdef HAVE_TIMESTAMP
2911 /*
2912  * extract timestamps from control message buffer
2913  */
2914 static l_fp
2915 	fetch_timestamp(struct recvbuf *rb, struct msghdr *msghdr, l_fp ts)
2916 {
2917 #ifdef USE_TIMESTAMP_CMSG
2918 	struct cmsghdr *cmsghdr;
2919 
2920 	cmsghdr = CMSG_FIRSTHDR(msghdr);
2921 	while (cmsghdr != NULL) {
2922 		switch (cmsghdr->cmsg_type)
2923 		{
2924 		case SCM_TIMESTAMP:
2925 		{
2926 			struct timeval *tvp = (struct timeval *)CMSG_DATA(cmsghdr);
2927 			double dtemp;
2928 			l_fp nts;
2929 			DPRINTF(4, ("fetch_timestamp: system network time stamp: %ld.%06ld\n", tvp->tv_sec, tvp->tv_usec));
2930 			nts.l_i = tvp->tv_sec + JAN_1970;
2931 			dtemp = tvp->tv_usec / 1e6;
2932 
2933  			/* fuzz lower bits not covered by precision */
2934  			if (sys_precision != 0)
2935  				dtemp += (ntp_random() / FRAC - .5) / (1 <<
2936  								       -sys_precision);
2937 
2938 			nts.l_uf = (u_int32)(dtemp*FRAC);
2939 #ifdef DEBUG_TIMING
2940 			{
2941 				l_fp dts = ts;
2942 				L_SUB(&dts, &nts);
2943 				collect_timing(rb, "input processing delay", 1, &dts);
2944 				DPRINTF(4, ("fetch_timestamp: timestamp delta: %s (incl. prec fuzz)\n", lfptoa(&dts, 9)));
2945 			}
2946 #endif
2947 			ts = nts;  /* network time stamp */
2948 			break;
2949 		}
2950 		default:
2951 			DPRINTF(4, ("fetch_timestamp: skipping control message 0x%x\n", cmsghdr->cmsg_type));
2952 			break;
2953 		}
2954 		cmsghdr = CMSG_NXTHDR(msghdr, cmsghdr);
2955 	}
2956 #endif
2957 	return ts;
2958 }
2959 #endif
2960 
2961 /*
2962  * Routine to read the network NTP packets for a specific interface
2963  * Return the number of bytes read. That way we know if we should
2964  * read it again or go on to the next one if no bytes returned
2965  */
2966 static inline int
2967 read_network_packet(SOCKET fd, struct interface *itf, l_fp ts)
2968 {
2969 	GETSOCKNAME_SOCKLEN_TYPE fromlen;
2970 	int buflen;
2971 	register struct recvbuf *rb;
2972 #ifdef HAVE_TIMESTAMP
2973 	struct msghdr msghdr;
2974 	struct iovec iovec;
2975 	char control[TIMESTAMP_CTLMSGBUF_SIZE];	/* pick up control messages */
2976 #endif
2977 
2978 	/*
2979 	 * Get a buffer and read the frame.  If we
2980 	 * haven't got a buffer, or this is received
2981 	 * on a disallowed socket, just dump the
2982 	 * packet.
2983 	 */
2984 
2985 	rb = get_free_recv_buffer();
2986 
2987 	if (rb == NULL || itf->ignore_packets == ISC_TRUE)
2988 	{
2989 		char buf[RX_BUFF_SIZE];
2990 		struct sockaddr_storage from;
2991 		if (rb != NULL)
2992 			freerecvbuf(rb);
2993 
2994 		fromlen = sizeof(from);
2995 		buflen = recvfrom(fd, buf, sizeof(buf), 0,
2996 				(struct sockaddr*)&from, &fromlen);
2997 		DPRINTF(4, ("%s on (%lu) fd=%d from %s\n",
2998 			(itf->ignore_packets == ISC_TRUE) ? "ignore" : "drop",
2999 			free_recvbuffs(), fd,
3000 			stoa(&from)));
3001 		if (itf->ignore_packets == ISC_TRUE)
3002 			packets_ignored++;
3003 		else
3004 			packets_dropped++;
3005 		return (buflen);
3006 	}
3007 
3008 	fromlen = sizeof(struct sockaddr_storage);
3009 
3010 #ifndef HAVE_TIMESTAMP
3011 	rb->recv_length = recvfrom(fd,
3012 			  (char *)&rb->recv_space,
3013 			   sizeof(rb->recv_space), 0,
3014 			   (struct sockaddr *)&rb->recv_srcadr,
3015 			   &fromlen);
3016 #else
3017 	iovec.iov_base        = (void *)&rb->recv_space;
3018 	iovec.iov_len         = sizeof(rb->recv_space);
3019 	msghdr.msg_name       = (void *)&rb->recv_srcadr;
3020 	msghdr.msg_namelen    = sizeof(rb->recv_srcadr);
3021 	msghdr.msg_iov        = &iovec;
3022 	msghdr.msg_iovlen     = 1;
3023 	msghdr.msg_control    = (void *)&control;
3024 	msghdr.msg_controllen = sizeof(control);
3025 	msghdr.msg_flags      = 0;
3026 	rb->recv_length       = recvmsg(fd, &msghdr, 0);
3027 #endif
3028 
3029 	buflen = rb->recv_length;
3030 
3031 	if (buflen == 0 || (buflen == -1 &&
3032 	    (errno==EWOULDBLOCK
3033 #ifdef EAGAIN
3034 	   || errno==EAGAIN
3035 #endif
3036 	 ))) {
3037 		freerecvbuf(rb);
3038 		return (buflen);
3039 	}
3040 	else if (buflen < 0)
3041 	{
3042 		netsyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
3043 		stoa(&rb->recv_srcadr), fd);
3044 		DPRINTF(5, ("read_network_packet: fd=%d dropped (bad recvfrom)\n", fd));
3045 		freerecvbuf(rb);
3046 		return (buflen);
3047 	}
3048 
3049 #ifdef DEBUG
3050 	if (debug > 2) {
3051 		if(rb->recv_srcadr.ss_family == AF_INET)
3052 			printf("read_network_packet: fd=%d length %d from %08lx %s\n",
3053 				fd, buflen,
3054 				(u_long)ntohl(((struct sockaddr_in*)&rb->recv_srcadr)->sin_addr.s_addr) &
3055 				0x00000000ffffffff,
3056 				stoa(&rb->recv_srcadr));
3057 		else
3058 			printf("read_network_packet: fd=%d length %d from %s\n",
3059 				fd, buflen,
3060 				stoa(&rb->recv_srcadr));
3061 	}
3062 #endif
3063 
3064 	/*
3065 	 * Got one.  Mark how and when it got here,
3066 	 * put it on the full list and do bookkeeping.
3067 	 */
3068 	rb->dstadr = itf;
3069 	rb->fd = fd;
3070 #ifdef HAVE_TIMESTAMP
3071 	ts = fetch_timestamp(rb, &msghdr, ts);  /* pick up a network time stamp if possible */
3072 #endif
3073 	rb->recv_time = ts;
3074 	rb->receiver = receive;
3075 
3076 	add_full_recv_buffer(rb);
3077 
3078 	itf->received++;
3079 	packets_received++;
3080 	return (buflen);
3081 }
3082 
3083 /*
3084  * input_handler - receive packets asynchronously
3085  */
3086 void
3087 input_handler(
3088 	l_fp *cts
3089 	)
3090 {
3091 
3092 	int buflen;
3093 	int n;
3094 	int doing;
3095 	SOCKET fd;
3096 	struct timeval tvzero;
3097 	l_fp ts;			/* Timestamp at BOselect() gob */
3098 #ifdef DEBUG_TIMING
3099 	l_fp ts_e;			/* Timestamp at EOselect() gob */
3100 #endif
3101 	fd_set fds;
3102 	int select_count = 0;
3103 	struct interface *interface;
3104 #if defined(HAS_ROUTING_SOCKET)
3105 	struct asyncio_reader *asyncio_reader;
3106 #endif
3107 
3108 	handler_calls++;
3109 
3110 	/*
3111 	 * If we have something to do, freeze a timestamp.
3112 	 * See below for the other cases (nothing (left) to do or error)
3113 	 */
3114 	ts = *cts;
3115 
3116 	/*
3117 	 * Do a poll to see who has data
3118 	 */
3119 
3120 	fds = activefds;
3121 	tvzero.tv_sec = tvzero.tv_usec = 0;
3122 
3123 	n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero);
3124 
3125 	/*
3126 	 * If there are no packets waiting just return
3127 	 */
3128 	if (n < 0)
3129 	{
3130 		int err = errno;
3131 		/*
3132 		 * extended FAU debugging output
3133 		 */
3134 		if (err != EINTR)
3135 		    netsyslog(LOG_ERR,
3136 			      "select(%d, %s, 0L, 0L, &0.0) error: %m",
3137 			      maxactivefd+1,
3138 			      fdbits(maxactivefd, &activefds));
3139 		if (err == EBADF) {
3140 			int j, b;
3141 			fds = activefds;
3142 			for (j = 0; j <= maxactivefd; j++)
3143 			    if ((FD_ISSET(j, &fds) && (read(j, &b, 0) == -1)))
3144 				netsyslog(LOG_ERR, "Bad file descriptor %d", j);
3145 		}
3146 		return;
3147 	}
3148 	else if (n == 0)
3149 		return;
3150 
3151 	++handler_pkts;
3152 
3153 #ifdef REFCLOCK
3154 	/*
3155 	 * Check out the reference clocks first, if any
3156 	 */
3157 
3158 	if (refio != NULL)
3159 	{
3160 		register struct refclockio *rp;
3161 
3162 		for (rp = refio; rp != NULL; rp = rp->next)
3163 		{
3164 			fd = rp->fd;
3165 
3166 			if (FD_ISSET(fd, &fds))
3167 			{
3168 				do {
3169 					++select_count;
3170 					buflen = read_refclock_packet(fd, rp, ts);
3171 				} while (buflen > 0);
3172 
3173 			} /* End if (FD_ISSET(fd, &fds)) */
3174 		} /* End for (rp = refio; rp != 0 && n > 0; rp = rp->next) */
3175 	} /* End if (refio != 0) */
3176 
3177 #endif /* REFCLOCK */
3178 
3179 	/*
3180 	 * Loop through the interfaces looking for data to read.
3181 	 */
3182 	for (interface = ISC_LIST_TAIL(inter_list);
3183 	     interface != NULL;
3184 	     interface = ISC_LIST_PREV(interface, link))
3185 	{
3186 		for (doing = 0; (doing < 2); doing++)
3187 		{
3188 			if (doing == 0)
3189 			{
3190 				fd = interface->fd;
3191 			}
3192 			else
3193 			{
3194 				if (!(interface->flags & INT_BCASTOPEN))
3195 				    break;
3196 				fd = interface->bfd;
3197 			}
3198 			if (fd < 0) continue;
3199 			if (FD_ISSET(fd, &fds))
3200 			{
3201 				do {
3202 					++select_count;
3203 					buflen = read_network_packet(fd, interface, ts);
3204 				} while (buflen > 0);
3205 			}
3206 		/* Check more interfaces */
3207 		}
3208 	}
3209 
3210 #ifdef HAS_ROUTING_SOCKET
3211 	/*
3212 	 * scan list of asyncio readers - currently only used for routing sockets
3213 	 */
3214 	asyncio_reader = ISC_LIST_TAIL(asyncio_reader_list);
3215 
3216 	while (asyncio_reader != NULL)
3217 	{
3218 	        struct asyncio_reader *next = ISC_LIST_PREV(asyncio_reader, link);
3219 		if (FD_ISSET(asyncio_reader->fd, &fds)) {
3220 			++select_count;
3221 			asyncio_reader->receiver(asyncio_reader);
3222 		}
3223 		asyncio_reader = next;
3224 	}
3225 #endif /* HAS_ROUTING_SOCKET */
3226 
3227 	/*
3228 	 * Done everything from that select.
3229 	 */
3230 
3231 	/*
3232 	 * If nothing to do, just return.
3233 	 * If an error occurred, complain and return.
3234 	 */
3235 	if (select_count == 0) /* We really had nothing to do */
3236 	{
3237 #ifdef DEBUG
3238 		if (debug)
3239 		    netsyslog(LOG_DEBUG, "input_handler: select() returned 0");
3240 #endif
3241 		return;
3242 	}
3243 		/* We've done our work */
3244 #ifdef DEBUG_TIMING
3245 	get_systime(&ts_e);
3246 	/*
3247 	 * (ts_e - ts) is the amount of time we spent
3248 	 * processing this gob of file descriptors.  Log
3249 	 * it.
3250 	 */
3251 	L_SUB(&ts_e, &ts);
3252 	collect_timing(NULL, "input handler", 1, &ts_e);
3253 	if (debug > 3)
3254 	    netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
3255 #endif
3256 	/* just bail. */
3257 	return;
3258 }
3259 
3260 #endif
3261 
3262 /*
3263  * findinterface - find local interface corresponding to address
3264  */
3265 struct interface *
3266 findinterface(
3267 	struct sockaddr_storage *addr
3268 	)
3269 {
3270 	struct interface *interface;
3271 
3272 	interface = findlocalinterface(addr, INT_WILDCARD);
3273 
3274 	if (interface == NULL)
3275 	{
3276 		DPRINTF(4, ("Found no interface for address %s - returning wildcard\n",
3277 			    stoa(addr)));
3278 
3279 		return (ANY_INTERFACE_CHOOSE(addr));
3280 	}
3281 	else
3282 	{
3283 		DPRINTF(4, ("Found interface #%d %s for address %s\n",
3284 			    interface->ifnum, interface->name, stoa(addr)));
3285 
3286 		return (interface);
3287 	}
3288 }
3289 
3290 /*
3291  * findlocalinterface - find local interface index corresponding to address
3292  *
3293  * This code attempts to find the local sending address for an outgoing
3294  * address by connecting a new socket to destinationaddress:NTP_PORT
3295  * and reading the sockname of the resulting connect.
3296  * the complicated sequence simulates the routing table lookup
3297  * for to first hop without duplicating any of the routing logic into
3298  * ntpd. preferably we would have used an API call - but its not there -
3299  * so this is the best we can do here short of duplicating to entire routing
3300  * logic in ntpd which would be a silly and really unportable thing to do.
3301  *
3302  */
3303 static struct interface *
3304 findlocalinterface(
3305 	struct sockaddr_storage *addr,
3306 	int flags
3307 	)
3308 {
3309 	SOCKET s;
3310 	int rtn;
3311 	struct sockaddr_storage saddr;
3312 	GETSOCKNAME_SOCKLEN_TYPE saddrlen = SOCKLEN(addr);
3313 	struct interface *iface;
3314 
3315 	DPRINTF(4, ("Finding interface for addr %s in list of addresses\n",
3316 		    stoa(addr)));
3317 
3318 	memset(&saddr, 0, sizeof(saddr));
3319 	saddr.ss_family = addr->ss_family;
3320 	if(addr->ss_family == AF_INET) {
3321 		memcpy(&((struct sockaddr_in*)&saddr)->sin_addr, &((struct sockaddr_in*)addr)->sin_addr, sizeof(struct in_addr));
3322 		((struct sockaddr_in*)&saddr)->sin_port = htons(NTP_PORT);
3323 	}
3324 #ifdef INCLUDE_IPV6_SUPPORT
3325 	else if(addr->ss_family == AF_INET6) {
3326  		memcpy(&((struct sockaddr_in6*)&saddr)->sin6_addr, &((struct sockaddr_in6*)addr)->sin6_addr, sizeof(struct in6_addr));
3327 		((struct sockaddr_in6*)&saddr)->sin6_port = htons(NTP_PORT);
3328 # ifdef ISC_PLATFORM_HAVESCOPEID
3329 		((struct sockaddr_in6*)&saddr)->sin6_scope_id = ((struct sockaddr_in6*)addr)->sin6_scope_id;
3330 # endif
3331 	}
3332 #endif
3333 
3334 	s = socket(addr->ss_family, SOCK_DGRAM, 0);
3335 	if (s == INVALID_SOCKET)
3336 		return NULL;
3337 
3338 	rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr));
3339 #ifndef SYS_WINNT
3340 	if (rtn < 0)
3341 #else
3342 	if (rtn == SOCKET_ERROR)
3343 #endif
3344 	{
3345 		closesocket(s);
3346 		return NULL;
3347 	}
3348 
3349 	rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen);
3350 	closesocket(s);
3351 #ifndef SYS_WINNT
3352 	if (rtn < 0)
3353 #else
3354 	if (rtn == SOCKET_ERROR)
3355 #endif
3356 		return NULL;
3357 
3358 	DPRINTF(4, ("findlocalinterface: kernel maps %s to %s\n", stoa(addr), stoa(&saddr)));
3359 
3360 	iface = getinterface(&saddr, flags);
3361 
3362 	/* Don't both with ignore interfaces */
3363 	if (iface != NULL && iface->ignore_packets == ISC_TRUE)
3364 	{
3365 		return NULL;
3366 	}
3367 	else
3368 	{
3369 		return iface;
3370 	}
3371 }
3372 
3373 /*
3374  * fetch an interface structure the matches the
3375  * address is has the given flags not set
3376  */
3377 static struct interface *
3378 getinterface(struct sockaddr_storage *addr, int flags)
3379 {
3380 	struct interface *interface = find_addr_in_list(addr);
3381 
3382 	if (interface != NULL && interface->flags & flags)
3383 	{
3384 		return NULL;
3385 	}
3386 	else
3387 	{
3388 		return interface;
3389 	}
3390 }
3391 
3392 /*
3393  * findlocalcastinterface - find local *cast interface index corresponding to address
3394  * depending on the flags passed
3395  */
3396 static struct interface *
3397 findlocalcastinterface(
3398 	struct sockaddr_storage *addr, int flags
3399 	)
3400 {
3401 	struct interface *interface;
3402 	struct interface *nif = NULL;
3403 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
3404 	isc_boolean_t want_linklocal;
3405 #endif
3406 
3407 	/*
3408 	 * see how kernel maps the mcast address
3409 	 */
3410         nif = findlocalinterface(addr, 0);
3411 
3412 	if (nif) {
3413 		DPRINTF(2, ("findlocalcastinterface: kernel recommends interface #%d %s\n", nif->ifnum, nif->name));
3414 		return nif;
3415 	}
3416 
3417 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
3418 	want_linklocal = ISC_FALSE;
3419 	if (addr_ismulticast(addr) && flags == INT_MULTICAST)
3420 	{
3421 		if (IN6_IS_ADDR_MC_LINKLOCAL(&((struct sockaddr_in6*)addr)->sin6_addr))
3422 		{
3423 			want_linklocal = ISC_TRUE;
3424 		}
3425 		else if (IN6_IS_ADDR_MC_SITELOCAL(&((struct sockaddr_in6*)addr)->sin6_addr))
3426 		{
3427 			want_linklocal = ISC_TRUE;
3428 		}
3429 	}
3430 #endif
3431 
3432 	for (interface = ISC_LIST_HEAD(inter_list);
3433 	     interface != NULL;
3434 	     interface = ISC_LIST_NEXT(interface, link))
3435 	  {
3436 		/* use only allowed addresses */
3437 		if (interface->ignore_packets == ISC_TRUE)
3438 			continue;
3439 
3440 		/* Skip the loopback and wildcard addresses */
3441 		if (interface->flags & (INT_LOOPBACK|INT_WILDCARD))
3442 			continue;
3443 
3444 		/* Skip if different family */
3445 		if(interface->sin.ss_family != addr->ss_family)
3446 			continue;
3447 
3448 		/* Is this it one of these based on flags? */
3449 		if (!(interface->flags & flags))
3450 			continue;
3451 
3452 		/* for IPv6 multicast check the address for linklocal */
3453 #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
3454 		if (flags == INT_MULTICAST && interface->sin.ss_family == AF_INET6 &&
3455 		   (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&interface->sin)->sin6_addr))
3456 		   && want_linklocal == ISC_TRUE)
3457 		{
3458 			nif = interface;
3459 			break;
3460 		}
3461 		/* If we want a linklocal address and this isn't it, skip */\
3462 		if (want_linklocal == ISC_TRUE)
3463 			continue;
3464 #endif
3465 		/* Otherwise just look for the flag */
3466 		if((interface->flags & flags))
3467 		{
3468 			nif = interface;
3469 			break;
3470 		}
3471 	}
3472 #ifdef DEBUG
3473 	if (debug > 2)
3474 	{
3475 		if (nif)
3476 			printf("findlocalcastinterface: found interface #%d %s\n", nif->ifnum, nif->name);
3477 		else
3478 			printf("findlocalcastinterface: no interface found for %s flags 0x%x\n", stoa(addr), flags);
3479 	}
3480 #endif
3481 	return (nif);
3482 }
3483 
3484 /*
3485  * findbcastinter - find broadcast interface corresponding to address
3486  */
3487 struct interface *
3488 findbcastinter(
3489 	struct sockaddr_storage *addr
3490 	)
3491 {
3492 #if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
3493         struct interface *interface;
3494 
3495 
3496 	DPRINTF(4, ("Finding broadcast/multicast interface for addr %s in list of addresses\n",
3497 		    stoa(addr)));
3498 
3499 	interface = findlocalinterface(addr, INT_LOOPBACK|INT_WILDCARD);
3500 
3501 	if (interface != NULL)
3502 	{
3503 		DPRINTF(4, ("Found bcast-/mcast- interface index #%d %s\n", interface->ifnum, interface->name));
3504 		return interface;
3505 	}
3506 
3507 	/* plan B - try to find something reasonable in our lists in case kernel lookup doesn't help */
3508 
3509 	for (interface = ISC_LIST_HEAD(inter_list);
3510 	     interface != NULL;
3511 	     interface = ISC_LIST_NEXT(interface, link))
3512 	{
3513 	        if (interface->flags & INT_WILDCARD)
3514 		        continue;
3515 
3516 		/* Don't bother with ignored interfaces */
3517 		if (interface->ignore_packets == ISC_TRUE)
3518 			continue;
3519 
3520 		/*
3521 		 * First look if this is the correct family
3522 		 */
3523 		if(interface->sin.ss_family != addr->ss_family)
3524 	  		continue;
3525 
3526 		/* Skip the loopback addresses */
3527 		if (interface->flags & INT_LOOPBACK)
3528 			continue;
3529 
3530 		/*
3531 		 * If we are looking to match a multicast address grab it.
3532 		 */
3533 		if (addr_ismulticast(addr) == ISC_TRUE && interface->flags & INT_MULTICAST)
3534 		{
3535 #ifdef INCLUDE_IPV6_SUPPORT
3536 			if(addr->ss_family == AF_INET6) {
3537 				/* Only use link-local address for link-scope mcast */
3538 				if(IN6_IS_ADDR_MC_LINKLOCAL(&((struct sockaddr_in6*)addr)->sin6_addr) &&
3539 				  !IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&interface->sin)->sin6_addr)) {
3540 					continue;
3541 				}
3542 			}
3543 #endif
3544 			break;
3545 		}
3546 
3547 		/*
3548 		 * We match only those interfaces marked as
3549 		 * broadcastable and either the explicit broadcast
3550 		 * address or the network portion of the IP address.
3551 		 * Sloppy.
3552 		 */
3553 		if(addr->ss_family == AF_INET) {
3554 			if (SOCKCMP(&interface->bcast, addr)) {
3555 				break;
3556 			}
3557 			if ((NSRCADR(&interface->sin) &
3558 			     NSRCADR(&interface->mask)) == (NSRCADR(addr) &
3559 							    NSRCADR(&interface->mask)))
3560 				break;
3561 		}
3562 #ifdef INCLUDE_IPV6_SUPPORT
3563 		else if(addr->ss_family == AF_INET6) {
3564 			if (SOCKCMP(&interface->bcast, addr)) {
3565 				break;
3566 			}
3567 			if (SOCKCMP(netof(&interface->sin), netof(addr))) {
3568 				break;
3569 			}
3570 		}
3571 #endif
3572 	}
3573 #endif /* SIOCGIFCONF */
3574 	if (interface == NULL) {
3575 		DPRINTF(4, ("No bcast interface found for %s\n", stoa(addr)));
3576 		return ANY_INTERFACE_CHOOSE(addr);
3577 	} else {
3578 		DPRINTF(4, ("Found bcast-/mcast- interface index #%d %s\n", interface->ifnum, interface->name));
3579 		return interface;
3580 	}
3581 }
3582 
3583 
3584 /*
3585  * io_clr_stats - clear I/O module statistics
3586  */
3587 void
3588 io_clr_stats(void)
3589 {
3590 	packets_dropped = 0;
3591 	packets_ignored = 0;
3592 	packets_received = 0;
3593 	packets_sent = 0;
3594 	packets_notsent = 0;
3595 
3596 	handler_calls = 0;
3597 	handler_pkts = 0;
3598 	io_timereset = current_time;
3599 }
3600 
3601 
3602 #ifdef REFCLOCK
3603 /*
3604  * io_addclock - add a reference clock to the list and arrange that we
3605  *				 get SIGIO interrupts from it.
3606  */
3607 int
3608 io_addclock(
3609 	struct refclockio *rio
3610 	)
3611 {
3612 	BLOCKIO();
3613 	/*
3614 	 * Stuff the I/O structure in the list and mark the descriptor
3615 	 * in use.	There is a harmless (I hope) race condition here.
3616 	 */
3617 	rio->next = refio;
3618 
3619 # ifdef HAVE_SIGNALED_IO
3620 	if (init_clock_sig(rio))
3621 	{
3622 		UNBLOCKIO();
3623 		return 0;
3624 	}
3625 # elif defined(HAVE_IO_COMPLETION_PORT)
3626 	if (io_completion_port_add_clock_io(rio))
3627 	{
3628 		UNBLOCKIO();
3629 		return 0;
3630 	}
3631 # endif
3632 
3633 	/*
3634 	 * enqueue
3635 	 */
3636 	refio = rio;
3637 
3638         /*
3639 	 * register fd
3640 	 */
3641 	add_fd_to_list(rio->fd, FD_TYPE_FILE);
3642 
3643 	UNBLOCKIO();
3644 	return 1;
3645 }
3646 
3647 /*
3648  * io_closeclock - close the clock in the I/O structure given
3649  */
3650 void
3651 io_closeclock(
3652 	struct refclockio *rio
3653 	)
3654 {
3655 	BLOCKIO();
3656 	/*
3657 	 * Remove structure from the list
3658 	 */
3659 	if (refio == rio)
3660 	{
3661 		refio = rio->next;
3662 	}
3663 	else
3664 	{
3665 		register struct refclockio *rp;
3666 
3667 		for (rp = refio; rp != NULL; rp = rp->next)
3668 		    if (rp->next == rio)
3669 		    {
3670 			    rp->next = rio->next;
3671 			    break;
3672 		    }
3673 
3674 		if (rp == NULL) {
3675 			UNBLOCKIO();
3676 			return;
3677 		}
3678 	}
3679 
3680 	/*
3681 	 * Close the descriptor.
3682 	 */
3683 	close_and_delete_fd_from_list(rio->fd);
3684 	UNBLOCKIO();
3685 }
3686 #endif	/* REFCLOCK */
3687 
3688 /*
3689  * On NT a SOCKET is an unsigned int so we cannot possibly keep it in
3690  * an array. So we use one of the ISC_LIST functions to hold the
3691  * socket value and use that when we want to enumerate it.
3692  */
3693 void
3694 kill_asyncio(int startfd)
3695 {
3696 	vsock_t *lsock;
3697 	vsock_t *next;
3698 
3699 	BLOCKIO();
3700 
3701 	lsock = ISC_LIST_HEAD(fd_list);
3702 	while (lsock != NULL) {
3703 		/*
3704 		 * careful here - list is being dismantled while
3705 		 * we scan it - setting next here insures that
3706 		 * we are able to correctly scan the list
3707 		 */
3708 		next = ISC_LIST_NEXT(lsock, link);
3709 		/*
3710 		 * will remove socket from list
3711 		 */
3712 		close_and_delete_fd_from_list(lsock->fd);
3713 		lsock = next;
3714 	}
3715 
3716 	UNBLOCKIO();
3717 }
3718 
3719 /*
3720  * Add and delete functions for the list of open sockets
3721  */
3722 static void
3723 add_fd_to_list(SOCKET fd, enum desc_type type) {
3724 	vsock_t *lsock = (vsock_t *)emalloc(sizeof(vsock_t));
3725 	lsock->fd = fd;
3726 	lsock->type = type;
3727 
3728 	ISC_LIST_APPEND(fd_list, lsock, link);
3729 	/*
3730 	 * I/O Completion Ports don't care about the select and FD_SET
3731 	 */
3732 #ifndef HAVE_IO_COMPLETION_PORT
3733 	if (fd < 0 || fd >= FD_SETSIZE) {
3734 		msyslog(LOG_ERR, "Too many sockets in use, FD_SETSIZE %d exceeded",
3735 			FD_SETSIZE);
3736 		exit(1);
3737 	}
3738 	/*
3739 	 * keep activefds in sync
3740 	 */
3741 	if (fd > maxactivefd)
3742 	    maxactivefd = fd;
3743 	FD_SET( (u_int)fd, &activefds);
3744 #endif
3745 }
3746 
3747 static void
3748 close_and_delete_fd_from_list(SOCKET fd) {
3749 
3750 	vsock_t *next;
3751 	vsock_t *lsock = ISC_LIST_HEAD(fd_list);
3752 
3753 	while(lsock != NULL) {
3754 		next = ISC_LIST_NEXT(lsock, link);
3755 		if(lsock->fd == fd) {
3756 			ISC_LIST_DEQUEUE_TYPE(fd_list, lsock, link, vsock_t);
3757 
3758 			switch (lsock->type) {
3759 			case FD_TYPE_SOCKET:
3760 #ifdef SYS_WINNT
3761 				closesocket(lsock->fd);
3762 				break;
3763 #endif
3764 			case FD_TYPE_FILE:
3765 				(void) close(lsock->fd);
3766 				break;
3767 			default:
3768 				msyslog(LOG_ERR, "internal error - illegal descriptor type %d - EXITING", (int)lsock->type);
3769 				exit(1);
3770 			}
3771 
3772 			free(lsock);
3773 			/*
3774 			 * I/O Completion Ports don't care about select and fd_set
3775 			 */
3776 #ifndef HAVE_IO_COMPLETION_PORT
3777 			/*
3778 			 * remove from activefds
3779 			 */
3780 			FD_CLR( (u_int) fd, &activefds);
3781 
3782 			if (fd == maxactivefd) {
3783 				int i, newmax = 0;
3784 				for (i = 0; i < maxactivefd; i++)
3785 					if (FD_ISSET(i, &activefds))
3786 						newmax = i;
3787 				maxactivefd = newmax;
3788 			}
3789 #endif
3790 			break;
3791 		}
3792 		lsock = next;
3793 	}
3794 }
3795 
3796 static void
3797 add_addr_to_list(struct sockaddr_storage *addr, struct interface *interface){
3798 #ifdef DEBUG
3799 	if (find_addr_in_list(addr) == NULL) {
3800 #endif
3801 		/* not there yet - add to list */
3802 		remaddr_t *laddr = (remaddr_t *)emalloc(sizeof(remaddr_t));
3803 		memcpy(&laddr->addr, addr, sizeof(struct sockaddr_storage));
3804 		laddr->interface = interface;
3805 
3806 		ISC_LIST_APPEND(remoteaddr_list, laddr, link);
3807 
3808 		DPRINTF(4, ("Added addr %s to list of addresses\n",
3809 			    stoa(addr)));
3810 #ifdef DEBUG
3811 	} else {
3812 		DPRINTF(4, ("WARNING: Attempt to add duplicate addr %s to address list\n",
3813 			    stoa(addr)));
3814 	}
3815 #endif
3816 }
3817 
3818 static void
3819 delete_addr_from_list(struct sockaddr_storage *addr) {
3820 
3821 	remaddr_t *next;
3822 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
3823 
3824 	while(laddr != NULL) {
3825 		next = ISC_LIST_NEXT(laddr, link);
3826 		if(SOCKCMP(&laddr->addr, addr)) {
3827 			ISC_LIST_DEQUEUE_TYPE(remoteaddr_list, laddr, link, remaddr_t);
3828 			DPRINTF(4, ("Deleted addr %s from list of addresses\n",
3829 				    stoa(addr)));
3830 			free(laddr);
3831 			break;
3832 		}
3833 		laddr = next;
3834 	}
3835 }
3836 
3837 static void
3838 delete_interface_from_list(struct interface *iface) {
3839 	remaddr_t *next;
3840 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
3841 
3842 	while(laddr != NULL) {
3843 		next = ISC_LIST_NEXT(laddr, link);
3844 		if (laddr->interface == iface) {
3845 			ISC_LIST_DEQUEUE_TYPE(remoteaddr_list, laddr, link, remaddr_t);
3846 			DPRINTF(4, ("Deleted addr %s for interface #%d %s from list of addresses\n",
3847 				    stoa(&laddr->addr), iface->ifnum, iface->name));
3848 			free(laddr);
3849 		}
3850 		laddr = next;
3851 	}
3852 }
3853 
3854 static struct interface *
3855 find_addr_in_list(struct sockaddr_storage *addr) {
3856 
3857 	remaddr_t *next;
3858 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
3859 	DPRINTF(4, ("Searching for addr %s in list of addresses - ",
3860 		    stoa(addr)));
3861 
3862 	while(laddr != NULL) {
3863 		next = ISC_LIST_NEXT(laddr, link);
3864 		if(SOCKCMP(&laddr->addr, addr)) {
3865 			DPRINTF(4, ("FOUND\n"));
3866 			return laddr->interface;
3867 		}
3868 		else
3869 			laddr = next;
3870 	}
3871 	DPRINTF(4, ("NOT FOUND\n"));
3872 	return NULL; /* Not found */
3873 }
3874 
3875 /*
3876  * Find the given address with the associated flag in the list
3877  */
3878 static struct interface *
3879 find_flagged_addr_in_list(struct sockaddr_storage *addr, int flag) {
3880 
3881 	remaddr_t *next;
3882 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
3883 	DPRINTF(4, ("Finding addr %s in list of addresses\n",
3884 		    stoa(addr)));
3885 
3886 	while(laddr != NULL) {
3887 		next = ISC_LIST_NEXT(laddr, link);
3888 		if(SOCKCMP(&laddr->addr, addr) && (laddr->interface->flags & flag)) {
3889 			return laddr->interface;
3890 			break;
3891 		}
3892 		else
3893 			laddr = next;
3894 	}
3895 	return NULL; /* Not found */
3896 }
3897 
3898 #ifdef HAS_ROUTING_SOCKET
3899 #include <net/route.h>
3900 
3901 #ifndef UPDATE_GRACE
3902 #define UPDATE_GRACE	2	/* wait UPDATE_GRACE seconds before scanning */
3903 #endif
3904 
3905 static void
3906 process_routing_msgs(struct asyncio_reader *reader)
3907 {
3908 	char buffer[5120];
3909 	char *p = buffer;
3910 
3911 	int cnt;
3912 
3913 	if (disable_dynamic_updates) {
3914 		/*
3915 		 * discard ourselves if we are not need any more
3916 		 * usually happens when running unprivileged
3917 		 */
3918 		remove_asyncio_reader(reader);
3919 		delete_asyncio_reader(reader);
3920 		return;
3921 	}
3922 
3923 	cnt = read(reader->fd, buffer, sizeof(buffer));
3924 
3925 	if (cnt < 0) {
3926 		msyslog(LOG_ERR, "i/o error on routing socket %m - disabling");
3927 		remove_asyncio_reader(reader);
3928 		delete_asyncio_reader(reader);
3929 		return;
3930 	}
3931 
3932 	/*
3933 	 * process routing message
3934 	 */
3935 	while ((p + sizeof(struct rt_msghdr)) <= (buffer + cnt))
3936 	{
3937 		struct rt_msghdr *rtm;
3938 
3939 		rtm = (struct rt_msghdr *)p;
3940 		if (rtm->rtm_version != RTM_VERSION) {
3941 			msyslog(LOG_ERR, "version mismatch on routing socket %m - disabling");
3942 			remove_asyncio_reader(reader);
3943 			delete_asyncio_reader(reader);
3944 			return;
3945 		}
3946 
3947 		switch (rtm->rtm_type) {
3948 #ifdef RTM_NEWADDR
3949 		case RTM_NEWADDR:
3950 #endif
3951 #ifdef RTM_DELADDR
3952 		case RTM_DELADDR:
3953 #endif
3954 #ifdef RTM_ADD
3955 		case RTM_ADD:
3956 #endif
3957 #ifdef RTM_DELETE
3958 		case RTM_DELETE:
3959 #endif
3960 #ifdef RTM_REDIRECT
3961 		case RTM_REDIRECT:
3962 #endif
3963 #ifdef RTM_CHANGE
3964 		case RTM_CHANGE:
3965 #endif
3966 #ifdef RTM_LOSING
3967 		case RTM_LOSING:
3968 #endif
3969 #ifdef RTM_IFINFO
3970 		case RTM_IFINFO:
3971 #endif
3972 #ifdef RTM_IFANNOUNCE
3973 		case RTM_IFANNOUNCE:
3974 #endif
3975 			/*
3976 			 * we are keen on new and deleted addresses and if an interface goes up and down or routing changes
3977 			 */
3978 			DPRINTF(3, ("routing message op = %d: scheduling interface update\n", rtm->rtm_type));
3979 			timer_interfacetimeout(current_time + UPDATE_GRACE);
3980 			break;
3981 		default:
3982 			/*
3983 			 * the rest doesn't bother us.
3984 			 */
3985 			DPRINTF(4, ("routing message op = %d: ignored\n", rtm->rtm_type));
3986 			break;
3987 		}
3988 		p += rtm->rtm_msglen;
3989 	}
3990 }
3991 
3992 /*
3993  * set up routing notifications
3994  */
3995 static void
3996 init_async_notifications()
3997 {
3998 	struct asyncio_reader *reader;
3999 	int fd = socket(PF_ROUTE, SOCK_RAW, 0);
4000 
4001 	if (fd >= 0) {
4002 		fd = move_fd(fd);
4003 		init_nonblocking_io(fd);
4004 #if defined(HAVE_SIGNALED_IO)
4005 		init_socket_sig(fd);
4006 #endif /* HAVE_SIGNALED_IO */
4007 
4008 		reader = new_asyncio_reader();
4009 
4010 		reader->fd = fd;
4011 		reader->receiver = process_routing_msgs;
4012 
4013 		add_asyncio_reader(reader, FD_TYPE_SOCKET);
4014 		msyslog(LOG_INFO, "Listening on routing socket on fd #%d for interface updates", fd);
4015 	} else {
4016 		msyslog(LOG_ERR, "unable to open routing socket (%m) - using polled interface update");
4017 	}
4018 }
4019 #else
4020 static void
4021 init_async_notifications()
4022 {
4023 }
4024 #endif
4025