2 * ntp_io.c - input/output routines for ntpd. The socket-opening code
3 * was shamelessly stolen from ntpd.
10 #include "ntp_machine.h"
14 #include "ntp_refclock.h"
16 #include "ntp_stdlib.h"
20 #ifdef HAVE_SYS_PARAM_H
21 # include <sys/param.h>
22 #endif /* HAVE_SYS_PARAM_H */
23 #ifdef HAVE_NETINET_IN_H
24 # include <netinet/in.h>
26 #ifdef HAVE_NETINET_IN_SYSTM_H
27 # include <netinet/in_systm.h>
28 #else /* Some old linux systems at least have in_system.h instead. */
29 # include <netinet/in_system.h>
30 #endif /* HAVE_NETINET_IN_SYSTM_H */
31 #include <netinet/ip.h>
32 #ifdef HAVE_SYS_IOCTL_H
33 # include <sys/ioctl.h>
35 #ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
36 # include <sys/sockio.h>
38 #include <arpa/inet.h>
40 #if _BSDI_VERSION >= 199510
44 #if defined(VMS) /* most likely UCX-specific */
46 #include <UCX$INETDEF.H>
48 /* "un*x"-compatible names for some items in UCX$INETDEF.H */
49 #define ifreq IFREQDEF
50 #define ifr_name IFR$T_NAME
51 #define ifr_addr IFR$R_DUMMY.IFR$T_ADDR
52 #define ifr_broadaddr IFR$R_DUMMY.IFR$T_BROADADDR
53 #define ifr_flags IFR$R_DUMMY.IFR$R_DUMMY_1_OVRL.IFR$W_FLAGS
54 #define IFF_UP IFR$M_IFF_UP
55 #define IFF_BROADCAST IFR$M_IFF_BROADCAST
56 #define IFF_LOOPBACK IFR$M_IFF_LOOPBACK
61 #if defined(VMS) || defined(SYS_WINNT)
62 /* structure used in SIOCGIFCONF request (after [KSR] OSF/1) */
64 int ifc_len; /* size of buffer */
67 struct ifreq *ifcu_req;
70 #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
71 #define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
75 #if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
76 # if defined(SYS_AIX) && defined(_IO) /* XXX Identify AIX some other way */
83 * We do asynchronous input using the SIGIO facility. A number of
84 * recvbuf buffers are preallocated for input. In the signal
85 * handler we poll to see which sockets are ready and read the
86 * packets from them into the recvbuf's along with a time stamp and
87 * an indication of the source host and the interface it was received
88 * through. This allows us to get as accurate receive time stamps
89 * as possible independent of other processing going on.
91 * We watch the number of recvbufs available to the signal handler
92 * and allocate more when this number drops below the low water
93 * mark. If the signal handler should run out of buffers in the
94 * interim it will drop incoming frames, the idea being that it is
95 * better to drop a packet than to be inaccurate.
100 * Other statistics of possible interest
102 volatile u_long packets_dropped; /* total number of packets dropped on reception */
103 volatile u_long packets_ignored; /* packets received on wild card interface */
104 volatile u_long packets_received; /* total number of packets received */
105 u_long packets_sent; /* total number of packets sent */
106 u_long packets_notsent; /* total number of packets which couldn't be sent */
108 volatile u_long handler_calls; /* number of calls to interrupt handler */
109 volatile u_long handler_pkts; /* number of pkts received by handler */
110 u_long io_timereset; /* time counters were reset */
115 struct interface *any_interface; /* default interface */
116 struct interface *loopback_interface; /* loopback interface */
117 struct interface inter_list[MAXINTERFACES];
122 * Refclock stuff. We keep a chain of structures with data concerning
123 * the guys we are doing I/O for.
125 static struct refclockio *refio;
126 #endif /* REFCLOCK */
129 * File descriptor masks etc. for call to select
134 static int create_sockets P((u_int));
135 static int open_socket P((struct sockaddr_in *, int, int));
136 static void close_socket P((int));
137 static void close_file P((int));
138 static char * fdbits P((int, fd_set *));
141 * init_io - initialize I/O data structures and call socket creation routine
147 WORD wVersionRequested;
150 #endif /* SYS_WINNT */
153 * Init buffer free list and stat counters
155 init_recvbuff(RECV_INIT);
157 packets_dropped = packets_received = 0;
159 packets_sent = packets_notsent = 0;
160 handler_calls = handler_pkts = 0;
162 loopback_interface = 0;
168 #if defined(HAVE_SIGNALED_IO)
173 wVersionRequested = MAKEWORD(1,1);
174 if (WSAStartup(wVersionRequested, &wsaData))
176 msyslog(LOG_ERR, "No useable winsock.dll: %m");
179 #endif /* SYS_WINNT */
185 (void) create_sockets(htons(NTP_PORT));
190 printf("init_io: maxactivefd %d\n", maxactivefd);
195 * create_sockets - create a socket for each interface plus a default
196 * socket for when we don't know where to send
203 #if _BSDI_VERSION >= 199510
205 struct ifaddrs *ifaddrs, *ifap;
206 struct sockaddr_in resmask;
207 #if _BSDI_VERSION < 199701
211 #else /* _BSDI_VERSION >= 199510 */
214 # endif /* STREAMS_TLI */
215 char buf[MAXINTERFACES*sizeof(struct ifreq)];
217 struct ifreq ifreq, *ifr;
218 int n, i, j, vs, size = 0;
219 struct sockaddr_in resmask;
220 #endif /* _BSDI_VERSION >= 199510 */
224 printf("create_sockets(%d)\n", ntohs( (u_short) port));
228 * create pseudo-interface with wildcard address
230 inter_list[0].sin.sin_family = AF_INET;
231 inter_list[0].sin.sin_port = port;
232 inter_list[0].sin.sin_addr.s_addr = htonl(INADDR_ANY);
233 (void) strncpy(inter_list[0].name, "wildcard",
234 sizeof(inter_list[0].name));
235 inter_list[0].mask.sin_addr.s_addr = htonl(~ (u_int32)0);
236 inter_list[0].received = 0;
237 inter_list[0].sent = 0;
238 inter_list[0].notsent = 0;
239 inter_list[0].flags = INT_BROADCAST;
240 any_interface = &inter_list[0];
242 #if _BSDI_VERSION >= 199510
243 #if _BSDI_VERSION >= 199701
244 if (getifaddrs(&ifaddrs) < 0)
246 msyslog(LOG_ERR, "getifaddrs: %m");
250 for (ifap = ifaddrs; ifap != NULL; ifap = ifap->ifa_next)
252 if (getifaddrs(&ifaddrs, &num_if) < 0)
254 msyslog(LOG_ERR, "create_sockets: getifaddrs() failed: %m");
260 for (ifap = ifaddrs, lp = ifap + num_if; ifap < lp; ifap++)
263 struct sockaddr_in *sin;
268 if (ifap->ifa_addr->sa_family != AF_INET)
271 if ((ifap->ifa_flags & IFF_UP) == 0)
274 if (ifap->ifa_flags & IFF_LOOPBACK) {
275 sin = (struct sockaddr_in *)ifap->ifa_addr;
276 if (ntohl(sin->sin_addr.s_addr) != 0x7f000001)
279 inter_list[i].flags = 0;
280 if (ifap->ifa_flags & IFF_BROADCAST)
281 inter_list[i].flags |= INT_BROADCAST;
282 strcpy(inter_list[i].name, ifap->ifa_name);
283 sin = (struct sockaddr_in *)ifap->ifa_addr;
284 inter_list[i].sin = *sin;
285 inter_list[i].sin.sin_port = port;
286 if (ifap->ifa_flags & IFF_LOOPBACK) {
287 inter_list[i].flags = INT_LOOPBACK;
288 if (loopback_interface == NULL
289 || ntohl(sin->sin_addr.s_addr) != 0x7f000001)
290 loopback_interface = &inter_list[i];
292 if (inter_list[i].flags & INT_BROADCAST) {
293 sin = (struct sockaddr_in *)ifap->ifa_broadaddr;
294 inter_list[i].bcast = *sin;
295 inter_list[i].bcast.sin_port = port;
297 if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) {
298 inter_list[i].mask.sin_addr.s_addr = 0xffffffff;
300 sin = (struct sockaddr_in *)ifap->ifa_netmask;
301 inter_list[i].mask = *sin;
303 inter_list[i].mask.sin_family = AF_INET;
304 inter_list[i].mask.sin_len = sizeof *sin;
307 * look for an already existing source interface address. If
308 * the machine has multiple point to point interfaces, then
309 * the local address may appear more than once.
311 * A second problem exists if we have two addresses on
312 * the same network (via "ifconfig alias ..."). Don't
313 * make two xntp interfaces for the two aliases on the
314 * one physical interface. -wsr
316 for (j=0; j < i; j++)
317 if (inter_list[j].sin.sin_addr.s_addr &
318 inter_list[j].mask.sin_addr.s_addr ==
319 inter_list[i].sin.sin_addr.s_addr &
320 inter_list[i].mask.sin_addr.s_addr)
322 if (inter_list[j].flags & INT_LOOPBACK)
323 inter_list[j] = inter_list[i];
328 if (i > MAXINTERFACES)
332 #else /* _BSDI_VERSION >= 199510 */
333 # ifdef USE_STREAMS_DEVICE_FOR_IF_CONFIG
334 if ((vs = open("/dev/ip", O_RDONLY)) < 0)
336 msyslog(LOG_ERR, "create_sockets: open(/dev/ip) failed: %m");
339 # else /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
341 (vs = socket(AF_INET, SOCK_DGRAM, 0))
344 # else /* SYS_WINNT */
346 # endif /* SYS_WINNT */
348 msyslog(LOG_ERR, "create_sockets: socket(AF_INET, SOCK_DGRAM) failed: %m");
351 # endif /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
354 # if !defined(SYS_WINNT)
355 ifc.ifc_len = sizeof(buf);
358 ioc.ic_cmd = SIOCGIFCONF;
360 ioc.ic_dp = (caddr_t)buf;
361 ioc.ic_len = sizeof(buf);
362 if(ioctl(vs, I_STR, &ioc) < 0 ||
363 ioc.ic_len < sizeof(struct ifreq))
365 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFCONF) failed: %m - exiting");
368 # ifdef SIZE_RETURNED_IN_BUFFER
369 ifc.ifc_len = ioc.ic_len - sizeof(int);
370 ifc.ifc_buf = buf + sizeof(int);
371 # else /* not SIZE_RETURNED_IN_BUFFER */
372 ifc.ifc_len = ioc.ic_len;
374 # endif /* not SIZE_RETURNED_IN_BUFFER */
376 # else /* not STREAMS_TLI */
377 ifc.ifc_len = sizeof(buf);
380 if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0)
382 if (WSAIoctl(vs, SIO_GET_INTERFACE_LIST, 0, 0, ifc.ifc_buf, ifc.ifc_len, &ifc.ifc_len, 0, 0) == SOCKET_ERROR)
383 # endif /* SYS_WINNT */
385 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFCONF) failed: %m - exiting");
389 # endif /* not STREAMS_TLI */
391 for(n = ifc.ifc_len, ifr = ifc.ifc_req; n > 0;
392 ifr = (struct ifreq *)((char *)ifr + size))
394 extern int listen_to_virtual_ips;
398 # ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
399 if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
400 size += ifr->ifr_addr.sa_len - sizeof(struct sockaddr);
404 # if !defined(SYS_WINNT)
405 /* Exclude logical interfaces (indicated by ':' in the interface name) */
407 printf("interface <%s> ", ifr->ifr_name);
408 if ((listen_to_virtual_ips == 0)
409 && (strchr(ifr->ifr_name, (int)':') != NULL)) {
418 # ifdef VMS /* VMS+UCX */
419 (((struct sockaddr *)&(ifr->ifr_addr))->sa_family != AF_INET)
421 (ifr->ifr_addr.sa_family != AF_INET)
422 # endif /* VMS+UCX */
425 printf("ignoring %s - not AF_INET\n",
429 # endif /* SYS_WINNT */
430 memcpy(&ifreq, ifr, sizeof(ifreq));
431 inter_list[i].flags = 0;
432 /* is it broadcast capable? */
435 ioc.ic_cmd = SIOCGIFFLAGS;
437 ioc.ic_dp = (caddr_t)&ifreq;
438 ioc.ic_len = sizeof(struct ifreq);
439 if(ioctl(vs, I_STR, &ioc)) {
440 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFFLAGS) failed: %m");
443 # else /* not STREAMS_TLI */
444 if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
446 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFFLAGS) failed: %m");
449 # endif /* not STREAMS_TLI */
450 if ((ifreq.ifr_flags & IFF_UP) == 0) {
452 printf("ignoring %s - interface not UP\n",
456 inter_list[i].flags = 0;
457 if (ifreq.ifr_flags & IFF_BROADCAST)
458 inter_list[i].flags |= INT_BROADCAST;
459 # endif /* not SYS_WINNT */
460 # if !defined(SUN_3_3_STINKS)
462 # if defined(IFF_LOCAL_LOOPBACK) /* defined(SYS_HPUX) && (SYS_HPUX < 8) */
463 (ifreq.ifr_flags & IFF_LOCAL_LOOPBACK)
464 # elif defined(IFF_LOOPBACK)
465 (ifreq.ifr_flags & IFF_LOOPBACK)
466 # else /* not IFF_LOCAL_LOOPBACK and not IFF_LOOPBACK */
467 /* test against 127.0.0.1 (yuck!!) */
468 (inter_list[i].sin.sin_addr.s_addr == inet_addr("127.0.0.1"))
469 # endif /* not IFF_LOCAL_LOOPBACK and not IFF_LOOPBACK */
473 inter_list[i].flags |= INT_LOOPBACK;
474 # endif /* not SYS_WINNT */
475 if (loopback_interface == 0)
477 loopback_interface = &inter_list[i];
480 # endif /* not SUN_3_3_STINKS */
485 ioc.ic_cmd = SIOCGIFADDR;
487 ioc.ic_dp = (caddr_t)&ifreq;
488 ioc.ic_len = sizeof(struct ifreq);
489 if (ioctl(vs, I_STR, &ioc))
491 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFADDR) failed: %m");
494 # else /* not STREAMS_TLI */
495 if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0)
498 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFADDR) failed: %m");
501 # endif /* not STREAMS_TLI */
502 # endif /* not SYS_WINNT */
504 # if defined(SYS_WINNT)
505 {int TODO_FillInTheNameWithSomeThingReasonble;}
507 (void)strncpy(inter_list[i].name, ifreq.ifr_name,
508 sizeof(inter_list[i].name));
510 inter_list[i].sin = *(struct sockaddr_in *)&ifr->ifr_addr;
511 inter_list[i].sin.sin_family = AF_INET;
512 inter_list[i].sin.sin_port = port;
514 # if defined(SUN_3_3_STINKS)
516 * Oh, barf! I'm too disgusted to even explain this
518 if (SRCADR(&inter_list[i].sin) == 0x7f000001)
520 inter_list[i].flags |= INT_LOOPBACK;
521 if (loopback_interface == 0)
522 loopback_interface = &inter_list[i];
524 # endif /* SUN_3_3_STINKS */
525 # if !defined SYS_WINNT && !defined SYS_CYGWIN32 /* no interface flags on NT */
526 if (inter_list[i].flags & INT_BROADCAST) {
528 ioc.ic_cmd = SIOCGIFBRDADDR;
530 ioc.ic_dp = (caddr_t)&ifreq;
531 ioc.ic_len = sizeof(struct ifreq);
532 if(ioctl(vs, I_STR, &ioc)) {
533 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFBRDADDR) failed: %m");
536 # else /* not STREAMS_TLI */
537 if (ioctl(vs, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
538 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFBRDADDR) failed: %m");
541 # endif /* not STREAMS_TLI */
543 # ifndef ifr_broadaddr
544 inter_list[i].bcast =
545 *(struct sockaddr_in *)&ifreq.ifr_addr;
547 inter_list[i].bcast =
548 *(struct sockaddr_in *)&ifreq.ifr_broadaddr;
549 # endif /* ifr_broadaddr */
550 inter_list[i].bcast.sin_family = AF_INET;
551 inter_list[i].bcast.sin_port = port;
555 ioc.ic_cmd = SIOCGIFNETMASK;
557 ioc.ic_dp = (caddr_t)&ifreq;
558 ioc.ic_len = sizeof(struct ifreq);
559 if(ioctl(vs, I_STR, &ioc)) {
560 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFNETMASK) failed: %m");
563 # else /* not STREAMS_TLI */
564 if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
565 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFNETMASK) failed: %m");
568 # endif /* not STREAMS_TLI */
569 inter_list[i].mask = *(struct sockaddr_in *)&ifreq.ifr_addr;
572 inter_list[i].bcast = ifreq.ifr_broadaddr;
573 inter_list[i].bcast.sin_family = AF_INET;
574 inter_list[i].bcast.sin_port = port;
575 inter_list[i].mask = ifreq.ifr_mask;
576 # endif /* not SYS_WINNT */
579 * look for an already existing source interface address. If
580 * the machine has multiple point to point interfaces, then
581 * the local address may appear more than once.
583 for (j=0; j < i; j++)
584 if (inter_list[j].sin.sin_addr.s_addr ==
585 inter_list[i].sin.sin_addr.s_addr) {
590 if (i > MAXINTERFACES)
594 #endif /* _BSDI_VERSION >= 199510 */
599 for (i = 0; i < ninterfaces; i++) {
600 inter_list[i].fd = open_socket(&inter_list[i].sin,
601 inter_list[i].flags & INT_BROADCAST, 0);
605 * Now that we have opened all the sockets, turn off the reuse flag for
608 for (i = 0; i < ninterfaces; i++) {
612 * if inter_list[ n ].fd is -1, we might have a adapter
613 * configured but not present
615 if ( inter_list[ i ].fd != -1 ) {
616 if (setsockopt(inter_list[i].fd, SOL_SOCKET,
617 SO_REUSEADDR, (char *)&off,
619 msyslog(LOG_ERR, "create_sockets: setsockopt(SO_REUSEADDR,off) failed: %m");
626 * enable possible multicast reception on the broadcast socket
628 inter_list[0].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
629 inter_list[0].bcast.sin_family = AF_INET;
630 inter_list[0].bcast.sin_port = port;
634 * Blacklist all bound interface addresses
636 resmask.sin_addr.s_addr = ~ (u_int32)0;
637 for (i = 1; i < ninterfaces; i++)
638 hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask,
639 RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
642 printf("create_sockets: ninterfaces=%d\n", ninterfaces);
643 for (i = 0; i < ninterfaces; i++) {
644 printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x\n",
649 inter_list[i].flags);
650 /* Leave these as three printf calls. */
652 inet_ntoa((inter_list[i].sin.sin_addr)));
653 if (inter_list[i].flags & INT_BROADCAST)
655 inet_ntoa((inter_list[i].bcast.sin_addr)));
657 inet_ntoa((inter_list[i].mask.sin_addr)));
661 #if defined (HAVE_IO_COMPLETION_PORT)
662 for (i = 0; i < ninterfaces; i++) {
663 io_completion_port_add_socket(&inter_list[i]);
670 * io_setbclient - open the broadcast client sockets
677 for (i = 1; i < ninterfaces; i++) {
678 if (!(inter_list[i].flags & INT_BROADCAST))
681 if (inter_list[i].flags & INT_BCASTOPEN)
685 inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
687 #ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */
688 inter_list[i].bfd = open_socket(&inter_list[i].bcast,
690 inter_list[i].flags |= INT_BCASTOPEN;
697 * io_multicast_add() - add multicast group address
706 int i = ninterfaces; /* Use the next interface */
707 u_int32 haddr = ntohl(addr);
708 struct in_addr iaddr;
710 struct sockaddr_in *sinp;
713 if (!IN_CLASSD(haddr)) {
715 "multicast address %s not class D",
719 for (i = 0; i < ninterfaces; i++) {
720 /* Already have this address */
721 if (inter_list[i].sin.sin_addr.s_addr == addr)
723 /* found a free slot */
724 if (inter_list[i].sin.sin_addr.s_addr == 0 &&
725 inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
726 inter_list[i].flags == 0)
729 sinp = &(inter_list[i].sin);
730 memset((char *)&mreq, 0, sizeof(mreq));
731 memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
732 sinp->sin_family = AF_INET;
733 sinp->sin_addr = iaddr;
734 sinp->sin_port = htons(123);
737 * Try opening a socket for the specified class D address. This
738 * works under SunOS 4.x, but not OSF1 .. :-(
740 s = open_socket(sinp, 0, 1);
742 memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
744 /* HACK ! -- stuff in an address */
745 inter_list[i].bcast.sin_addr.s_addr = addr;
747 "...multicast address %s using wildcard socket",
750 inter_list[i].fd = s;
751 inter_list[i].bfd = -1;
752 (void) strncpy(inter_list[i].name, "multicast",
753 sizeof(inter_list[i].name));
754 inter_list[i].mask.sin_addr.s_addr = htonl(~(u_int32)0);
758 * enable reception of multicast packets
760 mreq.imr_multiaddr = iaddr;
761 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
762 if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
763 (char *)&mreq, sizeof(mreq)) == -1)
765 "setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)",
766 mreq.imr_multiaddr.s_addr,
767 mreq.imr_interface.s_addr, inet_ntoa(iaddr));
768 inter_list[i].flags |= INT_MULTICAST;
769 if (i >= ninterfaces)
772 struct in_addr iaddr;
776 "cannot add multicast address %s as no MCAST support",
782 * io_unsetbclient - close the broadcast client sockets
785 io_unsetbclient(void)
789 for (i = 1; i < ninterfaces; i++)
791 if (!(inter_list[i].flags & INT_BCASTOPEN))
793 close_socket(inter_list[i].bfd);
794 inter_list[i].bfd = -1;
795 inter_list[i].flags &= ~INT_BCASTOPEN;
801 * io_multicast_del() - delete multicast group address
811 u_int32 haddr = ntohl(addr);
812 struct sockaddr_in sinaddr;
814 if (!IN_CLASSD(haddr))
816 sinaddr.sin_addr.s_addr = addr;
818 "invalid multicast address %s", ntoa(&sinaddr));
823 * Disable reception of multicast packets
825 mreq.imr_multiaddr.s_addr = addr;
826 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
827 for (i = 0; i < ninterfaces; i++)
829 if (!(inter_list[i].flags & INT_MULTICAST))
831 if (!(inter_list[i].fd < 0))
833 if (addr != inter_list[i].sin.sin_addr.s_addr)
837 /* we have an explicit fd, so we can close it */
838 close_socket(inter_list[i].fd);
839 memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
840 inter_list[i].fd = -1;
841 inter_list[i].bfd = -1;
845 /* We are sharing "any address" port :-( Don't close it! */
846 if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
847 (char *)&mreq, sizeof(mreq)) == -1)
848 msyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails: %m");
849 /* This is **WRONG** -- there may be others ! */
850 /* There should be a count of users ... */
851 inter_list[i].flags &= ~INT_MULTICAST;
854 #else /* not MCAST */
855 msyslog(LOG_ERR, "this function requires multicast kernel");
856 #endif /* not MCAST */
861 * open_socket - open a socket, returning the file descriptor
865 struct sockaddr_in *addr,
872 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
874 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
876 /* create a datagram (UDP) socket */
877 if ( (fd = socket(AF_INET, SOCK_DGRAM, 0))
882 #endif /* SYS_WINNT */
885 msyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed: %m");
890 /* set SO_REUSEADDR since we will be binding the same port
891 number on each interface */
892 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
893 (char *)&on, sizeof(on)))
895 msyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails: %m");
898 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
899 /* set IP_TOS to minimize packet delay */
900 tos = IPTOS_LOWDELAY;
901 if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)
903 msyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails: %m");
905 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
908 * bind the local address.
910 if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
913 "bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m",
914 fd, addr->sin_family, (int)ntohs(addr->sin_port),
916 IN_CLASSD(ntohl(addr->sin_addr.s_addr)), flags);
917 msyslog(LOG_ERR, buff);
921 * soft fail if opening a class D address
923 if (IN_CLASSD(ntohl(addr->sin_addr.s_addr)))
933 printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n",
936 (int)ntohs(addr->sin_port),
940 if (fd > maxactivefd)
942 FD_SET(fd, &activefds);
949 /* in vxWorks we use FIONBIO, but the others are defined for old systems, so
950 * all hell breaks loose if we leave them defined
957 #if defined(O_NONBLOCK) /* POSIX */
958 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
960 msyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails: %m");
964 #elif defined(FNDELAY)
965 if (fcntl(fd, F_SETFL, FNDELAY) < 0)
967 msyslog(LOG_ERR, "fcntl(FNDELAY) fails: %m");
971 #elif defined(O_NDELAY) /* generally the same as FNDELAY */
972 if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
974 msyslog(LOG_ERR, "fcntl(O_NDELAY) fails: %m");
978 #elif defined(FIONBIO)
981 (ioctl(fd,FIONBIO,&1) < 0)
982 # elif defined(SYS_WINNT)
983 (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
985 (ioctl(fd,FIONBIO,&on) < 0)
989 msyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m");
993 #elif defined(FIOSNBIO)
994 if (ioctl(fd,FIOSNBIO,&on) < 0)
996 msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails: %m");
1001 # include "Bletch: Need non-blocking I/O!"
1004 #ifdef HAVE_SIGNALED_IO
1005 init_socket_sig(fd);
1006 #endif /* not HAVE_SIGNALED_IO */
1009 * Turn off the SO_REUSEADDR socket option. It apparently
1010 * causes heartburn on systems with multicast IP installed.
1011 * On normal systems it only gets looked at when the address
1012 * is being bound anyway..
1015 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1016 (char *)&off, sizeof(off)))
1018 msyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m");
1022 /* if this interface can support broadcast, set SO_BROADCAST */
1023 if (flags & INT_BROADCAST)
1025 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1026 (char *)&on, sizeof(on)))
1028 msyslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
1031 #endif /* SO_BROADCAST */
1033 #if !defined(SYS_WINNT) && !defined(VMS)
1036 printf("flags for fd %d: 0%o\n", fd,
1037 fcntl(fd, F_GETFL, 0));
1039 #endif /* SYS_WINNT || VMS */
1046 * close_socket - close a socket and remove from the activefd list
1055 (void) closesocket(fd);
1056 FD_CLR( (u_int) fd, &activefds);
1058 if (fd >= maxactivefd) {
1060 for (i = 0; i < maxactivefd; i++)
1061 if (FD_ISSET(i, &activefds))
1063 maxactivefd = newmax;
1069 * close_file - close a file and remove from the activefd list
1070 * added 1/31/1997 Greg Schueman for Windows NT portability
1080 FD_CLR( (u_int) fd, &activefds);
1082 if (fd >= maxactivefd) {
1084 for (i = 0; i < maxactivefd; i++)
1085 if (FD_ISSET(i, &activefds))
1087 maxactivefd = newmax;
1092 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
1094 * sendpkt - send a packet to the specified destination. Maintain a
1095 * send error cache so that only the first consecutive error for a
1096 * destination is logged.
1100 struct sockaddr_in *dest,
1101 struct interface *inter,
1110 #endif /* SYS_WINNT */
1113 * Send error cache. Empty slots have port == 0
1114 * Set ERRORCACHESIZE to 0 to disable
1118 struct in_addr addr;
1121 #ifndef ERRORCACHESIZE
1122 #define ERRORCACHESIZE 8
1124 #if ERRORCACHESIZE > 0
1125 static struct cache badaddrs[ERRORCACHESIZE];
1127 #define badaddrs ((struct cache *)0) /* Only used in empty loops! */
1131 printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n",
1132 (ttl >= 0) ? "\tMCAST\t*****" : "",
1133 inter->fd, ntoa(dest),
1134 ntoa(&inter->sin), ttl, len);
1139 * for the moment we use the bcast option to set multicast ttl
1141 if (ttl > 0 && ttl != inter->last_ttl) {
1145 * set the multicast ttl for outgoing packets
1147 if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,
1148 &mttl, sizeof(mttl)) == -1)
1149 msyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails: %m");
1151 inter->last_ttl = ttl;
1155 for (slot = ERRORCACHESIZE; --slot >= 0; )
1156 if (badaddrs[slot].port == dest->sin_port &&
1157 badaddrs[slot].addr.s_addr == dest->sin_addr.s_addr)
1160 #if defined(HAVE_IO_COMPLETION_PORT)
1161 err = io_completion_port_sendto(inter, pkt, len, dest);
1162 if (err != ERROR_SUCCESS)
1164 cc = sendto(inter->fd, (char *)pkt, (size_t)len, 0, (struct sockaddr *)dest,
1165 sizeof(struct sockaddr_in));
1171 #if defined(HAVE_IO_COMPLETION_PORT)
1172 if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0)
1174 if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
1178 * Remember this, if there's an empty slot
1180 for (slot = ERRORCACHESIZE; --slot >= 0; )
1181 if (badaddrs[slot].port == 0)
1183 badaddrs[slot].port = dest->sin_port;
1184 badaddrs[slot].addr = dest->sin_addr;
1187 msyslog(LOG_ERR, "sendto(%s): %m", ntoa(dest));
1195 * He's not bad any more
1199 msyslog(LOG_INFO, "Connection re-established to %s", ntoa(dest));
1200 badaddrs[slot].port = 0;
1205 #if !defined(HAVE_IO_COMPLETION_PORT)
1207 * fdbits - generate ascii representation of fd_set (FAU debug support)
1208 * HFDF format - highest fd first.
1216 static char buffer[256];
1217 char * buf = buffer;
1219 count = (count < 256) ? count : 255;
1223 *buf++ = FD_ISSET(count, set) ? '#' : '-';
1232 * input_handler - receive packets asynchronously
1240 register struct recvbuf *rb;
1243 struct timeval tvzero;
1245 l_fp ts; /* Timestamp at BOselect() gob */
1246 l_fp ts_e; /* Timestamp at EOselect() gob */
1248 int select_count = 0;
1249 static int handler_count = 0;
1252 if (handler_count != 1)
1253 msyslog(LOG_ERR, "input_handler: handler_count is %d!", handler_count);
1260 * Do a poll to see who has data
1264 tvzero.tv_sec = tvzero.tv_usec = 0;
1267 * If we have something to do, freeze a timestamp.
1268 * See below for the other cases (nothing (left) to do or error)
1270 while (0 < (n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero)))
1277 * Check out the reference clocks first, if any
1281 register struct refclockio *rp;
1283 for (rp = refio; rp != 0 && n > 0; rp = rp->next)
1286 if (FD_ISSET(fd, &fds))
1289 if (free_recvbuffs() == 0)
1291 char buf[RX_BUFF_SIZE];
1293 (void) read(fd, buf, sizeof buf);
1298 rb = get_free_recv_buffer();
1300 i = (rp->datalen == 0
1301 || rp->datalen > sizeof(rb->recv_space))
1302 ? sizeof(rb->recv_space) : rp->datalen;
1304 read(fd, (char *)&rb->recv_space, (unsigned)i);
1306 if (rb->recv_length == -1)
1308 msyslog(LOG_ERR, "clock read fd %d: %m", fd);
1314 * Got one. Mark how and when it got here,
1315 * put it on the full list and do bookkeeping.
1317 rb->recv_srcclock = rp->srcclock;
1321 rb->receiver = rp->clock_recv;
1326 * have direct input routine for refclocks
1328 if (rp->io_input(rb) == 0)
1331 * data was consumed - nothing to pass up
1332 * into block input machine
1343 add_full_recv_buffer(rb);
1350 #endif /* REFCLOCK */
1353 * Loop through the interfaces looking for data to read.
1355 for (i = ninterfaces - 1; (i >= 0) && (n > 0); i--)
1357 for (doing = 0; (doing < 2) && (n > 0); doing++)
1361 fd = inter_list[i].fd;
1365 if (!(inter_list[i].flags & INT_BCASTOPEN))
1367 fd = inter_list[i].bfd;
1369 if (fd < 0) continue;
1370 if (FD_ISSET(fd, &fds))
1375 * Get a buffer and read the frame. If we
1376 * haven't got a buffer, or this is received
1377 * on the wild card socket, just dump the
1381 #ifdef UDP_WILDCARD_DELIVERY
1383 * these guys manage to put properly addressed
1384 * packets into the wildcard queue
1386 (free_recvbuffs() == 0)
1388 ((i == 0) || (free_recvbuffs() == 0))
1392 char buf[RX_BUFF_SIZE];
1393 struct sockaddr from;
1395 fromlen = sizeof from;
1396 (void) recvfrom(fd, buf, sizeof(buf), 0, &from, &fromlen);
1399 printf("%s on %d(%lu) fd=%d from %s\n",
1400 (i) ? "drop" : "ignore",
1401 i, free_recvbuffs(), fd,
1402 inet_ntoa(((struct sockaddr_in *) &from)->sin_addr));
1411 rb = get_free_recv_buffer();
1413 fromlen = sizeof(struct sockaddr_in);
1414 rb->recv_length = recvfrom(fd,
1415 (char *)&rb->recv_space,
1416 sizeof(rb->recv_space), 0,
1417 (struct sockaddr *)&rb->recv_srcadr,
1419 if (rb->recv_length == 0
1421 || errno==EWOULDBLOCK
1430 else if (rb->recv_length < 0)
1432 msyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
1433 inet_ntoa(rb->recv_srcadr.sin_addr), fd);
1436 printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd);
1443 printf("input_handler: if=%d fd=%d length %d from %08lx %s\n",
1444 i, fd, rb->recv_length,
1445 (u_long)ntohl(rb->recv_srcadr.sin_addr.s_addr) &
1447 inet_ntoa(rb->recv_srcadr.sin_addr));
1451 * Got one. Mark how and when it got here,
1452 * put it on the full list and do bookkeeping.
1454 rb->dstadr = &inter_list[i];
1457 rb->receiver = receive;
1459 add_full_recv_buffer(rb);
1461 inter_list[i].received++;
1465 /* Check more interfaces */
1470 * Done everything from that select. Poll again.
1475 * If nothing more to do, try again.
1476 * If nothing to do, just return.
1477 * If an error occurred, complain and return.
1481 if (select_count == 0) /* We really had nothing to do */
1484 msyslog(LOG_DEBUG, "input_handler: select() returned 0");
1488 /* We've done our work */
1491 * (ts_e - ts) is the amount of time we spent processing
1492 * this gob of file descriptors. Log it.
1496 msyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
1507 * extended FAU debugging output
1509 msyslog(LOG_ERR, "select(%d, %s, 0L, 0L, &0.000000) error: %m",
1510 maxactivefd+1, fdbits(maxactivefd, &activefds));
1515 for (j = 0; j <= maxactivefd; j++)
1517 (FD_ISSET(j, &fds) && (read(j, &b, 0) == -1))
1519 msyslog(LOG_ERR, "Bad file descriptor %d", j);
1525 msyslog(LOG_ERR, "input_handler: fell out of infinite for(;;) loop!");
1533 * findinterface - find interface corresponding to address
1537 struct sockaddr_in *addr
1541 struct sockaddr_in saddr;
1542 int saddrlen = sizeof(saddr);
1546 * This is considerably hoke. We open a socket, connect to it
1547 * and slap a getsockname() on it. If anything breaks, as it
1548 * probably will in some j-random knockoff, we just return the
1549 * wildcard interface.
1551 saddr.sin_family = AF_INET;
1552 saddr.sin_addr.s_addr = addr->sin_addr.s_addr;
1553 saddr.sin_port = htons(2000);
1554 s = socket(AF_INET, SOCK_DGRAM, 0);
1556 return (any_interface);
1558 rtn = connect(s, (struct sockaddr *)&saddr, sizeof(saddr));
1560 return (any_interface);
1562 rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen);
1564 return (any_interface);
1567 xaddr = NSRCADR(&saddr);
1568 for (i = 1; i < ninterfaces; i++) {
1571 * We match the unicast address only.
1573 if (NSRCADR(&inter_list[i].sin) == xaddr)
1574 return (&inter_list[i]);
1576 return (any_interface);
1581 * findbcastinter - find broadcast interface corresponding to address
1585 struct sockaddr_in *addr
1588 #if defined(SIOCGIFCONF) || defined(SYS_WINNT)
1590 register u_int32 xaddr;
1592 xaddr = NSRCADR(addr);
1593 for (i = 1; i < ninterfaces; i++) {
1596 * We match only those interfaces marked as
1597 * broadcastable and either the explicit broadcast
1598 * address or the network portion of the IP address.
1601 if (!(inter_list[i].flags & INT_BROADCAST))
1603 if (NSRCADR(&inter_list[i].bcast) == xaddr)
1604 return (&inter_list[i]);
1605 if ((NSRCADR(&inter_list[i].sin) &
1606 NSRCADR(&inter_list[i].mask)) == (xaddr &
1607 NSRCADR(&inter_list[i].mask)))
1608 return (&inter_list[i]);
1610 #endif /* SIOCGIFCONF */
1611 return (any_interface);
1616 * io_clr_stats - clear I/O module statistics
1621 packets_dropped = 0;
1622 packets_ignored = 0;
1623 packets_received = 0;
1625 packets_notsent = 0;
1629 io_timereset = current_time;
1635 * This is a hack so that I don't have to fool with these ioctls in the
1636 * pps driver ... we are already non-blocking and turn on SIGIO thru
1637 * another mechanisim
1641 struct refclockio *rio
1646 * Stuff the I/O structure in the list and mark the descriptor
1647 * in use. There is a harmless (I hope) race condition here.
1652 if (rio->fd > maxactivefd)
1653 maxactivefd = rio->fd;
1654 FD_SET(rio->fd, &activefds);
1660 * io_addclock - add a reference clock to the list and arrange that we
1661 * get SIGIO interrupts from it.
1665 struct refclockio *rio
1670 * Stuff the I/O structure in the list and mark the descriptor
1671 * in use. There is a harmless (I hope) race condition here.
1676 # ifdef HAVE_SIGNALED_IO
1677 if (init_clock_sig(rio))
1683 # elif defined(HAVE_IO_COMPLETION_PORT)
1684 if (io_completion_port_add_clock_io(rio))
1692 if (rio->fd > maxactivefd)
1693 maxactivefd = rio->fd;
1694 FD_SET(rio->fd, &activefds);
1701 * io_closeclock - close the clock in the I/O structure given
1705 struct refclockio *rio
1709 * Remove structure from the list
1717 register struct refclockio *rp;
1719 for (rp = refio; rp != 0; rp = rp->next)
1720 if (rp->next == rio)
1722 rp->next = rio->next;
1729 * Internal error. Report it.
1732 "internal error: refclockio structure not found");
1738 * Close the descriptor.
1740 close_file(rio->fd);
1742 #endif /* REFCLOCK */
1750 for (i = 0; i <= maxactivefd; i++)
1751 (void)close_socket(i);