xref: /freebsd/contrib/ntp/ntpd/ntp_io.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
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_if.h"
16 #include "ntp_stdlib.h"
17 #include "ntp.h"
18 
19 /* Don't include ISC's version of IPv6 variables and structures */
20 #define ISC_IPV6_H 1
21 #include <isc/interfaceiter.h>
22 #include <isc/list.h>
23 #include <isc/result.h>
24 
25 #ifdef SIM
26 #include "ntpsim.h"
27 #endif
28 
29 #include <stdio.h>
30 #include <signal.h>
31 #ifdef HAVE_SYS_PARAM_H
32 # include <sys/param.h>
33 #endif /* HAVE_SYS_PARAM_H */
34 #ifdef HAVE_NETINET_IN_H
35 # include <netinet/in.h>
36 #endif
37 #ifdef HAVE_NETINET_IN_SYSTM_H
38 # include <netinet/in_systm.h>
39 #else /* Some old linux systems at least have in_system.h instead. */
40 # ifdef HAVE_NETINET_IN_SYSTEM_H
41 #  include <netinet/in_system.h>
42 # endif
43 #endif /* HAVE_NETINET_IN_SYSTM_H */
44 #ifdef HAVE_NETINET_IP_H
45 # include <netinet/ip.h>
46 #endif
47 #ifdef HAVE_SYS_IOCTL_H
48 # include <sys/ioctl.h>
49 #endif
50 #ifdef HAVE_SYS_SOCKIO_H	/* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
51 # include <sys/sockio.h>
52 #endif
53 #include <arpa/inet.h>
54 
55 extern int listen_to_virtual_ips;
56 
57 #if defined(SYS_WINNT)
58 #include <transmitbuff.h>
59 #include <isc/win32os.h>
60 /*
61  * Define this macro to control the behavior of connection
62  * resets on UDP sockets.  See Microsoft KnowledgeBase Article Q263823
63  * for details.
64  * NOTE: This requires that Windows 2000 systems install Service Pack 2
65  * or later.
66  */
67 #ifndef SIO_UDP_CONNRESET
68 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
69 #endif
70 
71 #endif
72 
73 /*
74  * We do asynchronous input using the SIGIO facility.  A number of
75  * recvbuf buffers are preallocated for input.	In the signal
76  * handler we poll to see which sockets are ready and read the
77  * packets from them into the recvbuf's along with a time stamp and
78  * an indication of the source host and the interface it was received
79  * through.  This allows us to get as accurate receive time stamps
80  * as possible independent of other processing going on.
81  *
82  * We watch the number of recvbufs available to the signal handler
83  * and allocate more when this number drops below the low water
84  * mark.  If the signal handler should run out of buffers in the
85  * interim it will drop incoming frames, the idea being that it is
86  * better to drop a packet than to be inaccurate.
87  */
88 
89 
90 /*
91  * Other statistics of possible interest
92  */
93 volatile u_long packets_dropped;	/* total number of packets dropped on reception */
94 volatile u_long packets_ignored;	/* packets received on wild card interface */
95 volatile u_long packets_received;	/* total number of packets received */
96 u_long packets_sent;	/* total number of packets sent */
97 u_long packets_notsent; /* total number of packets which couldn't be sent */
98 
99 volatile u_long handler_calls;	/* number of calls to interrupt handler */
100 volatile u_long handler_pkts;	/* number of pkts received by handler */
101 u_long io_timereset;		/* time counters were reset */
102 
103 /*
104  * Interface stuff
105  */
106 struct interface *any_interface;	/* default ipv4 interface */
107 struct interface *any6_interface;	/* default ipv6 interface */
108 struct interface *loopback_interface;	/* loopback ipv4 interface */
109 struct interface *loopback6_interface;	/* loopback ipv6 interface */
110 struct interface inter_list[MAXINTERFACES]; /* Interface list */
111 int ninterfaces;			/* Total number of interfaces */
112 int nwilds;				/* Total number of wildcard intefaces */
113 int wildipv4 = -1;			/* Index into inter_list for IPv4 wildcard */
114 int wildipv6 = -1;			/* Index into inter_list for IPv6 wildcard */
115 
116 #ifdef REFCLOCK
117 /*
118  * Refclock stuff.	We keep a chain of structures with data concerning
119  * the guys we are doing I/O for.
120  */
121 static	struct refclockio *refio;
122 #endif /* REFCLOCK */
123 
124 
125 /*
126  * Define what the possible "soft" errors can be.  These are non-fatal returns
127  * of various network related functions, like recv() and so on.
128  *
129  * For some reason, BSDI (and perhaps others) will sometimes return <0
130  * from recv() but will have errno==0.  This is broken, but we have to
131  * work around it here.
132  */
133 #define SOFT_ERROR(e)	((e) == EAGAIN || \
134 			 (e) == EWOULDBLOCK || \
135 			 (e) == EINTR || \
136 			 (e) == 0)
137 
138 /*
139  * File descriptor masks etc. for call to select
140  * Not needed for I/O Completion Ports
141  */
142 fd_set activefds;
143 int maxactivefd;
144 
145 static	int create_sockets	P((u_short));
146 static	SOCKET	open_socket	P((struct sockaddr_storage *, int, int));
147 static	void	close_socket	P((SOCKET));
148 #ifdef REFCLOCK
149 static	void	close_file	P((SOCKET));
150 #endif
151 static	char *	fdbits		P((int, fd_set *));
152 static	void	set_reuseaddr	P((int));
153 
154 typedef struct vsock vsock_t;
155 
156 struct vsock {
157 	SOCKET				fd;
158 	ISC_LINK(vsock_t)		link;
159 };
160 
161 ISC_LIST(vsock_t)	sockets_list;
162 
163 typedef struct remaddr remaddr_t;
164 
165 struct remaddr {
166       struct sockaddr_storage        addr;
167       int                            if_index;
168       ISC_LINK(remaddr_t)              link;
169 };
170 
171 ISC_LIST(remaddr_t)       remoteaddr_list;
172 
173 void	add_socket_to_list	P((SOCKET));
174 void	delete_socket_from_list	P((SOCKET));
175 void	add_addr_to_list	P((struct sockaddr_storage *, int));
176 void	delete_addr_from_list	P((struct sockaddr_storage *));
177 int     find_addr_in_list P((struct sockaddr_storage *));
178 int	create_wildcards	P((u_short));
179 isc_boolean_t address_okay	P((isc_interface_t *));
180 void	convert_isc_if		P((isc_interface_t *, struct interface *, u_short));
181 
182 #ifdef SYS_WINNT
183 /*
184  * Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom
185  * to not work correctly, returning a WSACONNRESET error when a WSASendTo
186  * fails with an "ICMP port unreachable" response and preventing the
187  * socket from using the WSARecvFrom in subsequent operations.
188  * The function below fixes this, but requires that Windows 2000
189  * Service Pack 2 or later be installed on the system.  NT 4.0
190  * systems are not affected by this and work correctly.
191  * See Microsoft Knowledge Base Article Q263823 for details of this.
192  */
193 isc_result_t
194 connection_reset_fix(SOCKET fd) {
195 	DWORD dwBytesReturned = 0;
196 	BOOL  bNewBehavior = FALSE;
197 	DWORD status;
198 
199 	if(isc_win32os_majorversion() < 5)
200 		return (ISC_R_SUCCESS); /*  NT 4.0 has no problem */
201 
202 	/* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */
203 	status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,
204 			  sizeof(bNewBehavior), NULL, 0,
205 			  &dwBytesReturned, NULL, NULL);
206 	if (status != SOCKET_ERROR)
207 		return (ISC_R_SUCCESS);
208 	else
209 		return (ISC_R_UNEXPECTED);
210 }
211 #endif
212 /*
213  * init_io - initialize I/O data structures and call socket creation routine
214  */
215 void
216 init_io(void)
217 {
218 #ifdef SYS_WINNT
219 	init_transmitbuff();
220 #endif /* SYS_WINNT */
221 
222 	/*
223 	 * Init buffer free list and stat counters
224 	 */
225 	init_recvbuff(RECV_INIT);
226 
227 	packets_dropped = packets_received = 0;
228 	packets_ignored = 0;
229 	packets_sent = packets_notsent = 0;
230 	handler_calls = handler_pkts = 0;
231 	io_timereset = 0;
232 	loopback_interface = NULL;
233 	loopback6_interface = NULL;
234 
235 #ifdef REFCLOCK
236 	refio = 0;
237 #endif
238 
239 #if defined(HAVE_SIGNALED_IO)
240 	(void) set_signal();
241 #endif
242 
243 #ifdef SYS_WINNT
244 	if (!Win32InitSockets())
245 	{
246 		netsyslog(LOG_ERR, "No useable winsock.dll: %m");
247 		exit(1);
248 	}
249 #endif /* SYS_WINNT */
250 
251 	ISC_LIST_INIT(sockets_list);
252 
253         ISC_LIST_INIT(remoteaddr_list);
254 
255 	/*
256 	 * Create the sockets
257 	 */
258 	BLOCKIO();
259 	(void) create_sockets(htons(NTP_PORT));
260 	UNBLOCKIO();
261 
262 #ifdef DEBUG
263 	if (debug)
264 	    printf("init_io: maxactivefd %d\n", maxactivefd);
265 #endif
266 }
267 
268 int
269 create_wildcards(u_short port) {
270 
271 	int idx = 0;
272 	/*
273 	 * create pseudo-interface with wildcard IPv4 address
274 	 */
275 	inter_list[idx].sin.ss_family = AF_INET;
276 	((struct sockaddr_in*)&inter_list[idx].sin)->sin_addr.s_addr = htonl(INADDR_ANY);
277 	((struct sockaddr_in*)&inter_list[idx].sin)->sin_port = port;
278 	(void) strncpy(inter_list[idx].name, "wildcard", sizeof(inter_list[idx].name));
279 	inter_list[idx].mask.ss_family = AF_INET;
280 	((struct sockaddr_in*)&inter_list[idx].mask)->sin_addr.s_addr = htonl(~(u_int32)0);
281 	inter_list[idx].bfd = INVALID_SOCKET;
282 	inter_list[idx].num_mcast = 0;
283 	inter_list[idx].received = 0;
284 	inter_list[idx].sent = 0;
285 	inter_list[idx].notsent = 0;
286 	inter_list[idx].flags = INT_BROADCAST;
287 	any_interface = &inter_list[idx];
288 #if defined(MCAST)
289 	/*
290 	 * enable possible multicast reception on the broadcast socket
291 	 */
292 	inter_list[idx].bcast.ss_family = AF_INET;
293 	((struct sockaddr_in*)&inter_list[idx].bcast)->sin_port = port;
294 	((struct sockaddr_in*)&inter_list[idx].bcast)->sin_addr.s_addr = htonl(INADDR_ANY);
295 #endif /* MCAST */
296 	wildipv4 = idx;
297 	idx++;
298 
299 #ifdef HAVE_IPV6
300 	/*
301 	 * create pseudo-interface with wildcard IPv6 address
302 	 */
303 	if (isc_net_probeipv6() == ISC_R_SUCCESS) {
304 		inter_list[idx].sin.ss_family = AF_INET6;
305 		((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_addr = in6addr_any;
306 		((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_port = port;
307 		(void) strncpy(inter_list[idx].name, "wildcard", sizeof(inter_list[idx].name));
308 		inter_list[idx].mask.ss_family = AF_INET6;
309 		memset(&((struct sockaddr_in6*)&inter_list[idx].mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));
310 		inter_list[idx].bfd = INVALID_SOCKET;
311 		inter_list[idx].num_mcast = 0;
312 		inter_list[idx].received = 0;
313 		inter_list[idx].sent = 0;
314 		inter_list[idx].notsent = 0;
315 		inter_list[idx].flags = 0;
316 		any6_interface = &inter_list[idx];
317 		wildipv6 = idx;
318 		idx++;
319 	}
320 #endif
321 	return (idx);
322 }
323 
324 isc_boolean_t
325 address_okay(isc_interface_t *isc_if) {
326 
327 #ifdef DEBUG
328 	if (debug > 2)
329 	    printf("address_okay: listen Virtual: %d, IF name: %s, Up Flag: %d\n",
330 		    listen_to_virtual_ips, isc_if->name, (isc_if->flags & INTERFACE_F_UP));
331 #endif
332 
333 	if (listen_to_virtual_ips == 0  && (strchr(isc_if->name, (int)':') != NULL))
334 		return (ISC_FALSE);
335 
336 	/* XXXPDM This should be fixed later, but since we may not have set
337 	 * the UP flag, we at least get to use the interface.
338 	 * The UP flag is not always set so we don't do this right now.
339 	 */
340 /*	if ((isc_if->flags & INTERFACE_F_UP) == 0)
341 		return (ISC_FALSE);
342 */
343 	return (ISC_TRUE);
344 }
345 void
346 convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port) {
347 
348 	if(isc_if->af == AF_INET) {
349 		itf->sin.ss_family = (u_short) isc_if->af;
350 		strcpy(itf->name, isc_if->name);
351 		memcpy(&(((struct sockaddr_in*)&itf->sin)->sin_addr),
352 		       &(isc_if->address.type.in),
353 		       sizeof(struct in_addr));
354 		((struct sockaddr_in*)&itf->sin)->sin_port = port;
355 
356 		if((isc_if->flags & INTERFACE_F_BROADCAST) != 0) {
357 			itf->flags |= INT_BROADCAST;
358 			itf->bcast.ss_family = itf->sin.ss_family;
359 			memcpy(&(((struct sockaddr_in*)&itf->bcast)->sin_addr),
360 			       &(isc_if->broadcast.type.in),
361 				 sizeof(struct in_addr));
362 			((struct sockaddr_in*)&itf->bcast)->sin_port = port;
363 		}
364 
365 		itf->mask.ss_family = itf->sin.ss_family;
366 		memcpy(&(((struct sockaddr_in*)&itf->mask)->sin_addr),
367 		       &(isc_if->netmask.type.in),
368 		       sizeof(struct in_addr));
369 		((struct sockaddr_in*)&itf->mask)->sin_port = port;
370 
371 		if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback_interface == NULL))
372 		{
373 			loopback_interface = itf;
374 		}
375 	}
376 #ifdef HAVE_IPV6
377 	else if (isc_if->af == AF_INET6) {
378 		itf->sin.ss_family = (u_short) isc_if->af;
379 		strcpy(itf->name, isc_if->name);
380 		memcpy(&(((struct sockaddr_in6 *)&itf->sin)->sin6_addr),
381 		       &(isc_if->address.type.in6),
382 		       sizeof(struct in6_addr));
383 		((struct sockaddr_in6 *)&itf->sin)->sin6_port = port;
384 
385 		itf->mask.ss_family = itf->sin.ss_family;
386 		memcpy(&(((struct sockaddr_in6 *)&itf->mask)->sin6_addr),
387 		       &(isc_if->netmask.type.in6),
388 		       sizeof(struct in6_addr));
389 		((struct sockaddr_in6 *)&itf->mask)->sin6_port = port;
390 
391 		if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback6_interface == NULL))
392 		{
393 			loopback6_interface = itf;
394 		}
395 	}
396 #endif /* HAVE_IPV6 */
397 
398 		/* Process the rest of the flags */
399 
400 	if((isc_if->flags & INTERFACE_F_UP) != 0)
401 		itf->flags |= INT_UP;
402 	if((isc_if->flags & INTERFACE_F_LOOPBACK) != 0)
403 		itf->flags |= INT_LOOPBACK;
404 	if((isc_if->flags & INTERFACE_F_POINTTOPOINT) != 0)
405 		itf->flags |= INT_PPP;
406 }
407 /*
408  * create_sockets - create a socket for each interface plus a default
409  *			socket for when we don't know where to send
410  */
411 static int
412 create_sockets(
413 	u_short port
414 	)
415 {
416 	struct sockaddr_storage resmask;
417 	int i;
418 	isc_mem_t *mctx = NULL;
419 	isc_interfaceiter_t *iter = NULL;
420 	isc_boolean_t scan_ipv4 = ISC_FALSE;
421 	isc_boolean_t scan_ipv6 = ISC_FALSE;
422 	isc_result_t result;
423 	int idx = 0;
424 
425 #ifdef DEBUG
426 	if (debug)
427 	    printf("create_sockets(%d)\n", ntohs( (u_short) port));
428 #endif
429 
430 	if (isc_net_probeipv6() == ISC_R_SUCCESS)
431 		scan_ipv6 = ISC_TRUE;
432 #ifdef HAVE_IPV6
433 	else
434 		netsyslog(LOG_ERR, "no IPv6 interfaces found");
435 #endif
436 
437 	if (isc_net_probeipv4() == ISC_R_SUCCESS)
438 		scan_ipv4 = ISC_TRUE;
439 	else
440 		netsyslog(LOG_ERR, "no IPv4 interfaces found");
441 
442 	nwilds = create_wildcards(port);
443 	idx = nwilds;
444 
445 	result = isc_interfaceiter_create(mctx, &iter);
446 	if (result != ISC_R_SUCCESS)
447 		return (result);
448 
449 	for (result = isc_interfaceiter_first(iter);
450 	     result == ISC_R_SUCCESS;
451 	     result = isc_interfaceiter_next(iter))
452 	{
453 		isc_interface_t isc_if;
454 		unsigned int family;
455 
456 		result = isc_interfaceiter_current(iter, &isc_if);
457 		if (result != ISC_R_SUCCESS)
458 			break;
459 
460 		/* See if we have a valid family to use */
461 		family = isc_if.address.family;
462 		if (family != AF_INET && family != AF_INET6)
463 			continue;
464 		if (scan_ipv4 == ISC_FALSE && family == AF_INET)
465 			continue;
466 		if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
467 			continue;
468 
469 		/* Check to see if we are going to use the interface */
470 		if (address_okay(&isc_if) == ISC_TRUE) {
471 			convert_isc_if(&isc_if, &inter_list[idx], port);
472 			inter_list[idx].fd = INVALID_SOCKET;
473 			inter_list[idx].bfd = INVALID_SOCKET;
474 			inter_list[idx].num_mcast = 0;
475 			inter_list[idx].received = 0;
476 			inter_list[idx].sent = 0;
477 			inter_list[idx].notsent = 0;
478 			idx++;
479 		}
480 	}
481 	isc_interfaceiter_destroy(&iter);
482 
483 	ninterfaces = idx;
484 	/*
485 	 * I/O Completion Ports don't care about the select and FD_SET
486 	 */
487 #ifndef HAVE_IO_COMPLETION_PORT
488 	maxactivefd = 0;
489 	FD_ZERO(&activefds);
490 #endif
491 	for (i = 0; i < ninterfaces; i++) {
492 		inter_list[i].fd = open_socket(&inter_list[i].sin,
493 		    inter_list[i].flags & INT_BROADCAST, 0);
494 		if (inter_list[i].bfd != INVALID_SOCKET)
495 			msyslog(LOG_INFO, "Listening on interface %s, %s#%d",
496 				inter_list[i].name,
497 				stoa((&inter_list[i].sin)),
498 				NTP_PORT);
499 		if ((inter_list[i].flags & INT_BROADCAST) &&
500 		     inter_list[i].bfd != INVALID_SOCKET)
501 			msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
502 				stoa((&inter_list[i].bcast)),
503 				NTP_PORT);
504 #if defined (HAVE_IO_COMPLETION_PORT)
505 		if (inter_list[i].fd != INVALID_SOCKET) {
506 			io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
507 		}
508 #endif
509 	}
510 
511 	/*
512 	 * Now that we have opened all the sockets, turn off the reuse
513 	 * flag for security.
514 	 */
515 	set_reuseaddr(0);
516 
517 	/*
518 	 * Blacklist all bound interface addresses
519 	 * Wildcard interfaces are ignored.
520 	 */
521 
522 	for (i = nwilds; i < ninterfaces; i++) {
523 		SET_HOSTMASK(&resmask, inter_list[i].sin.ss_family);
524 		hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask,
525 		    RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
526 	}
527 
528 	/*
529 	 * Calculate the address hash for each interface address.
530 	 */
531 	for (i = 0; i < ninterfaces; i++) {
532 		inter_list[i].addr_refid = addr2refid(&inter_list[i].sin);
533 	}
534 
535 
536 #ifdef DEBUG
537 	if (debug > 1) {
538 		printf("create_sockets: ninterfaces=%d\n", ninterfaces);
539 		for (i = 0; i < ninterfaces; i++) {
540 			printf("interface %d:  fd=%d,  bfd=%d,  name=%.8s,  flags=0x%x\n",
541 			       i,
542 			       inter_list[i].fd,
543 			       inter_list[i].bfd,
544 			       inter_list[i].name,
545 			       inter_list[i].flags);
546 			/* Leave these as three printf calls. */
547 			printf("              sin=%s",
548 			       stoa((&inter_list[i].sin)));
549 			if (inter_list[i].flags & INT_BROADCAST)
550 			    printf("  bcast=%s,",
551 				   stoa((&inter_list[i].bcast)));
552 			printf("  mask=%s\n",
553 			       stoa((&inter_list[i].mask)));
554 		}
555 	}
556 #endif
557 	return ninterfaces;
558 }
559 
560 /*
561  * io_setbclient - open the broadcast client sockets
562  */
563 void
564 io_setbclient(void)
565 {
566 	int i;
567 
568 #ifdef OPEN_BCAST_SOCKET
569 	set_reuseaddr(1);
570 #endif
571 	for (i = nwilds; i < ninterfaces; i++) {
572 		/* Only IPv4 addresses are valid for broadcast */
573 		if (inter_list[i].bcast.ss_family != AF_INET)
574 			continue;
575 
576 		/* Is this a broadcast address? */
577 		if (!(inter_list[i].flags & INT_BROADCAST))
578 			continue;
579 
580 		/* Do we already have the broadcast address open? */
581 		if (inter_list[i].flags & INT_BCASTOPEN)
582 			continue;
583 
584 #ifdef	SYS_SOLARIS
585 		inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
586 #endif
587 #ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */
588 		inter_list[i].bfd = open_socket(&inter_list[i].bcast,
589 		    INT_BROADCAST, 1);
590 		if (inter_list[i].bfd != INVALID_SOCKET) {
591 			inter_list[i].flags |= INT_BCASTOPEN;
592 #if defined (HAVE_IO_COMPLETION_PORT)
593 			io_completion_port_add_socket(inter_list[i].bfd, &inter_list[i]);
594 #endif
595 		}
596 #ifdef DEBUG
597 		if (debug) {
598 			if (inter_list[i].bfd != INVALID_SOCKET)
599 				printf("io_setbclient: Opened broadcast client on interface %d, socket: %d\n",
600 				i, inter_list[i].bfd);
601 			else
602 				printf("io_setbclient: Unable to Open broadcast client on interface %d\n",
603 				i);
604 		}
605 #endif
606 #endif
607 	}
608 #ifdef OPEN_BCAST_SOCKET
609 	set_reuseaddr(0);
610 #endif
611 #ifdef DEBUG
612 	if (debug)
613 		printf("io_setbclient: Opened broadcast clients\n");
614 #endif
615 }
616 
617 /*
618  * set_reuseaddr() - set/clear REUSEADDR on all sockets
619  *			NB possible hole - should we be doing this on broadcast
620  *			fd's also?
621  */
622 static void
623 set_reuseaddr(int flag) {
624 	int i;
625 
626 	for (i=0; i < ninterfaces; i++) {
627 		/*
628 		 * if inter_list[ n ].fd  is -1, we might have a adapter
629 		 * configured but not present
630 		 */
631 		if (inter_list[i].fd != INVALID_SOCKET) {
632 			if (setsockopt(inter_list[i].fd, SOL_SOCKET,
633 					SO_REUSEADDR, (char *)&flag,
634 					sizeof(flag))) {
635 				netsyslog(LOG_ERR, "set_reuseaddr: setsockopt(SO_REUSEADDR, %s) failed: %m", flag ? "on" : "off");
636 			}
637 		}
638 	}
639 }
640 
641 
642 /*
643  * io_multicast_add() - add multicast group address
644  */
645 void
646 io_multicast_add(
647 	struct sockaddr_storage addr
648 	)
649 {
650 #ifdef MCAST
651 	struct ip_mreq mreq;
652 	int i = ninterfaces;	/* Use the next interface */
653 	u_int32 haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
654 	struct in_addr iaddr;
655 	SOCKET s;
656 	struct sockaddr_in *sinp;
657 
658 #ifdef HAVE_IPV6
659 	struct ipv6_mreq mreq6;
660 	struct in6_addr iaddr6;
661 	struct sockaddr_in6 *sin6p;
662 #endif /* HAVE_IPV6 */
663 
664 	switch (addr.ss_family)
665 	{
666 	case AF_INET :
667 		iaddr = (((struct sockaddr_in*)&addr)->sin_addr);
668 		if (!IN_CLASSD(haddr)) {
669 			netsyslog(LOG_ERR,
670 			"multicast address %s not class D",
671 				inet_ntoa(iaddr));
672 			return;
673 		}
674 		for (i = nwilds; i < ninterfaces; i++) {
675 			 /* Be sure it's the correct family */
676                         if (inter_list[i].sin.ss_family != AF_INET)
677                                 continue;
678 			/* Already have this address */
679 			if (SOCKCMP(&inter_list[i].sin, &addr))
680 				return;
681 			/* found a free slot */
682 			if (SOCKNUL(&inter_list[i].sin) &&
683 			inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
684 			inter_list[i].flags == 0)
685 			break;
686 		}
687 		sinp = (struct sockaddr_in*)&(inter_list[i].sin);
688 		memset((char *)&mreq, 0, sizeof(mreq));
689 		memset((char *)&inter_list[i], 0, sizeof(struct interface));
690 		sinp->sin_family = AF_INET;
691 		sinp->sin_addr = iaddr;
692 		sinp->sin_port = htons(NTP_PORT);
693 
694 		/*
695 		* Try opening a socket for the specified class D address. This
696 		* works under SunOS 4.x, but not OSF1 .. :-(
697 		*/
698 		set_reuseaddr(1);
699 		s = open_socket((struct sockaddr_storage*)sinp, 0, 1);
700 		set_reuseaddr(0);
701 		if (s == INVALID_SOCKET) {
702 			memset((char *)&inter_list[i], 0, sizeof(struct interface));
703 			if (wildipv4 >= 0) {
704 				i = wildipv4;
705 				/* HACK ! -- stuff in an address */
706 				inter_list[i].bcast = addr;
707 				netsyslog(LOG_ERR,
708 				"...multicast address %s using wildcard socket",
709 				inet_ntoa(iaddr));
710 			} else {
711 				netsyslog(LOG_ERR,
712 				"No wildcard socket available to use for address %s",
713 				inet_ntoa(iaddr));
714 				return;
715 			}
716 		} else {
717 			inter_list[i].fd = s;
718 			inter_list[i].bfd = INVALID_SOCKET;
719 			(void) strncpy(inter_list[i].name, "multicast",
720 			sizeof(inter_list[i].name));
721 			((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr = htonl(~(u_int32)0);
722 #if defined (HAVE_IO_COMPLETION_PORT)
723 			io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
724 #endif
725 		}
726 
727 		/*
728 		* enable reception of multicast packets
729 		*/
730 		mreq.imr_multiaddr = iaddr;
731 		mreq.imr_interface.s_addr = htonl(INADDR_ANY);
732 		if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
733 		(char *)&mreq, sizeof(mreq)) == -1)
734 			netsyslog(LOG_ERR,
735 			"setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)",
736 			mreq.imr_multiaddr.s_addr,
737 			mreq.imr_interface.s_addr, inet_ntoa(iaddr));
738 		inter_list[i].flags |= INT_MULTICAST;
739 		inter_list[i].num_mcast++;
740 		if (i >= ninterfaces)
741 			ninterfaces = i+1;
742 
743                 add_addr_to_list(&addr, i);
744 		break;
745 
746 #ifdef HAVE_IPV6
747 	case AF_INET6 :
748 
749 		iaddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
750 		if (!IN6_IS_ADDR_MULTICAST(&iaddr6)) {
751 			netsyslog(LOG_ERR,
752 			    "address %s not IPv6 multicast address",
753 				stoa(&addr));
754 			return;
755 		}
756 		for (i = nwilds; i < ninterfaces; i++) {
757 			/* Be sure it's the correct family */
758 			if(inter_list[i].sin.ss_family != AF_INET6)
759 				continue;
760 			/* Already have this address */
761 			if (SOCKCMP(&inter_list[i].sin, &addr))
762 				return;
763 			/* found a free slot */
764 			if (SOCKNUL(&inter_list[i].sin) &&
765 			    inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
766 			    inter_list[i].flags == 0)
767 			break;
768 		}
769 		sin6p = (struct sockaddr_in6*)&inter_list[i].sin;
770 		memset((char *)&mreq6, 0, sizeof(mreq6));
771 		memset((char *)&inter_list[i], 0, sizeof(struct interface));
772 		sin6p->sin6_family = AF_INET6;
773 		sin6p->sin6_addr = iaddr6;
774 		sin6p->sin6_port = htons(NTP_PORT);
775 
776 		/*
777 		 * Try opening a socket for the specified class D address. This
778 		 * works under SunOS 4.x, but not OSF1 .. :-(
779 		 */
780 		set_reuseaddr(1);
781 		s = open_socket((struct sockaddr_storage*)sin6p, 0, 1);
782 		set_reuseaddr(0);
783 		if(s == INVALID_SOCKET){
784 			memset((char *)&inter_list[i], 0, sizeof(struct interface));
785 			if (wildipv6 >= 0) {
786 				i = wildipv6;
787 				/* HACK ! -- stuff in an address */
788 				inter_list[i].bcast = addr;
789 				netsyslog(LOG_ERR,
790 				 "...multicast address %s using wildcard socket",
791 				 stoa(&addr));
792 			} else {
793 				netsyslog(LOG_ERR,
794 				"No wildcard socket available to use for address %s",
795 				stoa(&addr));
796 				return;
797 			}
798 		} else {
799 			inter_list[i].fd = s;
800 			inter_list[i].bfd = INVALID_SOCKET;
801 			(void)strncpy(inter_list[i].name, "multicast",
802 			   sizeof(inter_list[i].name));
803 			memset(&(((struct sockaddr_in6*)&inter_list[i].mask)->sin6_addr), 1, sizeof(struct in6_addr));
804 #if defined (HAVE_IO_COMPLETION_PORT)
805 			io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
806 #endif
807 		}
808 
809 		/*
810 		 * enable reception of multicast packets
811 		 */
812 		mreq6.ipv6mr_multiaddr = iaddr6;
813 		mreq6.ipv6mr_interface = 0;
814 		if(setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
815 		   (char *)&mreq6, sizeof(mreq6)) == -1)
816 			netsyslog(LOG_ERR,
817 			 "setsockopt IPV6_JOIN_GROUP fails: %m on interface %d(%s)",
818 			 mreq6.ipv6mr_interface, stoa(&addr));
819 		inter_list[i].flags |= INT_MULTICAST;
820 		inter_list[i].num_mcast++;
821 		if(i >= ninterfaces)
822 			ninterfaces = i+1;
823 
824                 add_addr_to_list(&addr, i);
825 		break;
826 #endif /* HAVE_IPV6 */
827 	}
828 
829 #ifdef DEBUG
830 	if (debug)
831 		printf("io_multicast_add %s\n", stoa(&addr));
832 #endif
833 #else /* MCAST */
834 	netsyslog(LOG_ERR,
835 	    "cannot add multicast address %s as no MCAST support",
836 	    stoa(&addr));
837 #endif /* MCAST */
838 }
839 
840 /*
841  * io_unsetbclient - close the broadcast client sockets
842  */
843 void
844 io_unsetbclient(void)
845 {
846 	int i;
847 
848 	for (i = nwilds; i < ninterfaces; i++)
849 	{
850 		if (!(inter_list[i].flags & INT_BCASTOPEN))
851 		    continue;
852 		close_socket(inter_list[i].bfd);
853 		inter_list[i].bfd = INVALID_SOCKET;
854 		inter_list[i].flags &= ~INT_BCASTOPEN;
855 	}
856 }
857 
858 
859 /*
860  * io_multicast_del() - delete multicast group address
861  */
862 void
863 io_multicast_del(
864 	struct sockaddr_storage addr
865 	)
866 {
867 #ifdef MCAST
868 	int i;
869 	struct ip_mreq mreq;
870 	u_int32 haddr;
871 
872 #ifdef HAVE_IPV6
873 	struct ipv6_mreq mreq6;
874 	struct in6_addr haddr6;
875 #endif /* HAVE_IPV6 */
876 
877 	switch (addr.ss_family)
878 	{
879 	case AF_INET :
880 
881 		haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
882 
883 		if (!IN_CLASSD(haddr))
884 		{
885 			netsyslog(LOG_ERR,
886 				 "invalid multicast address %s", stoa(&addr));
887 			return;
888 		}
889 
890 		/*
891 		* Disable reception of multicast packets
892 		*/
893 		mreq.imr_multiaddr = ((struct sockaddr_in*)&addr)->sin_addr;
894 		mreq.imr_interface.s_addr = htonl(INADDR_ANY);
895 		for (i = 0; i < ninterfaces; i++)
896 		{
897 			/* Be sure it's the correct family */
898 			if (inter_list[i].sin.ss_family != AF_INET)
899 				continue;
900 			if (!(inter_list[i].flags & INT_MULTICAST))
901 				continue;
902 			if (!(inter_list[i].fd < 0))
903 				continue;
904 			if (!SOCKCMP(&addr, &inter_list[i].sin))
905 				continue;
906 			if (i != wildipv4)
907 			{
908 				/* we have an explicit fd, so we can close it */
909 				close_socket(inter_list[i].fd);
910 				memset((char *)&inter_list[i], 0, sizeof(struct interface));
911 				inter_list[i].fd = INVALID_SOCKET;
912 				inter_list[i].bfd = INVALID_SOCKET;
913 			}
914 			else
915 			{
916 				/* We are sharing "any address" port :-(  Don't close it! */
917 				if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
918 					(char *)&mreq, sizeof(mreq)) == -1)
919 				netsyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails on address: %s %m",
920 					stoa(&addr));
921 				inter_list[i].num_mcast--;
922 				/* If there are none left negate the Multicast flag */
923 				if(inter_list[i].num_mcast == 0)
924 					inter_list[i].flags &= ~INT_MULTICAST;
925 			}
926 		}
927 		break;
928 
929 #ifdef HAVE_IPV6
930 	case AF_INET6 :
931 		haddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
932 
933 		if (!IN6_IS_ADDR_MULTICAST(&haddr6))
934 		{
935 			netsyslog(LOG_ERR,
936 				"invalid multicast address %s", stoa(&addr));
937 			return;
938 		}
939 
940 		/*
941 		* Disable reception of multicast packets
942 		*/
943 		mreq6.ipv6mr_multiaddr = ((struct sockaddr_in6*)&addr)->sin6_addr;
944 		mreq6.ipv6mr_interface = 0;
945 		for (i = 0; i < ninterfaces; i++)
946 		{
947 			/* Be sure it's the correct family */
948 			if (inter_list[i].sin.ss_family != AF_INET6)
949 				continue;
950 			if (!(inter_list[i].flags & INT_MULTICAST))
951 				continue;
952 			if (!(inter_list[i].fd < 0))
953 				continue;
954 			if (!SOCKCMP(&addr, &inter_list[i].sin))
955 				continue;
956 			if (i != wildipv6)
957 			{
958 				/* we have an explicit fd, so we can close it */
959 				close_socket(inter_list[i].fd);
960 				memset((char *)&inter_list[i], 0, sizeof(struct interface));
961 				inter_list[i].fd = INVALID_SOCKET;
962 				inter_list[i].bfd = INVALID_SOCKET;
963 			}
964 			else
965 			{
966 				/* We are sharing "any address" port :-(  Don't close it! */
967 				if (setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
968 					(char *)&mreq6, sizeof(mreq6)) == -1)
969 				netsyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails on address %s: %m",
970 					stoa(&addr));
971 				/* If there are none left negate the Multicast flag */
972 				if(inter_list[i].num_mcast == 0)
973 					inter_list[i].flags &= ~INT_MULTICAST;
974 			}
975 		}
976 		break;
977 #endif /* HAVE_IPV6 */
978 	}/* switch */
979         delete_addr_from_list(&addr);
980 
981 #else /* not MCAST */
982 	netsyslog(LOG_ERR, "this function requires multicast kernel");
983 #endif /* not MCAST */
984 }
985 
986 
987 /*
988  * open_socket - open a socket, returning the file descriptor
989  */
990 
991 static SOCKET
992 open_socket(
993 	struct sockaddr_storage *addr,
994 	int flags,
995 	int turn_off_reuse
996 	)
997 {
998 	int errval;
999 	SOCKET fd;
1000 	int on = 1, off = 0;
1001 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
1002 	int tos;
1003 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
1004 
1005 	if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS))
1006 		return (INVALID_SOCKET);
1007 
1008 	/* create a datagram (UDP) socket */
1009 #ifndef SYS_WINNT
1010 	if (  (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) < 0) {
1011 		errval = errno;
1012 		if(addr->ss_family == AF_INET)
1013 			netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
1014 				stoa(addr));
1015 		else if(addr->ss_family == AF_INET6)
1016 			netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
1017 				stoa(addr));
1018 		if (errval == EPROTONOSUPPORT || errval == EAFNOSUPPORT ||
1019 		    errval == EPFNOSUPPORT)
1020 			return (INVALID_SOCKET);
1021 		exit(1);
1022 		/*NOTREACHED*/
1023 	}
1024 #else
1025 	if (  (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
1026 		errval = WSAGetLastError();
1027 		if(addr->ss_family == AF_INET)
1028 			netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
1029 				stoa(addr));
1030 		else if(addr->ss_family == AF_INET6)
1031 			netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
1032 				stoa(addr));
1033 		if (errval == WSAEPROTONOSUPPORT || errval == WSAEAFNOSUPPORT ||
1034 		    errval == WSAEPFNOSUPPORT)
1035 			return (INVALID_SOCKET);
1036 		exit(1);
1037 		/*NOTREACHED*/
1038 	}
1039 	if (connection_reset_fix(fd) != ISC_R_SUCCESS) {
1040 		netsyslog(LOG_ERR, "connection_reset_fix(fd) failed on address %s: %m",
1041 			stoa(addr));
1042 	}
1043 
1044 #endif /* SYS_WINNT */
1045 
1046 	/* set SO_REUSEADDR since we will be binding the same port
1047 	   number on each interface */
1048 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1049 		       (char *)&on, sizeof(on)))
1050 	{
1051 		netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails on address %s: %m",
1052 			stoa(addr));
1053 	}
1054 
1055 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
1056 	/* set IP_TOS to minimize packet delay */
1057 	tos = IPTOS_LOWDELAY;
1058 	if (addr->ss_family == AF_INET)
1059 		if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)
1060 		{
1061 			netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m",
1062 				stoa(addr));
1063 		}
1064 
1065 #if defined(IPV6_V6ONLY)
1066         if (addr->ss_family == AF_INET6)
1067                 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
1068                 	(char*)&on, sizeof(on)))
1069                 {
1070                 	netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m",
1071 				stoa(addr));
1072 		}
1073 #else /* IPV6_V6ONLY */
1074 #if defined(IPV6_BINDV6ONLY)
1075         if (addr->ss_family == AF_INET6)
1076                 if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
1077                 	(char*)&on, sizeof(on)))
1078                 {
1079                 	netsyslog(LOG_ERR,
1080 			    "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
1081 			    stoa(addr));
1082 		}
1083 #endif /* IPV6_BINDV6ONLY */
1084 #endif /* IPV6_V6ONLY */
1085 
1086 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
1087 
1088 	/*
1089 	 * bind the local address.
1090 	 */
1091 	if (bind(fd, (struct sockaddr *)addr, SOCKLEN(addr)) < 0) {
1092 		char buff[160];
1093 
1094 		if(addr->ss_family == AF_INET)
1095 			sprintf(buff,
1096 				"bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m",
1097 				fd, addr->ss_family, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
1098 				stoa(addr),
1099 				IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags);
1100 		else if(addr->ss_family == AF_INET6)
1101 		                sprintf(buff,
1102                                 "bind() fd %d, family %d, port %d, addr %s, in6_is_addr_multicast=%d flags=%d fails: %%m",
1103                                 fd, addr->ss_family, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port),
1104                                 stoa(addr),
1105                                 IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags);
1106 		else return INVALID_SOCKET;
1107 
1108 		netsyslog(LOG_ERR, buff);
1109 		closesocket(fd);
1110 
1111 		/*
1112 		 * soft fail if opening a multicast address
1113 		 */
1114  		if(addr->ss_family == AF_INET){
1115 			if(IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)))
1116 				return (INVALID_SOCKET);
1117 		}
1118 		else {
1119 			if(IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr))
1120 				return (INVALID_SOCKET);
1121 		}
1122 #if 0
1123 		exit(1);
1124 #else
1125 		return INVALID_SOCKET;
1126 #endif
1127 	}
1128 #ifdef DEBUG
1129 	if (debug)
1130 	    printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n",
1131 		   fd,
1132 		   addr->ss_family,
1133 		   (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
1134 		   stoa(addr),
1135 		   flags);
1136 #endif
1137 
1138 	/*
1139 	 * I/O Completion Ports don't care about the select and FD_SET
1140 	 */
1141 #ifndef HAVE_IO_COMPLETION_PORT
1142 	if (fd > maxactivefd)
1143 	    maxactivefd = fd;
1144 	FD_SET(fd, &activefds);
1145 #endif
1146 	add_socket_to_list(fd);
1147 	/*
1148 	 * set non-blocking,
1149 	 */
1150 
1151 #ifdef USE_FIONBIO
1152 	/* in vxWorks we use FIONBIO, but the others are defined for old systems, so
1153 	 * all hell breaks loose if we leave them defined
1154 	 */
1155 #undef O_NONBLOCK
1156 #undef FNDELAY
1157 #undef O_NDELAY
1158 #endif
1159 
1160 #if defined(O_NONBLOCK) /* POSIX */
1161 	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
1162 	{
1163 		netsyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails on address %s: %m",
1164 			stoa(addr));
1165 		exit(1);
1166 		/*NOTREACHED*/
1167 	}
1168 #elif defined(FNDELAY)
1169 	if (fcntl(fd, F_SETFL, FNDELAY) < 0)
1170 	{
1171 		netsyslog(LOG_ERR, "fcntl(FNDELAY) fails on address %s: %m",
1172 			stoa(addr));
1173 		exit(1);
1174 		/*NOTREACHED*/
1175 	}
1176 #elif defined(O_NDELAY) /* generally the same as FNDELAY */
1177 	if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
1178 	{
1179 		netsyslog(LOG_ERR, "fcntl(O_NDELAY) fails on address %s: %m",
1180 			stoa(addr));
1181 		exit(1);
1182 		/*NOTREACHED*/
1183 	}
1184 #elif defined(FIONBIO)
1185 # if defined(VMS)
1186 		if (ioctl(fd,FIONBIO,&on) < 0)
1187 # elif defined(SYS_WINNT)
1188 		if (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
1189 # else
1190 		if (ioctl(fd,FIONBIO,&on) < 0)
1191 # endif
1192 	{
1193 		netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on address %s: %m",
1194 			stoa(addr));
1195 		exit(1);
1196 		/*NOTREACHED*/
1197 	}
1198 #elif defined(FIOSNBIO)
1199 	if (ioctl(fd,FIOSNBIO,&on) < 0)
1200 	{
1201 		netsyslog(LOG_ERR, "ioctl(FIOSNBIO) fails on address %s: %m",
1202 			stoa(addr));
1203 		exit(1);
1204 		/*NOTREACHED*/
1205 	}
1206 #else
1207 # include "Bletch: Need non-blocking I/O!"
1208 #endif
1209 
1210 #ifdef HAVE_SIGNALED_IO
1211 	init_socket_sig(fd);
1212 #endif /* not HAVE_SIGNALED_IO */
1213 
1214 	/*
1215 	 *	Turn off the SO_REUSEADDR socket option.  It apparently
1216 	 *	causes heartburn on systems with multicast IP installed.
1217 	 *	On normal systems it only gets looked at when the address
1218 	 *	is being bound anyway..
1219 	 */
1220 	if (turn_off_reuse)
1221 	    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1222 			   (char *)&off, sizeof(off)))
1223 	    {
1224 		    netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails on address %s: %m",
1225 			    stoa(addr));
1226 	    }
1227 
1228 #ifdef SO_BROADCAST
1229 	/* if this interface can support broadcast, set SO_BROADCAST */
1230 	if (flags & INT_BROADCAST)
1231 	{
1232 		if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1233 			       (char *)&on, sizeof(on)))
1234 		{
1235 			netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) on address %s: %m",
1236 				stoa(addr));
1237 		}
1238 	}
1239 #endif /* SO_BROADCAST */
1240 
1241 #if !defined(SYS_WINNT) && !defined(VMS)
1242 # ifdef DEBUG
1243 	if (debug > 1)
1244 	    printf("flags for fd %d: 0%o\n", fd,
1245 		   fcntl(fd, F_GETFL, 0));
1246 # endif
1247 #endif /* SYS_WINNT || VMS */
1248 
1249 	return fd;
1250 }
1251 
1252 
1253 /*
1254  * close_socket - close a socket and remove from the activefd list
1255  */
1256 static void
1257 close_socket(
1258 	     SOCKET fd
1259 	)
1260 {
1261 	SOCKET i, newmax;
1262 
1263 	(void) closesocket(fd);
1264 
1265 	/*
1266 	 * I/O Completion Ports don't care about select and fd_set
1267 	 */
1268 #ifndef HAVE_IO_COMPLETION_PORT
1269 	FD_CLR( (u_int) fd, &activefds);
1270 
1271 	if (fd == maxactivefd) {
1272 		newmax = 0;
1273 		for (i = 0; i < maxactivefd; i++)
1274 			if (FD_ISSET(i, &activefds))
1275 				newmax = i;
1276 		maxactivefd = newmax;
1277 	}
1278 #endif
1279 	delete_socket_from_list(fd);
1280 
1281 }
1282 
1283 
1284 /*
1285  * close_file - close a file and remove from the activefd list
1286  * added 1/31/1997 Greg Schueman for Windows NT portability
1287  */
1288 #ifdef REFCLOCK
1289 static void
1290 close_file(
1291 	SOCKET fd
1292 	)
1293 {
1294 	int i, newmax;
1295 
1296 	(void) close(fd);
1297 	/*
1298 	 * I/O Completion Ports don't care about select and fd_set
1299 	 */
1300 #ifndef HAVE_IO_COMPLETION_PORT
1301 	FD_CLR( (u_int) fd, &activefds);
1302 
1303 	if (fd == maxactivefd) {
1304 		newmax = 0;
1305 		for (i = 0; i < maxactivefd; i++)
1306 			if (FD_ISSET(i, &activefds))
1307 				newmax = i;
1308 		maxactivefd = newmax;
1309 	}
1310 #endif
1311 	delete_socket_from_list(fd);
1312 
1313 }
1314 #endif
1315 
1316 
1317 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
1318 /*
1319  * sendpkt - send a packet to the specified destination. Maintain a
1320  * send error cache so that only the first consecutive error for a
1321  * destination is logged.
1322  */
1323 void
1324 sendpkt(
1325 	struct sockaddr_storage *dest,
1326 	struct interface *inter,
1327 	int ttl,
1328 	struct pkt *pkt,
1329 	int len
1330 	)
1331 {
1332 	int cc, slot;
1333 #ifdef SYS_WINNT
1334 	DWORD err;
1335 #endif /* SYS_WINNT */
1336 
1337 	/*
1338 	 * Send error caches. Empty slots have port == 0
1339 	 * Set ERRORCACHESIZE to 0 to disable
1340 	 */
1341 	struct cache {
1342 		u_short port;
1343 		struct	in_addr addr;
1344 	};
1345 
1346 #ifdef HAVE_IPV6
1347 	struct cache6 {
1348 		u_short port;
1349 		struct in6_addr addr;
1350 	};
1351 #endif /* HAVE_IPV6 */
1352 
1353 #ifndef ERRORCACHESIZE
1354 #define ERRORCACHESIZE 8
1355 #endif
1356 #if ERRORCACHESIZE > 0
1357 	static struct cache badaddrs[ERRORCACHESIZE];
1358 #ifdef HAVE_IPV6
1359 	static struct cache6 badaddrs6[ERRORCACHESIZE];
1360 #endif /* HAVE_IPV6 */
1361 #else
1362 #define badaddrs ((struct cache *)0)		/* Only used in empty loops! */
1363 #ifdef HAVE_IPV6
1364 #define badaddrs6 ((struct cache6 *)0)		/* Only used in empty loops! */
1365 #endif /* HAVE_IPV6 */
1366 #endif
1367 #ifdef DEBUG
1368 	if (debug > 1)
1369 	    printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n",
1370 		   (ttl >= 0) ? "\tMCAST\t*****" : "",
1371 		   inter->fd, stoa(dest),
1372 		   stoa(&inter->sin), ttl, len);
1373 #endif
1374 
1375 #ifdef MCAST
1376 
1377 	switch (inter->sin.ss_family) {
1378 
1379 	case AF_INET :
1380 
1381 		/*
1382 		* for the moment we use the bcast option to set multicast ttl
1383 		*/
1384 		if (ttl > 0 && ttl != inter->last_ttl) {
1385 
1386 			/*
1387 			* set the multicast ttl for outgoing packets
1388 			*/
1389 			if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,
1390 				(char *) &ttl, sizeof(ttl)) != 0) {
1391 				netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m",
1392 					stoa(&inter->sin));
1393 			}
1394 			else
1395    				inter->last_ttl = ttl;
1396 		}
1397 		break;
1398 
1399 #ifdef HAVE_IPV6
1400 	case AF_INET6 :
1401 
1402 	 	/*
1403 		 * for the moment we use the bcast option to set
1404 		 * multicast max hops
1405 		 */
1406         	if (ttl > 0 && ttl != inter->last_ttl) {
1407 
1408                 	/*
1409                  	* set the multicast ttl for outgoing packets
1410                  	*/
1411                 	if (setsockopt(inter->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
1412                     	&ttl, sizeof(ttl)) == -1)
1413 	                        netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m",
1414 					stoa(&inter->sin));
1415                 	else
1416 	                        inter->last_ttl = ttl;
1417 	        }
1418 	        break;
1419 #endif /* HAVE_IPV6 */
1420 
1421 	default :
1422 		exit(1);
1423 
1424 	}
1425 
1426 
1427 #endif /* MCAST */
1428 
1429 	for (slot = ERRORCACHESIZE; --slot >= 0; )
1430 		if(dest->ss_family == AF_INET) {
1431 			if (badaddrs[slot].port == ((struct sockaddr_in*)dest)->sin_port &&
1432 				badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr)
1433 			break;
1434 		}
1435 #ifdef HAVE_IPV6
1436 		else if (dest->ss_family == AF_INET6) {
1437 			if (badaddrs6[slot].port == ((struct sockaddr_in6*)dest)->sin6_port &&
1438 				badaddrs6[slot].addr.s6_addr == ((struct sockaddr_in6*)dest)->sin6_addr.s6_addr)
1439 			break;
1440 		}
1441 #endif /* HAVE_IPV6 */
1442 		else exit(1);  /* address family not supported yet */
1443 
1444 #if defined(HAVE_IO_COMPLETION_PORT)
1445         err = io_completion_port_sendto(inter, pkt, len, dest);
1446 	if (err != ERROR_SUCCESS)
1447 #else
1448 #ifdef SIM
1449         cc = srvr_rply(&ntp_node,  dest, inter, pkt);
1450 #else /* SIM */
1451 	cc = sendto(inter->fd, (char *)pkt, (unsigned int)len, 0, (struct sockaddr *)dest,
1452 		    SOCKLEN(dest));
1453 #endif /* SIM */
1454 	if (cc == -1)
1455 #endif
1456 	{
1457 		inter->notsent++;
1458 		packets_notsent++;
1459 #if defined(HAVE_IO_COMPLETION_PORT)
1460 		err = WSAGetLastError();
1461 		if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0)
1462 #else
1463 		if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
1464 #endif
1465 		{
1466 			/*
1467 			 * Remember this, if there's an empty slot
1468 			 */
1469 			switch (dest->ss_family) {
1470 
1471 			case AF_INET :
1472 
1473 				for (slot = ERRORCACHESIZE; --slot >= 0; )
1474 					if (badaddrs[slot].port == 0)
1475 					{
1476 						badaddrs[slot].port = SRCPORT(dest);
1477 						badaddrs[slot].addr = ((struct sockaddr_in*)dest)->sin_addr;
1478 						break;
1479 					}
1480 				break;
1481 
1482 #ifdef HAVE_IPV6
1483 			case AF_INET6 :
1484 
1485 				for (slot = ERRORCACHESIZE; --slot >= 0; )
1486         				if (badaddrs6[slot].port == 0)
1487             				{
1488                                     		badaddrs6[slot].port = SRCPORT(dest);
1489                                     		badaddrs6[slot].addr = ((struct sockaddr_in6*)dest)->sin6_addr;
1490                                     		break;
1491                             		}
1492                 		break;
1493 #endif /* HAVE_IPV6 */
1494 
1495 			default :
1496 				exit(1);
1497 			}
1498 
1499 			netsyslog(LOG_ERR, "sendto(%s): %m", stoa(dest));
1500 		}
1501 	}
1502 	else
1503 	{
1504 		inter->sent++;
1505 		packets_sent++;
1506 		/*
1507 		 * He's not bad any more
1508 		 */
1509 		if (slot >= 0)
1510 		{
1511 			netsyslog(LOG_INFO, "Connection re-established to %s", stoa(dest));
1512 			switch (dest->ss_family) {
1513 			case AF_INET :
1514 				badaddrs[slot].port = 0;
1515 				break;
1516 #ifdef HAVE_IPV6
1517 			case AF_INET6 :
1518 				badaddrs6[slot].port = 0;
1519 				break;
1520 #endif /* HAVE_IPV6 */
1521 			}
1522 		}
1523 	}
1524 }
1525 
1526 #if !defined(HAVE_IO_COMPLETION_PORT)
1527 /*
1528  * fdbits - generate ascii representation of fd_set (FAU debug support)
1529  * HFDF format - highest fd first.
1530  */
1531 static char *
1532 fdbits(
1533 	int count,
1534 	fd_set *set
1535 	)
1536 {
1537 	static char buffer[256];
1538 	char * buf = buffer;
1539 
1540 	count = (count < 256) ? count : 255;
1541 
1542 	while (count >= 0)
1543 	{
1544 		*buf++ = FD_ISSET(count, set) ? '#' : '-';
1545 		count--;
1546 	}
1547 	*buf = '\0';
1548 
1549 	return buffer;
1550 }
1551 
1552 /*
1553  * input_handler - receive packets asynchronously
1554  */
1555 void
1556 input_handler(
1557 	l_fp *cts
1558 	)
1559 {
1560 	register int i, n;
1561 	register struct recvbuf *rb;
1562 	register int doing;
1563 	register SOCKET fd;
1564 	struct timeval tvzero;
1565 	int fromlen;
1566 	l_fp ts;			/* Timestamp at BOselect() gob */
1567 	l_fp ts_e;			/* Timestamp at EOselect() gob */
1568 	fd_set fds;
1569 	int select_count = 0;
1570 	static int handler_count = 0;
1571 
1572 	++handler_count;
1573 	if (handler_count != 1)
1574 	    msyslog(LOG_ERR, "input_handler: handler_count is %d!", handler_count);
1575 	handler_calls++;
1576 	ts = *cts;
1577 
1578 	for (;;)
1579 	{
1580 		/*
1581 		 * Do a poll to see who has data
1582 		 */
1583 
1584 		fds = activefds;
1585 		tvzero.tv_sec = tvzero.tv_usec = 0;
1586 
1587 		/*
1588 		 * If we have something to do, freeze a timestamp.
1589 		 * See below for the other cases (nothing (left) to do or error)
1590 		 */
1591 		while (0 < (n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero)))
1592 		{
1593 			++select_count;
1594 			++handler_pkts;
1595 
1596 #ifdef REFCLOCK
1597 			/*
1598 			 * Check out the reference clocks first, if any
1599 			 */
1600 			if (refio != 0)
1601 			{
1602 				register struct refclockio *rp;
1603 
1604 				for (rp = refio; rp != 0 && n > 0; rp = rp->next)
1605 				{
1606 					fd = rp->fd;
1607 					if (FD_ISSET(fd, &fds))
1608 					{
1609 						n--;
1610 						if (free_recvbuffs() == 0)
1611 						{
1612 							char buf[RX_BUFF_SIZE];
1613 
1614 							(void) read(fd, buf, sizeof buf);
1615 							packets_dropped++;
1616 							goto select_again;
1617 						}
1618 
1619 						rb = get_free_recv_buffer();
1620 
1621 						i = (rp->datalen == 0
1622 						     || rp->datalen > sizeof(rb->recv_space))
1623 						    ? sizeof(rb->recv_space) : rp->datalen;
1624 						rb->recv_length =
1625 						    read(fd, (char *)&rb->recv_space, (unsigned)i);
1626 
1627 						if (rb->recv_length == -1)
1628 						{
1629 							netsyslog(LOG_ERR, "clock read fd %d: %m", fd);
1630 							freerecvbuf(rb);
1631 							goto select_again;
1632 						}
1633 
1634 						/*
1635 						 * Got one.  Mark how
1636 						 * and when it got here,
1637 						 * put it on the full
1638 						 * list and do
1639 						 * bookkeeping.
1640 						 */
1641 						rb->recv_srcclock = rp->srcclock;
1642 						rb->dstadr = 0;
1643 						rb->fd = fd;
1644 						rb->recv_time = ts;
1645 						rb->receiver = rp->clock_recv;
1646 
1647 						if (rp->io_input)
1648 						{
1649 							/*
1650 							 * have direct
1651 							 * input routine
1652 							 * for refclocks
1653 							 */
1654 							if (rp->io_input(rb) == 0)
1655 							{
1656 								/*
1657 								 * data
1658 								 * was
1659 								 * consumed
1660 								 * -
1661 								 * nothing
1662 								 * to
1663 								 * pass
1664 								 * up
1665 								 * into
1666 								 * block
1667 								 * input
1668 								 * machine
1669 								 */
1670 								freerecvbuf(rb);
1671 #if 1
1672 								goto select_again;
1673 #else
1674 								continue;
1675 #endif
1676 							}
1677 						}
1678 
1679 						add_full_recv_buffer(rb);
1680 
1681 						rp->recvcount++;
1682 						packets_received++;
1683 					}
1684 				}
1685 			}
1686 #endif /* REFCLOCK */
1687 
1688 			/*
1689 			 * Loop through the interfaces looking for data
1690 			 * to read.
1691 			 */
1692 			for (i = ninterfaces - 1; (i >= 0) && (n > 0); i--)
1693 			{
1694 				for (doing = 0; (doing < 2) && (n > 0); doing++)
1695 				{
1696 					if (doing == 0)
1697 					{
1698 						fd = inter_list[i].fd;
1699 					}
1700 					else
1701 					{
1702 						if (!(inter_list[i].flags & INT_BCASTOPEN))
1703 						    break;
1704 						fd = inter_list[i].bfd;
1705 					}
1706 					if (fd < 0) continue;
1707 					if (FD_ISSET(fd, &fds))
1708 					{
1709 						n--;
1710 
1711 						/*
1712 						 * Get a buffer and read
1713 						 * the frame.  If we
1714 						 * haven't got a buffer,
1715 						 * or this is received
1716 						 * on the wild card
1717 						 * socket, just dump the
1718 						 * packet.
1719 						 */
1720 						if (
1721 #ifdef UDP_WILDCARD_DELIVERY
1722 				/*
1723 				 * these guys manage to put properly addressed
1724 				 * packets into the wildcard queue
1725 				 */
1726 							(free_recvbuffs() == 0)
1727 #else
1728 							((i == wildipv4) || (i == wildipv6)||
1729 							(free_recvbuffs() == 0))
1730 #endif
1731 							)
1732 	{
1733 		char buf[RX_BUFF_SIZE];
1734 		struct sockaddr_storage from;
1735 
1736 		fromlen = sizeof from;
1737 		(void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen);
1738 #ifdef DEBUG
1739 		if (debug)
1740 		    printf("%s on %d(%lu) fd=%d from %s\n",
1741 			   (i) ? "drop" : "ignore",
1742 			   i, free_recvbuffs(), fd,
1743 			   stoa(&from));
1744 #endif
1745 		if (i == wildipv4 || i == wildipv6)
1746 		    packets_ignored++;
1747 		else
1748 		    packets_dropped++;
1749 		goto select_again;
1750 	}
1751 
1752 	rb = get_free_recv_buffer();
1753 
1754 	fromlen = sizeof(struct sockaddr_storage);
1755 	rb->recv_length = recvfrom(fd,
1756 				   (char *)&rb->recv_space,
1757 				   sizeof(rb->recv_space), 0,
1758 				   (struct sockaddr *)&rb->recv_srcadr,
1759 				   &fromlen);
1760 	if (rb->recv_length == 0
1761 #ifdef EWOULDBLOCK
1762 		 || errno==EWOULDBLOCK
1763 #endif
1764 #ifdef EAGAIN
1765 		 || errno==EAGAIN
1766 #endif
1767 		 ) {
1768 		freerecvbuf(rb);
1769 	    continue;
1770 	}
1771 	else if (rb->recv_length < 0)
1772 	{
1773 		netsyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
1774  			stoa(&rb->recv_srcadr), fd);
1775 #ifdef DEBUG
1776 		if (debug)
1777 		    printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd);
1778 #endif
1779 		freerecvbuf(rb);
1780 		continue;
1781 	}
1782 #ifdef DEBUG
1783 	if (debug > 2) {
1784 		if(rb->recv_srcadr.ss_family == AF_INET)
1785 			printf("input_handler: if=%d fd=%d length %d from %08lx %s\n",
1786 		   		i, fd, rb->recv_length,
1787 				(u_long)ntohl(((struct sockaddr_in*)&rb->recv_srcadr)->sin_addr.s_addr) &
1788 				0x00000000ffffffff,
1789 			   	stoa(&rb->recv_srcadr));
1790 		else
1791 			printf("input_handler: if=%d fd=%d length %d from %s\n",
1792 				i, fd, rb->recv_length,
1793 				stoa(&rb->recv_srcadr));
1794         }
1795 #endif
1796 
1797 	/*
1798 	 * Got one.  Mark how and when it got here,
1799 	 * put it on the full list and do bookkeeping.
1800 	 */
1801 	rb->dstadr = &inter_list[i];
1802 	rb->fd = fd;
1803 	rb->recv_time = ts;
1804 	rb->receiver = receive;
1805 
1806 	add_full_recv_buffer(rb);
1807 
1808 	inter_list[i].received++;
1809 	packets_received++;
1810 	goto select_again;
1811 					}
1812 					/* Check more interfaces */
1813 				}
1814 			}
1815 		select_again:;
1816 			/*
1817 			 * Done everything from that select.  Poll again.
1818 			 */
1819 		}
1820 
1821 		/*
1822 		 * If nothing more to do, try again.
1823 		 * If nothing to do, just return.
1824 		 * If an error occurred, complain and return.
1825 		 */
1826 		if (n == 0)
1827 		{
1828 			if (select_count == 0) /* We really had nothing to do */
1829 			{
1830 				if (debug)
1831 				    netsyslog(LOG_DEBUG, "input_handler: select() returned 0");
1832 				--handler_count;
1833 				return;
1834 			}
1835 			/* We've done our work */
1836 			get_systime(&ts_e);
1837 			/*
1838 			 * (ts_e - ts) is the amount of time we spent
1839 			 * processing this gob of file descriptors.  Log
1840 			 * it.
1841 			 */
1842 			L_SUB(&ts_e, &ts);
1843 			if (debug > 3)
1844 			    netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
1845 
1846 			/* just bail. */
1847 			--handler_count;
1848 			return;
1849 		}
1850 		else if (n == -1)
1851 		{
1852 			int err = errno;
1853 
1854 			/*
1855 			 * extended FAU debugging output
1856 			 */
1857 			if (err != EINTR)
1858 			    netsyslog(LOG_ERR,
1859 				      "select(%d, %s, 0L, 0L, &0.0) error: %m",
1860 				      maxactivefd+1,
1861 				      fdbits(maxactivefd, &activefds));
1862 			if (err == EBADF) {
1863 				int j, b;
1864 
1865 				fds = activefds;
1866 				for (j = 0; j <= maxactivefd; j++)
1867 				    if (
1868 					    (FD_ISSET(j, &fds) && (read(j, &b, 0) == -1))
1869 					    )
1870 					netsyslog(LOG_ERR, "Bad file descriptor %d", j);
1871 			}
1872 			--handler_count;
1873 			return;
1874 		}
1875 	}
1876 	msyslog(LOG_ERR, "input_handler: fell out of infinite for(;;) loop!");
1877 	--handler_count;
1878 	return;
1879 }
1880 
1881 #endif
1882 /*
1883  * findinterface - find interface corresponding to address
1884  */
1885 struct interface *
1886 findinterface(
1887 	struct sockaddr_storage *addr
1888 	)
1889 {
1890 	SOCKET s;
1891 	int rtn, i;
1892 	struct sockaddr_storage saddr;
1893 	int saddrlen = SOCKLEN(addr);
1894 	/*
1895 	 * This is considerably hoke. We open a socket, connect to it
1896 	 * and slap a getsockname() on it. If anything breaks, as it
1897 	 * probably will in some j-random knockoff, we just return the
1898 	 * wildcard interface.
1899 	 */
1900 	memset(&saddr, 0, sizeof(saddr));
1901 	saddr.ss_family = addr->ss_family;
1902 	if(addr->ss_family == AF_INET)
1903 		memcpy(&((struct sockaddr_in*)&saddr)->sin_addr, &((struct sockaddr_in*)addr)->sin_addr, sizeof(struct in_addr));
1904 	else if(addr->ss_family == AF_INET6)
1905 		memcpy(&((struct sockaddr_in6*)&saddr)->sin6_addr, &((struct sockaddr_in6*)addr)->sin6_addr, sizeof(struct in6_addr));
1906 	((struct sockaddr_in*)&saddr)->sin_port = htons(2000);
1907 	s = socket(addr->ss_family, SOCK_DGRAM, 0);
1908 	if (s == INVALID_SOCKET)
1909 		return ANY_INTERFACE_CHOOSE(addr);
1910 
1911 	rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr));
1912 #ifndef SYS_WINNT
1913 	if (rtn < 0)
1914 #else
1915 	if (rtn == SOCKET_ERROR)
1916 #endif
1917 	{
1918 		closesocket(s);
1919 		return ANY_INTERFACE_CHOOSE(addr);
1920 	}
1921 
1922 	rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen);
1923 	closesocket(s);
1924 #ifndef SYS_WINNT
1925 	if (rtn < 0)
1926 #else
1927 	if (rtn == SOCKET_ERROR)
1928 #endif
1929 		return ANY_INTERFACE_CHOOSE(addr);
1930 
1931 	for (i = 0; i < ninterfaces; i++) {
1932 		/*
1933 		* First look if is the the correct family
1934 		*/
1935 		if(inter_list[i].sin.ss_family != saddr.ss_family)
1936 	  		continue;
1937 		/*
1938 		 * We match the unicast address only.
1939 		 */
1940 		if (SOCKCMP(&inter_list[i].sin, &saddr))
1941 			return (&inter_list[i]);
1942 	}
1943 	return ANY_INTERFACE_CHOOSE(addr);
1944 }
1945 
1946 /*
1947  * findbcastinter - find broadcast interface corresponding to address
1948  */
1949 struct interface *
1950 findbcastinter(
1951 	struct sockaddr_storage *addr
1952 	)
1953 {
1954 #if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
1955 	register int i;
1956 
1957 	i = find_addr_in_list(addr);
1958 	if(i >= 0)
1959 	     return (&inter_list[i]);
1960 
1961 	for (i = 0; i < ninterfaces; i++) {
1962 		/*
1963 		* First look if this is the correct family
1964 		*/
1965 		if(inter_list[i].sin.ss_family != addr->ss_family)
1966 	  		continue;
1967 		/*
1968 		 * We match only those interfaces marked as
1969 		 * broadcastable and either the explicit broadcast
1970 		 * address or the network portion of the IP address.
1971 		 * Sloppy.
1972 		 */
1973 		if (!(inter_list[i].flags & INT_BROADCAST))
1974 			continue;
1975 		if(addr->ss_family == AF_INET) {
1976 			if (SOCKCMP(&inter_list[i].bcast, addr))
1977 				return (&inter_list[i]);
1978 			if ((NSRCADR(&inter_list[i].sin) &
1979 				NSRCADR(&inter_list[i].mask)) == (NSRCADR(addr) &
1980 			    	NSRCADR(&inter_list[i].mask)))
1981 				return (&inter_list[i]);
1982 		}
1983 		else if(addr->ss_family == AF_INET6) {
1984 			if (SOCKCMP(&inter_list[i].bcast, addr))
1985 				return (&inter_list[i]);
1986 			if (SOCKCMP(netof(&inter_list[i].sin), netof(addr)))
1987 				return (&inter_list[i]);
1988 		     }
1989 	}
1990 #endif /* SIOCGIFCONF */
1991  	return ANY_INTERFACE_CHOOSE(addr);
1992 }
1993 
1994 
1995 /*
1996  * io_clr_stats - clear I/O module statistics
1997  */
1998 void
1999 io_clr_stats(void)
2000 {
2001 	packets_dropped = 0;
2002 	packets_ignored = 0;
2003 	packets_received = 0;
2004 	packets_sent = 0;
2005 	packets_notsent = 0;
2006 
2007 	handler_calls = 0;
2008 	handler_pkts = 0;
2009 	io_timereset = current_time;
2010 }
2011 
2012 
2013 #ifdef REFCLOCK
2014 /*
2015  * This is a hack so that I don't have to fool with these ioctls in the
2016  * pps driver ... we are already non-blocking and turn on SIGIO thru
2017  * another mechanisim
2018  */
2019 int
2020 io_addclock_simple(
2021 	struct refclockio *rio
2022 	)
2023 {
2024 	BLOCKIO();
2025 	/*
2026 	 * Stuff the I/O structure in the list and mark the descriptor
2027 	 * in use.	There is a harmless (I hope) race condition here.
2028 	 */
2029 	rio->next = refio;
2030 	refio = rio;
2031 
2032 	/*
2033 	 * I/O Completion Ports don't care about select and fd_set
2034 	 */
2035 #ifndef HAVE_IO_COMPLETION_PORT
2036 	if (rio->fd > maxactivefd)
2037 	    maxactivefd = rio->fd;
2038 	FD_SET(rio->fd, &activefds);
2039 #endif
2040 	UNBLOCKIO();
2041 	return 1;
2042 }
2043 
2044 /*
2045  * io_addclock - add a reference clock to the list and arrange that we
2046  *				 get SIGIO interrupts from it.
2047  */
2048 int
2049 io_addclock(
2050 	struct refclockio *rio
2051 	)
2052 {
2053 	BLOCKIO();
2054 	/*
2055 	 * Stuff the I/O structure in the list and mark the descriptor
2056 	 * in use.	There is a harmless (I hope) race condition here.
2057 	 */
2058 	rio->next = refio;
2059 	refio = rio;
2060 
2061 # ifdef HAVE_SIGNALED_IO
2062 	if (init_clock_sig(rio))
2063 	{
2064 		refio = rio->next;
2065 		UNBLOCKIO();
2066 		return 0;
2067 	}
2068 # elif defined(HAVE_IO_COMPLETION_PORT)
2069 	if (io_completion_port_add_clock_io(rio))
2070 	{
2071 		add_socket_to_list(rio->fd);
2072 		refio = rio->next;
2073 		UNBLOCKIO();
2074 		return 0;
2075 	}
2076 # endif
2077 
2078 	/*
2079 	 * I/O Completion Ports don't care about select and fd_set
2080 	 */
2081 #ifndef HAVE_IO_COMPLETION_PORT
2082 	if (rio->fd > maxactivefd)
2083 	    maxactivefd = rio->fd;
2084 	FD_SET(rio->fd, &activefds);
2085 #endif
2086 	UNBLOCKIO();
2087 	return 1;
2088 }
2089 
2090 /*
2091  * io_closeclock - close the clock in the I/O structure given
2092  */
2093 void
2094 io_closeclock(
2095 	struct refclockio *rio
2096 	)
2097 {
2098 	/*
2099 	 * Remove structure from the list
2100 	 */
2101 	if (refio == rio)
2102 	{
2103 		refio = rio->next;
2104 	}
2105 	else
2106 	{
2107 		register struct refclockio *rp;
2108 
2109 		for (rp = refio; rp != 0; rp = rp->next)
2110 		    if (rp->next == rio)
2111 		    {
2112 			    rp->next = rio->next;
2113 			    break;
2114 		    }
2115 
2116 		if (rp == 0)
2117 		{
2118 			/*
2119 			 * Internal error.	Report it.
2120 			 */
2121 			msyslog(LOG_ERR,
2122 				"internal error: refclockio structure not found");
2123 			return;
2124 		}
2125 	}
2126 
2127 	/*
2128 	 * Close the descriptor.
2129 	 */
2130 	close_file(rio->fd);
2131 }
2132 #endif	/* REFCLOCK */
2133 
2134 	/*
2135 	 * I/O Completion Ports don't care about select and fd_set
2136 	 */
2137 #ifndef HAVE_IO_COMPLETION_PORT
2138 void
2139 kill_asyncio(
2140 	int startfd
2141 	)
2142 {
2143 	SOCKET i;
2144 
2145 	BLOCKIO();
2146 	for (i = startfd; i <= maxactivefd; i++)
2147 	    (void)close_socket(i);
2148 }
2149 #else
2150 /*
2151  * On NT a SOCKET is an unsigned int so we cannot possibly keep it in
2152  * an array. So we use one of the ISC_LIST functions to hold the
2153  * socket value and use that when we want to enumerate it.
2154  */
2155 void
2156 kill_asyncio(int startfd)
2157 {
2158 	vsock_t *lsock;
2159 	vsock_t *next;
2160 
2161 	BLOCKIO();
2162 
2163 	lsock = ISC_LIST_HEAD(sockets_list);
2164 	while (lsock != NULL) {
2165 		next = ISC_LIST_NEXT(lsock, link);
2166 		close_socket(lsock->fd);
2167 		lsock = next;
2168 	}
2169 
2170 }
2171 #endif
2172 /*
2173  * Add and delete functions for the list of open sockets
2174  */
2175 void
2176 add_socket_to_list(SOCKET fd){
2177 	vsock_t *lsock = malloc(sizeof(vsock_t));
2178 	lsock->fd = fd;
2179 
2180 	ISC_LIST_APPEND(sockets_list, lsock, link);
2181 }
2182 void
2183 delete_socket_from_list(SOCKET fd) {
2184 
2185 	vsock_t *next;
2186 	vsock_t *lsock = ISC_LIST_HEAD(sockets_list);
2187 
2188 	while(lsock != NULL) {
2189 		next = ISC_LIST_NEXT(lsock, link);
2190 		if(lsock->fd == fd) {
2191 			ISC_LIST_DEQUEUE(sockets_list, lsock, link);
2192 			free(lsock);
2193 			break;
2194 		}
2195 		else
2196 			lsock = next;
2197 	}
2198 }
2199 void
2200 add_addr_to_list(struct sockaddr_storage *addr, int if_index){
2201 	remaddr_t *laddr = malloc(sizeof(remaddr_t));
2202 	memcpy(&laddr->addr, addr, sizeof(addr));
2203 	laddr->if_index = if_index;
2204 
2205 	ISC_LIST_APPEND(remoteaddr_list, laddr, link);
2206 #ifdef DEBUG
2207 	if (debug)
2208 	    printf("Added addr %s to list of addresses\n",
2209 		   stoa(addr));
2210 #endif
2211 
2212 
2213 }
2214 void
2215 delete_addr_from_list(struct sockaddr_storage *addr) {
2216 
2217 	remaddr_t *next;
2218 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
2219 
2220 	while(laddr != NULL) {
2221 		next = ISC_LIST_NEXT(laddr, link);
2222 		if(SOCKCMP(&laddr->addr, addr)) {
2223 			ISC_LIST_DEQUEUE(remoteaddr_list, laddr, link);
2224 			free(laddr);
2225 			break;
2226 		}
2227 		else
2228 			laddr = next;
2229 	}
2230 #ifdef DEBUG
2231 	if (debug)
2232 	    printf("Deleted addr %s from list of addresses\n",
2233 		   stoa(addr));
2234 #endif
2235 }
2236 int
2237 find_addr_in_list(struct sockaddr_storage *addr) {
2238 
2239 	remaddr_t *next;
2240 	remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
2241 #ifdef DEBUG
2242 	if (debug)
2243 	    printf("Finding addr %s in list of addresses\n",
2244 		   stoa(addr));
2245 #endif
2246 
2247 	while(laddr != NULL) {
2248 		next = ISC_LIST_NEXT(laddr, link);
2249 		if(SOCKCMP(&laddr->addr, addr)) {
2250 			return (laddr->if_index);
2251 			break;
2252 		}
2253 		else
2254 			laddr = next;
2255 	}
2256 	return (-1); /* Not found */
2257 }
2258