xref: /freebsd/contrib/ntp/ntpd/ntp_io.c (revision 5129159789cc9d7bc514e4546b88e3427695002d)
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 <stdio.h>
11 #include <signal.h>
12 #include <sys/types.h>
13 #ifdef HAVE_SYS_PARAM_H
14 # include <sys/param.h>
15 #endif /* HAVE_SYS_PARAM_H */
16 #ifdef HAVE_SYS_TIME_H
17 # include <sys/time.h>
18 #endif
19 #ifdef HAVE_NETINET_IN_H
20 # include <netinet/in.h>
21 #endif
22 #ifdef HAVE_SYS_IOCTL_H
23 # include <sys/ioctl.h>
24 #endif
25 #ifdef HAVE_SYS_SOCKIO_H	/* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
26 # include <sys/sockio.h>
27 #endif
28 #include <arpa/inet.h>
29 
30 #if _BSDI_VERSION >= 199510
31 # include <ifaddrs.h>
32 #endif
33 
34 #include "ntp_machine.h"
35 #include "ntpd.h"
36 #include "ntp_io.h"
37 #include "iosignal.h"
38 #include "ntp_refclock.h"
39 #include "ntp_if.h"
40 #include "ntp_stdlib.h"
41 
42 #if defined(VMS)		/* most likely UCX-specific */
43 
44 #include <UCX$INETDEF.H>
45 
46 /* "un*x"-compatible names for some items in UCX$INETDEF.H */
47 #define ifreq		IFREQDEF
48 #define ifr_name	IFR$T_NAME
49 #define ifr_addr		IFR$R_DUMMY.IFR$T_ADDR
50 #define ifr_broadaddr	IFR$R_DUMMY.IFR$T_BROADADDR
51 #define ifr_flags		IFR$R_DUMMY.IFR$R_DUMMY_1_OVRL.IFR$W_FLAGS
52 #define IFF_UP		IFR$M_IFF_UP
53 #define IFF_BROADCAST	IFR$M_IFF_BROADCAST
54 #define IFF_LOOPBACK	IFR$M_IFF_LOOPBACK
55 
56 #endif /* VMS */
57 
58 
59 #if defined(VMS) || defined(SYS_WINNT)
60 /* structure used in SIOCGIFCONF request (after [KSR] OSF/1) */
61 struct ifconf {
62 	int ifc_len;			/* size of buffer */
63 	union {
64 		caddr_t ifcu_buf;
65 		struct ifreq *ifcu_req;
66 	} ifc_ifcu;
67 };
68 #define ifc_buf ifc_ifcu.ifcu_buf	/* buffer address */
69 #define ifc_req ifc_ifcu.ifcu_req	/* array of structures returned */
70 
71 #endif /* VMS */
72 
73 #if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
74 # if defined(SYS_AIX) && defined(_IO) /* XXX Identify AIX some other way */
75 #  undef _IO
76 # endif
77 # include <stropts.h>
78 #endif
79 
80 /*
81  * We do asynchronous input using the SIGIO facility.  A number of
82  * recvbuf buffers are preallocated for input.	In the signal
83  * handler we poll to see which sockets are ready and read the
84  * packets from them into the recvbuf's along with a time stamp and
85  * an indication of the source host and the interface it was received
86  * through.  This allows us to get as accurate receive time stamps
87  * as possible independent of other processing going on.
88  *
89  * We watch the number of recvbufs available to the signal handler
90  * and allocate more when this number drops below the low water
91  * mark.  If the signal handler should run out of buffers in the
92  * interim it will drop incoming frames, the idea being that it is
93  * better to drop a packet than to be inaccurate.
94  */
95 
96 
97 /*
98  * Other statistics of possible interest
99  */
100 volatile u_long packets_dropped;	/* total number of packets dropped on reception */
101 volatile u_long packets_ignored;	/* packets received on wild card interface */
102 volatile u_long packets_received;	/* total number of packets received */
103 u_long packets_sent;	/* total number of packets sent */
104 u_long packets_notsent; /* total number of packets which couldn't be sent */
105 
106 volatile u_long handler_calls;	/* number of calls to interrupt handler */
107 volatile u_long handler_pkts;	/* number of pkts received by handler */
108 u_long io_timereset;		/* time counters were reset */
109 
110 /*
111  * Interface stuff
112  */
113 struct interface *any_interface;	/* pointer to default interface */
114 struct interface *loopback_interface;	/* point to loopback interface */
115 static	struct interface inter_list[MAXINTERFACES];
116 static	int ninterfaces;
117 
118 #ifdef REFCLOCK
119 /*
120  * Refclock stuff.	We keep a chain of structures with data concerning
121  * the guys we are doing I/O for.
122  */
123 static	struct refclockio *refio;
124 #endif /* REFCLOCK */
125 
126 /*
127  * File descriptor masks etc. for call to select
128  */
129 fd_set activefds;
130 int maxactivefd;
131 
132 static	int create_sockets	P((u_int));
133 static	int open_socket		P((struct sockaddr_in *, int, int));
134 static	void	close_socket	P((int));
135 static	void	close_file	P((int));
136 static	char *	fdbits		P((int, fd_set *));
137 
138 /*
139  * init_io - initialize I/O data structures and call socket creation routine
140  */
141 void
142 init_io(void)
143 {
144 #ifdef SYS_WINNT
145 	WORD wVersionRequested;
146 	WSADATA wsaData;
147 	init_transmitbuff();
148 #endif /* SYS_WINNT */
149 
150 	/*
151 	 * Init buffer free list and stat counters
152 	 */
153 	init_recvbuff(RECV_INIT);
154 
155 	packets_dropped = packets_received = 0;
156 	packets_ignored = 0;
157 	packets_sent = packets_notsent = 0;
158 	handler_calls = handler_pkts = 0;
159 	io_timereset = 0;
160 	loopback_interface = 0;
161 
162 #ifdef REFCLOCK
163 	refio = 0;
164 #endif
165 
166 #if defined(HAVE_SIGNALED_IO)
167 	(void) set_signal();
168 #endif
169 
170 #ifdef SYS_WINNT
171 	wVersionRequested = MAKEWORD(1,1);
172 	if (WSAStartup(wVersionRequested, &wsaData))
173 	{
174 		msyslog(LOG_ERR, "No useable winsock.dll: %m");
175 		exit(1);
176 	}
177 #endif /* SYS_WINNT */
178 
179 	/*
180 	 * Create the sockets
181 	 */
182 	BLOCKIO();
183 	(void) create_sockets(htons(NTP_PORT));
184 	UNBLOCKIO();
185 
186 #ifdef DEBUG
187 	if (debug)
188 	    printf("init_io: maxactivefd %d\n", maxactivefd);
189 #endif
190 }
191 
192 /*
193  * create_sockets - create a socket for each interface plus a default
194  *			socket for when we don't know where to send
195  */
196 static int
197 create_sockets(
198 	u_int port
199 	)
200 {
201 #if _BSDI_VERSION >= 199510
202 	int i, j;
203 	struct ifaddrs *ifaddrs, *ifap;
204 	struct sockaddr_in resmask;
205 #if 	_BSDI_VERSION < 199701
206 	struct ifaddrs *lp;
207 	int num_if;
208 #endif
209 #else	/* _BSDI_VERSION >= 199510 */
210 # ifdef STREAMS_TLI
211 	struct strioctl ioc;
212 # endif /* STREAMS_TLI */
213 	char	buf[MAXINTERFACES*sizeof(struct ifreq)];
214 	struct	ifconf	ifc;
215 	struct	ifreq	ifreq, *ifr;
216 	int n, i, j, vs, size = 0;
217 	struct sockaddr_in resmask;
218 #endif	/* _BSDI_VERSION >= 199510 */
219 
220 #ifdef DEBUG
221 	if (debug)
222 	    printf("create_sockets(%d)\n", ntohs( (u_short) port));
223 #endif
224 
225 	/*
226 	 * create pseudo-interface with wildcard address
227 	 */
228 	inter_list[0].sin.sin_family = AF_INET;
229 	inter_list[0].sin.sin_port = port;
230 	inter_list[0].sin.sin_addr.s_addr = htonl(INADDR_ANY);
231 	(void) strncpy(inter_list[0].name, "wildcard",
232 		       sizeof(inter_list[0].name));
233 	inter_list[0].mask.sin_addr.s_addr = htonl(~ (u_int32)0);
234 	inter_list[0].received = 0;
235 	inter_list[0].sent = 0;
236 	inter_list[0].notsent = 0;
237 	inter_list[0].flags = INT_BROADCAST;
238 
239 #if _BSDI_VERSION >= 199510
240 #if 	_BSDI_VERSION >= 199701
241 	if (getifaddrs(&ifaddrs) < 0)
242 	{
243 		msyslog(LOG_ERR, "getifaddrs: %m");
244 		exit(1);
245 	}
246 	i = 1;
247 	for (ifap = ifaddrs; ifap != NULL; ifap = ifap->ifa_next)
248 #else
249 	    if (getifaddrs(&ifaddrs, &num_if) < 0)
250 	    {
251 		    msyslog(LOG_ERR, "create_sockets: getifaddrs() failed: %m");
252 		    exit(1);
253 	    }
254 
255 	i = 1;
256 
257 	for (ifap = ifaddrs, lp = ifap + num_if; ifap < lp; ifap++)
258 #endif
259 	{
260 		struct sockaddr_in *sin;
261 
262 		if (!ifap->ifa_addr)
263 		    continue;
264 
265 		if (ifap->ifa_addr->sa_family != AF_INET)
266 		    continue;
267 
268 		if ((ifap->ifa_flags & IFF_UP) == 0)
269 		    continue;
270 
271 		if (ifap->ifa_flags & IFF_LOOPBACK)
272 		{
273 			sin = (struct sockaddr_in *)ifap->ifa_addr;
274 			if (ntohl(sin->sin_addr.s_addr) != 0x7f000001)
275 			{
276 				continue;
277 			}
278 		}
279 
280 		inter_list[i].flags = 0;
281 		if (ifap->ifa_flags & IFF_BROADCAST)
282 		    inter_list[i].flags |= INT_BROADCAST;
283 
284 		(void)strcpy(inter_list[i].name, ifap->ifa_name);
285 
286 		sin = (struct sockaddr_in *)ifap->ifa_addr;
287 		inter_list[i].sin = *sin;
288 		inter_list[i].sin.sin_port = port;
289 
290 		if (ifap->ifa_flags & IFF_LOOPBACK)
291 		{
292 			inter_list[i].flags = INT_LOOPBACK;
293 			if (loopback_interface == NULL
294 			    || ntohl(sin->sin_addr.s_addr) != 0x7f000001)
295 			    loopback_interface = &inter_list[i];
296 		}
297 
298 		if (inter_list[i].flags & INT_BROADCAST)
299 		{
300 			sin = (struct sockaddr_in *)ifap->ifa_broadaddr;
301 			inter_list[i].bcast = *sin;
302 			inter_list[i].bcast.sin_port = port;
303 		}
304 
305 		if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
306 		{
307 			inter_list[i].mask.sin_addr.s_addr = 0xffffffff;
308 		}
309 		else
310 		{
311 			sin = (struct sockaddr_in *)ifap->ifa_netmask;
312 			inter_list[i].mask = *sin;
313 		}
314 		inter_list[i].mask.sin_family = AF_INET;
315 		inter_list[i].mask.sin_len = sizeof *sin;
316 
317 		/*
318 		 * look for an already existing source interface address.  If
319 		 * the machine has multiple point to point interfaces, then
320 		 * the local address may appear more than once.
321 		 *
322 		 * A second problem exists if we have two addresses on
323 		 * the same network (via "ifconfig alias ...").  Don't
324 		 * make two xntp interfaces for the two aliases on the
325 		 * one physical interface. -wsr
326 		 */
327 		for (j=0; j < i; j++)
328 		    if (inter_list[j].sin.sin_addr.s_addr &
329 			inter_list[j].mask.sin_addr.s_addr ==
330 			inter_list[i].sin.sin_addr.s_addr &
331 			inter_list[i].mask.sin_addr.s_addr)
332 		    {
333 			    if (inter_list[j].flags & INT_LOOPBACK)
334 				inter_list[j] = inter_list[i];
335 			    break;
336 		    }
337 		if (j == i)
338 		    i++;
339 		if (i > MAXINTERFACES)
340 		    break;
341 	}
342 	free(ifaddrs);
343 #else	/* _BSDI_VERSION >= 199510 */
344 # ifdef USE_STREAMS_DEVICE_FOR_IF_CONFIG
345 	if ((vs = open("/dev/ip", O_RDONLY)) < 0)
346 	{
347 		msyslog(LOG_ERR, "create_sockets: open(/dev/ip) failed: %m");
348 		exit(1);
349 	}
350 # else /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
351 	if (
352 		(vs = socket(AF_INET, SOCK_DGRAM, 0))
353 #  ifndef SYS_WINNT
354 		< 0
355 #  else /* SYS_WINNT */
356 		== INVALID_SOCKET
357 #  endif /* SYS_WINNT */
358 		) {
359 		msyslog(LOG_ERR, "create_sockets: socket(AF_INET, SOCK_DGRAM) failed: %m");
360 		exit(1);
361 	}
362 # endif /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
363 
364 	i = 1;
365 # if !defined(SYS_WINNT)
366 	ifc.ifc_len = sizeof(buf);
367 # endif
368 # ifdef STREAMS_TLI
369 	ioc.ic_cmd = SIOCGIFCONF;
370 	ioc.ic_timout = 0;
371 	ioc.ic_dp = (caddr_t)buf;
372 	ioc.ic_len = sizeof(buf);
373 	if(ioctl(vs, I_STR, &ioc) < 0 ||
374 	   ioc.ic_len < sizeof(struct ifreq))
375 	{
376 		msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFCONF) failed: %m - exiting");
377 		exit(1);
378 	}
379 #  ifdef SIZE_RETURNED_IN_BUFFER
380 	ifc.ifc_len = ioc.ic_len - sizeof(int);
381 	ifc.ifc_buf = buf + sizeof(int);
382 #  else /* not SIZE_RETURNED_IN_BUFFER */
383 	ifc.ifc_len = ioc.ic_len;
384 	ifc.ifc_buf = buf;
385 #  endif /* not SIZE_RETURNED_IN_BUFFER */
386 
387 # else /* not STREAMS_TLI */
388 	ifc.ifc_len = sizeof(buf);
389 	ifc.ifc_buf = buf;
390 #  ifndef SYS_WINNT
391 	if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0)
392 #  else
393  	if (WSAIoctl(vs, SIO_GET_INTERFACE_LIST, 0, 0, ifc.ifc_buf, ifc.ifc_len, &ifc.ifc_len, 0, 0) == SOCKET_ERROR)
394 #  endif /* SYS_WINNT */
395 {
396 		msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFCONF) failed: %m - exiting");
397 		exit(1);
398 }
399 
400 # endif /* not STREAMS_TLI */
401 
402 	for(n = ifc.ifc_len, ifr = ifc.ifc_req; n > 0;
403 	    ifr = (struct ifreq *)((char *)ifr + size))
404 	{
405 		extern int listen_to_virtual_ips;
406 
407 		size = sizeof(*ifr);
408 
409 # ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
410 		if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
411 		    size += ifr->ifr_addr.sa_len - sizeof(struct sockaddr);
412 # endif
413 		n -= size;
414 
415 # if !defined(SYS_WINNT)
416 		/* Exclude logical interfaces (indicated by ':' in the interface name)	*/
417 		if (debug)
418 			printf("interface <%s> ", ifr->ifr_name);
419 		if ((listen_to_virtual_ips == 0)
420 		    && (strchr(ifr->ifr_name, (int)':') != NULL)) {
421 			if (debug)
422 			    printf("ignored\n");
423 			continue;
424 		}
425 		if (debug)
426 		    printf("OK\n");
427 
428 		if (
429 #  ifdef VMS /* VMS+UCX */
430 			(((struct sockaddr *)&(ifr->ifr_addr))->sa_family != AF_INET)
431 #  else
432 			(ifr->ifr_addr.sa_family != AF_INET)
433 #  endif /* VMS+UCX */
434 			) {
435 			if (debug)
436 			    printf("ignoring %s - not AF_INET\n",
437 				   ifr->ifr_name);
438 			continue;
439 		}
440 # endif /* SYS_WINNT */
441 		ifreq = *ifr;
442 		inter_list[i].flags = 0;
443 		/* is it broadcast capable? */
444 # ifndef SYS_WINNT
445 #  ifdef STREAMS_TLI
446 		ioc.ic_cmd = SIOCGIFFLAGS;
447 		ioc.ic_timout = 0;
448 		ioc.ic_dp = (caddr_t)&ifreq;
449 		ioc.ic_len = sizeof(struct ifreq);
450 		if(ioctl(vs, I_STR, &ioc)) {
451 			msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFFLAGS) failed: %m");
452 			continue;
453 		}
454 #  else /* not STREAMS_TLI */
455 		if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
456 			if (errno != ENXIO)
457 			    msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFFLAGS) failed: %m");
458 			continue;
459 		}
460 #  endif /* not STREAMS_TLI */
461 		if ((ifreq.ifr_flags & IFF_UP) == 0) {
462 			if (debug)
463 			    printf("ignoring %s - interface not UP\n",
464 				   ifr->ifr_name);
465 			continue;
466 		}
467 		inter_list[i].flags = 0;
468 		if (ifreq.ifr_flags & IFF_BROADCAST)
469 		    inter_list[i].flags |= INT_BROADCAST;
470 # endif /* not SYS_WINNT */
471 # if !defined(SUN_3_3_STINKS)
472 		if (
473 #  if defined(IFF_LOCAL_LOOPBACK) /* defined(SYS_HPUX) && (SYS_HPUX < 8) */
474 			(ifreq.ifr_flags & IFF_LOCAL_LOOPBACK)
475 #  elif defined(IFF_LOOPBACK)
476 			(ifreq.ifr_flags & IFF_LOOPBACK)
477 #  else /* not IFF_LOCAL_LOOPBACK and not IFF_LOOPBACK */
478 			/* test against 127.0.0.1 (yuck!!) */
479 			(inter_list[i].sin.sin_addr.s_addr == inet_addr("127.0.0.1"))
480 #  endif /* not IFF_LOCAL_LOOPBACK and not IFF_LOOPBACK */
481 			)
482 		{
483 #  ifndef SYS_WINNT
484 			inter_list[i].flags |= INT_LOOPBACK;
485 #  endif /* not SYS_WINNT */
486 			if (loopback_interface == 0)
487 			{
488 				loopback_interface = &inter_list[i];
489 			}
490 		}
491 # endif /* not SUN_3_3_STINKS */
492 
493 #if 0
494 # ifndef SYS_WINNT
495 #  ifdef STREAMS_TLI
496 		ioc.ic_cmd = SIOCGIFADDR;
497 		ioc.ic_timout = 0;
498 		ioc.ic_dp = (caddr_t)&ifreq;
499 		ioc.ic_len = sizeof(struct ifreq);
500 		if (ioctl(vs, I_STR, &ioc))
501 		{
502 			msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFADDR) failed: %m");
503 			continue;
504 		}
505 #  else /* not STREAMS_TLI */
506 		if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0)
507 		{
508 			if (errno != ENXIO)
509 			    msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFADDR) failed: %m");
510 			continue;
511 		}
512 #  endif /* not STREAMS_TLI */
513 # endif /* not SYS_WINNT */
514 #endif /* 0 */
515 # if defined(SYS_WINNT)
516 		{int TODO_FillInTheNameWithSomeThingReasonble;}
517 # else
518   		(void)strncpy(inter_list[i].name, ifreq.ifr_name,
519   			      sizeof(inter_list[i].name));
520 # endif
521 		inter_list[i].sin = *(struct sockaddr_in *)&ifr->ifr_addr;
522 		inter_list[i].sin.sin_family = AF_INET;
523 		inter_list[i].sin.sin_port = port;
524 
525 # if defined(SUN_3_3_STINKS)
526 		/*
527 		 * Oh, barf!  I'm too disgusted to even explain this
528 		 */
529 		if (SRCADR(&inter_list[i].sin) == 0x7f000001)
530 		{
531 			inter_list[i].flags |= INT_LOOPBACK;
532 			if (loopback_interface == 0)
533 			    loopback_interface = &inter_list[i];
534 		}
535 # endif /* SUN_3_3_STINKS */
536 # if !defined SYS_WINNT && !defined SYS_CYGWIN32 /* no interface flags on NT */
537 		if (inter_list[i].flags & INT_BROADCAST) {
538 #  ifdef STREAMS_TLI
539 			ioc.ic_cmd = SIOCGIFBRDADDR;
540 			ioc.ic_timout = 0;
541 			ioc.ic_dp = (caddr_t)&ifreq;
542 			ioc.ic_len = sizeof(struct ifreq);
543 			if(ioctl(vs, I_STR, &ioc)) {
544 				msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFBRDADDR) failed: %m");
545 				exit(1);
546 			}
547 #  else /* not STREAMS_TLI */
548 			if (ioctl(vs, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
549 				msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFBRDADDR) failed: %m");
550 				exit(1);
551 			}
552 #  endif /* not STREAMS_TLI */
553 
554 #  ifndef ifr_broadaddr
555 			inter_list[i].bcast =
556 			    *(struct sockaddr_in *)&ifreq.ifr_addr;
557 #  else
558 			inter_list[i].bcast =
559 			    *(struct sockaddr_in *)&ifreq.ifr_broadaddr;
560 #  endif /* ifr_broadaddr */
561 			inter_list[i].bcast.sin_family = AF_INET;
562 			inter_list[i].bcast.sin_port = port;
563 		}
564 
565 #  ifdef STREAMS_TLI
566 		ioc.ic_cmd = SIOCGIFNETMASK;
567 		ioc.ic_timout = 0;
568 		ioc.ic_dp = (caddr_t)&ifreq;
569 		ioc.ic_len = sizeof(struct ifreq);
570 		if(ioctl(vs, I_STR, &ioc)) {
571 			msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFNETMASK) failed: %m");
572 			exit(1);
573 		}
574 #  else /* not STREAMS_TLI */
575 		if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
576 			msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFNETMASK) failed: %m");
577 			exit(1);
578 		}
579 #  endif /* not STREAMS_TLI */
580 		inter_list[i].mask                 = *(struct sockaddr_in *)&ifreq.ifr_addr;
581 # else
582 		/* winnt here */
583 		inter_list[i].bcast                = ifreq.ifr_broadaddr;
584 		inter_list[i].bcast.sin_family	   = AF_INET;
585 		inter_list[i].bcast.sin_port	   = port;
586 		inter_list[i].mask                 = ifreq.ifr_mask;
587 # endif /* not SYS_WINNT */
588 
589 		/*
590 		 * look for an already existing source interface address.  If
591 		 * the machine has multiple point to point interfaces, then
592 		 * the local address may appear more than once.
593 		 */
594 		for (j=0; j < i; j++)
595 		    if (inter_list[j].sin.sin_addr.s_addr ==
596 			inter_list[i].sin.sin_addr.s_addr) {
597 			    break;
598 		    }
599 		if (j == i)
600 		    i++;
601 		if (i > MAXINTERFACES)
602 		    break;
603 	}
604 	closesocket(vs);
605 #endif	/* _BSDI_VERSION >= 199510 */
606 
607 	ninterfaces = i;
608 	maxactivefd = 0;
609 	FD_ZERO(&activefds);
610 	for (i = 0; i < ninterfaces; i++) {
611 		inter_list[i].fd =
612 		    open_socket(&inter_list[i].sin,
613 				inter_list[i].flags & INT_BROADCAST, 0);
614 	}
615 
616 	/*
617 	 * Now that we have opened all the sockets, turn off the reuse flag for
618 	 * security.
619 	 */
620 	for (i = 0; i < ninterfaces; i++) {
621 		int off = 0;
622 
623 		/*
624 		 * if inter_list[ n ].fd  is -1, we might have a adapter
625 		 * configured but not present
626 		 */
627 		if ( inter_list[ i ].fd != -1 ) {
628 			if (setsockopt(inter_list[i].fd, SOL_SOCKET,
629 				       SO_REUSEADDR, (char *)&off,
630 				       sizeof(off))) {
631 				msyslog(LOG_ERR, "create_sockets: setsockopt(SO_REUSEADDR,off) failed: %m");
632 			}
633 		}
634 	}
635 
636 #if defined(MCAST)
637 	/*
638 	 * enable possible multicast reception on the broadcast socket
639 	 */
640 	inter_list[0].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
641 	inter_list[0].bcast.sin_family = AF_INET;
642 	inter_list[0].bcast.sin_port = port;
643 #endif /* MCAST */
644 
645 	/*
646 	 * Blacklist all bound interface addresses
647 	 */
648 	resmask.sin_addr.s_addr = ~ (u_int32)0;
649 	for (i = 1; i < ninterfaces; i++)
650 	    hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask,
651 			  RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
652 
653 	any_interface = &inter_list[0];
654 #ifdef DEBUG
655 	if (debug > 2) {
656 		printf("create_sockets: ninterfaces=%d\n", ninterfaces);
657 		for (i = 0; i < ninterfaces; i++) {
658 			printf("interface %d:  fd=%d,  bfd=%d,  name=%.8s,  flags=0x%x\n",
659 			       i,
660 			       inter_list[i].fd,
661 			       inter_list[i].bfd,
662 			       inter_list[i].name,
663 			       inter_list[i].flags);
664 			/* Leave these as three printf calls. */
665 			printf("              sin=%s",
666 			       inet_ntoa((inter_list[i].sin.sin_addr)));
667 			if (inter_list[i].flags & INT_BROADCAST)
668 			    printf("  bcast=%s,",
669 				   inet_ntoa((inter_list[i].bcast.sin_addr)));
670 			printf("  mask=%s\n",
671 			       inet_ntoa((inter_list[i].mask.sin_addr)));
672 		}
673 	}
674 #endif
675 #if defined (HAVE_IO_COMPLETION_PORT)
676 	for (i = 0; i < ninterfaces; i++) {
677 		io_completion_port_add_socket(&inter_list[i]);
678 	}
679 #endif
680 	return ninterfaces;
681 }
682 
683 /*
684  * io_setbclient - open the broadcast client sockets
685  */
686 void
687 io_setbclient(void)
688 {
689 	int i;
690 
691 	for (i = 1; i < ninterfaces; i++)
692 	{
693 		if (!(inter_list[i].flags & INT_BROADCAST))
694 		    continue;
695 		if (inter_list[i].flags & INT_BCASTOPEN)
696 		    continue;
697 #ifdef	SYS_SOLARIS
698 		inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
699 #endif
700 #ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */
701 		inter_list[i].bfd = open_socket(&inter_list[i].bcast, INT_BROADCAST, 1);
702 		inter_list[i].flags |= INT_BCASTOPEN;
703 #endif
704 	}
705 }
706 
707 
708 /*
709  * io_multicast_add() - add multicast group address
710  */
711 void
712 io_multicast_add(
713 	u_int32 addr
714 	)
715 {
716 #ifdef MCAST
717 	struct ip_mreq mreq;
718 	int i = ninterfaces;	/* Use the next interface */
719 	u_int32 haddr = ntohl(addr);
720 	struct in_addr iaddr;
721 	int s;
722 	struct sockaddr_in *sinp;
723 
724 	iaddr.s_addr = addr;
725 
726 	if (!IN_CLASSD(haddr))
727 	{
728 		msyslog(LOG_ERR,
729 			"cannot add multicast address %s as it is not class D",
730 			inet_ntoa(iaddr));
731 		return;
732 	}
733 
734 	for (i = 0; i < ninterfaces; i++)
735 	{
736 		/* Already have this address */
737 		if (inter_list[i].sin.sin_addr.s_addr == addr) return;
738 		/* found a free slot */
739 		if (inter_list[i].sin.sin_addr.s_addr == 0 &&
740 		    inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
741 		    inter_list[i].flags == 0) break;
742 	}
743 	sinp = &(inter_list[i].sin);
744 
745 	memset((char *)&mreq, 0, sizeof(mreq));
746 	memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
747 	sinp->sin_family = AF_INET;
748 	sinp->sin_addr = iaddr;
749 	sinp->sin_port = htons(123);
750 
751 	s = open_socket(sinp, 0, 1);
752 	/* Try opening a socket for the specified class D address */
753 	/* This works under SunOS 4.x, but not OSF1 .. :-( */
754 	if (s < 0)
755 	{
756 		memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
757 		i = 0;
758 		/* HACK ! -- stuff in an address */
759 		inter_list[i].bcast.sin_addr.s_addr = addr;
760 		msyslog(LOG_ERR, "...multicast address %s using wildcard socket",
761 			inet_ntoa(iaddr));
762 	}
763 	else
764 	{
765 		inter_list[i].fd = s;
766 		inter_list[i].bfd = -1;
767 		(void) strncpy(inter_list[i].name, "multicast",
768 			       sizeof(inter_list[i].name));
769 		inter_list[i].mask.sin_addr.s_addr = htonl(~(u_int32)0);
770 	}
771 
772 	/*
773 	 * enable reception of multicast packets
774 	 */
775 	mreq.imr_multiaddr = iaddr;
776 	mreq.imr_interface.s_addr = htonl(INADDR_ANY);
777 	if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
778 		       (char *)&mreq, sizeof(mreq)) == -1)
779 	    msyslog(LOG_ERR,
780 		    "setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)",
781 		    mreq.imr_multiaddr.s_addr, mreq.imr_interface.s_addr,
782 		    inet_ntoa(iaddr));
783 	inter_list[i].flags |= INT_MULTICAST;
784 	if (i >= ninterfaces) ninterfaces = i+1;
785 #else /* MCAST */
786 	struct in_addr iaddr;
787 
788 	iaddr.s_addr = addr;
789 	msyslog(LOG_ERR, "cannot add multicast address %s as no MCAST support",
790 		inet_ntoa(iaddr));
791 #endif /* MCAST */
792 }
793 
794 /*
795  * io_unsetbclient - close the broadcast client sockets
796  */
797 void
798 io_unsetbclient(void)
799 {
800 	int i;
801 
802 	for (i = 1; i < ninterfaces; i++)
803 	{
804 		if (!(inter_list[i].flags & INT_BCASTOPEN))
805 		    continue;
806 		close_socket(inter_list[i].bfd);
807 		inter_list[i].bfd = -1;
808 		inter_list[i].flags &= ~INT_BCASTOPEN;
809 	}
810 }
811 
812 
813 /*
814  * io_multicast_del() - delete multicast group address
815  */
816 void
817 io_multicast_del(
818 	u_int32 addr
819 	)
820 {
821 #ifdef MCAST
822 	int i;
823 	struct ip_mreq mreq;
824 	u_int32 haddr = ntohl(addr);
825 	struct sockaddr_in sinaddr;
826 
827 	if (!IN_CLASSD(haddr))
828 	{
829 		sinaddr.sin_addr.s_addr = addr;
830 		msyslog(LOG_ERR,
831 			"invalid multicast address %s", ntoa(&sinaddr));
832 		return;
833 	}
834 
835 	/*
836 	 * Disable reception of multicast packets
837 	 */
838 	mreq.imr_multiaddr.s_addr = addr;
839 	mreq.imr_interface.s_addr = htonl(INADDR_ANY);
840 	for (i = 0; i < ninterfaces; i++)
841 	{
842 		if (!(inter_list[i].flags & INT_MULTICAST))
843 		    continue;
844 		if (!(inter_list[i].fd < 0))
845 		    continue;
846 		if (addr != inter_list[i].sin.sin_addr.s_addr)
847 		    continue;
848 		if (i != 0)
849 		{
850 			/* we have an explicit fd, so we can close it */
851 			close_socket(inter_list[i].fd);
852 			memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
853 			inter_list[i].fd = -1;
854 			inter_list[i].bfd = -1;
855 		}
856 		else
857 		{
858 			/* We are sharing "any address" port :-(  Don't close it! */
859 			if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
860 				       (char *)&mreq, sizeof(mreq)) == -1)
861 			    msyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails: %m");
862 			/* This is **WRONG** -- there may be others ! */
863 			/* There should be a count of users ... */
864 			inter_list[i].flags &= ~INT_MULTICAST;
865 		}
866 	}
867 #else /* not MCAST */
868 	msyslog(LOG_ERR, "this function requires multicast kernel");
869 #endif /* not MCAST */
870 }
871 
872 
873 /*
874  * open_socket - open a socket, returning the file descriptor
875  */
876 static int
877 open_socket(
878 	struct sockaddr_in *addr,
879 	int flags,
880 	int turn_off_reuse
881 	)
882 {
883 	int fd;
884 	int on = 1, off = 0;
885 
886 	/* create a datagram (UDP) socket */
887 	if (  (fd = socket(AF_INET, SOCK_DGRAM, 0))
888 #ifndef SYS_WINNT
889 	      < 0
890 #else
891 	      == INVALID_SOCKET
892 #endif /* SYS_WINNT */
893 	      )
894 	{
895 		msyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed: %m");
896 		exit(1);
897 		/*NOTREACHED*/
898 	}
899 
900 	/* set SO_REUSEADDR since we will be binding the same port
901 	   number on each interface */
902 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
903 		       (char *)&on, sizeof(on)))
904 	{
905 		msyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails: %m");
906 	}
907 
908 	/*
909 	 * bind the local address.
910 	 */
911 	if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
912 		char buff[160];
913 		sprintf(buff,
914 			"bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m",
915 			fd, addr->sin_family, (int)ntohs(addr->sin_port),
916 			ntoa(addr),
917 			IN_CLASSD(ntohl(addr->sin_addr.s_addr)), flags);
918 		msyslog(LOG_ERR, buff);
919 		closesocket(fd);
920 
921 		/*
922 		 * soft fail if opening a class D address
923 		 */
924 		if (IN_CLASSD(ntohl(addr->sin_addr.s_addr)))
925 		    return -1;
926 #if 0
927 		exit(1);
928 #else
929 		return -1;
930 #endif
931 	}
932 #ifdef DEBUG
933 	if (debug)
934 	    printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n",
935 		   fd,
936 		   addr->sin_family,
937 		   (int)ntohs(addr->sin_port),
938 		   ntoa(addr),
939 		   flags);
940 #endif
941 	if (fd > maxactivefd)
942 	    maxactivefd = fd;
943 	FD_SET(fd, &activefds);
944 
945 	/*
946 	 * set non-blocking,
947 	 */
948 
949 #ifdef USE_FIONBIO
950 	/* in vxWorks we use FIONBIO, but the others are defined for old systems, so
951 	 * all hell breaks loose if we leave them defined
952 	 */
953 #undef O_NONBLOCK
954 #undef FNDELAY
955 #undef O_NDELAY
956 #endif
957 
958 #if defined(O_NONBLOCK) /* POSIX */
959 	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
960 	{
961 		msyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails: %m");
962 		exit(1);
963 		/*NOTREACHED*/
964 	}
965 #elif defined(FNDELAY)
966 	if (fcntl(fd, F_SETFL, FNDELAY) < 0)
967 	{
968 		msyslog(LOG_ERR, "fcntl(FNDELAY) fails: %m");
969 		exit(1);
970 		/*NOTREACHED*/
971 	}
972 #elif defined(O_NDELAY) /* generally the same as FNDELAY */
973 	if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
974 	{
975 		msyslog(LOG_ERR, "fcntl(O_NDELAY) fails: %m");
976 		exit(1);
977 		/*NOTREACHED*/
978 	}
979 #elif defined(FIONBIO)
980 	if (
981 # if defined(VMS)
982 		(ioctl(fd,FIONBIO,&1) < 0)
983 # elif defined(SYS_WINNT)
984 		(ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
985 # else
986 		(ioctl(fd,FIONBIO,&on) < 0)
987 # endif
988 	   )
989 	{
990 		msyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m");
991 		exit(1);
992 		/*NOTREACHED*/
993 	}
994 #elif defined(FIOSNBIO)
995 	if (ioctl(fd,FIOSNBIO,&on) < 0)
996 	{
997 		msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails: %m");
998 		exit(1);
999 		/*NOTREACHED*/
1000 	}
1001 #else
1002 # include "Bletch: Need non-blocking I/O!"
1003 #endif
1004 
1005 #ifdef HAVE_SIGNALED_IO
1006 	init_socket_sig(fd);
1007 #endif /* not HAVE_SIGNALED_IO */
1008 
1009 	/*
1010 	 *	Turn off the SO_REUSEADDR socket option.  It apparently
1011 	 *	causes heartburn on systems with multicast IP installed.
1012 	 *	On normal systems it only gets looked at when the address
1013 	 *	is being bound anyway..
1014 	 */
1015 	if (turn_off_reuse)
1016 	    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1017 			   (char *)&off, sizeof(off)))
1018 	    {
1019 		    msyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m");
1020 	    }
1021 
1022 #ifdef SO_BROADCAST
1023 	/* if this interface can support broadcast, set SO_BROADCAST */
1024 	if (flags & INT_BROADCAST)
1025 	{
1026 		if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1027 			       (char *)&on, sizeof(on)))
1028 		{
1029 			msyslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
1030 		}
1031 	}
1032 #endif /* SO_BROADCAST */
1033 
1034 #if !defined(SYS_WINNT) && !defined(VMS)
1035 # ifdef DEBUG
1036 	if (debug > 1)
1037 	    printf("flags for fd %d: 0%o\n", fd,
1038 		   fcntl(fd, F_GETFL, 0));
1039 # endif
1040 #endif /* SYS_WINNT || VMS */
1041 
1042 	return fd;
1043 }
1044 
1045 
1046 /*
1047  * close_socket - close a socket and remove from the activefd list
1048  */
1049 static void
1050 close_socket(
1051 	int fd
1052 	)
1053 {
1054 	int i, newmax;
1055 
1056 	(void) closesocket(fd);
1057 	FD_CLR( (u_int) fd, &activefds);
1058 
1059 	if (fd >= maxactivefd)
1060 	{
1061 		newmax = 0;
1062 		for (i = 0; i < maxactivefd; i++)
1063 		    if (FD_ISSET(i, &activefds))
1064 			newmax = i;
1065 		maxactivefd = newmax;
1066 	}
1067 }
1068 
1069 
1070 /*
1071  * close_file - close a file and remove from the activefd list
1072  * added 1/31/1997 Greg Schueman for Windows NT portability
1073  */
1074 static void
1075 close_file(
1076 	int fd
1077 	)
1078 {
1079 	int i, newmax;
1080 
1081 	(void) close(fd);
1082 	FD_CLR( (u_int) fd, &activefds);
1083 
1084 	if (fd >= maxactivefd)
1085 	{
1086 		newmax = 0;
1087 		for (i = 0; i < maxactivefd; i++)
1088 		    if (FD_ISSET(i, &activefds))
1089 			newmax = i;
1090 		maxactivefd = newmax;
1091 	}
1092 }
1093 
1094 
1095 /*
1096  * findbcastinter - find broadcast interface corresponding to address
1097  */
1098 struct interface *
1099 findbcastinter(
1100 	struct sockaddr_in *addr
1101 	)
1102 {
1103 #if defined(SIOCGIFCONF) || defined(SYS_WINNT)
1104 	register int i;
1105 	register u_int32 netnum;
1106 
1107 	netnum = NSRCADR(addr);
1108 	for (i = 1; i < ninterfaces; i++)
1109 	{
1110 		if (!(inter_list[i].flags & INT_BROADCAST))
1111 		    continue;
1112 		if (NSRCADR(&inter_list[i].bcast) == netnum)
1113 		    return &inter_list[i];
1114 		if ((NSRCADR(&inter_list[i].sin) & NSRCADR(&inter_list[i].mask))
1115 		    == (netnum & NSRCADR(&inter_list[i].mask)))
1116 		    return &inter_list[i];
1117 	}
1118 #endif /* SIOCGIFCONF */
1119 	return any_interface;
1120 }
1121 
1122 
1123 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
1124 /*
1125  * sendpkt - send a packet to the specified destination. Maintain a
1126  * send error cache so that only the first consecutive error for a
1127  * destination is logged.
1128  */
1129 void
1130 sendpkt(
1131 	struct sockaddr_in *dest,
1132 	struct interface *inter,
1133 	int ttl,
1134 	struct pkt *pkt,
1135 	int len
1136 	)
1137 {
1138 	int cc, slot;
1139 #ifdef SYS_WINNT
1140 	DWORD err;
1141 #endif /* SYS_WINNT */
1142 
1143 	/*
1144 	 * Send error cache. Empty slots have port == 0
1145 	 * Set ERRORCACHESIZE to 0 to disable
1146 	 */
1147 	struct cache {
1148 		u_short port;
1149 		struct	in_addr addr;
1150 	};
1151 
1152 #ifndef ERRORCACHESIZE
1153 #define ERRORCACHESIZE 8
1154 #endif
1155 #if ERRORCACHESIZE > 0
1156 	static struct cache badaddrs[ERRORCACHESIZE];
1157 #else
1158 #define badaddrs ((struct cache *)0)		/* Only used in empty loops! */
1159 #endif
1160 
1161 	/*
1162 	 * check if the source address is a multicast address - replace
1163 	 * interface with any-interface if so.
1164 	 */
1165 	if (IN_MULTICAST(ntohl(inter->sin.sin_addr.s_addr)))
1166 	    inter = any_interface;
1167 #ifdef DEBUG
1168 	if (debug > 1)
1169 	    printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n",
1170 		   (ttl >= 0) ? "\tMCAST\t*****" : "",
1171 		   inter->fd, ntoa(dest),
1172 		   ntoa(&inter->sin), ttl, len);
1173 #endif
1174 
1175 #ifdef MCAST
1176 	/* for the moment we use the bcast option to set multicast ttl */
1177 	if (ttl >= 0 && ttl != inter->last_ttl)
1178 	{
1179 		char mttl = ttl;
1180 
1181 		/* set the multicast ttl for outgoing packets */
1182 		if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,
1183 			       &mttl, sizeof(mttl)) == -1)
1184 		{
1185 			msyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails: %m");
1186 		}
1187 		else inter->last_ttl = ttl;
1188 	}
1189 #endif /* MCAST */
1190 
1191 	for (slot = ERRORCACHESIZE; --slot >= 0; )
1192 	    if (badaddrs[slot].port == dest->sin_port &&
1193 		badaddrs[slot].addr.s_addr == dest->sin_addr.s_addr)
1194 		break;
1195 
1196 #if defined(HAVE_IO_COMPLETION_PORT)
1197         err = io_completion_port_sendto(inter, pkt, len, dest);
1198 	if (err != ERROR_SUCCESS)
1199 #else
1200 	cc = sendto(inter->fd, (char *)pkt, len, 0, (struct sockaddr *)dest,
1201 		    sizeof(struct sockaddr_in));
1202 	if (cc == -1)
1203 #endif
1204 	{
1205 		inter->notsent++;
1206 		packets_notsent++;
1207 #if defined(HAVE_IO_COMPLETION_PORT)
1208 		if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0)
1209 #else
1210 		if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
1211 #endif
1212 		{
1213 			/*
1214 			 * Remember this, if there's an empty slot
1215 			 */
1216 			for (slot = ERRORCACHESIZE; --slot >= 0; )
1217 			    if (badaddrs[slot].port == 0)
1218 			    {
1219 				    badaddrs[slot].port = dest->sin_port;
1220 				    badaddrs[slot].addr = dest->sin_addr;
1221 				    break;
1222 			    }
1223 			msyslog(LOG_ERR, "sendto(%s): %m", ntoa(dest));
1224 		}
1225 	}
1226 	else
1227 	{
1228 		inter->sent++;
1229 		packets_sent++;
1230 		/*
1231 		 * He's not bad any more
1232 		 */
1233 		if (slot >= 0)
1234 		{
1235 			msyslog(LOG_INFO, "Connection re-established to %s", ntoa(dest));
1236 			badaddrs[slot].port = 0;
1237 		}
1238 	}
1239 }
1240 
1241 #if !defined(HAVE_IO_COMPLETION_PORT)
1242 /*
1243  * fdbits - generate ascii representation of fd_set (FAU debug support)
1244  * HFDF format - highest fd first.
1245  */
1246 static char *
1247 fdbits(
1248 	int count,
1249 	fd_set *set
1250 	)
1251 {
1252 	static char buffer[256];
1253 	char * buf = buffer;
1254 
1255 	count = (count < 256) ? count : 255;
1256 
1257 	while (count >= 0)
1258 	{
1259 		*buf++ = FD_ISSET(count, set) ? '#' : '-';
1260 		count--;
1261 	}
1262 	*buf = '\0';
1263 
1264 	return buffer;
1265 }
1266 
1267 /*
1268  * input_handler - receive packets asynchronously
1269  */
1270 extern void
1271 input_handler(
1272 	l_fp *cts
1273 	)
1274 {
1275 	register int i, n;
1276 	register struct recvbuf *rb;
1277 	register int doing;
1278 	register int fd;
1279 	struct timeval tvzero;
1280 	int fromlen;
1281 	l_fp ts;			/* Timestamp at BOselect() gob */
1282 	l_fp ts_e;			/* Timestamp at EOselect() gob */
1283 	fd_set fds;
1284 	int select_count = 0;
1285 	static int handler_count = 0;
1286 
1287 	++handler_count;
1288 	if (handler_count != 1)
1289 	    msyslog(LOG_ERR, "input_handler: handler_count is %d!", handler_count);
1290 	handler_calls++;
1291 	ts = *cts;
1292 
1293 	for (;;)
1294 	{
1295 		/*
1296 		 * Do a poll to see who has data
1297 		 */
1298 
1299 		fds = activefds;
1300 		tvzero.tv_sec = tvzero.tv_usec = 0;
1301 
1302 		/*
1303 		 * If we have something to do, freeze a timestamp.
1304 		 * See below for the other cases (nothing (left) to do or error)
1305 		 */
1306 		while (0 < (n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero)))
1307 		{
1308 			++select_count;
1309 			++handler_pkts;
1310 
1311 #ifdef REFCLOCK
1312 			/*
1313 			 * Check out the reference clocks first, if any
1314 			 */
1315 			if (refio != 0)
1316 			{
1317 				register struct refclockio *rp;
1318 
1319 				for (rp = refio; rp != 0 && n > 0; rp = rp->next)
1320 				{
1321 					fd = rp->fd;
1322 					if (FD_ISSET(fd, &fds))
1323 					{
1324 						n--;
1325 						if (free_recvbuffs() == 0)
1326 						{
1327 							char buf[RX_BUFF_SIZE];
1328 
1329 #ifndef SYS_WINNT
1330 							(void) read(fd, buf, sizeof buf);
1331 #else
1332 							(void) ReadFile((HANDLE)fd, buf, (DWORD)sizeof buf, NULL, NULL);
1333 #endif /* SYS_WINNT */
1334 							packets_dropped++;
1335 							goto select_again;
1336 						}
1337 
1338 						rb = get_free_recv_buffer();
1339 
1340 						i = (rp->datalen == 0
1341 						     || rp->datalen > sizeof(rb->recv_space))
1342 						    ? sizeof(rb->recv_space) : rp->datalen;
1343 #ifndef SYS_WINNT
1344 						rb->recv_length =
1345 						    read(fd, (char *)&rb->recv_space, (unsigned)i)
1346 #else  /* SYS_WINNT */
1347 						    ReadFile((HANDLE)fd, (char *)&rb->recv_space, (DWORD)i,
1348 							     (LPDWORD)&(rb->recv_length), NULL)
1349 #endif /* SYS_WINNT */
1350 						    ;
1351 
1352 						if (rb->recv_length == -1)
1353 						{
1354 							msyslog(LOG_ERR, "clock read fd %d: %m", fd);
1355 							freerecvbuf(rb);
1356 							goto select_again;
1357 						}
1358 
1359 						/*
1360 						 * Got one.  Mark how and when it got here,
1361 						 * put it on the full list and do bookkeeping.
1362 						 */
1363 						rb->recv_srcclock = rp->srcclock;
1364 						rb->dstadr = 0;
1365 						rb->fd = fd;
1366 						rb->recv_time = ts;
1367 						rb->receiver = rp->clock_recv;
1368 
1369 						if (rp->io_input)
1370 						{
1371 							/*
1372 							 * have direct input routine for refclocks
1373 							 */
1374 							if (rp->io_input(rb) == 0)
1375 							{
1376 								/*
1377 								 * data was consumed - nothing to pass up
1378 								 * into block input machine
1379 								 */
1380 								freerecvbuf(rb);
1381 #if 1
1382 								goto select_again;
1383 #else
1384 								continue;
1385 #endif
1386 							}
1387 						}
1388 
1389 						add_full_recv_buffer(rb);
1390 
1391 						rp->recvcount++;
1392 						packets_received++;
1393 					}
1394 				}
1395 			}
1396 #endif /* REFCLOCK */
1397 
1398 			/*
1399 			 * Loop through the interfaces looking for data to read.
1400 			 */
1401 			for (i = ninterfaces - 1; (i >= 0) && (n > 0); i--)
1402 			{
1403 				for (doing = 0; (doing < 2) && (n > 0); doing++)
1404 				{
1405 					if (doing == 0)
1406 					{
1407 						fd = inter_list[i].fd;
1408 					}
1409 					else
1410 					{
1411 						if (!(inter_list[i].flags & INT_BCASTOPEN))
1412 						    break;
1413 						fd = inter_list[i].bfd;
1414 					}
1415 					if (fd < 0) continue;
1416 					if (FD_ISSET(fd, &fds))
1417 					{
1418 						n--;
1419 
1420 						/*
1421 						 * Get a buffer and read the frame.  If we
1422 						 * haven't got a buffer, or this is received
1423 						 * on the wild card socket, just dump the
1424 						 * packet.
1425 						 */
1426 						if (
1427 #ifdef UDP_WILDCARD_DELIVERY
1428 				/*
1429 				 * these guys manage to put properly addressed
1430 				 * packets into the wildcard queue
1431 				 */
1432 							(free_recvbuffs() == 0)
1433 #else
1434 							((i == 0) || (free_recvbuffs() == 0))
1435 #endif
1436 							)
1437 	{
1438 		char buf[RX_BUFF_SIZE];
1439 		struct sockaddr from;
1440 
1441 		fromlen = sizeof from;
1442 		(void) recvfrom(fd, buf, sizeof(buf), 0, &from, &fromlen);
1443 #ifdef DEBUG
1444 		if (debug)
1445 		    printf("%s on %d(%lu) fd=%d from %s\n",
1446 			   (i) ? "drop" : "ignore",
1447 			   i, free_recvbuffs(), fd,
1448 			   inet_ntoa(((struct sockaddr_in *) &from)->sin_addr));
1449 #endif
1450 		if (i == 0)
1451 		    packets_ignored++;
1452 		else
1453 		    packets_dropped++;
1454 		goto select_again;
1455 	}
1456 
1457 	rb = get_free_recv_buffer();
1458 
1459 	fromlen = sizeof(struct sockaddr_in);
1460 	rb->recv_length = recvfrom(fd,
1461 				   (char *)&rb->recv_space,
1462 				   sizeof(rb->recv_space), 0,
1463 				   (struct sockaddr *)&rb->recv_srcadr,
1464 				   &fromlen);
1465 	if (rb->recv_length == 0
1466 #ifdef EWOULDBLOCK
1467 		 || errno==EWOULDBLOCK
1468 #endif
1469 #ifdef EAGAIN
1470 		 || errno==EAGAIN
1471 #endif
1472 		 ) {
1473 		freerecvbuf(rb);
1474 	    continue;
1475 	}
1476 	else if (rb->recv_length < 0)
1477 	{
1478 		msyslog(LOG_ERR, "recvfrom() fd=%d: %m", fd);
1479 #ifdef DEBUG
1480 		if (debug)
1481 		    printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd);
1482 #endif
1483 		freerecvbuf(rb);
1484 		continue;
1485 	}
1486 #ifdef DEBUG
1487 	if (debug > 2)
1488 	    printf("input_handler: fd=%d length %d from %08lx %s\n",
1489 		   fd, rb->recv_length,
1490 		   (u_long)ntohl(rb->recv_srcadr.sin_addr.s_addr) &
1491 		   0x00000000ffffffff,
1492 		   inet_ntoa(rb->recv_srcadr.sin_addr));
1493 #endif
1494 
1495 	/*
1496 	 * Got one.  Mark how and when it got here,
1497 	 * put it on the full list and do bookkeeping.
1498 	 */
1499 	rb->dstadr = &inter_list[i];
1500 	rb->fd = fd;
1501 	rb->recv_time = ts;
1502 	rb->receiver = receive;
1503 
1504 	add_full_recv_buffer(rb);
1505 
1506 	inter_list[i].received++;
1507 	packets_received++;
1508 	goto select_again;
1509 					}
1510 					/* Check more interfaces */
1511 				}
1512 			}
1513 		select_again:;
1514 			/*
1515 			 * Done everything from that select.  Poll again.
1516 			 */
1517 		}
1518 
1519 		/*
1520 		 * If nothing more to do, try again.
1521 		 * If nothing to do, just return.
1522 		 * If an error occurred, complain and return.
1523 		 */
1524 		if (n == 0)
1525 		{
1526 			if (select_count == 0) /* We really had nothing to do */
1527 			{
1528 				if (debug)
1529 				    msyslog(LOG_DEBUG, "input_handler: select() returned 0");
1530 				--handler_count;
1531 				return;
1532 			}
1533 			/* We've done our work */
1534 			get_systime(&ts_e);
1535 			/*
1536 			 * (ts_e - ts) is the amount of time we spent processing
1537 			 * this gob of file descriptors.  Log it.
1538 			 */
1539 			L_SUB(&ts_e, &ts);
1540 			if (debug > 3)
1541 			    msyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
1542 
1543 			/* just bail. */
1544 			--handler_count;
1545 			return;
1546 		}
1547 		else if (n == -1)
1548 		{
1549 #ifndef SYS_WINNT
1550 			int err = errno;
1551 #else
1552 			DWORD err = WSAGetLastError();
1553 #endif /* SYS_WINNT */
1554 
1555 			/*
1556 			 * extended FAU debugging output
1557 			 */
1558 			msyslog(LOG_ERR, "select(%d, %s, 0L, 0L, &0.000000) error: %m",
1559 				maxactivefd+1, fdbits(maxactivefd, &activefds));
1560 			if (
1561 #ifndef SYS_WINNT
1562 				(err == EBADF)
1563 #else
1564 				(err == WSAEBADF)
1565 #endif /* SYS_WINNT */
1566 				)
1567 			{
1568 				int j, b;
1569 
1570 				fds = activefds;
1571 				for (j = 0; j <= maxactivefd; j++)
1572 				    if (
1573 #ifndef SYS_WINNT
1574 					    (FD_ISSET(j, &fds) && (read(j, &b, 0) == -1))
1575 #else
1576 					    (FD_ISSET(j, &fds) && (!ReadFile((HANDLE)j, &b, 0, NULL, NULL)))
1577 #endif /* SYS_WINNT */
1578 					    )
1579 					msyslog(LOG_ERR, "Bad file descriptor %d", j);
1580 			}
1581 			--handler_count;
1582 			return;
1583 		}
1584 	}
1585 	msyslog(LOG_ERR, "input_handler: fell out of infinite for(;;) loop!");
1586 	--handler_count;
1587 	return;
1588 }
1589 
1590 #endif
1591 
1592 /*
1593  * findinterface - utility used by other modules to find an interface
1594  *		   given an address.
1595  */
1596 struct interface *
1597 findinterface(
1598 	struct sockaddr_in *addr
1599 	)
1600 {
1601 	register int i;
1602 	register u_int32 saddr;
1603 
1604 	/*
1605 	 * Just match the address portion.
1606 	 */
1607 	saddr = addr->sin_addr.s_addr;
1608 	for (i = 0; i < ninterfaces; i++)
1609 	{
1610 		if (inter_list[i].sin.sin_addr.s_addr == saddr)
1611 		    return &inter_list[i];
1612 	}
1613 	return (struct interface *)0;
1614 }
1615 
1616 
1617 /*
1618  * io_clr_stats - clear I/O module statistics
1619  */
1620 void
1621 io_clr_stats(void)
1622 {
1623 	packets_dropped = 0;
1624 	packets_ignored = 0;
1625 	packets_received = 0;
1626 	packets_sent = 0;
1627 	packets_notsent = 0;
1628 
1629 	handler_calls = 0;
1630 	handler_pkts = 0;
1631 	io_timereset = current_time;
1632 }
1633 
1634 
1635 #ifdef REFCLOCK
1636 /*
1637  * This is a hack so that I don't have to fool with these ioctls in the
1638  * pps driver ... we are already non-blocking and turn on SIGIO thru
1639  * another mechanisim
1640  */
1641 int
1642 io_addclock_simple(
1643 	struct refclockio *rio
1644 	)
1645 {
1646 	BLOCKIO();
1647 	/*
1648 	 * Stuff the I/O structure in the list and mark the descriptor
1649 	 * in use.	There is a harmless (I hope) race condition here.
1650 	 */
1651 	rio->next = refio;
1652 	refio = rio;
1653 
1654 	if (rio->fd > maxactivefd)
1655 	    maxactivefd = rio->fd;
1656 	FD_SET(rio->fd, &activefds);
1657 	UNBLOCKIO();
1658 	return 1;
1659 }
1660 
1661 /*
1662  * io_addclock - add a reference clock to the list and arrange that we
1663  *				 get SIGIO interrupts from it.
1664  */
1665 int
1666 io_addclock(
1667 	struct refclockio *rio
1668 	)
1669 {
1670 	BLOCKIO();
1671 	/*
1672 	 * Stuff the I/O structure in the list and mark the descriptor
1673 	 * in use.	There is a harmless (I hope) race condition here.
1674 	 */
1675 	rio->next = refio;
1676 	refio = rio;
1677 
1678 # ifdef HAVE_SIGNALED_IO
1679 	if (init_clock_sig(rio))
1680 	{
1681 		refio = rio->next;
1682 		UNBLOCKIO();
1683 		return 0;
1684 	}
1685 # elif defined(HAVE_IO_COMPLETION_PORT)
1686 	if (io_completion_port_add_clock_io(rio))
1687 	{
1688 		refio = rio->next;
1689 		UNBLOCKIO();
1690 		return 0;
1691 	}
1692 # endif
1693 
1694 	if (rio->fd > maxactivefd)
1695 	    maxactivefd = rio->fd;
1696 	FD_SET(rio->fd, &activefds);
1697 
1698 	UNBLOCKIO();
1699 	return 1;
1700 }
1701 
1702 /*
1703  * io_closeclock - close the clock in the I/O structure given
1704  */
1705 void
1706 io_closeclock(
1707 	struct refclockio *rio
1708 	)
1709 {
1710 	/*
1711 	 * Remove structure from the list
1712 	 */
1713 	if (refio == rio)
1714 	{
1715 		refio = rio->next;
1716 	}
1717 	else
1718 	{
1719 		register struct refclockio *rp;
1720 
1721 		for (rp = refio; rp != 0; rp = rp->next)
1722 		    if (rp->next == rio)
1723 		    {
1724 			    rp->next = rio->next;
1725 			    break;
1726 		    }
1727 
1728 		if (rp == 0)
1729 		{
1730 			/*
1731 			 * Internal error.	Report it.
1732 			 */
1733 			msyslog(LOG_ERR,
1734 				"internal error: refclockio structure not found");
1735 			return;
1736 		}
1737 	}
1738 
1739 	/*
1740 	 * Close the descriptor.
1741 	 */
1742 	close_file(rio->fd);
1743 }
1744 #endif	/* REFCLOCK */
1745 
1746 void
1747 kill_asyncio(void)
1748 {
1749 	int i;
1750 
1751 	BLOCKIO();
1752 	for (i = 0; i <= maxactivefd; i++)
1753 	    (void)close_socket(i);
1754 }
1755