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