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