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"
19 /* Don't include ISC's version of IPv6 variables and structures */
21 #include <isc/interfaceiter.h>
23 #include <isc/result.h>
31 #ifdef HAVE_SYS_PARAM_H
32 # include <sys/param.h>
33 #endif /* HAVE_SYS_PARAM_H */
34 #ifdef HAVE_NETINET_IN_H
35 # include <netinet/in.h>
37 #ifdef HAVE_NETINET_IN_SYSTM_H
38 # include <netinet/in_systm.h>
39 #else /* Some old linux systems at least have in_system.h instead. */
40 # ifdef HAVE_NETINET_IN_SYSTEM_H
41 # include <netinet/in_system.h>
43 #endif /* HAVE_NETINET_IN_SYSTM_H */
44 #ifdef HAVE_NETINET_IP_H
45 # include <netinet/ip.h>
47 #ifdef HAVE_SYS_IOCTL_H
48 # include <sys/ioctl.h>
50 #ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
51 # include <sys/sockio.h>
53 #include <arpa/inet.h>
55 extern int listen_to_virtual_ips;
57 #if defined(SYS_WINNT)
58 #include <transmitbuff.h>
59 #include <isc/win32os.h>
61 * Define this macro to control the behavior of connection
62 * resets on UDP sockets. See Microsoft KnowledgeBase Article Q263823
64 * NOTE: This requires that Windows 2000 systems install Service Pack 2
67 #ifndef SIO_UDP_CONNRESET
68 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
74 * We do asynchronous input using the SIGIO facility. A number of
75 * recvbuf buffers are preallocated for input. In the signal
76 * handler we poll to see which sockets are ready and read the
77 * packets from them into the recvbuf's along with a time stamp and
78 * an indication of the source host and the interface it was received
79 * through. This allows us to get as accurate receive time stamps
80 * as possible independent of other processing going on.
82 * We watch the number of recvbufs available to the signal handler
83 * and allocate more when this number drops below the low water
84 * mark. If the signal handler should run out of buffers in the
85 * interim it will drop incoming frames, the idea being that it is
86 * better to drop a packet than to be inaccurate.
91 * Other statistics of possible interest
93 volatile u_long packets_dropped; /* total number of packets dropped on reception */
94 volatile u_long packets_ignored; /* packets received on wild card interface */
95 volatile u_long packets_received; /* total number of packets received */
96 u_long packets_sent; /* total number of packets sent */
97 u_long packets_notsent; /* total number of packets which couldn't be sent */
99 volatile u_long handler_calls; /* number of calls to interrupt handler */
100 volatile u_long handler_pkts; /* number of pkts received by handler */
101 u_long io_timereset; /* time counters were reset */
106 struct interface *any_interface; /* default ipv4 interface */
107 struct interface *any6_interface; /* default ipv6 interface */
108 struct interface *loopback_interface; /* loopback ipv4 interface */
109 struct interface *loopback6_interface; /* loopback ipv6 interface */
110 struct interface inter_list[MAXINTERFACES]; /* Interface list */
111 int ninterfaces; /* Total number of interfaces */
112 int nwilds; /* Total number of wildcard intefaces */
113 int wildipv4 = -1; /* Index into inter_list for IPv4 wildcard */
114 int wildipv6 = -1; /* Index into inter_list for IPv6 wildcard */
118 * Refclock stuff. We keep a chain of structures with data concerning
119 * the guys we are doing I/O for.
121 static struct refclockio *refio;
122 #endif /* REFCLOCK */
126 * Define what the possible "soft" errors can be. These are non-fatal returns
127 * of various network related functions, like recv() and so on.
129 * For some reason, BSDI (and perhaps others) will sometimes return <0
130 * from recv() but will have errno==0. This is broken, but we have to
131 * work around it here.
133 #define SOFT_ERROR(e) ((e) == EAGAIN || \
134 (e) == EWOULDBLOCK || \
139 * File descriptor masks etc. for call to select
140 * Not needed for I/O Completion Ports
145 static int create_sockets P((u_short));
146 static SOCKET open_socket P((struct sockaddr_storage *, int, int));
147 static void close_socket P((SOCKET));
149 static void close_file P((SOCKET));
151 static char * fdbits P((int, fd_set *));
152 static void set_reuseaddr P((int));
154 typedef struct vsock vsock_t;
158 ISC_LINK(vsock_t) link;
161 ISC_LIST(vsock_t) sockets_list;
163 typedef struct remaddr remaddr_t;
166 struct sockaddr_storage addr;
168 ISC_LINK(remaddr_t) link;
171 ISC_LIST(remaddr_t) remoteaddr_list;
173 void add_socket_to_list P((SOCKET));
174 void delete_socket_from_list P((SOCKET));
175 void add_addr_to_list P((struct sockaddr_storage *, int));
176 void delete_addr_from_list P((struct sockaddr_storage *));
177 int find_addr_in_list P((struct sockaddr_storage *));
178 int create_wildcards P((u_short));
179 isc_boolean_t address_okay P((isc_interface_t *));
180 void convert_isc_if P((isc_interface_t *, struct interface *, u_short));
184 * Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom
185 * to not work correctly, returning a WSACONNRESET error when a WSASendTo
186 * fails with an "ICMP port unreachable" response and preventing the
187 * socket from using the WSARecvFrom in subsequent operations.
188 * The function below fixes this, but requires that Windows 2000
189 * Service Pack 2 or later be installed on the system. NT 4.0
190 * systems are not affected by this and work correctly.
191 * See Microsoft Knowledge Base Article Q263823 for details of this.
194 connection_reset_fix(SOCKET fd) {
195 DWORD dwBytesReturned = 0;
196 BOOL bNewBehavior = FALSE;
199 if(isc_win32os_majorversion() < 5)
200 return (ISC_R_SUCCESS); /* NT 4.0 has no problem */
202 /* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */
203 status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,
204 sizeof(bNewBehavior), NULL, 0,
205 &dwBytesReturned, NULL, NULL);
206 if (status != SOCKET_ERROR)
207 return (ISC_R_SUCCESS);
209 return (ISC_R_UNEXPECTED);
213 * init_io - initialize I/O data structures and call socket creation routine
220 #endif /* SYS_WINNT */
223 * Init buffer free list and stat counters
225 init_recvbuff(RECV_INIT);
227 packets_dropped = packets_received = 0;
229 packets_sent = packets_notsent = 0;
230 handler_calls = handler_pkts = 0;
232 loopback_interface = NULL;
233 loopback6_interface = NULL;
239 #if defined(HAVE_SIGNALED_IO)
244 if (!Win32InitSockets())
246 netsyslog(LOG_ERR, "No useable winsock.dll: %m");
249 #endif /* SYS_WINNT */
251 ISC_LIST_INIT(sockets_list);
253 ISC_LIST_INIT(remoteaddr_list);
259 (void) create_sockets(htons(NTP_PORT));
264 printf("init_io: maxactivefd %d\n", maxactivefd);
269 create_wildcards(u_short port) {
273 * create pseudo-interface with wildcard IPv4 address
275 inter_list[idx].sin.ss_family = AF_INET;
276 ((struct sockaddr_in*)&inter_list[idx].sin)->sin_addr.s_addr = htonl(INADDR_ANY);
277 ((struct sockaddr_in*)&inter_list[idx].sin)->sin_port = port;
278 (void) strncpy(inter_list[idx].name, "wildcard", sizeof(inter_list[idx].name));
279 inter_list[idx].mask.ss_family = AF_INET;
280 ((struct sockaddr_in*)&inter_list[idx].mask)->sin_addr.s_addr = htonl(~(u_int32)0);
281 inter_list[idx].bfd = INVALID_SOCKET;
282 inter_list[idx].num_mcast = 0;
283 inter_list[idx].received = 0;
284 inter_list[idx].sent = 0;
285 inter_list[idx].notsent = 0;
286 inter_list[idx].flags = INT_BROADCAST;
287 any_interface = &inter_list[idx];
290 * enable possible multicast reception on the broadcast socket
292 inter_list[idx].bcast.ss_family = AF_INET;
293 ((struct sockaddr_in*)&inter_list[idx].bcast)->sin_port = port;
294 ((struct sockaddr_in*)&inter_list[idx].bcast)->sin_addr.s_addr = htonl(INADDR_ANY);
301 * create pseudo-interface with wildcard IPv6 address
303 if (isc_net_probeipv6() == ISC_R_SUCCESS) {
304 inter_list[idx].sin.ss_family = AF_INET6;
305 ((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_addr = in6addr_any;
306 ((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_port = port;
307 (void) strncpy(inter_list[idx].name, "wildcard", sizeof(inter_list[idx].name));
308 inter_list[idx].mask.ss_family = AF_INET6;
309 memset(&((struct sockaddr_in6*)&inter_list[idx].mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));
310 inter_list[idx].bfd = INVALID_SOCKET;
311 inter_list[idx].num_mcast = 0;
312 inter_list[idx].received = 0;
313 inter_list[idx].sent = 0;
314 inter_list[idx].notsent = 0;
315 inter_list[idx].flags = 0;
316 any6_interface = &inter_list[idx];
325 address_okay(isc_interface_t *isc_if) {
329 printf("address_okay: listen Virtual: %d, IF name: %s, Up Flag: %d\n",
330 listen_to_virtual_ips, isc_if->name, (isc_if->flags & INTERFACE_F_UP));
333 if (listen_to_virtual_ips == 0 && (strchr(isc_if->name, (int)':') != NULL))
336 /* XXXPDM This should be fixed later, but since we may not have set
337 * the UP flag, we at least get to use the interface.
338 * The UP flag is not always set so we don't do this right now.
340 /* if ((isc_if->flags & INTERFACE_F_UP) == 0)
346 convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port) {
348 if(isc_if->af == AF_INET) {
349 itf->sin.ss_family = (u_short) isc_if->af;
350 strcpy(itf->name, isc_if->name);
351 memcpy(&(((struct sockaddr_in*)&itf->sin)->sin_addr),
352 &(isc_if->address.type.in),
353 sizeof(struct in_addr));
354 ((struct sockaddr_in*)&itf->sin)->sin_port = port;
356 if((isc_if->flags & INTERFACE_F_BROADCAST) != 0) {
357 itf->flags |= INT_BROADCAST;
358 itf->bcast.ss_family = itf->sin.ss_family;
359 memcpy(&(((struct sockaddr_in*)&itf->bcast)->sin_addr),
360 &(isc_if->broadcast.type.in),
361 sizeof(struct in_addr));
362 ((struct sockaddr_in*)&itf->bcast)->sin_port = port;
365 itf->mask.ss_family = itf->sin.ss_family;
366 memcpy(&(((struct sockaddr_in*)&itf->mask)->sin_addr),
367 &(isc_if->netmask.type.in),
368 sizeof(struct in_addr));
369 ((struct sockaddr_in*)&itf->mask)->sin_port = port;
371 if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback_interface == NULL))
373 loopback_interface = itf;
377 else if (isc_if->af == AF_INET6) {
378 itf->sin.ss_family = (u_short) isc_if->af;
379 strcpy(itf->name, isc_if->name);
380 memcpy(&(((struct sockaddr_in6 *)&itf->sin)->sin6_addr),
381 &(isc_if->address.type.in6),
382 sizeof(struct in6_addr));
383 ((struct sockaddr_in6 *)&itf->sin)->sin6_port = port;
385 itf->mask.ss_family = itf->sin.ss_family;
386 memcpy(&(((struct sockaddr_in6 *)&itf->mask)->sin6_addr),
387 &(isc_if->netmask.type.in6),
388 sizeof(struct in6_addr));
389 ((struct sockaddr_in6 *)&itf->mask)->sin6_port = port;
391 if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback6_interface == NULL))
393 loopback6_interface = itf;
396 #endif /* HAVE_IPV6 */
398 /* Process the rest of the flags */
400 if((isc_if->flags & INTERFACE_F_UP) != 0)
401 itf->flags |= INT_UP;
402 if((isc_if->flags & INTERFACE_F_LOOPBACK) != 0)
403 itf->flags |= INT_LOOPBACK;
404 if((isc_if->flags & INTERFACE_F_POINTTOPOINT) != 0)
405 itf->flags |= INT_PPP;
408 * create_sockets - create a socket for each interface plus a default
409 * socket for when we don't know where to send
416 struct sockaddr_storage resmask;
418 isc_mem_t *mctx = NULL;
419 isc_interfaceiter_t *iter = NULL;
420 isc_boolean_t scan_ipv4 = ISC_FALSE;
421 isc_boolean_t scan_ipv6 = ISC_FALSE;
427 printf("create_sockets(%d)\n", ntohs( (u_short) port));
430 if (isc_net_probeipv6() == ISC_R_SUCCESS)
431 scan_ipv6 = ISC_TRUE;
434 netsyslog(LOG_ERR, "no IPv6 interfaces found");
437 if (isc_net_probeipv4() == ISC_R_SUCCESS)
438 scan_ipv4 = ISC_TRUE;
440 netsyslog(LOG_ERR, "no IPv4 interfaces found");
442 nwilds = create_wildcards(port);
445 result = isc_interfaceiter_create(mctx, &iter);
446 if (result != ISC_R_SUCCESS)
449 for (result = isc_interfaceiter_first(iter);
450 result == ISC_R_SUCCESS;
451 result = isc_interfaceiter_next(iter))
453 isc_interface_t isc_if;
456 result = isc_interfaceiter_current(iter, &isc_if);
457 if (result != ISC_R_SUCCESS)
460 /* See if we have a valid family to use */
461 family = isc_if.address.family;
462 if (family != AF_INET && family != AF_INET6)
464 if (scan_ipv4 == ISC_FALSE && family == AF_INET)
466 if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
469 /* Check to see if we are going to use the interface */
470 if (address_okay(&isc_if) == ISC_TRUE) {
471 convert_isc_if(&isc_if, &inter_list[idx], port);
472 inter_list[idx].fd = INVALID_SOCKET;
473 inter_list[idx].bfd = INVALID_SOCKET;
474 inter_list[idx].num_mcast = 0;
475 inter_list[idx].received = 0;
476 inter_list[idx].sent = 0;
477 inter_list[idx].notsent = 0;
481 isc_interfaceiter_destroy(&iter);
485 * I/O Completion Ports don't care about the select and FD_SET
487 #ifndef HAVE_IO_COMPLETION_PORT
491 for (i = 0; i < ninterfaces; i++) {
492 inter_list[i].fd = open_socket(&inter_list[i].sin,
493 inter_list[i].flags & INT_BROADCAST, 0);
494 if (inter_list[i].bfd != INVALID_SOCKET)
495 msyslog(LOG_INFO, "Listening on interface %s, %s#%d",
497 stoa((&inter_list[i].sin)),
499 if ((inter_list[i].flags & INT_BROADCAST) &&
500 inter_list[i].bfd != INVALID_SOCKET)
501 msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
502 stoa((&inter_list[i].bcast)),
504 #if defined (HAVE_IO_COMPLETION_PORT)
505 if (inter_list[i].fd != INVALID_SOCKET) {
506 io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
512 * Now that we have opened all the sockets, turn off the reuse
518 * Blacklist all bound interface addresses
519 * Wildcard interfaces are ignored.
522 for (i = nwilds; i < ninterfaces; i++) {
523 SET_HOSTMASK(&resmask, inter_list[i].sin.ss_family);
524 hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask,
525 RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
529 * Calculate the address hash for each interface address.
531 for (i = 0; i < ninterfaces; i++) {
532 inter_list[i].addr_refid = addr2refid(&inter_list[i].sin);
538 printf("create_sockets: ninterfaces=%d\n", ninterfaces);
539 for (i = 0; i < ninterfaces; i++) {
540 printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x\n",
545 inter_list[i].flags);
546 /* Leave these as three printf calls. */
548 stoa((&inter_list[i].sin)));
549 if (inter_list[i].flags & INT_BROADCAST)
551 stoa((&inter_list[i].bcast)));
553 stoa((&inter_list[i].mask)));
561 * io_setbclient - open the broadcast client sockets
568 #ifdef OPEN_BCAST_SOCKET
571 for (i = nwilds; i < ninterfaces; i++) {
572 /* Only IPv4 addresses are valid for broadcast */
573 if (inter_list[i].bcast.ss_family != AF_INET)
576 /* Is this a broadcast address? */
577 if (!(inter_list[i].flags & INT_BROADCAST))
580 /* Do we already have the broadcast address open? */
581 if (inter_list[i].flags & INT_BCASTOPEN)
585 inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
587 #ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */
588 inter_list[i].bfd = open_socket(&inter_list[i].bcast,
590 if (inter_list[i].bfd != INVALID_SOCKET) {
591 inter_list[i].flags |= INT_BCASTOPEN;
592 #if defined (HAVE_IO_COMPLETION_PORT)
593 io_completion_port_add_socket(inter_list[i].bfd, &inter_list[i]);
598 if (inter_list[i].bfd != INVALID_SOCKET)
599 printf("io_setbclient: Opened broadcast client on interface %d, socket: %d\n",
600 i, inter_list[i].bfd);
602 printf("io_setbclient: Unable to Open broadcast client on interface %d\n",
608 #ifdef OPEN_BCAST_SOCKET
613 printf("io_setbclient: Opened broadcast clients\n");
618 * set_reuseaddr() - set/clear REUSEADDR on all sockets
619 * NB possible hole - should we be doing this on broadcast
623 set_reuseaddr(int flag) {
626 for (i=0; i < ninterfaces; i++) {
628 * if inter_list[ n ].fd is -1, we might have a adapter
629 * configured but not present
631 if (inter_list[i].fd != INVALID_SOCKET) {
632 if (setsockopt(inter_list[i].fd, SOL_SOCKET,
633 SO_REUSEADDR, (char *)&flag,
635 netsyslog(LOG_ERR, "set_reuseaddr: setsockopt(SO_REUSEADDR, %s) failed: %m", flag ? "on" : "off");
643 * io_multicast_add() - add multicast group address
647 struct sockaddr_storage addr
652 int i = ninterfaces; /* Use the next interface */
653 u_int32 haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
654 struct in_addr iaddr;
656 struct sockaddr_in *sinp;
659 struct ipv6_mreq mreq6;
660 struct in6_addr iaddr6;
661 struct sockaddr_in6 *sin6p;
662 #endif /* HAVE_IPV6 */
664 switch (addr.ss_family)
667 iaddr = (((struct sockaddr_in*)&addr)->sin_addr);
668 if (!IN_CLASSD(haddr)) {
670 "multicast address %s not class D",
674 for (i = nwilds; i < ninterfaces; i++) {
675 /* Be sure it's the correct family */
676 if (inter_list[i].sin.ss_family != AF_INET)
678 /* Already have this address */
679 if (SOCKCMP(&inter_list[i].sin, &addr))
681 /* found a free slot */
682 if (SOCKNUL(&inter_list[i].sin) &&
683 inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
684 inter_list[i].flags == 0)
687 sinp = (struct sockaddr_in*)&(inter_list[i].sin);
688 memset((char *)&mreq, 0, sizeof(mreq));
689 memset((char *)&inter_list[i], 0, sizeof(struct interface));
690 sinp->sin_family = AF_INET;
691 sinp->sin_addr = iaddr;
692 sinp->sin_port = htons(NTP_PORT);
695 * Try opening a socket for the specified class D address. This
696 * works under SunOS 4.x, but not OSF1 .. :-(
699 s = open_socket((struct sockaddr_storage*)sinp, 0, 1);
701 if (s == INVALID_SOCKET) {
702 memset((char *)&inter_list[i], 0, sizeof(struct interface));
705 /* HACK ! -- stuff in an address */
706 inter_list[i].bcast = addr;
708 "...multicast address %s using wildcard socket",
712 "No wildcard socket available to use for address %s",
717 inter_list[i].fd = s;
718 inter_list[i].bfd = INVALID_SOCKET;
719 (void) strncpy(inter_list[i].name, "multicast",
720 sizeof(inter_list[i].name));
721 ((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr = htonl(~(u_int32)0);
722 #if defined (HAVE_IO_COMPLETION_PORT)
723 io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
728 * enable reception of multicast packets
730 mreq.imr_multiaddr = iaddr;
731 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
732 if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
733 (char *)&mreq, sizeof(mreq)) == -1)
735 "setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)",
736 mreq.imr_multiaddr.s_addr,
737 mreq.imr_interface.s_addr, inet_ntoa(iaddr));
738 inter_list[i].flags |= INT_MULTICAST;
739 inter_list[i].num_mcast++;
740 if (i >= ninterfaces)
743 add_addr_to_list(&addr, i);
749 iaddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
750 if (!IN6_IS_ADDR_MULTICAST(&iaddr6)) {
752 "address %s not IPv6 multicast address",
756 for (i = nwilds; i < ninterfaces; i++) {
757 /* Be sure it's the correct family */
758 if(inter_list[i].sin.ss_family != AF_INET6)
760 /* Already have this address */
761 if (SOCKCMP(&inter_list[i].sin, &addr))
763 /* found a free slot */
764 if (SOCKNUL(&inter_list[i].sin) &&
765 inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
766 inter_list[i].flags == 0)
769 sin6p = (struct sockaddr_in6*)&inter_list[i].sin;
770 memset((char *)&mreq6, 0, sizeof(mreq6));
771 memset((char *)&inter_list[i], 0, sizeof(struct interface));
772 sin6p->sin6_family = AF_INET6;
773 sin6p->sin6_addr = iaddr6;
774 sin6p->sin6_port = htons(NTP_PORT);
777 * Try opening a socket for the specified class D address. This
778 * works under SunOS 4.x, but not OSF1 .. :-(
781 s = open_socket((struct sockaddr_storage*)sin6p, 0, 1);
783 if(s == INVALID_SOCKET){
784 memset((char *)&inter_list[i], 0, sizeof(struct interface));
787 /* HACK ! -- stuff in an address */
788 inter_list[i].bcast = addr;
790 "...multicast address %s using wildcard socket",
794 "No wildcard socket available to use for address %s",
799 inter_list[i].fd = s;
800 inter_list[i].bfd = INVALID_SOCKET;
801 (void)strncpy(inter_list[i].name, "multicast",
802 sizeof(inter_list[i].name));
803 memset(&(((struct sockaddr_in6*)&inter_list[i].mask)->sin6_addr), 1, sizeof(struct in6_addr));
804 #if defined (HAVE_IO_COMPLETION_PORT)
805 io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
810 * enable reception of multicast packets
812 mreq6.ipv6mr_multiaddr = iaddr6;
813 mreq6.ipv6mr_interface = 0;
814 if(setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
815 (char *)&mreq6, sizeof(mreq6)) == -1)
817 "setsockopt IPV6_JOIN_GROUP fails: %m on interface %d(%s)",
818 mreq6.ipv6mr_interface, stoa(&addr));
819 inter_list[i].flags |= INT_MULTICAST;
820 inter_list[i].num_mcast++;
824 add_addr_to_list(&addr, i);
826 #endif /* HAVE_IPV6 */
831 printf("io_multicast_add %s\n", stoa(&addr));
835 "cannot add multicast address %s as no MCAST support",
841 * io_unsetbclient - close the broadcast client sockets
844 io_unsetbclient(void)
848 for (i = nwilds; i < ninterfaces; i++)
850 if (!(inter_list[i].flags & INT_BCASTOPEN))
852 close_socket(inter_list[i].bfd);
853 inter_list[i].bfd = INVALID_SOCKET;
854 inter_list[i].flags &= ~INT_BCASTOPEN;
860 * io_multicast_del() - delete multicast group address
864 struct sockaddr_storage addr
873 struct ipv6_mreq mreq6;
874 struct in6_addr haddr6;
875 #endif /* HAVE_IPV6 */
877 switch (addr.ss_family)
881 haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
883 if (!IN_CLASSD(haddr))
886 "invalid multicast address %s", stoa(&addr));
891 * Disable reception of multicast packets
893 mreq.imr_multiaddr = ((struct sockaddr_in*)&addr)->sin_addr;
894 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
895 for (i = 0; i < ninterfaces; i++)
897 /* Be sure it's the correct family */
898 if (inter_list[i].sin.ss_family != AF_INET)
900 if (!(inter_list[i].flags & INT_MULTICAST))
902 if (!(inter_list[i].fd < 0))
904 if (!SOCKCMP(&addr, &inter_list[i].sin))
908 /* we have an explicit fd, so we can close it */
909 close_socket(inter_list[i].fd);
910 memset((char *)&inter_list[i], 0, sizeof(struct interface));
911 inter_list[i].fd = INVALID_SOCKET;
912 inter_list[i].bfd = INVALID_SOCKET;
916 /* We are sharing "any address" port :-( Don't close it! */
917 if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
918 (char *)&mreq, sizeof(mreq)) == -1)
919 netsyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails on address: %s %m",
921 inter_list[i].num_mcast--;
922 /* If there are none left negate the Multicast flag */
923 if(inter_list[i].num_mcast == 0)
924 inter_list[i].flags &= ~INT_MULTICAST;
931 haddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
933 if (!IN6_IS_ADDR_MULTICAST(&haddr6))
936 "invalid multicast address %s", stoa(&addr));
941 * Disable reception of multicast packets
943 mreq6.ipv6mr_multiaddr = ((struct sockaddr_in6*)&addr)->sin6_addr;
944 mreq6.ipv6mr_interface = 0;
945 for (i = 0; i < ninterfaces; i++)
947 /* Be sure it's the correct family */
948 if (inter_list[i].sin.ss_family != AF_INET6)
950 if (!(inter_list[i].flags & INT_MULTICAST))
952 if (!(inter_list[i].fd < 0))
954 if (!SOCKCMP(&addr, &inter_list[i].sin))
958 /* we have an explicit fd, so we can close it */
959 close_socket(inter_list[i].fd);
960 memset((char *)&inter_list[i], 0, sizeof(struct interface));
961 inter_list[i].fd = INVALID_SOCKET;
962 inter_list[i].bfd = INVALID_SOCKET;
966 /* We are sharing "any address" port :-( Don't close it! */
967 if (setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
968 (char *)&mreq6, sizeof(mreq6)) == -1)
969 netsyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails on address %s: %m",
971 /* If there are none left negate the Multicast flag */
972 if(inter_list[i].num_mcast == 0)
973 inter_list[i].flags &= ~INT_MULTICAST;
977 #endif /* HAVE_IPV6 */
979 delete_addr_from_list(&addr);
981 #else /* not MCAST */
982 netsyslog(LOG_ERR, "this function requires multicast kernel");
983 #endif /* not MCAST */
988 * open_socket - open a socket, returning the file descriptor
993 struct sockaddr_storage *addr,
1000 int on = 1, off = 0;
1001 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
1003 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
1005 if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS))
1006 return (INVALID_SOCKET);
1008 /* create a datagram (UDP) socket */
1010 if ( (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) < 0) {
1012 if(addr->ss_family == AF_INET)
1013 netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
1015 else if(addr->ss_family == AF_INET6)
1016 netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
1018 if (errval == EPROTONOSUPPORT || errval == EAFNOSUPPORT ||
1019 errval == EPFNOSUPPORT)
1020 return (INVALID_SOCKET);
1025 if ( (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
1026 errval = WSAGetLastError();
1027 if(addr->ss_family == AF_INET)
1028 netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
1030 else if(addr->ss_family == AF_INET6)
1031 netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
1033 if (errval == WSAEPROTONOSUPPORT || errval == WSAEAFNOSUPPORT ||
1034 errval == WSAEPFNOSUPPORT)
1035 return (INVALID_SOCKET);
1039 if (connection_reset_fix(fd) != ISC_R_SUCCESS) {
1040 netsyslog(LOG_ERR, "connection_reset_fix(fd) failed on address %s: %m",
1044 #endif /* SYS_WINNT */
1046 /* set SO_REUSEADDR since we will be binding the same port
1047 number on each interface */
1048 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1049 (char *)&on, sizeof(on)))
1051 netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails on address %s: %m",
1055 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
1056 /* set IP_TOS to minimize packet delay */
1057 tos = IPTOS_LOWDELAY;
1058 if (addr->ss_family == AF_INET)
1059 if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)
1061 netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m",
1065 #if defined(IPV6_V6ONLY)
1066 if (addr->ss_family == AF_INET6)
1067 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
1068 (char*)&on, sizeof(on)))
1070 netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m",
1073 #else /* IPV6_V6ONLY */
1074 #if defined(IPV6_BINDV6ONLY)
1075 if (addr->ss_family == AF_INET6)
1076 if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
1077 (char*)&on, sizeof(on)))
1080 "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
1083 #endif /* IPV6_BINDV6ONLY */
1084 #endif /* IPV6_V6ONLY */
1086 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
1089 * bind the local address.
1091 if (bind(fd, (struct sockaddr *)addr, SOCKLEN(addr)) < 0) {
1094 if(addr->ss_family == AF_INET)
1096 "bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m",
1097 fd, addr->ss_family, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
1099 IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags);
1100 else if(addr->ss_family == AF_INET6)
1102 "bind() fd %d, family %d, port %d, addr %s, in6_is_addr_multicast=%d flags=%d fails: %%m",
1103 fd, addr->ss_family, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port),
1105 IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags);
1106 else return INVALID_SOCKET;
1108 netsyslog(LOG_ERR, buff);
1112 * soft fail if opening a multicast address
1114 if(addr->ss_family == AF_INET){
1115 if(IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)))
1116 return (INVALID_SOCKET);
1119 if(IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr))
1120 return (INVALID_SOCKET);
1125 return INVALID_SOCKET;
1130 printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n",
1133 (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
1139 * I/O Completion Ports don't care about the select and FD_SET
1141 #ifndef HAVE_IO_COMPLETION_PORT
1142 if (fd > maxactivefd)
1144 FD_SET(fd, &activefds);
1146 add_socket_to_list(fd);
1152 /* in vxWorks we use FIONBIO, but the others are defined for old systems, so
1153 * all hell breaks loose if we leave them defined
1160 #if defined(O_NONBLOCK) /* POSIX */
1161 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
1163 netsyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails on address %s: %m",
1168 #elif defined(FNDELAY)
1169 if (fcntl(fd, F_SETFL, FNDELAY) < 0)
1171 netsyslog(LOG_ERR, "fcntl(FNDELAY) fails on address %s: %m",
1176 #elif defined(O_NDELAY) /* generally the same as FNDELAY */
1177 if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
1179 netsyslog(LOG_ERR, "fcntl(O_NDELAY) fails on address %s: %m",
1184 #elif defined(FIONBIO)
1186 if (ioctl(fd,FIONBIO,&on) < 0)
1187 # elif defined(SYS_WINNT)
1188 if (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
1190 if (ioctl(fd,FIONBIO,&on) < 0)
1193 netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on address %s: %m",
1198 #elif defined(FIOSNBIO)
1199 if (ioctl(fd,FIOSNBIO,&on) < 0)
1201 netsyslog(LOG_ERR, "ioctl(FIOSNBIO) fails on address %s: %m",
1207 # include "Bletch: Need non-blocking I/O!"
1210 #ifdef HAVE_SIGNALED_IO
1211 init_socket_sig(fd);
1212 #endif /* not HAVE_SIGNALED_IO */
1215 * Turn off the SO_REUSEADDR socket option. It apparently
1216 * causes heartburn on systems with multicast IP installed.
1217 * On normal systems it only gets looked at when the address
1218 * is being bound anyway..
1221 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1222 (char *)&off, sizeof(off)))
1224 netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails on address %s: %m",
1229 /* if this interface can support broadcast, set SO_BROADCAST */
1230 if (flags & INT_BROADCAST)
1232 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1233 (char *)&on, sizeof(on)))
1235 netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) on address %s: %m",
1239 #endif /* SO_BROADCAST */
1241 #if !defined(SYS_WINNT) && !defined(VMS)
1244 printf("flags for fd %d: 0%o\n", fd,
1245 fcntl(fd, F_GETFL, 0));
1247 #endif /* SYS_WINNT || VMS */
1254 * close_socket - close a socket and remove from the activefd list
1263 (void) closesocket(fd);
1266 * I/O Completion Ports don't care about select and fd_set
1268 #ifndef HAVE_IO_COMPLETION_PORT
1269 FD_CLR( (u_int) fd, &activefds);
1271 if (fd == maxactivefd) {
1273 for (i = 0; i < maxactivefd; i++)
1274 if (FD_ISSET(i, &activefds))
1276 maxactivefd = newmax;
1279 delete_socket_from_list(fd);
1285 * close_file - close a file and remove from the activefd list
1286 * added 1/31/1997 Greg Schueman for Windows NT portability
1298 * I/O Completion Ports don't care about select and fd_set
1300 #ifndef HAVE_IO_COMPLETION_PORT
1301 FD_CLR( (u_int) fd, &activefds);
1303 if (fd == maxactivefd) {
1305 for (i = 0; i < maxactivefd; i++)
1306 if (FD_ISSET(i, &activefds))
1308 maxactivefd = newmax;
1311 delete_socket_from_list(fd);
1317 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
1319 * sendpkt - send a packet to the specified destination. Maintain a
1320 * send error cache so that only the first consecutive error for a
1321 * destination is logged.
1325 struct sockaddr_storage *dest,
1326 struct interface *inter,
1335 #endif /* SYS_WINNT */
1338 * Send error caches. Empty slots have port == 0
1339 * Set ERRORCACHESIZE to 0 to disable
1343 struct in_addr addr;
1349 struct in6_addr addr;
1351 #endif /* HAVE_IPV6 */
1353 #ifndef ERRORCACHESIZE
1354 #define ERRORCACHESIZE 8
1356 #if ERRORCACHESIZE > 0
1357 static struct cache badaddrs[ERRORCACHESIZE];
1359 static struct cache6 badaddrs6[ERRORCACHESIZE];
1360 #endif /* HAVE_IPV6 */
1362 #define badaddrs ((struct cache *)0) /* Only used in empty loops! */
1364 #define badaddrs6 ((struct cache6 *)0) /* Only used in empty loops! */
1365 #endif /* HAVE_IPV6 */
1369 printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n",
1370 (ttl >= 0) ? "\tMCAST\t*****" : "",
1371 inter->fd, stoa(dest),
1372 stoa(&inter->sin), ttl, len);
1377 switch (inter->sin.ss_family) {
1382 * for the moment we use the bcast option to set multicast ttl
1384 if (ttl > 0 && ttl != inter->last_ttl) {
1387 * set the multicast ttl for outgoing packets
1389 if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,
1390 (char *) &ttl, sizeof(ttl)) != 0) {
1391 netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m",
1395 inter->last_ttl = ttl;
1403 * for the moment we use the bcast option to set
1404 * multicast max hops
1406 if (ttl > 0 && ttl != inter->last_ttl) {
1409 * set the multicast ttl for outgoing packets
1411 if (setsockopt(inter->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
1412 &ttl, sizeof(ttl)) == -1)
1413 netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m",
1416 inter->last_ttl = ttl;
1419 #endif /* HAVE_IPV6 */
1429 for (slot = ERRORCACHESIZE; --slot >= 0; )
1430 if(dest->ss_family == AF_INET) {
1431 if (badaddrs[slot].port == ((struct sockaddr_in*)dest)->sin_port &&
1432 badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr)
1436 else if (dest->ss_family == AF_INET6) {
1437 if (badaddrs6[slot].port == ((struct sockaddr_in6*)dest)->sin6_port &&
1438 badaddrs6[slot].addr.s6_addr == ((struct sockaddr_in6*)dest)->sin6_addr.s6_addr)
1441 #endif /* HAVE_IPV6 */
1442 else exit(1); /* address family not supported yet */
1444 #if defined(HAVE_IO_COMPLETION_PORT)
1445 err = io_completion_port_sendto(inter, pkt, len, dest);
1446 if (err != ERROR_SUCCESS)
1449 cc = srvr_rply(&ntp_node, dest, inter, pkt);
1451 cc = sendto(inter->fd, (char *)pkt, (unsigned int)len, 0, (struct sockaddr *)dest,
1459 #if defined(HAVE_IO_COMPLETION_PORT)
1460 err = WSAGetLastError();
1461 if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0)
1463 if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
1467 * Remember this, if there's an empty slot
1469 switch (dest->ss_family) {
1473 for (slot = ERRORCACHESIZE; --slot >= 0; )
1474 if (badaddrs[slot].port == 0)
1476 badaddrs[slot].port = SRCPORT(dest);
1477 badaddrs[slot].addr = ((struct sockaddr_in*)dest)->sin_addr;
1485 for (slot = ERRORCACHESIZE; --slot >= 0; )
1486 if (badaddrs6[slot].port == 0)
1488 badaddrs6[slot].port = SRCPORT(dest);
1489 badaddrs6[slot].addr = ((struct sockaddr_in6*)dest)->sin6_addr;
1493 #endif /* HAVE_IPV6 */
1499 netsyslog(LOG_ERR, "sendto(%s): %m", stoa(dest));
1507 * He's not bad any more
1511 netsyslog(LOG_INFO, "Connection re-established to %s", stoa(dest));
1512 switch (dest->ss_family) {
1514 badaddrs[slot].port = 0;
1518 badaddrs6[slot].port = 0;
1520 #endif /* HAVE_IPV6 */
1526 #if !defined(HAVE_IO_COMPLETION_PORT)
1528 * fdbits - generate ascii representation of fd_set (FAU debug support)
1529 * HFDF format - highest fd first.
1537 static char buffer[256];
1538 char * buf = buffer;
1540 count = (count < 256) ? count : 255;
1544 *buf++ = FD_ISSET(count, set) ? '#' : '-';
1553 * input_handler - receive packets asynchronously
1561 register struct recvbuf *rb;
1564 struct timeval tvzero;
1566 l_fp ts; /* Timestamp at BOselect() gob */
1567 l_fp ts_e; /* Timestamp at EOselect() gob */
1569 int select_count = 0;
1570 static int handler_count = 0;
1573 if (handler_count != 1)
1574 msyslog(LOG_ERR, "input_handler: handler_count is %d!", handler_count);
1581 * Do a poll to see who has data
1585 tvzero.tv_sec = tvzero.tv_usec = 0;
1588 * If we have something to do, freeze a timestamp.
1589 * See below for the other cases (nothing (left) to do or error)
1591 while (0 < (n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero)))
1598 * Check out the reference clocks first, if any
1602 register struct refclockio *rp;
1604 for (rp = refio; rp != 0 && n > 0; rp = rp->next)
1607 if (FD_ISSET(fd, &fds))
1610 if (free_recvbuffs() == 0)
1612 char buf[RX_BUFF_SIZE];
1614 (void) read(fd, buf, sizeof buf);
1619 rb = get_free_recv_buffer();
1621 i = (rp->datalen == 0
1622 || rp->datalen > sizeof(rb->recv_space))
1623 ? sizeof(rb->recv_space) : rp->datalen;
1625 read(fd, (char *)&rb->recv_space, (unsigned)i);
1627 if (rb->recv_length == -1)
1629 netsyslog(LOG_ERR, "clock read fd %d: %m", fd);
1636 * and when it got here,
1637 * put it on the full
1641 rb->recv_srcclock = rp->srcclock;
1645 rb->receiver = rp->clock_recv;
1654 if (rp->io_input(rb) == 0)
1679 add_full_recv_buffer(rb);
1686 #endif /* REFCLOCK */
1689 * Loop through the interfaces looking for data
1692 for (i = ninterfaces - 1; (i >= 0) && (n > 0); i--)
1694 for (doing = 0; (doing < 2) && (n > 0); doing++)
1698 fd = inter_list[i].fd;
1702 if (!(inter_list[i].flags & INT_BCASTOPEN))
1704 fd = inter_list[i].bfd;
1706 if (fd < 0) continue;
1707 if (FD_ISSET(fd, &fds))
1712 * Get a buffer and read
1714 * haven't got a buffer,
1715 * or this is received
1717 * socket, just dump the
1721 #ifdef UDP_WILDCARD_DELIVERY
1723 * these guys manage to put properly addressed
1724 * packets into the wildcard queue
1726 (free_recvbuffs() == 0)
1728 ((i == wildipv4) || (i == wildipv6)||
1729 (free_recvbuffs() == 0))
1733 char buf[RX_BUFF_SIZE];
1734 struct sockaddr_storage from;
1736 fromlen = sizeof from;
1737 (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen);
1740 printf("%s on %d(%lu) fd=%d from %s\n",
1741 (i) ? "drop" : "ignore",
1742 i, free_recvbuffs(), fd,
1745 if (i == wildipv4 || i == wildipv6)
1752 rb = get_free_recv_buffer();
1754 fromlen = sizeof(struct sockaddr_storage);
1755 rb->recv_length = recvfrom(fd,
1756 (char *)&rb->recv_space,
1757 sizeof(rb->recv_space), 0,
1758 (struct sockaddr *)&rb->recv_srcadr,
1760 if (rb->recv_length == 0
1762 || errno==EWOULDBLOCK
1771 else if (rb->recv_length < 0)
1773 netsyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
1774 stoa(&rb->recv_srcadr), fd);
1777 printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd);
1784 if(rb->recv_srcadr.ss_family == AF_INET)
1785 printf("input_handler: if=%d fd=%d length %d from %08lx %s\n",
1786 i, fd, rb->recv_length,
1787 (u_long)ntohl(((struct sockaddr_in*)&rb->recv_srcadr)->sin_addr.s_addr) &
1789 stoa(&rb->recv_srcadr));
1791 printf("input_handler: if=%d fd=%d length %d from %s\n",
1792 i, fd, rb->recv_length,
1793 stoa(&rb->recv_srcadr));
1798 * Got one. Mark how and when it got here,
1799 * put it on the full list and do bookkeeping.
1801 rb->dstadr = &inter_list[i];
1804 rb->receiver = receive;
1806 add_full_recv_buffer(rb);
1808 inter_list[i].received++;
1812 /* Check more interfaces */
1817 * Done everything from that select. Poll again.
1822 * If nothing more to do, try again.
1823 * If nothing to do, just return.
1824 * If an error occurred, complain and return.
1828 if (select_count == 0) /* We really had nothing to do */
1831 netsyslog(LOG_DEBUG, "input_handler: select() returned 0");
1835 /* We've done our work */
1838 * (ts_e - ts) is the amount of time we spent
1839 * processing this gob of file descriptors. Log
1844 netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
1855 * extended FAU debugging output
1859 "select(%d, %s, 0L, 0L, &0.0) error: %m",
1861 fdbits(maxactivefd, &activefds));
1866 for (j = 0; j <= maxactivefd; j++)
1868 (FD_ISSET(j, &fds) && (read(j, &b, 0) == -1))
1870 netsyslog(LOG_ERR, "Bad file descriptor %d", j);
1876 msyslog(LOG_ERR, "input_handler: fell out of infinite for(;;) loop!");
1883 * findinterface - find interface corresponding to address
1887 struct sockaddr_storage *addr
1892 struct sockaddr_storage saddr;
1893 int saddrlen = SOCKLEN(addr);
1895 * This is considerably hoke. We open a socket, connect to it
1896 * and slap a getsockname() on it. If anything breaks, as it
1897 * probably will in some j-random knockoff, we just return the
1898 * wildcard interface.
1900 memset(&saddr, 0, sizeof(saddr));
1901 saddr.ss_family = addr->ss_family;
1902 if(addr->ss_family == AF_INET)
1903 memcpy(&((struct sockaddr_in*)&saddr)->sin_addr, &((struct sockaddr_in*)addr)->sin_addr, sizeof(struct in_addr));
1904 else if(addr->ss_family == AF_INET6)
1905 memcpy(&((struct sockaddr_in6*)&saddr)->sin6_addr, &((struct sockaddr_in6*)addr)->sin6_addr, sizeof(struct in6_addr));
1906 ((struct sockaddr_in*)&saddr)->sin_port = htons(2000);
1907 s = socket(addr->ss_family, SOCK_DGRAM, 0);
1908 if (s == INVALID_SOCKET)
1909 return ANY_INTERFACE_CHOOSE(addr);
1911 rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr));
1915 if (rtn == SOCKET_ERROR)
1919 return ANY_INTERFACE_CHOOSE(addr);
1922 rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen);
1927 if (rtn == SOCKET_ERROR)
1929 return ANY_INTERFACE_CHOOSE(addr);
1931 for (i = 0; i < ninterfaces; i++) {
1933 * First look if is the the correct family
1935 if(inter_list[i].sin.ss_family != saddr.ss_family)
1938 * We match the unicast address only.
1940 if (SOCKCMP(&inter_list[i].sin, &saddr))
1941 return (&inter_list[i]);
1943 return ANY_INTERFACE_CHOOSE(addr);
1947 * findbcastinter - find broadcast interface corresponding to address
1951 struct sockaddr_storage *addr
1954 #if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
1957 i = find_addr_in_list(addr);
1959 return (&inter_list[i]);
1961 for (i = 0; i < ninterfaces; i++) {
1963 * First look if this is the correct family
1965 if(inter_list[i].sin.ss_family != addr->ss_family)
1968 * We match only those interfaces marked as
1969 * broadcastable and either the explicit broadcast
1970 * address or the network portion of the IP address.
1973 if (!(inter_list[i].flags & INT_BROADCAST))
1975 if(addr->ss_family == AF_INET) {
1976 if (SOCKCMP(&inter_list[i].bcast, addr))
1977 return (&inter_list[i]);
1978 if ((NSRCADR(&inter_list[i].sin) &
1979 NSRCADR(&inter_list[i].mask)) == (NSRCADR(addr) &
1980 NSRCADR(&inter_list[i].mask)))
1981 return (&inter_list[i]);
1983 else if(addr->ss_family == AF_INET6) {
1984 if (SOCKCMP(&inter_list[i].bcast, addr))
1985 return (&inter_list[i]);
1986 if (SOCKCMP(netof(&inter_list[i].sin), netof(addr)))
1987 return (&inter_list[i]);
1990 #endif /* SIOCGIFCONF */
1991 return ANY_INTERFACE_CHOOSE(addr);
1996 * io_clr_stats - clear I/O module statistics
2001 packets_dropped = 0;
2002 packets_ignored = 0;
2003 packets_received = 0;
2005 packets_notsent = 0;
2009 io_timereset = current_time;
2015 * This is a hack so that I don't have to fool with these ioctls in the
2016 * pps driver ... we are already non-blocking and turn on SIGIO thru
2017 * another mechanisim
2021 struct refclockio *rio
2026 * Stuff the I/O structure in the list and mark the descriptor
2027 * in use. There is a harmless (I hope) race condition here.
2033 * I/O Completion Ports don't care about select and fd_set
2035 #ifndef HAVE_IO_COMPLETION_PORT
2036 if (rio->fd > maxactivefd)
2037 maxactivefd = rio->fd;
2038 FD_SET(rio->fd, &activefds);
2045 * io_addclock - add a reference clock to the list and arrange that we
2046 * get SIGIO interrupts from it.
2050 struct refclockio *rio
2055 * Stuff the I/O structure in the list and mark the descriptor
2056 * in use. There is a harmless (I hope) race condition here.
2061 # ifdef HAVE_SIGNALED_IO
2062 if (init_clock_sig(rio))
2068 # elif defined(HAVE_IO_COMPLETION_PORT)
2069 if (io_completion_port_add_clock_io(rio))
2071 add_socket_to_list(rio->fd);
2079 * I/O Completion Ports don't care about select and fd_set
2081 #ifndef HAVE_IO_COMPLETION_PORT
2082 if (rio->fd > maxactivefd)
2083 maxactivefd = rio->fd;
2084 FD_SET(rio->fd, &activefds);
2091 * io_closeclock - close the clock in the I/O structure given
2095 struct refclockio *rio
2099 * Remove structure from the list
2107 register struct refclockio *rp;
2109 for (rp = refio; rp != 0; rp = rp->next)
2110 if (rp->next == rio)
2112 rp->next = rio->next;
2119 * Internal error. Report it.
2122 "internal error: refclockio structure not found");
2128 * Close the descriptor.
2130 close_file(rio->fd);
2132 #endif /* REFCLOCK */
2135 * I/O Completion Ports don't care about select and fd_set
2137 #ifndef HAVE_IO_COMPLETION_PORT
2146 for (i = startfd; i <= maxactivefd; i++)
2147 (void)close_socket(i);
2151 * On NT a SOCKET is an unsigned int so we cannot possibly keep it in
2152 * an array. So we use one of the ISC_LIST functions to hold the
2153 * socket value and use that when we want to enumerate it.
2156 kill_asyncio(int startfd)
2163 lsock = ISC_LIST_HEAD(sockets_list);
2164 while (lsock != NULL) {
2165 next = ISC_LIST_NEXT(lsock, link);
2166 close_socket(lsock->fd);
2173 * Add and delete functions for the list of open sockets
2176 add_socket_to_list(SOCKET fd){
2177 vsock_t *lsock = malloc(sizeof(vsock_t));
2180 ISC_LIST_APPEND(sockets_list, lsock, link);
2183 delete_socket_from_list(SOCKET fd) {
2186 vsock_t *lsock = ISC_LIST_HEAD(sockets_list);
2188 while(lsock != NULL) {
2189 next = ISC_LIST_NEXT(lsock, link);
2190 if(lsock->fd == fd) {
2191 ISC_LIST_DEQUEUE(sockets_list, lsock, link);
2200 add_addr_to_list(struct sockaddr_storage *addr, int if_index){
2201 remaddr_t *laddr = malloc(sizeof(remaddr_t));
2202 memcpy(&laddr->addr, addr, sizeof(addr));
2203 laddr->if_index = if_index;
2205 ISC_LIST_APPEND(remoteaddr_list, laddr, link);
2208 printf("Added addr %s to list of addresses\n",
2215 delete_addr_from_list(struct sockaddr_storage *addr) {
2218 remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
2220 while(laddr != NULL) {
2221 next = ISC_LIST_NEXT(laddr, link);
2222 if(SOCKCMP(&laddr->addr, addr)) {
2223 ISC_LIST_DEQUEUE(remoteaddr_list, laddr, link);
2232 printf("Deleted addr %s from list of addresses\n",
2237 find_addr_in_list(struct sockaddr_storage *addr) {
2240 remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
2243 printf("Finding addr %s in list of addresses\n",
2247 while(laddr != NULL) {
2248 next = ISC_LIST_NEXT(laddr, link);
2249 if(SOCKCMP(&laddr->addr, addr)) {
2250 return (laddr->if_index);
2256 return (-1); /* Not found */