]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ntp/ntpd/ntp_io.c
This commit was generated by cvs2svn to compensate for changes in r161818,
[FreeBSD/FreeBSD.git] / contrib / ntp / ntpd / ntp_io.c
1 /*
2  * ntp_io.c - input/output routines for ntpd.   The socket-opening code
3  *                 was shamelessly stolen from ntpd.
4  */
5
6 #ifdef HAVE_CONFIG_H
7 # include <config.h>
8 #endif
9
10 #include "ntp_machine.h"
11 #include "ntpd.h"
12 #include "ntp_io.h"
13 #include "iosignal.h"
14 #include "ntp_refclock.h"
15 #include "ntp_if.h"
16 #include "ntp_stdlib.h"
17 #include "ntp.h"
18
19 /* Don't include ISC's version of IPv6 variables and structures */
20 #define ISC_IPV6_H 1
21 #include <isc/interfaceiter.h>
22 #include <isc/list.h>
23 #include <isc/result.h>
24
25 #ifdef SIM
26 #include "ntpsim.h"
27 #endif
28
29 #include <stdio.h>
30 #include <signal.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>
36 #endif
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>
42 # endif
43 #endif /* HAVE_NETINET_IN_SYSTM_H */
44 #ifdef HAVE_NETINET_IP_H
45 # include <netinet/ip.h>
46 #endif
47 #ifdef HAVE_SYS_IOCTL_H
48 # include <sys/ioctl.h>
49 #endif
50 #ifdef HAVE_SYS_SOCKIO_H        /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
51 # include <sys/sockio.h>
52 #endif
53 #include <arpa/inet.h>
54
55 extern int listen_to_virtual_ips;
56
57 #if defined(SYS_WINNT)
58 #include <transmitbuff.h>
59 #include <isc/win32os.h>
60 /*
61  * Define this macro to control the behavior of connection
62  * resets on UDP sockets.  See Microsoft KnowledgeBase Article Q263823
63  * for details.
64  * NOTE: This requires that Windows 2000 systems install Service Pack 2
65  * or later.
66  */
67 #ifndef SIO_UDP_CONNRESET 
68 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) 
69 #endif
70
71 #endif
72
73 /*
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.
81  *
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.
87  */
88
89
90 /*
91  * Other statistics of possible interest
92  */
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 */
98
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 */
102
103 /*
104  * Interface stuff
105  */
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 */
115
116 #ifdef REFCLOCK
117 /*
118  * Refclock stuff.      We keep a chain of structures with data concerning
119  * the guys we are doing I/O for.
120  */
121 static  struct refclockio *refio;
122 #endif /* REFCLOCK */
123
124
125 /*
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.
128  *
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.
132  */
133 #define SOFT_ERROR(e)   ((e) == EAGAIN || \
134                          (e) == EWOULDBLOCK || \
135                          (e) == EINTR || \
136                          (e) == 0)
137
138 /*
139  * File descriptor masks etc. for call to select
140  * Not needed for I/O Completion Ports
141  */
142 fd_set activefds;
143 int maxactivefd;
144
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));
148 #ifdef REFCLOCK
149 static  void    close_file      P((SOCKET));
150 #endif
151 static  char *  fdbits          P((int, fd_set *));
152 static  void    set_reuseaddr   P((int));
153
154 typedef struct vsock vsock_t;
155
156 struct vsock {
157         SOCKET                          fd;
158         ISC_LINK(vsock_t)               link;
159 };
160
161 ISC_LIST(vsock_t)       sockets_list;
162
163 typedef struct remaddr remaddr_t;
164
165 struct remaddr {
166       struct sockaddr_storage        addr;
167       int                            if_index;
168       ISC_LINK(remaddr_t)              link;
169 };
170
171 ISC_LIST(remaddr_t)       remoteaddr_list;
172
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));
181
182 #ifdef SYS_WINNT
183 /*
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.
192  */
193 isc_result_t
194 connection_reset_fix(SOCKET fd) {
195         DWORD dwBytesReturned = 0;
196         BOOL  bNewBehavior = FALSE;
197         DWORD status;
198
199         if(isc_win32os_majorversion() < 5)
200                 return (ISC_R_SUCCESS); /*  NT 4.0 has no problem */
201
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);
208         else
209                 return (ISC_R_UNEXPECTED);
210 }
211 #endif
212 /*
213  * init_io - initialize I/O data structures and call socket creation routine
214  */
215 void
216 init_io(void)
217 {
218 #ifdef SYS_WINNT
219         init_transmitbuff();
220 #endif /* SYS_WINNT */
221
222         /*
223          * Init buffer free list and stat counters
224          */
225         init_recvbuff(RECV_INIT);
226
227         packets_dropped = packets_received = 0;
228         packets_ignored = 0;
229         packets_sent = packets_notsent = 0;
230         handler_calls = handler_pkts = 0;
231         io_timereset = 0;
232         loopback_interface = NULL;
233         loopback6_interface = NULL;
234
235 #ifdef REFCLOCK
236         refio = 0;
237 #endif
238
239 #if defined(HAVE_SIGNALED_IO)
240         (void) set_signal();
241 #endif
242
243 #ifdef SYS_WINNT
244         if (!Win32InitSockets())
245         {
246                 netsyslog(LOG_ERR, "No useable winsock.dll: %m");
247                 exit(1);
248         }
249 #endif /* SYS_WINNT */
250
251         ISC_LIST_INIT(sockets_list);
252
253         ISC_LIST_INIT(remoteaddr_list);
254
255         /*
256          * Create the sockets
257          */
258         BLOCKIO();
259         (void) create_sockets(htons(NTP_PORT));
260         UNBLOCKIO();
261
262 #ifdef DEBUG
263         if (debug)
264             printf("init_io: maxactivefd %d\n", maxactivefd);
265 #endif
266 }
267
268 int
269 create_wildcards(u_short port) {
270
271         int idx = 0;
272         /*
273          * create pseudo-interface with wildcard IPv4 address
274          */
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];
288 #if defined(MCAST)
289         /*
290          * enable possible multicast reception on the broadcast socket
291          */
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);
295 #endif /* MCAST */
296         wildipv4 = idx;
297         idx++;
298
299 #ifdef HAVE_IPV6
300         /*
301          * create pseudo-interface with wildcard IPv6 address
302          */
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];
317                 wildipv6 = idx;
318                 idx++;
319         }
320 #endif
321         return (idx);
322 }
323
324 isc_boolean_t
325 address_okay(isc_interface_t *isc_if) {
326
327 #ifdef DEBUG
328         if (debug > 2)
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));
331 #endif
332
333         if (listen_to_virtual_ips == 0  && (strchr(isc_if->name, (int)':') != NULL))
334                 return (ISC_FALSE);
335
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.
339          */
340 /*      if ((isc_if->flags & INTERFACE_F_UP) == 0)
341                 return (ISC_FALSE);
342 */
343         return (ISC_TRUE);
344 }
345 void
346 convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port) {
347
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;
355
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;
363                 }
364
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;
370
371                 if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback_interface == NULL))
372                 {
373                         loopback_interface = itf;
374                 }
375         }
376 #ifdef HAVE_IPV6
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;
384
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;
390
391                 if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback6_interface == NULL))
392                 {
393                         loopback6_interface = itf;
394                 }
395         }
396 #endif /* HAVE_IPV6 */
397
398                 /* Process the rest of the flags */
399
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;
406 }
407 /*
408  * create_sockets - create a socket for each interface plus a default
409  *                      socket for when we don't know where to send
410  */
411 static int
412 create_sockets(
413         u_short port
414         )
415 {
416         struct sockaddr_storage resmask;
417         int i;
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;
422         isc_result_t result;
423         int idx = 0;
424
425 #ifdef DEBUG
426         if (debug)
427             printf("create_sockets(%d)\n", ntohs( (u_short) port));
428 #endif
429
430         if (isc_net_probeipv6() == ISC_R_SUCCESS)
431                 scan_ipv6 = ISC_TRUE;
432 #ifdef HAVE_IPV6
433         else
434                 netsyslog(LOG_ERR, "no IPv6 interfaces found");
435 #endif
436
437         if (isc_net_probeipv4() == ISC_R_SUCCESS)
438                 scan_ipv4 = ISC_TRUE;
439         else
440                 netsyslog(LOG_ERR, "no IPv4 interfaces found");
441
442         nwilds = create_wildcards(port);
443         idx = nwilds;
444
445         result = isc_interfaceiter_create(mctx, &iter);
446         if (result != ISC_R_SUCCESS)
447                 return (result);
448
449         for (result = isc_interfaceiter_first(iter);
450              result == ISC_R_SUCCESS;
451              result = isc_interfaceiter_next(iter))
452         {
453                 isc_interface_t isc_if;
454                 unsigned int family; 
455
456                 result = isc_interfaceiter_current(iter, &isc_if);
457                 if (result != ISC_R_SUCCESS)
458                         break;
459
460                 /* See if we have a valid family to use */
461                 family = isc_if.address.family;
462                 if (family != AF_INET && family != AF_INET6)
463                         continue;
464                 if (scan_ipv4 == ISC_FALSE && family == AF_INET)
465                         continue;
466                 if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
467                         continue;
468
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;
478                         idx++;
479                 }
480         }
481         isc_interfaceiter_destroy(&iter);
482
483         ninterfaces = idx;
484         /*
485          * I/O Completion Ports don't care about the select and FD_SET
486          */
487 #ifndef HAVE_IO_COMPLETION_PORT
488         maxactivefd = 0;
489         FD_ZERO(&activefds);
490 #endif
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",
496                                 inter_list[i].name,
497                                 stoa((&inter_list[i].sin)),
498                                 NTP_PORT);
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)),
503                                 NTP_PORT);
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]);
507                 }
508 #endif
509         }
510
511         /*
512          * Now that we have opened all the sockets, turn off the reuse
513          * flag for security.
514          */
515         set_reuseaddr(0);
516
517         /*
518          * Blacklist all bound interface addresses
519          * Wildcard interfaces are ignored.
520          */
521
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);
526         }
527
528         /*
529          * Calculate the address hash for each interface address.
530          */
531         for (i = 0; i < ninterfaces; i++) {
532                 inter_list[i].addr_refid = addr2refid(&inter_list[i].sin);
533         }
534
535
536 #ifdef DEBUG
537         if (debug > 1) {
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",
541                                i,
542                                inter_list[i].fd,
543                                inter_list[i].bfd,
544                                inter_list[i].name,
545                                inter_list[i].flags);
546                         /* Leave these as three printf calls. */
547                         printf("              sin=%s",
548                                stoa((&inter_list[i].sin)));
549                         if (inter_list[i].flags & INT_BROADCAST)
550                             printf("  bcast=%s,",
551                                    stoa((&inter_list[i].bcast)));
552                         printf("  mask=%s\n",
553                                stoa((&inter_list[i].mask)));
554                 }
555         }
556 #endif
557         return ninterfaces;
558 }
559
560 /*
561  * io_setbclient - open the broadcast client sockets
562  */
563 void
564 io_setbclient(void)
565 {
566         int i;
567
568 #ifdef OPEN_BCAST_SOCKET
569         set_reuseaddr(1);
570 #endif
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)
574                         continue;
575
576                 /* Is this a broadcast address? */
577                 if (!(inter_list[i].flags & INT_BROADCAST))
578                         continue;
579
580                 /* Do we already have the broadcast address open? */
581                 if (inter_list[i].flags & INT_BCASTOPEN)
582                         continue;
583
584 #ifdef  SYS_SOLARIS
585                 inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
586 #endif
587 #ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */
588                 inter_list[i].bfd = open_socket(&inter_list[i].bcast,
589                     INT_BROADCAST, 1);
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]);
594 #endif
595                 }
596 #ifdef DEBUG
597                 if (debug) {
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);
601                         else
602                                 printf("io_setbclient: Unable to Open broadcast client on interface %d\n",
603                                 i);
604                 }
605 #endif
606 #endif
607         }
608 #ifdef OPEN_BCAST_SOCKET
609         set_reuseaddr(0);
610 #endif
611 #ifdef DEBUG
612         if (debug)
613                 printf("io_setbclient: Opened broadcast clients\n");
614 #endif
615 }
616
617 /*
618  * set_reuseaddr() - set/clear REUSEADDR on all sockets
619  *                      NB possible hole - should we be doing this on broadcast
620  *                      fd's also?
621  */
622 static void
623 set_reuseaddr(int flag) {
624         int i;
625
626         for (i=0; i < ninterfaces; i++) {
627                 /*
628                  * if inter_list[ n ].fd  is -1, we might have a adapter
629                  * configured but not present
630                  */
631                 if (inter_list[i].fd != INVALID_SOCKET) {
632                         if (setsockopt(inter_list[i].fd, SOL_SOCKET,
633                                         SO_REUSEADDR, (char *)&flag,
634                                         sizeof(flag))) {
635                                 netsyslog(LOG_ERR, "set_reuseaddr: setsockopt(SO_REUSEADDR, %s) failed: %m", flag ? "on" : "off");
636                         }
637                 }
638         }
639 }
640
641
642 /*
643  * io_multicast_add() - add multicast group address
644  */
645 void
646 io_multicast_add(
647         struct sockaddr_storage addr
648         )
649 {
650 #ifdef MCAST
651         struct ip_mreq mreq;
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;
655         SOCKET s;
656         struct sockaddr_in *sinp;
657
658 #ifdef HAVE_IPV6
659         struct ipv6_mreq mreq6;
660         struct in6_addr iaddr6;
661         struct sockaddr_in6 *sin6p;
662 #endif /* HAVE_IPV6 */
663
664         switch (addr.ss_family)
665         {
666         case AF_INET :
667                 iaddr = (((struct sockaddr_in*)&addr)->sin_addr);
668                 if (!IN_CLASSD(haddr)) {
669                         netsyslog(LOG_ERR,
670                         "multicast address %s not class D",
671                                 inet_ntoa(iaddr));
672                         return;
673                 }
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)
677                                 continue;
678                         /* Already have this address */
679                         if (SOCKCMP(&inter_list[i].sin, &addr))
680                                 return;
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)
685                         break;
686                 }
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);
693
694                 /*
695                 * Try opening a socket for the specified class D address. This
696                 * works under SunOS 4.x, but not OSF1 .. :-(
697                 */
698                 set_reuseaddr(1);
699                 s = open_socket((struct sockaddr_storage*)sinp, 0, 1);
700                 set_reuseaddr(0);
701                 if (s == INVALID_SOCKET) {
702                         memset((char *)&inter_list[i], 0, sizeof(struct interface));
703                         if (wildipv4 >= 0) {
704                                 i = wildipv4;
705                                 /* HACK ! -- stuff in an address */
706                                 inter_list[i].bcast = addr;
707                                 netsyslog(LOG_ERR,
708                                 "...multicast address %s using wildcard socket",
709                                 inet_ntoa(iaddr));
710                         } else {
711                                 netsyslog(LOG_ERR,
712                                 "No wildcard socket available to use for address %s",
713                                 inet_ntoa(iaddr));
714                                 return;
715                         }
716                 } else {
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]);
724 #endif
725                 }
726
727                 /*
728                 * enable reception of multicast packets
729                 */
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)
734                         netsyslog(LOG_ERR,
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)
741                         ninterfaces = i+1;
742
743                 add_addr_to_list(&addr, i);
744                 break;
745
746 #ifdef HAVE_IPV6
747         case AF_INET6 :
748
749                 iaddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
750                 if (!IN6_IS_ADDR_MULTICAST(&iaddr6)) {
751                         netsyslog(LOG_ERR,
752                             "address %s not IPv6 multicast address",
753                                 stoa(&addr));
754                         return;
755                 }
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)
759                                 continue;
760                         /* Already have this address */
761                         if (SOCKCMP(&inter_list[i].sin, &addr))
762                                 return;
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)
767                         break;
768                 }
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);
775
776                 /*
777                  * Try opening a socket for the specified class D address. This
778                  * works under SunOS 4.x, but not OSF1 .. :-(
779                  */
780                 set_reuseaddr(1);
781                 s = open_socket((struct sockaddr_storage*)sin6p, 0, 1);
782                 set_reuseaddr(0);
783                 if(s == INVALID_SOCKET){
784                         memset((char *)&inter_list[i], 0, sizeof(struct interface));
785                         if (wildipv6 >= 0) {
786                                 i = wildipv6;
787                                 /* HACK ! -- stuff in an address */
788                                 inter_list[i].bcast = addr;
789                                 netsyslog(LOG_ERR,
790                                  "...multicast address %s using wildcard socket",
791                                  stoa(&addr));
792                         } else {
793                                 netsyslog(LOG_ERR,
794                                 "No wildcard socket available to use for address %s",
795                                 stoa(&addr));
796                                 return;
797                         }
798                 } else {
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]);
806 #endif
807                 }
808
809                 /*
810                  * enable reception of multicast packets
811                  */
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)
816                         netsyslog(LOG_ERR,
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++;
821                 if(i >= ninterfaces)
822                         ninterfaces = i+1;
823
824                 add_addr_to_list(&addr, i);
825                 break;
826 #endif /* HAVE_IPV6 */
827         }
828
829 #ifdef DEBUG
830         if (debug)
831                 printf("io_multicast_add %s\n", stoa(&addr));
832 #endif
833 #else /* MCAST */
834         netsyslog(LOG_ERR,
835             "cannot add multicast address %s as no MCAST support",
836             stoa(&addr));
837 #endif /* MCAST */
838 }
839
840 /*
841  * io_unsetbclient - close the broadcast client sockets
842  */
843 void
844 io_unsetbclient(void)
845 {
846         int i;
847
848         for (i = nwilds; i < ninterfaces; i++)
849         {
850                 if (!(inter_list[i].flags & INT_BCASTOPEN))
851                     continue;
852                 close_socket(inter_list[i].bfd);
853                 inter_list[i].bfd = INVALID_SOCKET;
854                 inter_list[i].flags &= ~INT_BCASTOPEN;
855         }
856 }
857
858
859 /*
860  * io_multicast_del() - delete multicast group address
861  */
862 void
863 io_multicast_del(
864         struct sockaddr_storage addr
865         )
866 {
867 #ifdef MCAST
868         int i;
869         struct ip_mreq mreq;
870         u_int32 haddr;
871
872 #ifdef HAVE_IPV6
873         struct ipv6_mreq mreq6;
874         struct in6_addr haddr6;
875 #endif /* HAVE_IPV6 */
876
877         switch (addr.ss_family)
878         {
879         case AF_INET :
880
881                 haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
882
883                 if (!IN_CLASSD(haddr))
884                 {
885                         netsyslog(LOG_ERR,
886                                  "invalid multicast address %s", stoa(&addr));
887                         return;
888                 }
889
890                 /*
891                 * Disable reception of multicast packets
892                 */
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++)
896                 {
897                         /* Be sure it's the correct family */
898                         if (inter_list[i].sin.ss_family != AF_INET)
899                                 continue;
900                         if (!(inter_list[i].flags & INT_MULTICAST))
901                                 continue;
902                         if (!(inter_list[i].fd < 0))
903                                 continue;
904                         if (!SOCKCMP(&addr, &inter_list[i].sin))
905                                 continue;
906                         if (i != wildipv4)
907                         {
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;
913                         }
914                         else
915                         {
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",
920                                         stoa(&addr));
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;
925                         }
926                 }
927                 break;
928
929 #ifdef HAVE_IPV6
930         case AF_INET6 :
931                 haddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
932
933                 if (!IN6_IS_ADDR_MULTICAST(&haddr6))
934                 {
935                         netsyslog(LOG_ERR,
936                                 "invalid multicast address %s", stoa(&addr));
937                         return;
938                 }
939
940                 /*
941                 * Disable reception of multicast packets
942                 */
943                 mreq6.ipv6mr_multiaddr = ((struct sockaddr_in6*)&addr)->sin6_addr;
944                 mreq6.ipv6mr_interface = 0;
945                 for (i = 0; i < ninterfaces; i++)
946                 {
947                         /* Be sure it's the correct family */
948                         if (inter_list[i].sin.ss_family != AF_INET6)
949                                 continue;
950                         if (!(inter_list[i].flags & INT_MULTICAST))
951                                 continue;
952                         if (!(inter_list[i].fd < 0))
953                                 continue;
954                         if (!SOCKCMP(&addr, &inter_list[i].sin))
955                                 continue;
956                         if (i != wildipv6)
957                         {
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;
963                         }
964                         else
965                         {
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",
970                                         stoa(&addr));
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;
974                         }
975                 }
976                 break;
977 #endif /* HAVE_IPV6 */
978         }/* switch */
979         delete_addr_from_list(&addr);
980
981 #else /* not MCAST */
982         netsyslog(LOG_ERR, "this function requires multicast kernel");
983 #endif /* not MCAST */
984 }
985
986
987 /*
988  * open_socket - open a socket, returning the file descriptor
989  */
990
991 static SOCKET
992 open_socket(
993         struct sockaddr_storage *addr,
994         int flags,
995         int turn_off_reuse
996         )
997 {
998         int errval;
999         SOCKET fd;
1000         int on = 1, off = 0;
1001 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
1002         int tos;
1003 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
1004
1005         if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS))
1006                 return (INVALID_SOCKET);
1007
1008         /* create a datagram (UDP) socket */
1009 #ifndef SYS_WINNT
1010         if (  (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) < 0) {
1011                 errval = errno;
1012                 if(addr->ss_family == AF_INET)
1013                         netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
1014                                 stoa(addr));
1015                 else if(addr->ss_family == AF_INET6)
1016                         netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
1017                                 stoa(addr));
1018                 if (errval == EPROTONOSUPPORT || errval == EAFNOSUPPORT ||
1019                     errval == EPFNOSUPPORT)
1020                         return (INVALID_SOCKET);
1021                 exit(1);
1022                 /*NOTREACHED*/
1023         }
1024 #else
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",
1029                                 stoa(addr));
1030                 else if(addr->ss_family == AF_INET6)
1031                         netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
1032                                 stoa(addr));
1033                 if (errval == WSAEPROTONOSUPPORT || errval == WSAEAFNOSUPPORT ||
1034                     errval == WSAEPFNOSUPPORT)
1035                         return (INVALID_SOCKET);
1036                 exit(1);
1037                 /*NOTREACHED*/
1038         }
1039         if (connection_reset_fix(fd) != ISC_R_SUCCESS) {
1040                 netsyslog(LOG_ERR, "connection_reset_fix(fd) failed on address %s: %m",
1041                         stoa(addr));
1042         }
1043
1044 #endif /* SYS_WINNT */
1045
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)))
1050         {
1051                 netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails on address %s: %m",
1052                         stoa(addr));
1053         }
1054
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)
1060                 {
1061                         netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m",
1062                                 stoa(addr));
1063                 }
1064
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)))
1069                 {
1070                         netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m",
1071                                 stoa(addr));
1072                 }
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)))
1078                 {
1079                         netsyslog(LOG_ERR,
1080                             "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
1081                             stoa(addr));
1082                 }
1083 #endif /* IPV6_BINDV6ONLY */
1084 #endif /* IPV6_V6ONLY */
1085
1086 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
1087
1088         /*
1089          * bind the local address.
1090          */
1091         if (bind(fd, (struct sockaddr *)addr, SOCKLEN(addr)) < 0) {
1092                 char buff[160];
1093
1094                 if(addr->ss_family == AF_INET)
1095                         sprintf(buff,
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),
1098                                 stoa(addr),
1099                                 IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags);
1100                 else if(addr->ss_family == AF_INET6)
1101                                 sprintf(buff,
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),
1104                                 stoa(addr),
1105                                 IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags);
1106                 else return INVALID_SOCKET;
1107
1108                 netsyslog(LOG_ERR, buff);
1109                 closesocket(fd);
1110
1111                 /*
1112                  * soft fail if opening a multicast address
1113                  */
1114                 if(addr->ss_family == AF_INET){
1115                         if(IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)))
1116                                 return (INVALID_SOCKET);
1117                 }
1118                 else {
1119                         if(IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr))
1120                                 return (INVALID_SOCKET);
1121                 }
1122 #if 0
1123                 exit(1);
1124 #else
1125                 return INVALID_SOCKET;
1126 #endif
1127         }
1128 #ifdef DEBUG
1129         if (debug)
1130             printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n",
1131                    fd,
1132                    addr->ss_family,
1133                    (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
1134                    stoa(addr),
1135                    flags);
1136 #endif
1137
1138         /*
1139          * I/O Completion Ports don't care about the select and FD_SET
1140          */
1141 #ifndef HAVE_IO_COMPLETION_PORT
1142         if (fd > maxactivefd)
1143             maxactivefd = fd;
1144         FD_SET(fd, &activefds);
1145 #endif
1146         add_socket_to_list(fd);
1147         /*
1148          * set non-blocking,
1149          */
1150
1151 #ifdef USE_FIONBIO
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
1154          */
1155 #undef O_NONBLOCK
1156 #undef FNDELAY
1157 #undef O_NDELAY
1158 #endif
1159
1160 #if defined(O_NONBLOCK) /* POSIX */
1161         if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
1162         {
1163                 netsyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails on address %s: %m",
1164                         stoa(addr));
1165                 exit(1);
1166                 /*NOTREACHED*/
1167         }
1168 #elif defined(FNDELAY)
1169         if (fcntl(fd, F_SETFL, FNDELAY) < 0)
1170         {
1171                 netsyslog(LOG_ERR, "fcntl(FNDELAY) fails on address %s: %m",
1172                         stoa(addr));
1173                 exit(1);
1174                 /*NOTREACHED*/
1175         }
1176 #elif defined(O_NDELAY) /* generally the same as FNDELAY */
1177         if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
1178         {
1179                 netsyslog(LOG_ERR, "fcntl(O_NDELAY) fails on address %s: %m",
1180                         stoa(addr));
1181                 exit(1);
1182                 /*NOTREACHED*/
1183         }
1184 #elif defined(FIONBIO)
1185 # if defined(VMS)
1186                 if (ioctl(fd,FIONBIO,&on) < 0)
1187 # elif defined(SYS_WINNT)
1188                 if (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
1189 # else
1190                 if (ioctl(fd,FIONBIO,&on) < 0)
1191 # endif
1192         {
1193                 netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on address %s: %m",
1194                         stoa(addr));
1195                 exit(1);
1196                 /*NOTREACHED*/
1197         }
1198 #elif defined(FIOSNBIO)
1199         if (ioctl(fd,FIOSNBIO,&on) < 0)
1200         {
1201                 netsyslog(LOG_ERR, "ioctl(FIOSNBIO) fails on address %s: %m",
1202                         stoa(addr));
1203                 exit(1);
1204                 /*NOTREACHED*/
1205         }
1206 #else
1207 # include "Bletch: Need non-blocking I/O!"
1208 #endif
1209
1210 #ifdef HAVE_SIGNALED_IO
1211         init_socket_sig(fd);
1212 #endif /* not HAVE_SIGNALED_IO */
1213
1214         /*
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..
1219          */
1220         if (turn_off_reuse)
1221             if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1222                            (char *)&off, sizeof(off)))
1223             {
1224                     netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails on address %s: %m",
1225                             stoa(addr));
1226             }
1227
1228 #ifdef SO_BROADCAST
1229         /* if this interface can support broadcast, set SO_BROADCAST */
1230         if (flags & INT_BROADCAST)
1231         {
1232                 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1233                                (char *)&on, sizeof(on)))
1234                 {
1235                         netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) on address %s: %m",
1236                                 stoa(addr));
1237                 }
1238         }
1239 #endif /* SO_BROADCAST */
1240
1241 #if !defined(SYS_WINNT) && !defined(VMS)
1242 # ifdef DEBUG
1243         if (debug > 1)
1244             printf("flags for fd %d: 0%o\n", fd,
1245                    fcntl(fd, F_GETFL, 0));
1246 # endif
1247 #endif /* SYS_WINNT || VMS */
1248
1249         return fd;
1250 }
1251
1252
1253 /*
1254  * close_socket - close a socket and remove from the activefd list
1255  */
1256 static void
1257 close_socket(
1258              SOCKET fd
1259         )
1260 {
1261         SOCKET i, newmax;
1262
1263         (void) closesocket(fd);
1264
1265         /*
1266          * I/O Completion Ports don't care about select and fd_set
1267          */
1268 #ifndef HAVE_IO_COMPLETION_PORT
1269         FD_CLR( (u_int) fd, &activefds);
1270
1271         if (fd == maxactivefd) {
1272                 newmax = 0;
1273                 for (i = 0; i < maxactivefd; i++)
1274                         if (FD_ISSET(i, &activefds))
1275                                 newmax = i;
1276                 maxactivefd = newmax;
1277         }
1278 #endif
1279         delete_socket_from_list(fd);
1280
1281 }
1282
1283
1284 /*
1285  * close_file - close a file and remove from the activefd list
1286  * added 1/31/1997 Greg Schueman for Windows NT portability
1287  */
1288 #ifdef REFCLOCK
1289 static void
1290 close_file(
1291         SOCKET fd
1292         )
1293 {
1294         int i, newmax;
1295
1296         (void) close(fd);
1297         /*
1298          * I/O Completion Ports don't care about select and fd_set
1299          */
1300 #ifndef HAVE_IO_COMPLETION_PORT
1301         FD_CLR( (u_int) fd, &activefds);
1302
1303         if (fd == maxactivefd) {
1304                 newmax = 0;
1305                 for (i = 0; i < maxactivefd; i++)
1306                         if (FD_ISSET(i, &activefds))
1307                                 newmax = i;
1308                 maxactivefd = newmax;
1309         }
1310 #endif
1311         delete_socket_from_list(fd);
1312
1313 }
1314 #endif
1315
1316
1317 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
1318 /*
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.
1322  */
1323 void
1324 sendpkt(
1325         struct sockaddr_storage *dest,
1326         struct interface *inter,
1327         int ttl,
1328         struct pkt *pkt,
1329         int len
1330         )
1331 {
1332         int cc, slot;
1333 #ifdef SYS_WINNT
1334         DWORD err;
1335 #endif /* SYS_WINNT */
1336
1337         /*
1338          * Send error caches. Empty slots have port == 0
1339          * Set ERRORCACHESIZE to 0 to disable
1340          */
1341         struct cache {
1342                 u_short port;
1343                 struct  in_addr addr;
1344         };
1345
1346 #ifdef HAVE_IPV6
1347         struct cache6 {
1348                 u_short port;
1349                 struct in6_addr addr;
1350         };
1351 #endif /* HAVE_IPV6 */
1352
1353 #ifndef ERRORCACHESIZE
1354 #define ERRORCACHESIZE 8
1355 #endif
1356 #if ERRORCACHESIZE > 0
1357         static struct cache badaddrs[ERRORCACHESIZE];
1358 #ifdef HAVE_IPV6
1359         static struct cache6 badaddrs6[ERRORCACHESIZE];
1360 #endif /* HAVE_IPV6 */
1361 #else
1362 #define badaddrs ((struct cache *)0)            /* Only used in empty loops! */
1363 #ifdef HAVE_IPV6
1364 #define badaddrs6 ((struct cache6 *)0)          /* Only used in empty loops! */
1365 #endif /* HAVE_IPV6 */
1366 #endif
1367 #ifdef DEBUG
1368         if (debug > 1)
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);
1373 #endif
1374
1375 #ifdef MCAST
1376
1377         switch (inter->sin.ss_family) {
1378
1379         case AF_INET :
1380
1381                 /*
1382                 * for the moment we use the bcast option to set multicast ttl
1383                 */
1384                 if (ttl > 0 && ttl != inter->last_ttl) {
1385
1386                         /*
1387                         * set the multicast ttl for outgoing packets
1388                         */
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",
1392                                         stoa(&inter->sin));
1393                         }
1394                         else
1395                                 inter->last_ttl = ttl;
1396                 }
1397                 break;
1398
1399 #ifdef HAVE_IPV6
1400         case AF_INET6 :
1401
1402                 /*
1403                  * for the moment we use the bcast option to set
1404                  * multicast max hops
1405                  */
1406                 if (ttl > 0 && ttl != inter->last_ttl) {
1407
1408                         /*
1409                         * set the multicast ttl for outgoing packets
1410                         */
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",
1414                                         stoa(&inter->sin));
1415                         else
1416                                 inter->last_ttl = ttl;
1417                 }
1418                 break;
1419 #endif /* HAVE_IPV6 */
1420
1421         default :
1422                 exit(1);
1423
1424         }
1425
1426
1427 #endif /* MCAST */
1428
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)
1433                         break;
1434                 }
1435 #ifdef HAVE_IPV6
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)
1439                         break;
1440                 }
1441 #endif /* HAVE_IPV6 */
1442                 else exit(1);  /* address family not supported yet */
1443
1444 #if defined(HAVE_IO_COMPLETION_PORT)
1445         err = io_completion_port_sendto(inter, pkt, len, dest);
1446         if (err != ERROR_SUCCESS)
1447 #else
1448 #ifdef SIM
1449         cc = srvr_rply(&ntp_node,  dest, inter, pkt);
1450 #else /* SIM */
1451         cc = sendto(inter->fd, (char *)pkt, (unsigned int)len, 0, (struct sockaddr *)dest,
1452                     SOCKLEN(dest));
1453 #endif /* SIM */
1454         if (cc == -1)
1455 #endif
1456         {
1457                 inter->notsent++;
1458                 packets_notsent++;
1459 #if defined(HAVE_IO_COMPLETION_PORT)
1460                 err = WSAGetLastError();
1461                 if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0)
1462 #else
1463                 if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
1464 #endif
1465                 {
1466                         /*
1467                          * Remember this, if there's an empty slot
1468                          */
1469                         switch (dest->ss_family) {
1470
1471                         case AF_INET :
1472
1473                                 for (slot = ERRORCACHESIZE; --slot >= 0; )
1474                                         if (badaddrs[slot].port == 0)
1475                                         {
1476                                                 badaddrs[slot].port = SRCPORT(dest);
1477                                                 badaddrs[slot].addr = ((struct sockaddr_in*)dest)->sin_addr;
1478                                                 break;
1479                                         }
1480                                 break;
1481
1482 #ifdef HAVE_IPV6
1483                         case AF_INET6 :
1484
1485                                 for (slot = ERRORCACHESIZE; --slot >= 0; )
1486                                         if (badaddrs6[slot].port == 0)
1487                                         {
1488                                                 badaddrs6[slot].port = SRCPORT(dest);
1489                                                 badaddrs6[slot].addr = ((struct sockaddr_in6*)dest)->sin6_addr;
1490                                                 break;
1491                                         }
1492                                 break;
1493 #endif /* HAVE_IPV6 */
1494
1495                         default :
1496                                 exit(1);
1497                         }
1498
1499                         netsyslog(LOG_ERR, "sendto(%s): %m", stoa(dest));
1500                 }
1501         }
1502         else
1503         {
1504                 inter->sent++;
1505                 packets_sent++;
1506                 /*
1507                  * He's not bad any more
1508                  */
1509                 if (slot >= 0)
1510                 {
1511                         netsyslog(LOG_INFO, "Connection re-established to %s", stoa(dest));
1512                         switch (dest->ss_family) {
1513                         case AF_INET :
1514                                 badaddrs[slot].port = 0;
1515                                 break;
1516 #ifdef HAVE_IPV6
1517                         case AF_INET6 :
1518                                 badaddrs6[slot].port = 0;
1519                                 break;
1520 #endif /* HAVE_IPV6 */
1521                         }
1522                 }
1523         }
1524 }
1525
1526 #if !defined(HAVE_IO_COMPLETION_PORT)
1527 /*
1528  * fdbits - generate ascii representation of fd_set (FAU debug support)
1529  * HFDF format - highest fd first.
1530  */
1531 static char *
1532 fdbits(
1533         int count,
1534         fd_set *set
1535         )
1536 {
1537         static char buffer[256];
1538         char * buf = buffer;
1539
1540         count = (count < 256) ? count : 255;
1541
1542         while (count >= 0)
1543         {
1544                 *buf++ = FD_ISSET(count, set) ? '#' : '-';
1545                 count--;
1546         }
1547         *buf = '\0';
1548
1549         return buffer;
1550 }
1551
1552 /*
1553  * input_handler - receive packets asynchronously
1554  */
1555 void
1556 input_handler(
1557         l_fp *cts
1558         )
1559 {
1560         register int i, n;
1561         register struct recvbuf *rb;
1562         register int doing;
1563         register SOCKET fd;
1564         struct timeval tvzero;
1565         int fromlen;
1566         l_fp ts;                        /* Timestamp at BOselect() gob */
1567         l_fp ts_e;                      /* Timestamp at EOselect() gob */
1568         fd_set fds;
1569         int select_count = 0;
1570         static int handler_count = 0;
1571
1572         ++handler_count;
1573         if (handler_count != 1)
1574             msyslog(LOG_ERR, "input_handler: handler_count is %d!", handler_count);
1575         handler_calls++;
1576         ts = *cts;
1577
1578         for (;;)
1579         {
1580                 /*
1581                  * Do a poll to see who has data
1582                  */
1583
1584                 fds = activefds;
1585                 tvzero.tv_sec = tvzero.tv_usec = 0;
1586
1587                 /*
1588                  * If we have something to do, freeze a timestamp.
1589                  * See below for the other cases (nothing (left) to do or error)
1590                  */
1591                 while (0 < (n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero)))
1592                 {
1593                         ++select_count;
1594                         ++handler_pkts;
1595
1596 #ifdef REFCLOCK
1597                         /*
1598                          * Check out the reference clocks first, if any
1599                          */
1600                         if (refio != 0)
1601                         {
1602                                 register struct refclockio *rp;
1603
1604                                 for (rp = refio; rp != 0 && n > 0; rp = rp->next)
1605                                 {
1606                                         fd = rp->fd;
1607                                         if (FD_ISSET(fd, &fds))
1608                                         {
1609                                                 n--;
1610                                                 if (free_recvbuffs() == 0)
1611                                                 {
1612                                                         char buf[RX_BUFF_SIZE];
1613
1614                                                         (void) read(fd, buf, sizeof buf);
1615                                                         packets_dropped++;
1616                                                         goto select_again;
1617                                                 }
1618
1619                                                 rb = get_free_recv_buffer();
1620
1621                                                 i = (rp->datalen == 0
1622                                                      || rp->datalen > sizeof(rb->recv_space))
1623                                                     ? sizeof(rb->recv_space) : rp->datalen;
1624                                                 rb->recv_length =
1625                                                     read(fd, (char *)&rb->recv_space, (unsigned)i);
1626
1627                                                 if (rb->recv_length == -1)
1628                                                 {
1629                                                         netsyslog(LOG_ERR, "clock read fd %d: %m", fd);
1630                                                         freerecvbuf(rb);
1631                                                         goto select_again;
1632                                                 }
1633
1634                                                 /*
1635                                                  * Got one.  Mark how
1636                                                  * and when it got here,
1637                                                  * put it on the full
1638                                                  * list and do
1639                                                  * bookkeeping.
1640                                                  */
1641                                                 rb->recv_srcclock = rp->srcclock;
1642                                                 rb->dstadr = 0;
1643                                                 rb->fd = fd;
1644                                                 rb->recv_time = ts;
1645                                                 rb->receiver = rp->clock_recv;
1646
1647                                                 if (rp->io_input)
1648                                                 {
1649                                                         /*
1650                                                          * have direct
1651                                                          * input routine
1652                                                          * for refclocks
1653                                                          */
1654                                                         if (rp->io_input(rb) == 0)
1655                                                         {
1656                                                                 /*
1657                                                                  * data
1658                                                                  * was
1659                                                                  * consumed
1660                                                                  * -
1661                                                                  * nothing
1662                                                                  * to
1663                                                                  * pass
1664                                                                  * up
1665                                                                  * into
1666                                                                  * block
1667                                                                  * input
1668                                                                  * machine
1669                                                                  */
1670                                                                 freerecvbuf(rb);
1671 #if 1
1672                                                                 goto select_again;
1673 #else
1674                                                                 continue;
1675 #endif
1676                                                         }
1677                                                 }
1678
1679                                                 add_full_recv_buffer(rb);
1680
1681                                                 rp->recvcount++;
1682                                                 packets_received++;
1683                                         }
1684                                 }
1685                         }
1686 #endif /* REFCLOCK */
1687
1688                         /*
1689                          * Loop through the interfaces looking for data
1690                          * to read.
1691                          */
1692                         for (i = ninterfaces - 1; (i >= 0) && (n > 0); i--)
1693                         {
1694                                 for (doing = 0; (doing < 2) && (n > 0); doing++)
1695                                 {
1696                                         if (doing == 0)
1697                                         {
1698                                                 fd = inter_list[i].fd;
1699                                         }
1700                                         else
1701                                         {
1702                                                 if (!(inter_list[i].flags & INT_BCASTOPEN))
1703                                                     break;
1704                                                 fd = inter_list[i].bfd;
1705                                         }
1706                                         if (fd < 0) continue;
1707                                         if (FD_ISSET(fd, &fds))
1708                                         {
1709                                                 n--;
1710
1711                                                 /*
1712                                                  * Get a buffer and read
1713                                                  * the frame.  If we
1714                                                  * haven't got a buffer,
1715                                                  * or this is received
1716                                                  * on the wild card
1717                                                  * socket, just dump the
1718                                                  * packet.
1719                                                  */
1720                                                 if (
1721 #ifdef UDP_WILDCARD_DELIVERY
1722                                 /*
1723                                  * these guys manage to put properly addressed
1724                                  * packets into the wildcard queue
1725                                  */
1726                                                         (free_recvbuffs() == 0)
1727 #else
1728                                                         ((i == wildipv4) || (i == wildipv6)||
1729                                                         (free_recvbuffs() == 0))
1730 #endif
1731                                                         )
1732         {
1733                 char buf[RX_BUFF_SIZE];
1734                 struct sockaddr_storage from;
1735
1736                 fromlen = sizeof from;
1737                 (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen);
1738 #ifdef DEBUG
1739                 if (debug)
1740                     printf("%s on %d(%lu) fd=%d from %s\n",
1741                            (i) ? "drop" : "ignore",
1742                            i, free_recvbuffs(), fd,
1743                            stoa(&from));
1744 #endif
1745                 if (i == wildipv4 || i == wildipv6)
1746                     packets_ignored++;
1747                 else
1748                     packets_dropped++;
1749                 goto select_again;
1750         }
1751
1752         rb = get_free_recv_buffer();
1753
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,
1759                                    &fromlen);
1760         if (rb->recv_length == 0
1761 #ifdef EWOULDBLOCK
1762                  || errno==EWOULDBLOCK
1763 #endif
1764 #ifdef EAGAIN
1765                  || errno==EAGAIN
1766 #endif
1767                  ) {
1768                 freerecvbuf(rb);
1769             continue;
1770         }
1771         else if (rb->recv_length < 0)
1772         {
1773                 netsyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
1774                         stoa(&rb->recv_srcadr), fd);
1775 #ifdef DEBUG
1776                 if (debug)
1777                     printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd);
1778 #endif
1779                 freerecvbuf(rb);
1780                 continue;
1781         }
1782 #ifdef DEBUG
1783         if (debug > 2) {
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) &
1788                                 0x00000000ffffffff,
1789                                 stoa(&rb->recv_srcadr));
1790                 else
1791                         printf("input_handler: if=%d fd=%d length %d from %s\n",
1792                                 i, fd, rb->recv_length,
1793                                 stoa(&rb->recv_srcadr));
1794         }
1795 #endif
1796
1797         /*
1798          * Got one.  Mark how and when it got here,
1799          * put it on the full list and do bookkeeping.
1800          */
1801         rb->dstadr = &inter_list[i];
1802         rb->fd = fd;
1803         rb->recv_time = ts;
1804         rb->receiver = receive;
1805
1806         add_full_recv_buffer(rb);
1807
1808         inter_list[i].received++;
1809         packets_received++;
1810         goto select_again;
1811                                         }
1812                                         /* Check more interfaces */
1813                                 }
1814                         }
1815                 select_again:;
1816                         /*
1817                          * Done everything from that select.  Poll again.
1818                          */
1819                 }
1820
1821                 /*
1822                  * If nothing more to do, try again.
1823                  * If nothing to do, just return.
1824                  * If an error occurred, complain and return.
1825                  */
1826                 if (n == 0)
1827                 {
1828                         if (select_count == 0) /* We really had nothing to do */
1829                         {
1830                                 if (debug)
1831                                     netsyslog(LOG_DEBUG, "input_handler: select() returned 0");
1832                                 --handler_count;
1833                                 return;
1834                         }
1835                         /* We've done our work */
1836                         get_systime(&ts_e);
1837                         /*
1838                          * (ts_e - ts) is the amount of time we spent
1839                          * processing this gob of file descriptors.  Log
1840                          * it.
1841                          */
1842                         L_SUB(&ts_e, &ts);
1843                         if (debug > 3)
1844                             netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
1845
1846                         /* just bail. */
1847                         --handler_count;
1848                         return;
1849                 }
1850                 else if (n == -1)
1851                 {
1852                         int err = errno;
1853
1854                         /*
1855                          * extended FAU debugging output
1856                          */
1857                         if (err != EINTR)
1858                             netsyslog(LOG_ERR,
1859                                       "select(%d, %s, 0L, 0L, &0.0) error: %m",
1860                                       maxactivefd+1,
1861                                       fdbits(maxactivefd, &activefds));
1862                         if (err == EBADF) {
1863                                 int j, b;
1864
1865                                 fds = activefds;
1866                                 for (j = 0; j <= maxactivefd; j++)
1867                                     if (
1868                                             (FD_ISSET(j, &fds) && (read(j, &b, 0) == -1))
1869                                             )
1870                                         netsyslog(LOG_ERR, "Bad file descriptor %d", j);
1871                         }
1872                         --handler_count;
1873                         return;
1874                 }
1875         }
1876         msyslog(LOG_ERR, "input_handler: fell out of infinite for(;;) loop!");
1877         --handler_count;
1878         return;
1879 }
1880
1881 #endif
1882 /*
1883  * findinterface - find interface corresponding to address
1884  */
1885 struct interface *
1886 findinterface(
1887         struct sockaddr_storage *addr
1888         )
1889 {
1890         SOCKET s;
1891         int rtn, i;
1892         struct sockaddr_storage saddr;
1893         int saddrlen = SOCKLEN(addr);
1894         /*
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.
1899          */
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);
1910
1911         rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr));
1912 #ifndef SYS_WINNT
1913         if (rtn < 0)
1914 #else
1915         if (rtn == SOCKET_ERROR)
1916 #endif
1917         {
1918                 closesocket(s);
1919                 return ANY_INTERFACE_CHOOSE(addr);
1920         }
1921
1922         rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen);
1923         closesocket(s);
1924 #ifndef SYS_WINNT
1925         if (rtn < 0)
1926 #else
1927         if (rtn == SOCKET_ERROR)
1928 #endif
1929                 return ANY_INTERFACE_CHOOSE(addr);
1930
1931         for (i = 0; i < ninterfaces; i++) {
1932                 /*
1933                 * First look if is the the correct family
1934                 */
1935                 if(inter_list[i].sin.ss_family != saddr.ss_family)
1936                         continue;
1937                 /*
1938                  * We match the unicast address only.
1939                  */
1940                 if (SOCKCMP(&inter_list[i].sin, &saddr))
1941                         return (&inter_list[i]);
1942         }
1943         return ANY_INTERFACE_CHOOSE(addr);
1944 }
1945
1946 /*
1947  * findbcastinter - find broadcast interface corresponding to address
1948  */
1949 struct interface *
1950 findbcastinter(
1951         struct sockaddr_storage *addr
1952         )
1953 {
1954 #if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
1955         register int i;
1956         
1957         i = find_addr_in_list(addr);
1958         if(i >= 0)
1959              return (&inter_list[i]);
1960
1961         for (i = 0; i < ninterfaces; i++) {
1962                 /*
1963                 * First look if this is the correct family
1964                 */
1965                 if(inter_list[i].sin.ss_family != addr->ss_family)
1966                         continue;
1967                 /*
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.
1971                  * Sloppy.
1972                  */
1973                 if (!(inter_list[i].flags & INT_BROADCAST))
1974                         continue;
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]);
1982                 }
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]);
1988                      }
1989         }
1990 #endif /* SIOCGIFCONF */
1991         return ANY_INTERFACE_CHOOSE(addr);
1992 }
1993
1994
1995 /*
1996  * io_clr_stats - clear I/O module statistics
1997  */
1998 void
1999 io_clr_stats(void)
2000 {
2001         packets_dropped = 0;
2002         packets_ignored = 0;
2003         packets_received = 0;
2004         packets_sent = 0;
2005         packets_notsent = 0;
2006
2007         handler_calls = 0;
2008         handler_pkts = 0;
2009         io_timereset = current_time;
2010 }
2011
2012
2013 #ifdef REFCLOCK
2014 /*
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
2018  */
2019 int
2020 io_addclock_simple(
2021         struct refclockio *rio
2022         )
2023 {
2024         BLOCKIO();
2025         /*
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.
2028          */
2029         rio->next = refio;
2030         refio = rio;
2031
2032         /*
2033          * I/O Completion Ports don't care about select and fd_set
2034          */
2035 #ifndef HAVE_IO_COMPLETION_PORT
2036         if (rio->fd > maxactivefd)
2037             maxactivefd = rio->fd;
2038         FD_SET(rio->fd, &activefds);
2039 #endif
2040         UNBLOCKIO();
2041         return 1;
2042 }
2043
2044 /*
2045  * io_addclock - add a reference clock to the list and arrange that we
2046  *                               get SIGIO interrupts from it.
2047  */
2048 int
2049 io_addclock(
2050         struct refclockio *rio
2051         )
2052 {
2053         BLOCKIO();
2054         /*
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.
2057          */
2058         rio->next = refio;
2059         refio = rio;
2060
2061 # ifdef HAVE_SIGNALED_IO
2062         if (init_clock_sig(rio))
2063         {
2064                 refio = rio->next;
2065                 UNBLOCKIO();
2066                 return 0;
2067         }
2068 # elif defined(HAVE_IO_COMPLETION_PORT)
2069         if (io_completion_port_add_clock_io(rio))
2070         {
2071                 add_socket_to_list(rio->fd);
2072                 refio = rio->next;
2073                 UNBLOCKIO();
2074                 return 0;
2075         }
2076 # endif
2077
2078         /*
2079          * I/O Completion Ports don't care about select and fd_set
2080          */
2081 #ifndef HAVE_IO_COMPLETION_PORT
2082         if (rio->fd > maxactivefd)
2083             maxactivefd = rio->fd;
2084         FD_SET(rio->fd, &activefds);
2085 #endif
2086         UNBLOCKIO();
2087         return 1;
2088 }
2089
2090 /*
2091  * io_closeclock - close the clock in the I/O structure given
2092  */
2093 void
2094 io_closeclock(
2095         struct refclockio *rio
2096         )
2097 {
2098         /*
2099          * Remove structure from the list
2100          */
2101         if (refio == rio)
2102         {
2103                 refio = rio->next;
2104         }
2105         else
2106         {
2107                 register struct refclockio *rp;
2108
2109                 for (rp = refio; rp != 0; rp = rp->next)
2110                     if (rp->next == rio)
2111                     {
2112                             rp->next = rio->next;
2113                             break;
2114                     }
2115
2116                 if (rp == 0)
2117                 {
2118                         /*
2119                          * Internal error.      Report it.
2120                          */
2121                         msyslog(LOG_ERR,
2122                                 "internal error: refclockio structure not found");
2123                         return;
2124                 }
2125         }
2126
2127         /*
2128          * Close the descriptor.
2129          */
2130         close_file(rio->fd);
2131 }
2132 #endif  /* REFCLOCK */
2133
2134         /*
2135          * I/O Completion Ports don't care about select and fd_set
2136          */
2137 #ifndef HAVE_IO_COMPLETION_PORT
2138 void
2139 kill_asyncio(
2140         int startfd
2141         )
2142 {
2143         SOCKET i;
2144
2145         BLOCKIO();
2146         for (i = startfd; i <= maxactivefd; i++)
2147             (void)close_socket(i);
2148 }
2149 #else
2150 /*
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.
2154  */
2155 void
2156 kill_asyncio(int startfd)
2157 {
2158         vsock_t *lsock;
2159         vsock_t *next;
2160
2161         BLOCKIO();
2162
2163         lsock = ISC_LIST_HEAD(sockets_list);
2164         while (lsock != NULL) {
2165                 next = ISC_LIST_NEXT(lsock, link);
2166                 close_socket(lsock->fd);
2167                 lsock = next;
2168         }
2169
2170 }
2171 #endif
2172 /*
2173  * Add and delete functions for the list of open sockets
2174  */
2175 void
2176 add_socket_to_list(SOCKET fd){
2177         vsock_t *lsock = malloc(sizeof(vsock_t));
2178         lsock->fd = fd;
2179
2180         ISC_LIST_APPEND(sockets_list, lsock, link);
2181 }
2182 void
2183 delete_socket_from_list(SOCKET fd) {
2184
2185         vsock_t *next;
2186         vsock_t *lsock = ISC_LIST_HEAD(sockets_list);
2187
2188         while(lsock != NULL) {
2189                 next = ISC_LIST_NEXT(lsock, link);
2190                 if(lsock->fd == fd) {
2191                         ISC_LIST_DEQUEUE(sockets_list, lsock, link);
2192                         free(lsock);
2193                         break;
2194                 }
2195                 else
2196                         lsock = next;
2197         }
2198 }
2199 void
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;
2204
2205         ISC_LIST_APPEND(remoteaddr_list, laddr, link);
2206 #ifdef DEBUG
2207         if (debug)
2208             printf("Added addr %s to list of addresses\n",
2209                    stoa(addr));
2210 #endif
2211
2212
2213 }
2214 void
2215 delete_addr_from_list(struct sockaddr_storage *addr) {
2216
2217         remaddr_t *next;
2218         remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
2219
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);
2224                         free(laddr);
2225                         break;
2226                 }
2227                 else
2228                         laddr = next;
2229         }
2230 #ifdef DEBUG
2231         if (debug)
2232             printf("Deleted addr %s from list of addresses\n",
2233                    stoa(addr));
2234 #endif
2235 }
2236 int
2237 find_addr_in_list(struct sockaddr_storage *addr) {
2238
2239         remaddr_t *next;
2240         remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
2241 #ifdef DEBUG
2242         if (debug)
2243             printf("Finding addr %s in list of addresses\n",
2244                    stoa(addr));
2245 #endif
2246
2247         while(laddr != NULL) {
2248                 next = ISC_LIST_NEXT(laddr, link);
2249                 if(SOCKCMP(&laddr->addr, addr)) {
2250                         return (laddr->if_index);
2251                         break;
2252                 }
2253                 else
2254                         laddr = next;
2255         }
2256         return (-1); /* Not found */
2257 }