Annotation of embedaddon/ntp/ntpd/ntp_io.c, revision 1.1.1.1
1.1 misho 1: /*
2: * ntp_io.c - input/output routines for ntpd. The socket-opening code
3: * was shamelessly stolen from ntpd.
4: */
5:
6: #ifdef HAVE_CONFIG_H
7: # include <config.h>
8: #endif
9:
10: #include <stdio.h>
11: #include <signal.h>
12: #ifdef HAVE_SYS_PARAM_H
13: # include <sys/param.h>
14: #endif
15: #ifdef HAVE_SYS_IOCTL_H
16: # include <sys/ioctl.h>
17: #endif
18: #ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
19: # include <sys/sockio.h>
20: #endif
21: #ifdef HAVE_SYS_UIO_H
22: # include <sys/uio.h>
23: #endif
24:
25: #include "ntp_machine.h"
26: #include "ntpd.h"
27: #include "ntp_io.h"
28: #include "iosignal.h"
29: #include "ntp_lists.h"
30: #include "ntp_refclock.h"
31: #include "ntp_stdlib.h"
32: #include "ntp_request.h"
33: #include "ntp.h"
34: #include "ntp_unixtime.h"
35: #include "ntp_assert.h"
36: #include "ntpd-opts.h"
37:
38: /* Don't include ISC's version of IPv6 variables and structures */
39: #define ISC_IPV6_H 1
40: #include <isc/mem.h>
41: #include <isc/interfaceiter.h>
42: #include <isc/netaddr.h>
43: #include <isc/result.h>
44: #include <isc/sockaddr.h>
45:
46: #ifdef SIM
47: #include "ntpsim.h"
48: #endif
49:
50: #ifdef HAS_ROUTING_SOCKET
51: # include <net/route.h>
52: # ifdef HAVE_RTNETLINK
53: # include <linux/rtnetlink.h>
54: # endif
55: #endif
56:
57:
58: /*
59: * setsockopt does not always have the same arg declaration
60: * across all platforms. If it's not defined we make it empty
61: */
62:
63: #ifndef SETSOCKOPT_ARG_CAST
64: #define SETSOCKOPT_ARG_CAST
65: #endif
66:
67: extern int listen_to_virtual_ips;
68:
69: /*
70: * NIC rule entry
71: */
72: typedef struct nic_rule_tag nic_rule;
73:
74: struct nic_rule_tag {
75: nic_rule * next;
76: nic_rule_action action;
77: nic_rule_match match_type;
78: char * if_name;
79: sockaddr_u addr;
80: int prefixlen;
81: };
82:
83: /*
84: * NIC rule listhead. Entries are added at the head so that the first
85: * match in the list is the last matching rule specified.
86: */
87: nic_rule *nic_rule_list;
88:
89:
90: #if defined(SO_TIMESTAMP) && defined(SCM_TIMESTAMP)
91: #if defined(CMSG_FIRSTHDR)
92: #define HAVE_TIMESTAMP
93: #define USE_TIMESTAMP_CMSG
94: #ifndef TIMESTAMP_CTLMSGBUF_SIZE
95: #define TIMESTAMP_CTLMSGBUF_SIZE 1536 /* moderate default */
96: #endif
97: #else
98: /* fill in for old/other timestamp interfaces */
99: #endif
100: #endif
101:
102: #if defined(SYS_WINNT)
103: #include <transmitbuff.h>
104: #include <isc/win32os.h>
105: /*
106: * Windows C runtime ioctl() can't deal properly with sockets,
107: * map to ioctlsocket for this source file.
108: */
109: #define ioctl(fd, opt, val) ioctlsocket((fd), (opt), (u_long *)(val))
110: #endif /* SYS_WINNT */
111:
112: /*
113: * We do asynchronous input using the SIGIO facility. A number of
114: * recvbuf buffers are preallocated for input. In the signal
115: * handler we poll to see which sockets are ready and read the
116: * packets from them into the recvbuf's along with a time stamp and
117: * an indication of the source host and the interface it was received
118: * through. This allows us to get as accurate receive time stamps
119: * as possible independent of other processing going on.
120: *
121: * We watch the number of recvbufs available to the signal handler
122: * and allocate more when this number drops below the low water
123: * mark. If the signal handler should run out of buffers in the
124: * interim it will drop incoming frames, the idea being that it is
125: * better to drop a packet than to be inaccurate.
126: */
127:
128:
129: /*
130: * Other statistics of possible interest
131: */
132: volatile u_long packets_dropped; /* total number of packets dropped on reception */
133: volatile u_long packets_ignored; /* packets received on wild card interface */
134: volatile u_long packets_received; /* total number of packets received */
135: u_long packets_sent; /* total number of packets sent */
136: u_long packets_notsent; /* total number of packets which couldn't be sent */
137:
138: volatile u_long handler_calls; /* number of calls to interrupt handler */
139: volatile u_long handler_pkts; /* number of pkts received by handler */
140: u_long io_timereset; /* time counters were reset */
141:
142: /*
143: * Interface stuff
144: */
145: endpt * any_interface; /* wildcard ipv4 interface */
146: endpt * any6_interface; /* wildcard ipv6 interface */
147: endpt * loopback_interface; /* loopback ipv4 interface */
148:
149: isc_boolean_t broadcast_client_enabled; /* is broadcast client enabled */
150: int ninterfaces; /* Total number of interfaces */
151:
152: int disable_dynamic_updates; /* scan interfaces once only */
153:
154: #ifdef REFCLOCK
155: /*
156: * Refclock stuff. We keep a chain of structures with data concerning
157: * the guys we are doing I/O for.
158: */
159: static struct refclockio *refio;
160: #endif /* REFCLOCK */
161:
162: #if defined(HAVE_IPTOS_SUPPORT)
163: /* set IP_TOS to minimize packet delay */
164: # if defined(IPTOS_PREC_INTERNETCONTROL)
165: unsigned int qos = IPTOS_PREC_INTERNETCONTROL;
166: # else
167: unsigned int qos = IPTOS_LOWDELAY;
168: # endif
169: #endif
170:
171: /*
172: * File descriptor masks etc. for call to select
173: * Not needed for I/O Completion Ports
174: */
175: fd_set activefds;
176: int maxactivefd;
177: /*
178: * bit alternating value to detect verified interfaces during an update cycle
179: */
180: static u_short sys_interphase = 0;
181:
182: static endpt * new_interface(endpt *);
183: static void add_interface(endpt *);
184: static int update_interfaces(u_short, interface_receiver_t,
185: void *);
186: static void remove_interface(endpt *);
187: static endpt * create_interface(u_short, endpt *);
188:
189: static int move_fd (SOCKET);
190: static int is_wildcard_addr (const sockaddr_u *);
191:
192: /*
193: * Multicast functions
194: */
195: static isc_boolean_t addr_ismulticast (sockaddr_u *);
196: static isc_boolean_t is_anycast (sockaddr_u *,
197: const char *);
198:
199: /*
200: * Not all platforms support multicast
201: */
202: #ifdef MCAST
203: static isc_boolean_t socket_multicast_enable (endpt *, sockaddr_u *);
204: static isc_boolean_t socket_multicast_disable(endpt *, sockaddr_u *);
205: #endif
206:
207: #ifdef DEBUG
208: static void interface_dump (const endpt *);
209: static void sockaddr_dump (const sockaddr_u *);
210: static void print_interface (const endpt *, char *, char *);
211: #define DPRINT_INTERFACE(level, args) do { if (debug >= (level)) { print_interface args; } } while (0)
212: #else
213: #define DPRINT_INTERFACE(level, args) do {} while (0)
214: #endif
215:
216: typedef struct vsock vsock_t;
217: enum desc_type { FD_TYPE_SOCKET, FD_TYPE_FILE };
218:
219: struct vsock {
220: vsock_t * link;
221: SOCKET fd;
222: enum desc_type type;
223: };
224:
225: vsock_t *fd_list;
226:
227: #if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
228: /*
229: * async notification processing (e. g. routing sockets)
230: */
231: /*
232: * support for receiving data on fd that is not a refclock or a socket
233: * like e. g. routing sockets
234: */
235: struct asyncio_reader {
236: struct asyncio_reader *link; /* the list this is being kept in */
237: SOCKET fd; /* fd to be read */
238: void *data; /* possibly local data */
239: void (*receiver)(struct asyncio_reader *); /* input handler */
240: };
241:
242: struct asyncio_reader *asyncio_reader_list;
243:
244: static void delete_asyncio_reader (struct asyncio_reader *);
245: static struct asyncio_reader *new_asyncio_reader (void);
246: static void add_asyncio_reader (struct asyncio_reader *, enum desc_type);
247: static void remove_asyncio_reader (struct asyncio_reader *);
248:
249: #endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
250:
251: static void init_async_notifications (void);
252:
253: static int addr_eqprefix (const sockaddr_u *, const sockaddr_u *,
254: int);
255: static int addr_samesubnet (const sockaddr_u *, const sockaddr_u *,
256: const sockaddr_u *, const sockaddr_u *);
257: static int create_sockets (u_short);
258: static SOCKET open_socket (sockaddr_u *, int, int, endpt *);
259: static char * fdbits (int, fd_set *);
260: static void set_reuseaddr (int);
261: static isc_boolean_t socket_broadcast_enable (struct interface *, SOCKET, sockaddr_u *);
262: static isc_boolean_t socket_broadcast_disable (struct interface *, sockaddr_u *);
263:
264: typedef struct remaddr remaddr_t;
265:
266: struct remaddr {
267: remaddr_t * link;
268: sockaddr_u addr;
269: endpt * ep;
270: };
271:
272: remaddr_t * remoteaddr_list;
273: endpt * ep_list; /* complete endpt list */
274: endpt * mc4_list; /* IPv4 mcast-capable unicast endpts */
275: endpt * mc6_list; /* IPv6 mcast-capable unicast endpts */
276:
277: static endpt * wildipv4;
278: static endpt * wildipv6;
279:
280: static void add_fd_to_list (SOCKET, enum desc_type);
281: static endpt * find_addr_in_list (sockaddr_u *);
282: static endpt * find_flagged_addr_in_list(sockaddr_u *, u_int32);
283: static void delete_addr_from_list (sockaddr_u *);
284: static void delete_interface_from_list(endpt *);
285: static void close_and_delete_fd_from_list(SOCKET);
286: static void add_addr_to_list (sockaddr_u *, endpt *);
287: static void create_wildcards (u_short);
288: static endpt * getinterface (sockaddr_u *, u_int32);
289: static endpt * findlocalinterface (sockaddr_u *, int, int);
290: static endpt * findclosestinterface (sockaddr_u *, int);
291: #ifdef DEBUG
292: static const char * action_text (nic_rule_action);
293: #endif
294: static nic_rule_action interface_action(char *, sockaddr_u *, u_int32);
295: static void convert_isc_if (isc_interface_t *,
296: endpt *, u_short);
297: static void calc_addr_distance(sockaddr_u *,
298: const sockaddr_u *,
299: const sockaddr_u *);
300: static int cmp_addr_distance(const sockaddr_u *,
301: const sockaddr_u *);
302:
303: /*
304: * Routines to read the ntp packets
305: */
306: #if !defined(HAVE_IO_COMPLETION_PORT)
307: static inline int read_network_packet (SOCKET, struct interface *, l_fp);
308: static inline int read_refclock_packet (SOCKET, struct refclockio *, l_fp);
309: #endif
310:
311:
312: #ifdef SYS_WINNT
313: /*
314: * Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom
315: * to not work correctly, returning a WSACONNRESET error when a WSASendTo
316: * fails with an "ICMP port unreachable" response and preventing the
317: * socket from using the WSARecvFrom in subsequent operations.
318: * The function below fixes this, but requires that Windows 2000
319: * Service Pack 2 or later be installed on the system. NT 4.0
320: * systems are not affected by this and work correctly.
321: * See Microsoft Knowledge Base Article Q263823 for details of this.
322: */
323: void
324: connection_reset_fix(
325: SOCKET fd,
326: sockaddr_u * addr
327: )
328: {
329: DWORD dw;
330: BOOL bNewBehavior = FALSE;
331: DWORD status;
332:
333: /*
334: * disable bad behavior using IOCTL: SIO_UDP_CONNRESET
335: * NT 4.0 has no problem
336: */
337: if (isc_win32os_majorversion() >= 5) {
338: status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,
339: sizeof(bNewBehavior), NULL, 0,
340: &dw, NULL, NULL);
341: if (SOCKET_ERROR == status)
342: msyslog(LOG_ERR,
343: "connection_reset_fix() failed for address %s: %m",
344: stoa(addr));
345: }
346: }
347: #endif
348:
349: /*
350: * on Unix systems the stdio library typically
351: * makes use of file descriptors in the lower
352: * integer range. stdio usually will make use
353: * of the file descriptors in the range of
354: * [0..FOPEN_MAX)
355: * in order to keep this range clean, for socket
356: * file descriptors we attempt to move them above
357: * FOPEN_MAX. This is not as easy as it sounds as
358: * FOPEN_MAX changes from implementation to implementation
359: * and may exceed to current file decriptor limits.
360: * We are using following strategy:
361: * - keep a current socket fd boundary initialized with
362: * max(0, min(getdtablesize() - FD_CHUNK, FOPEN_MAX))
363: * - attempt to move the descriptor to the boundary or
364: * above.
365: * - if that fails and boundary > 0 set boundary
366: * to min(0, socket_fd_boundary - FD_CHUNK)
367: * -> retry
368: * if failure and boundary == 0 return old fd
369: * - on success close old fd return new fd
370: *
371: * effects:
372: * - fds will be moved above the socket fd boundary
373: * if at all possible.
374: * - the socket boundary will be reduced until
375: * allocation is possible or 0 is reached - at this
376: * point the algrithm will be disabled
377: */
378: static int
379: move_fd(
380: SOCKET fd
381: )
382: {
383: #if !defined(SYS_WINNT) && defined(F_DUPFD)
384: #ifndef FD_CHUNK
385: #define FD_CHUNK 10
386: #endif
387: /*
388: * number of fds we would like to have for
389: * stdio FILE* available.
390: * we can pick a "low" number as our use of
391: * FILE* is limited to log files and temporarily
392: * to data and config files. Except for log files
393: * we don't keep the other FILE* open beyond the
394: * scope of the function that opened it.
395: */
396: #ifndef FD_PREFERRED_SOCKBOUNDARY
397: #define FD_PREFERRED_SOCKBOUNDARY 48
398: #endif
399:
400: #ifndef HAVE_GETDTABLESIZE
401: /*
402: * if we have no idea about the max fd value set up things
403: * so we will start at FOPEN_MAX
404: */
405: #define getdtablesize() (FOPEN_MAX+FD_CHUNK)
406: #endif
407:
408: #ifndef FOPEN_MAX
409: #define FOPEN_MAX 20 /* assume that for the lack of anything better */
410: #endif
411: static SOCKET socket_boundary = -1;
412: SOCKET newfd;
413:
414: NTP_REQUIRE((int)fd >= 0);
415:
416: /*
417: * check whether boundary has be set up
418: * already
419: */
420: if (socket_boundary == -1) {
421: socket_boundary = max(0, min(getdtablesize() - FD_CHUNK,
422: min(FOPEN_MAX, FD_PREFERRED_SOCKBOUNDARY)));
423: #ifdef DEBUG
424: msyslog(LOG_DEBUG,
425: "ntp_io: estimated max descriptors: %d, initial socket boundary: %d",
426: getdtablesize(), socket_boundary);
427: #endif
428: }
429:
430: /*
431: * Leave a space for stdio to work in. potentially moving the
432: * socket_boundary lower until allocation succeeds.
433: */
434: do {
435: if (fd >= 0 && fd < socket_boundary) {
436: /* inside reserved range: attempt to move fd */
437: newfd = fcntl(fd, F_DUPFD, socket_boundary);
438:
439: if (newfd != -1) {
440: /* success: drop the old one - return the new one */
441: close(fd);
442: return newfd;
443: }
444: } else {
445: /* outside reserved range: no work - return the original one */
446: return fd;
447: }
448: socket_boundary = max(0, socket_boundary - FD_CHUNK);
449: #ifdef DEBUG
450: msyslog(LOG_DEBUG,
451: "ntp_io: selecting new socket boundary: %d",
452: socket_boundary);
453: #endif
454: } while (socket_boundary > 0);
455: #else
456: NTP_REQUIRE((int)fd >= 0);
457: #endif /* !defined(SYS_WINNT) && defined(F_DUPFD) */
458: return fd;
459: }
460:
461: #ifdef DEBUG_TIMING
462: /*
463: * collect timing information for various processing
464: * paths. currently we only pass then on to the file
465: * for later processing. this could also do histogram
466: * based analysis in other to reduce the load (and skew)
467: * dur to the file output
468: */
469: void
470: collect_timing(struct recvbuf *rb, const char *tag, int count, l_fp *dts)
471: {
472: char buf[256];
473:
474: snprintf(buf, sizeof(buf), "%s %d %s %s",
475: (rb != NULL)
476: ? ((rb->dstadr != NULL)
477: ? stoa(&rb->recv_srcadr)
478: : "-REFCLOCK-")
479: : "-",
480: count, lfptoa(dts, 9), tag);
481: record_timing_stats(buf);
482: }
483: #endif
484:
485: /*
486: * About dynamic interfaces, sockets, reception and more...
487: *
488: * the code solves following tasks:
489: *
490: * - keep a current list of active interfaces in order
491: * to bind to to the interface address on NTP_PORT so that
492: * all wild and specific bindings for NTP_PORT are taken by ntpd
493: * to avoid other daemons messing with the time or sockets.
494: * - all interfaces keep a list of peers that are referencing
495: * the interface in order to quickly re-assign the peers to
496: * new interface in case an interface is deleted (=> gone from system or
497: * down)
498: * - have a preconfigured socket ready with the right local address
499: * for transmission and reception
500: * - have an address list for all destination addresses used within ntpd
501: * to find the "right" preconfigured socket.
502: * - facilitate updating the internal interface list with respect to
503: * the current kernel state
504: *
505: * special issues:
506: *
507: * - mapping of multicast addresses to the interface affected is not always
508: * one to one - especially on hosts with multiple interfaces
509: * the code here currently allocates a separate interface entry for those
510: * multicast addresses
511: * iff it is able to bind to a *new* socket with the multicast address (flags |= MCASTIF)
512: * in case of failure the multicast address is bound to an existing interface.
513: * - on some systems it is perfectly legal to assign the same address to
514: * multiple interfaces. Therefore this code does not keep a list of interfaces
515: * but a list of interfaces that represent a unique address as determined by the kernel
516: * by the procedure in findlocalinterface. Thus it is perfectly legal to see only
517: * one representative of a group of real interfaces if they share the same address.
518: *
519: * Frank Kardel 20050910
520: */
521:
522: /*
523: * init_io - initialize I/O data structures and call socket creation routine
524: */
525: void
526: init_io(void)
527: {
528: /*
529: * Init buffer free list and stat counters
530: */
531: init_recvbuff(RECV_INIT);
532:
533: #ifdef SYS_WINNT
534: init_io_completion_port();
535: #endif /* SYS_WINNT */
536:
537: #if defined(HAVE_SIGNALED_IO)
538: (void) set_signal();
539: #endif
540: }
541:
542:
543: /*
544: * io_open_sockets - call socket creation routine
545: */
546: void
547: io_open_sockets(void)
548: {
549: static int already_opened;
550:
551: if (already_opened || HAVE_OPT( SAVECONFIGQUIT ))
552: return;
553:
554: already_opened = 1;
555:
556: /*
557: * Create the sockets
558: */
559: BLOCKIO();
560: create_sockets(NTP_PORT);
561: UNBLOCKIO();
562:
563: init_async_notifications();
564:
565: DPRINTF(3, ("io_open_sockets: maxactivefd %d\n", maxactivefd));
566: }
567:
568:
569: #ifdef DEBUG
570: /*
571: * function to dump the contents of the interface structure
572: * for debugging use only.
573: */
574: void
575: interface_dump(const endpt *itf)
576: {
577: printf("Dumping interface: %p\n", itf);
578: printf("fd = %d\n", itf->fd);
579: printf("bfd = %d\n", itf->bfd);
580: printf("sin = %s,\n", stoa(&itf->sin));
581: sockaddr_dump(&itf->sin);
582: printf("bcast = %s,\n", stoa(&itf->bcast));
583: sockaddr_dump(&itf->bcast);
584: printf("mask = %s,\n", stoa(&itf->mask));
585: sockaddr_dump(&itf->mask);
586: printf("name = %s\n", itf->name);
587: printf("flags = 0x%08x\n", itf->flags);
588: printf("last_ttl = %d\n", itf->last_ttl);
589: printf("addr_refid = %08x\n", itf->addr_refid);
590: printf("num_mcast = %d\n", itf->num_mcast);
591: printf("received = %ld\n", itf->received);
592: printf("sent = %ld\n", itf->sent);
593: printf("notsent = %ld\n", itf->notsent);
594: printf("ifindex = %u\n", itf->ifindex);
595: printf("peercnt = %u\n", itf->peercnt);
596: printf("phase = %u\n", itf->phase);
597: }
598:
599: /*
600: * sockaddr_dump - hex dump the start of a sockaddr_u
601: */
602: static void
603: sockaddr_dump(const sockaddr_u *psau)
604: {
605: /* Limit the size of the sockaddr_storage hex dump */
606: const int maxsize = min(32, sizeof(psau->sa6));
607: const u_char * cp;
608: int i;
609:
610: cp = (const void *)&psau->sa;
611:
612: for(i = 0; i < maxsize; i++) {
613: printf("%02x", *cp++);
614: if (!((i + 1) % 4))
615: printf(" ");
616: }
617: printf("\n");
618: }
619:
620: /*
621: * print_interface - helper to output debug information
622: */
623: static void
624: print_interface(const endpt *iface, char *pfx, char *sfx)
625: {
626: printf("%sinterface #%d: fd=%d, bfd=%d, name=%s, flags=0x%x, ifindex=%u, sin=%s",
627: pfx,
628: iface->ifnum,
629: iface->fd,
630: iface->bfd,
631: iface->name,
632: iface->flags,
633: iface->ifindex,
634: stoa(&iface->sin));
635: if (AF_INET == iface->family) {
636: if (iface->flags & INT_BROADCAST)
637: printf(", bcast=%s", stoa(&iface->bcast));
638: printf(", mask=%s", stoa(&iface->mask));
639: }
640: printf(", %s:%s",
641: (iface->ignore_packets)
642: ? "Disabled"
643: : "Enabled",
644: sfx);
645: if (debug > 4) /* in-depth debugging only */
646: interface_dump(iface);
647: }
648: #endif
649:
650: #if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
651: /*
652: * create an asyncio_reader structure
653: */
654: static struct asyncio_reader *
655: new_asyncio_reader(void)
656: {
657: struct asyncio_reader *reader;
658:
659: reader = emalloc(sizeof(*reader));
660:
661: memset(reader, 0, sizeof(*reader));
662: reader->fd = INVALID_SOCKET;
663: return reader;
664: }
665:
666: /*
667: * delete a reader
668: */
669: static void
670: delete_asyncio_reader(
671: struct asyncio_reader *reader
672: )
673: {
674: free(reader);
675: }
676:
677: /*
678: * add asynchio_reader
679: */
680: static void
681: add_asyncio_reader(
682: struct asyncio_reader * reader,
683: enum desc_type type)
684: {
685: LINK_SLIST(asyncio_reader_list, reader, link);
686: add_fd_to_list(reader->fd, type);
687: }
688:
689: /*
690: * remove asynchio_reader
691: */
692: static void
693: remove_asyncio_reader(
694: struct asyncio_reader *reader
695: )
696: {
697: struct asyncio_reader *unlinked;
698:
699: UNLINK_SLIST(unlinked, asyncio_reader_list, reader, link,
700: struct asyncio_reader);
701:
702: if (reader->fd != INVALID_SOCKET)
703: close_and_delete_fd_from_list(reader->fd);
704:
705: reader->fd = INVALID_SOCKET;
706: }
707: #endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
708:
709:
710: /* compare two sockaddr prefixes */
711: static int
712: addr_eqprefix(
713: const sockaddr_u * a,
714: const sockaddr_u * b,
715: int prefixlen
716: )
717: {
718: isc_netaddr_t isc_a;
719: isc_netaddr_t isc_b;
720: isc_sockaddr_t isc_sa;
721:
722: memset(&isc_sa, 0, sizeof(isc_sa));
723: memcpy(&isc_sa.type.sa, &a->sa,
724: min(sizeof(isc_sa.type), sizeof(*a)));
725: isc_netaddr_fromsockaddr(&isc_a, &isc_sa);
726:
727: memset(&isc_sa, 0, sizeof(isc_sa));
728: memcpy(&isc_sa.type.sa, &b->sa,
729: min(sizeof(isc_sa.type), sizeof(*b)));
730: isc_netaddr_fromsockaddr(&isc_b, &isc_sa);
731:
732: return (int)isc_netaddr_eqprefix(&isc_a, &isc_b,
733: (u_int)prefixlen);
734: }
735:
736:
737: static int
738: addr_samesubnet(
739: const sockaddr_u * a,
740: const sockaddr_u * a_mask,
741: const sockaddr_u * b,
742: const sockaddr_u * b_mask
743: )
744: {
745: const u_int32 * pa;
746: const u_int32 * pa_limit;
747: const u_int32 * pb;
748: const u_int32 * pm;
749: size_t loops;
750:
751: NTP_REQUIRE(AF(a) == AF(a_mask));
752: NTP_REQUIRE(AF(b) == AF(b_mask));
753: /*
754: * With address and mask families verified to match, comparing
755: * the masks also validates the address's families match.
756: */
757: if (!SOCK_EQ(a_mask, b_mask))
758: return FALSE;
759:
760: if (IS_IPV6(a)) {
761: loops = sizeof(NSRCADR6(a)) / sizeof(*pa);
762: pa = (const void *)&NSRCADR6(a);
763: pb = (const void *)&NSRCADR6(b);
764: pm = (const void *)&NSRCADR6(a_mask);
765: } else {
766: loops = sizeof(NSRCADR(a)) / sizeof(*pa);
767: pa = (const void *)&NSRCADR(a);
768: pb = (const void *)&NSRCADR(b);
769: pm = (const void *)&NSRCADR(a_mask);
770: }
771: for (pa_limit = pa + loops; pa < pa_limit; pa++, pb++, pm++)
772: if ((*pa & *pm) != (*pb & *pm))
773: return FALSE;
774:
775: return TRUE;
776: }
777:
778:
779: /*
780: * Code to tell if we have an IP address
781: * If we have then return the sockaddr structure
782: * and set the return value
783: * see the bind9/getaddresses.c for details
784: */
785: int
786: is_ip_address(
787: const char * host,
788: sockaddr_u * addr
789: )
790: {
791: struct in_addr in4;
792: struct in6_addr in6;
793: char tmpbuf[128];
794: char *pch;
795:
796: NTP_REQUIRE(host != NULL);
797: NTP_REQUIRE(addr != NULL);
798:
799: memset(addr, 0, sizeof(*addr));
800:
801: /*
802: * Try IPv4, then IPv6. In order to handle the extended format
803: * for IPv6 scoped addresses (address%scope_ID), we'll use a local
804: * working buffer of 128 bytes. The length is an ad-hoc value, but
805: * should be enough for this purpose; the buffer can contain a string
806: * of at least 80 bytes for scope_ID in addition to any IPv6 numeric
807: * addresses (up to 46 bytes), the delimiter character and the
808: * terminating NULL character.
809: */
810: if (inet_pton(AF_INET, host, &in4) == 1) {
811: AF(addr) = AF_INET;
812: SET_ADDR4N(addr, in4.s_addr);
813:
814: return TRUE;
815: } else if (sizeof(tmpbuf) > strlen(host)) {
816: if ('[' == host[0]) {
817: strncpy(tmpbuf, &host[1], sizeof(tmpbuf));
818: pch = strchr(tmpbuf, ']');
819: if (pch != NULL)
820: *pch = '\0';
821: } else
822: strncpy(tmpbuf, host, sizeof(tmpbuf));
823: pch = strchr(tmpbuf, '%');
824: if (pch != NULL)
825: *pch = '\0';
826:
827: if (inet_pton(AF_INET6, tmpbuf, &in6) == 1) {
828: AF(addr) = AF_INET6;
829: SET_ADDR6N(addr, in6);
830:
831: return TRUE;
832: }
833: }
834: /*
835: * If we got here it was not an IP address
836: */
837: return FALSE;
838: }
839:
840:
841: /*
842: * interface list enumerator - visitor pattern
843: */
844: void
845: interface_enumerate(
846: interface_receiver_t receiver,
847: void * data
848: )
849: {
850: interface_info_t ifi;
851:
852: ifi.action = IFS_EXISTS;
853: for (ifi.ep = ep_list; ifi.ep != NULL; ifi.ep = ifi.ep->elink)
854: (*receiver)(data, &ifi);
855: }
856:
857: /*
858: * do standard initialization of interface structure
859: */
860: static void
861: init_interface(
862: endpt *ep
863: )
864: {
865: memset(ep, 0, sizeof(*ep));
866: ep->fd = INVALID_SOCKET;
867: ep->bfd = INVALID_SOCKET;
868: ep->phase = sys_interphase;
869: }
870:
871:
872: /*
873: * create new interface structure initialize from
874: * template structure or via standard initialization
875: * function
876: */
877: static struct interface *
878: new_interface(
879: struct interface *interface
880: )
881: {
882: static u_int sys_ifnum = 0;
883: struct interface * iface;
884:
885: iface = emalloc(sizeof(*iface));
886:
887: if (NULL == interface)
888: init_interface(iface);
889: else /* use the template */
890: memcpy(iface, interface, sizeof(*iface));
891:
892: /* count every new instance of an interface in the system */
893: iface->ifnum = sys_ifnum++;
894: iface->starttime = current_time;
895:
896: return iface;
897: }
898:
899:
900: /*
901: * return interface storage into free memory pool
902: */
903: static inline void
904: delete_interface(
905: endpt *ep
906: )
907: {
908: free(ep);
909: }
910:
911:
912: /*
913: * link interface into list of known interfaces
914: */
915: static void
916: add_interface(
917: endpt * ep
918: )
919: {
920: endpt ** pmclisthead;
921: endpt * scan;
922: endpt * scan_next;
923: endpt * unlinked;
924: sockaddr_u * addr;
925: int ep_local;
926: int scan_local;
927: int same_subnet;
928: int ep_univ_iid; /* iface ID from MAC address */
929: int scan_univ_iid; /* see RFC 4291 */
930: int ep_privacy; /* random local iface ID */
931: int scan_privacy; /* see RFC 4941 */
932: int rc;
933:
934: /*
935: * Calculate the address hash
936: */
937: ep->addr_refid = addr2refid(&ep->sin);
938:
939: LINK_SLIST(ep_list, ep, elink);
940: ninterfaces++;
941: #ifdef MCAST
942: /* the rest is for enabled multicast-capable addresses only */
943: if (ep->ignore_packets || !(INT_MULTICAST & ep->flags) ||
944: INT_LOOPBACK & ep->flags)
945: return;
946: # ifndef INCLUDE_IPV6_MULTICAST_SUPPORT
947: if (AF_INET6 == ep->family)
948: return;
949: # endif
950: pmclisthead = (AF_INET == ep->family)
951: ? &mc4_list
952: : &mc6_list;
953:
954: if (AF_INET6 == ep->family) {
955: ep_local =
956: IN6_IS_ADDR_LINKLOCAL(PSOCK_ADDR6(&ep->sin)) ||
957: IN6_IS_ADDR_SITELOCAL(PSOCK_ADDR6(&ep->sin));
958: ep_univ_iid = IS_IID_UNIV(&ep->sin);
959: ep_privacy = !!(INT_PRIVACY & ep->flags);
960: } else {
961: ep_local = FALSE;
962: ep_univ_iid = FALSE;
963: ep_privacy = FALSE;
964: }
965: DPRINTF(4, ("add_interface mcast-capable %s%s%s%s\n",
966: stoa(&ep->sin),
967: (ep_local) ? " link/scope-local" : "",
968: (ep_univ_iid) ? " univ-IID" : "",
969: (ep_privacy) ? " privacy" : ""));
970: /*
971: * If we have multiple local addresses on the same network
972: * interface, and some are link- or site-local, do not multicast
973: * out from the link-/site-local addresses by default, to avoid
974: * duplicate manycastclient associations between v6 peers using
975: * link-local and global addresses. link-local can still be
976: * chosen using "nic ignore myv6globalprefix::/64".
977: * Similarly, if we have multiple global addresses from the same
978: * prefix on the same network interface, multicast from one,
979: * preferring EUI-64, then static, then least RFC 4941 privacy
980: * addresses.
981: */
982: for (scan = *pmclisthead; scan != NULL; scan = scan_next) {
983: scan_next = scan->mclink;
984: if (ep->family != scan->family)
985: continue;
986: if (strcmp(ep->name, scan->name))
987: continue;
988: same_subnet = addr_samesubnet(&ep->sin, &ep->mask,
989: &scan->sin, &scan->mask);
990: if (AF_INET6 == ep->family) {
991: addr = &scan->sin;
992: scan_local =
993: IN6_IS_ADDR_LINKLOCAL(PSOCK_ADDR6(addr)) ||
994: IN6_IS_ADDR_SITELOCAL(PSOCK_ADDR6(addr));
995: scan_univ_iid = IS_IID_UNIV(addr);
996: scan_privacy = !!(INT_PRIVACY & scan->flags);
997: } else {
998: scan_local = FALSE;
999: scan_univ_iid = FALSE;
1000: scan_privacy = FALSE;
1001: }
1002: DPRINTF(4, ("add_interface mcast-capable scan %s%s%s%s\n",
1003: stoa(&scan->sin),
1004: (scan_local) ? " link/scope-local" : "",
1005: (scan_univ_iid) ? " univ-IID" : "",
1006: (scan_privacy) ? " privacy" : ""));
1007: if ((ep_local && !scan_local) || (same_subnet &&
1008: ((ep_privacy && !scan_privacy) ||
1009: (!ep_univ_iid && scan_univ_iid)))) {
1010: DPRINTF(4, ("did not add %s to %s of IPv6 multicast-capable list which already has %s\n",
1011: stoa(&ep->sin),
1012: (ep_local)
1013: ? "tail"
1014: : "head",
1015: stoa(&scan->sin)));
1016: return;
1017: }
1018: if ((scan_local && !ep_local) || (same_subnet &&
1019: ((scan_privacy && !ep_privacy) ||
1020: (!scan_univ_iid && ep_univ_iid)))) {
1021: UNLINK_SLIST(unlinked, *pmclisthead,
1022: scan, mclink, endpt);
1023: DPRINTF(4, ("%s %s from IPv6 multicast-capable list to add %s\n",
1024: (unlinked != scan)
1025: ? "Failed to remove"
1026: : "removed",
1027: stoa(&scan->sin), stoa(&ep->sin)));
1028: }
1029: }
1030: /*
1031: * Add link/site local at the tail of the multicast-
1032: * capable unicast interfaces list, so that ntpd will
1033: * send from global addresses before link-/site-local
1034: * ones.
1035: */
1036: if (ep_local)
1037: LINK_TAIL_SLIST(*pmclisthead, ep, mclink, endpt);
1038: else
1039: LINK_SLIST(*pmclisthead, ep, mclink);
1040: DPRINTF(4, ("added %s to %s of IPv%s multicast-capable unicast local address list\n",
1041: stoa(&ep->sin),
1042: (ep_local)
1043: ? "tail"
1044: : "head",
1045: (AF_INET == ep->family)
1046: ? "4"
1047: : "6"));
1048:
1049: /*
1050: * select the local address from which to send to multicast.
1051: */
1052: switch (AF(&ep->sin)) {
1053: case AF_INET :
1054: rc = setsockopt(ep->fd, IPPROTO_IP,
1055: IP_MULTICAST_IF,
1056: (void *)&NSRCADR(&ep->sin),
1057: sizeof(NSRCADR(&ep->sin)));
1058: if (rc)
1059: msyslog(LOG_ERR,
1060: "setsockopt IP_MULTICAST_IF %s fails: %m",
1061: stoa(&ep->sin));
1062: break;
1063: # ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1064: case AF_INET6 :
1065: rc = setsockopt(ep->fd, IPPROTO_IPV6,
1066: IPV6_MULTICAST_IF,
1067: (void *)&ep->ifindex,
1068: sizeof(ep->ifindex));
1069: if (rc)
1070: msyslog(LOG_ERR,
1071: "setsockopt IPV6_MULTICAST_IF %u for %s fails: %m",
1072: ep->ifindex, stoa(&ep->sin));
1073: break;
1074: # endif
1075: }
1076: #endif /* MCAST */
1077: }
1078:
1079:
1080: /*
1081: * remove interface from known interface list and clean up
1082: * associated resources
1083: */
1084: static void
1085: remove_interface(
1086: endpt * ep
1087: )
1088: {
1089: endpt * unlinked;
1090: endpt ** pmclisthead;
1091: sockaddr_u resmask;
1092:
1093: UNLINK_SLIST(unlinked, ep_list, ep, elink, endpt);
1094: if (!ep->ignore_packets && INT_MULTICAST & ep->flags) {
1095: pmclisthead = (AF_INET == ep->family)
1096: ? &mc4_list
1097: : &mc6_list;
1098: UNLINK_SLIST(unlinked, *pmclisthead, ep, mclink, endpt);
1099: DPRINTF(4, ("%s %s IPv%s multicast-capable unicast local address list\n",
1100: stoa(&ep->sin),
1101: (unlinked != NULL)
1102: ? "removed from"
1103: : "not found on",
1104: (AF_INET == ep->family)
1105: ? "4"
1106: : "6"));
1107: }
1108: delete_interface_from_list(ep);
1109:
1110: if (ep->fd != INVALID_SOCKET) {
1111: msyslog(LOG_INFO,
1112: "Deleting interface #%d %s, %s#%d, interface stats: received=%ld, sent=%ld, dropped=%ld, active_time=%ld secs",
1113: ep->ifnum,
1114: ep->name,
1115: stoa(&ep->sin),
1116: SRCPORT(&ep->sin),
1117: ep->received,
1118: ep->sent,
1119: ep->notsent,
1120: current_time - ep->starttime);
1121: close_and_delete_fd_from_list(ep->fd);
1122: }
1123:
1124: if (ep->bfd != INVALID_SOCKET) {
1125: msyslog(LOG_INFO,
1126: "Deleting broadcast address %s#%d from interface #%d %s",
1127: stoa(&ep->bcast), SRCPORT(&ep->bcast),
1128: ep->ifnum, ep->name);
1129: close_and_delete_fd_from_list(ep->bfd);
1130: }
1131:
1132: ninterfaces--;
1133: ntp_monclearinterface(ep);
1134:
1135: /* remove restrict interface entry */
1136: SET_HOSTMASK(&resmask, AF(&ep->sin));
1137: hack_restrict(RESTRICT_REMOVEIF, &ep->sin, &resmask,
1138: RESM_NTPONLY | RESM_INTERFACE, RES_IGNORE);
1139: }
1140:
1141:
1142: static void
1143: log_listen_address(
1144: endpt * ep
1145: )
1146: {
1147: msyslog(LOG_INFO, "%s on %d %s %s UDP %d",
1148: (ep->ignore_packets)
1149: ? "Listen and drop"
1150: : "Listen normally",
1151: ep->ifnum,
1152: ep->name,
1153: stoa(&ep->sin),
1154: SRCPORT(&ep->sin));
1155: }
1156:
1157:
1158: static void
1159: create_wildcards(
1160: u_short port
1161: )
1162: {
1163: int v4wild, v6wild;
1164: sockaddr_u wildaddr;
1165: nic_rule_action action;
1166: struct interface * wildif;
1167:
1168: /*
1169: * silence "potentially uninitialized" warnings from VC9
1170: * failing to follow the logic. Ideally action could remain
1171: * uninitialized, and the memset be the first statement under
1172: * the first if (v4wild).
1173: */
1174: action = ACTION_LISTEN;
1175: memset(&wildaddr, 0, sizeof(wildaddr));
1176:
1177: /*
1178: * create pseudo-interface with wildcard IPv4 address
1179: */
1180: v4wild = ipv4_works;
1181: if (v4wild) {
1182: /* set wildaddr to the v4 wildcard address 0.0.0.0 */
1183: AF(&wildaddr) = AF_INET;
1184: SET_ADDR4(&wildaddr, INADDR_ANY);
1185: SET_PORT(&wildaddr, port);
1186:
1187: /* check for interface/nic rules affecting the wildcard */
1188: action = interface_action(NULL, &wildaddr, 0);
1189: v4wild = (ACTION_IGNORE != action);
1190: }
1191: if (v4wild) {
1192: wildif = new_interface(NULL);
1193:
1194: strncpy(wildif->name, "v4wildcard", sizeof(wildif->name));
1195: memcpy(&wildif->sin, &wildaddr, sizeof(wildif->sin));
1196: wildif->family = AF_INET;
1197: AF(&wildif->mask) = AF_INET;
1198: SET_ONESMASK(&wildif->mask);
1199:
1200: wildif->flags = INT_BROADCAST | INT_UP | INT_WILDCARD;
1201: wildif->ignore_packets = (ACTION_DROP == action);
1202: #if defined(MCAST)
1203: /*
1204: * enable multicast reception on the broadcast socket
1205: */
1206: AF(&wildif->bcast) = AF_INET;
1207: SET_ADDR4(&wildif->bcast, INADDR_ANY);
1208: SET_PORT(&wildif->bcast, port);
1209: #endif /* MCAST */
1210: wildif->fd = open_socket(&wildif->sin, 0, 1, wildif);
1211:
1212: if (wildif->fd != INVALID_SOCKET) {
1213: wildipv4 = wildif;
1214: any_interface = wildif;
1215:
1216: add_addr_to_list(&wildif->sin, wildif);
1217: add_interface(wildif);
1218: log_listen_address(wildif);
1219: } else {
1220: msyslog(LOG_ERR,
1221: "unable to bind to wildcard address %s - another process may be running - EXITING",
1222: stoa(&wildif->sin));
1223: exit(1);
1224: }
1225: DPRINT_INTERFACE(2, (wildif, "created ", "\n"));
1226: }
1227:
1228: #ifdef INCLUDE_IPV6_SUPPORT
1229: /*
1230: * create pseudo-interface with wildcard IPv6 address
1231: */
1232: v6wild = ipv6_works;
1233: if (v6wild) {
1234: /* set wildaddr to the v6 wildcard address :: */
1235: memset(&wildaddr, 0, sizeof(wildaddr));
1236: AF(&wildaddr) = AF_INET6;
1237: SET_ADDR6N(&wildaddr, in6addr_any);
1238: SET_PORT(&wildaddr, port);
1239: SET_SCOPE(&wildaddr, 0);
1240:
1241: /* check for interface/nic rules affecting the wildcard */
1242: action = interface_action(NULL, &wildaddr, 0);
1243: v6wild = (ACTION_IGNORE != action);
1244: }
1245: if (v6wild) {
1246: wildif = new_interface(NULL);
1247:
1248: strncpy(wildif->name, "v6wildcard", sizeof(wildif->name));
1249: memcpy(&wildif->sin, &wildaddr, sizeof(wildif->sin));
1250: wildif->family = AF_INET6;
1251: AF(&wildif->mask) = AF_INET6;
1252: SET_ONESMASK(&wildif->mask);
1253:
1254: wildif->flags = INT_UP | INT_WILDCARD;
1255: wildif->ignore_packets = (ACTION_DROP == action);
1256:
1257: wildif->fd = open_socket(&wildif->sin, 0, 1, wildif);
1258:
1259: if (wildif->fd != INVALID_SOCKET) {
1260: wildipv6 = wildif;
1261: any6_interface = wildif;
1262: add_addr_to_list(&wildif->sin, wildif);
1263: add_interface(wildif);
1264: log_listen_address(wildif);
1265: } else {
1266: msyslog(LOG_ERR,
1267: "unable to bind to wildcard address %s - another process may be running - EXITING",
1268: stoa(&wildif->sin));
1269: exit(1);
1270: }
1271: DPRINT_INTERFACE(2, (wildif, "created ", "\n"));
1272: }
1273: #endif
1274: }
1275:
1276:
1277: /*
1278: * add_nic_rule() -- insert a rule entry at the head of nic_rule_list.
1279: */
1280: void
1281: add_nic_rule(
1282: nic_rule_match match_type,
1283: const char * if_name, /* interface name or numeric address */
1284: int prefixlen,
1285: nic_rule_action action
1286: )
1287: {
1288: nic_rule * rule;
1289: isc_boolean_t is_ip;
1290:
1291: rule = emalloc(sizeof(*rule));
1292: memset(rule, 0, sizeof(*rule));
1293: rule->match_type = match_type;
1294: rule->prefixlen = prefixlen;
1295: rule->action = action;
1296:
1297: if (MATCH_IFNAME == match_type) {
1298: NTP_REQUIRE(NULL != if_name);
1299: rule->if_name = estrdup(if_name);
1300: } else if (MATCH_IFADDR == match_type) {
1301: NTP_REQUIRE(NULL != if_name);
1302: /* set rule->addr */
1303: is_ip = is_ip_address(if_name, &rule->addr);
1304: NTP_REQUIRE(is_ip);
1305: } else
1306: NTP_REQUIRE(NULL == if_name);
1307:
1308: LINK_SLIST(nic_rule_list, rule, next);
1309: }
1310:
1311:
1312: #ifdef DEBUG
1313: static const char *
1314: action_text(
1315: nic_rule_action action
1316: )
1317: {
1318: const char *t;
1319:
1320: switch (action) {
1321:
1322: default:
1323: t = "ERROR"; /* quiet uninit warning */
1324: DPRINTF(1, ("fatal: unknown nic_rule_action %d\n",
1325: action));
1326: NTP_ENSURE(0);
1327: break;
1328:
1329: case ACTION_LISTEN:
1330: t = "listen";
1331: break;
1332:
1333: case ACTION_IGNORE:
1334: t = "ignore";
1335: break;
1336:
1337: case ACTION_DROP:
1338: t = "drop";
1339: break;
1340: }
1341:
1342: return t;
1343: }
1344: #endif /* DEBUG */
1345:
1346:
1347: static nic_rule_action
1348: interface_action(
1349: char * if_name,
1350: sockaddr_u * if_addr,
1351: u_int32 if_flags
1352: )
1353: {
1354: nic_rule * rule;
1355: int isloopback;
1356: int iswildcard;
1357:
1358: DPRINTF(4, ("interface_action: %s %s ",
1359: (if_name != NULL)
1360: ? if_name
1361: : "wildcard",
1362: stoa(if_addr)));
1363:
1364: iswildcard = is_wildcard_addr(if_addr);
1365:
1366: /*
1367: * Always listen on 127.0.0.1 - required by ntp_intres
1368: */
1369: if (INT_LOOPBACK & if_flags) {
1370: isloopback = TRUE;
1371: if (IS_IPV4(if_addr)) {
1372: DPRINTF(4, ("IPv4 loopback - listen\n"));
1373: return ACTION_LISTEN;
1374: }
1375: } else {
1376: isloopback = FALSE;
1377: }
1378:
1379: /*
1380: * Find any matching NIC rule from --interface / -I or ntp.conf
1381: * interface/nic rules.
1382: */
1383: for (rule = nic_rule_list; rule != NULL; rule = rule->next) {
1384:
1385: switch (rule->match_type) {
1386:
1387: case MATCH_ALL:
1388: /* loopback and wildcard excluded from "all" */
1389: if (isloopback || iswildcard)
1390: break;
1391: DPRINTF(4, ("nic all %s\n",
1392: action_text(rule->action)));
1393: return rule->action;
1394:
1395: case MATCH_IPV4:
1396: if (IS_IPV4(if_addr)) {
1397: DPRINTF(4, ("nic ipv4 %s\n",
1398: action_text(rule->action)));
1399: return rule->action;
1400: }
1401: break;
1402:
1403: case MATCH_IPV6:
1404: if (IS_IPV6(if_addr)) {
1405: DPRINTF(4, ("nic ipv6 %s\n",
1406: action_text(rule->action)));
1407: return rule->action;
1408: }
1409: break;
1410:
1411: case MATCH_WILDCARD:
1412: if (iswildcard) {
1413: DPRINTF(4, ("nic wildcard %s\n",
1414: action_text(rule->action)));
1415: return rule->action;
1416: }
1417: break;
1418:
1419: case MATCH_IFADDR:
1420: if (rule->prefixlen != -1) {
1421: if (addr_eqprefix(if_addr, &rule->addr,
1422: rule->prefixlen)) {
1423:
1424: DPRINTF(4, ("subnet address match - %s\n",
1425: action_text(rule->action)));
1426: return rule->action;
1427: }
1428: } else
1429: if (SOCK_EQ(if_addr, &rule->addr)) {
1430:
1431: DPRINTF(4, ("address match - %s\n",
1432: action_text(rule->action)));
1433: return rule->action;
1434: }
1435: break;
1436:
1437: case MATCH_IFNAME:
1438: if (if_name != NULL
1439: && !strcasecmp(if_name, rule->if_name)) {
1440:
1441: DPRINTF(4, ("interface name match - %s\n",
1442: action_text(rule->action)));
1443: return rule->action;
1444: }
1445: break;
1446: }
1447: }
1448:
1449: /*
1450: * Unless explicitly disabled such as with "nic ignore ::1"
1451: * listen on loopback addresses. Since ntpq and ntpdc query
1452: * "localhost" by default, which typically resolves to ::1 and
1453: * 127.0.0.1, it's useful to default to listening on both.
1454: */
1455: if (isloopback) {
1456: DPRINTF(4, ("default loopback listen\n"));
1457: return ACTION_LISTEN;
1458: }
1459:
1460: /*
1461: * Treat wildcard addresses specially. If there is no explicit
1462: * "nic ... wildcard" or "nic ... 0.0.0.0" or "nic ... ::" rule
1463: * default to drop.
1464: */
1465: if (iswildcard) {
1466: DPRINTF(4, ("default wildcard drop\n"));
1467: return ACTION_DROP;
1468: }
1469:
1470: /*
1471: * Check for "virtual IP" (colon in the interface name) after
1472: * the rules so that "ntpd --interface eth0:1 -novirtualips"
1473: * does indeed listen on eth0:1's addresses.
1474: */
1475: if (!listen_to_virtual_ips && if_name != NULL
1476: && (strchr(if_name, ':') != NULL)) {
1477:
1478: DPRINTF(4, ("virtual ip - ignore\n"));
1479: return ACTION_IGNORE;
1480: }
1481:
1482: /*
1483: * If there are no --interface/-I command-line options and no
1484: * interface/nic rules in ntp.conf, the default action is to
1485: * listen. In the presence of rules from either, the default
1486: * is to ignore. This implements ntpd's traditional listen-
1487: * every default with no interface listen configuration, and
1488: * ensures a single -I eth0 or "nic listen eth0" means do not
1489: * listen on any other addresses.
1490: */
1491: if (NULL == nic_rule_list) {
1492: DPRINTF(4, ("default listen\n"));
1493: return ACTION_LISTEN;
1494: }
1495:
1496: DPRINTF(4, ("implicit ignore\n"));
1497: return ACTION_IGNORE;
1498: }
1499:
1500:
1501: static void
1502: convert_isc_if(
1503: isc_interface_t *isc_if,
1504: endpt *itf,
1505: u_short port
1506: )
1507: {
1508: const u_char v6loop[16] = {0, 0, 0, 0, 0, 0, 0, 0,
1509: 0, 0, 0, 0, 0, 0, 0, 1};
1510:
1511: strncpy(itf->name, isc_if->name, sizeof(itf->name));
1512: itf->name[sizeof(itf->name) - 1] = 0; /* strncpy may not */
1513: itf->ifindex = isc_if->ifindex;
1514: itf->family = (u_short)isc_if->af;
1515: AF(&itf->sin) = itf->family;
1516: AF(&itf->mask) = itf->family;
1517: AF(&itf->bcast) = itf->family;
1518: SET_PORT(&itf->sin, port);
1519: SET_PORT(&itf->mask, port);
1520: SET_PORT(&itf->bcast, port);
1521:
1522: if (IS_IPV4(&itf->sin)) {
1523: NSRCADR(&itf->sin) = isc_if->address.type.in.s_addr;
1524: NSRCADR(&itf->mask) = isc_if->netmask.type.in.s_addr;
1525:
1526: if (isc_if->flags & INTERFACE_F_BROADCAST) {
1527: itf->flags |= INT_BROADCAST;
1528: NSRCADR(&itf->bcast) =
1529: isc_if->broadcast.type.in.s_addr;
1530: }
1531: }
1532: #ifdef INCLUDE_IPV6_SUPPORT
1533: else if (IS_IPV6(&itf->sin)) {
1534: SET_ADDR6N(&itf->sin, isc_if->address.type.in6);
1535: SET_ADDR6N(&itf->mask, isc_if->netmask.type.in6);
1536:
1537: SET_SCOPE(&itf->sin, isc_if->address.zone);
1538: }
1539: #endif /* INCLUDE_IPV6_SUPPORT */
1540:
1541:
1542: /* Process the rest of the flags */
1543:
1544: itf->flags |=
1545: ((INTERFACE_F_UP & isc_if->flags)
1546: ? INT_UP : 0)
1547: | ((INTERFACE_F_LOOPBACK & isc_if->flags)
1548: ? INT_LOOPBACK : 0)
1549: | ((INTERFACE_F_POINTTOPOINT & isc_if->flags)
1550: ? INT_PPP : 0)
1551: | ((INTERFACE_F_MULTICAST & isc_if->flags)
1552: ? INT_MULTICAST : 0)
1553: | ((INTERFACE_F_PRIVACY & isc_if->flags)
1554: ? INT_PRIVACY : 0)
1555: ;
1556:
1557: /*
1558: * Clear the loopback flag if the address is not localhost.
1559: * http://bugs.ntp.org/1683
1560: */
1561: if (INT_LOOPBACK & itf->flags) {
1562: if (AF_INET == itf->family) {
1563: if (127 != (SRCADR(&itf->sin) >> 24))
1564: itf->flags &= ~INT_LOOPBACK;
1565: } else {
1566: if (memcmp(v6loop, NSRCADR6(&itf->sin),
1567: sizeof(NSRCADR6(&itf->sin))))
1568: itf->flags &= ~INT_LOOPBACK;
1569: }
1570: }
1571: }
1572:
1573:
1574: /*
1575: * refresh_interface
1576: *
1577: * some OSes have been observed to keep
1578: * cached routes even when more specific routes
1579: * become available.
1580: * this can be mitigated by re-binding
1581: * the socket.
1582: */
1583: static int
1584: refresh_interface(
1585: struct interface * interface
1586: )
1587: {
1588: #ifdef OS_MISSES_SPECIFIC_ROUTE_UPDATES
1589: if (interface->fd != INVALID_SOCKET) {
1590: close_and_delete_fd_from_list(interface->fd);
1591: interface->fd = open_socket(&interface->sin,
1592: 0, 0, interface);
1593: /*
1594: * reset TTL indication so TTL is is set again
1595: * next time around
1596: */
1597: interface->last_ttl = 0;
1598: return (interface->fd != INVALID_SOCKET);
1599: } else
1600: return 0; /* invalid sockets are not refreshable */
1601: #else /* !OS_MISSES_SPECIFIC_ROUTE_UPDATES */
1602: return (interface->fd != INVALID_SOCKET);
1603: #endif /* !OS_MISSES_SPECIFIC_ROUTE_UPDATES */
1604: }
1605:
1606: /*
1607: * interface_update - externally callable update function
1608: */
1609: void
1610: interface_update(
1611: interface_receiver_t receiver,
1612: void * data)
1613: {
1614: int new_interface_found;
1615:
1616: if (disable_dynamic_updates)
1617: return;
1618:
1619: BLOCKIO();
1620: new_interface_found = update_interfaces(NTP_PORT, receiver, data);
1621: UNBLOCKIO();
1622:
1623: if (!new_interface_found)
1624: return;
1625:
1626: #ifdef DEBUG
1627: msyslog(LOG_DEBUG, "new interface(s) found: waking up resolver");
1628: #endif
1629: #ifdef SYS_WINNT
1630: /* wake up the resolver thread */
1631: if (ResolverEventHandle != NULL)
1632: SetEvent(ResolverEventHandle);
1633: #else
1634: /* write any single byte to the pipe to wake up the resolver process */
1635: write( resolver_pipe_fd[1], &new_interface_found, 1 );
1636: #endif
1637: }
1638:
1639:
1640: /*
1641: * sau_from_netaddr() - convert network address on-wire formats.
1642: * Convert from libisc's isc_netaddr_t to NTP's sockaddr_u
1643: */
1644: void
1645: sau_from_netaddr(
1646: sockaddr_u *psau,
1647: const isc_netaddr_t *pna
1648: )
1649: {
1650: memset(psau, 0, sizeof(*psau));
1651: AF(psau) = (u_short)pna->family;
1652: switch (pna->family) {
1653:
1654: case AF_INET:
1655: memcpy(&psau->sa4.sin_addr, &pna->type.in,
1656: sizeof(psau->sa4.sin_addr));
1657: break;
1658:
1659: case AF_INET6:
1660: memcpy(&psau->sa6.sin6_addr, &pna->type.in6,
1661: sizeof(psau->sa6.sin6_addr));
1662: break;
1663: }
1664: }
1665:
1666:
1667: static int
1668: is_wildcard_addr(
1669: const sockaddr_u *psau
1670: )
1671: {
1672: if (IS_IPV4(psau) && !NSRCADR(psau))
1673: return 1;
1674:
1675: #ifdef INCLUDE_IPV6_SUPPORT
1676: if (IS_IPV6(psau) && S_ADDR6_EQ(psau, &in6addr_any))
1677: return 1;
1678: #endif
1679:
1680: return 0;
1681: }
1682:
1683:
1684: #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
1685: /*
1686: * enable/disable re-use of wildcard address socket
1687: */
1688: static void
1689: set_wildcard_reuse(
1690: u_short family,
1691: int on
1692: )
1693: {
1694: struct interface *any;
1695: SOCKET fd = INVALID_SOCKET;
1696:
1697: any = ANY_INTERFACE_BYFAM(family);
1698: if (any != NULL)
1699: fd = any->fd;
1700:
1701: if (fd != INVALID_SOCKET) {
1702: if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1703: (char *)&on, sizeof(on)))
1704: msyslog(LOG_ERR,
1705: "set_wildcard_reuse: setsockopt(SO_REUSEADDR, %s) failed: %m",
1706: on ? "on" : "off");
1707:
1708: DPRINTF(4, ("set SO_REUSEADDR to %s on %s\n",
1709: on ? "on" : "off",
1710: stoa(&any->sin)));
1711: }
1712: }
1713: #endif /* OS_NEEDS_REUSEADDR_FOR_IFADDRBIND */
1714:
1715:
1716: static isc_boolean_t
1717: is_anycast(
1718: sockaddr_u *psau,
1719: const char *name
1720: )
1721: {
1722: #if defined(INCLUDE_IPV6_SUPPORT) && defined(SIOCGIFAFLAG_IN6) && \
1723: defined(IN6_IFF_ANYCAST)
1724: struct in6_ifreq ifr6;
1725: int fd;
1726: u_int32 flags6;
1727:
1728: if (psau->sa.sa_family != AF_INET6)
1729: return ISC_FALSE;
1730: if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
1731: return ISC_FALSE;
1732: memset(&ifr6, 0, sizeof(ifr6));
1733: memcpy(&ifr6.ifr_addr, &psau->sa6, sizeof(ifr6.ifr_addr));
1734: strncpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name));
1735: if (ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
1736: close(fd);
1737: return ISC_FALSE;
1738: }
1739: close(fd);
1740: flags6 = ifr6.ifr_ifru.ifru_flags6;
1741: if ((flags6 & IN6_IFF_ANYCAST) != 0)
1742: return ISC_TRUE;
1743: #endif /* INCLUDE_IPV6_SUPPORT && SIOCGIFAFLAG_IN6 && IN6_IFF_ANYCAST */
1744: return ISC_FALSE;
1745: }
1746:
1747:
1748: /*
1749: * update_interface strategy
1750: *
1751: * toggle configuration phase
1752: *
1753: * Phase 1:
1754: * forall currently existing interfaces
1755: * if address is known:
1756: * drop socket - rebind again
1757: *
1758: * if address is NOT known:
1759: * attempt to create a new interface entry
1760: *
1761: * Phase 2:
1762: * forall currently known non MCAST and WILDCARD interfaces
1763: * if interface does not match configuration phase (not seen in phase 1):
1764: * remove interface from known interface list
1765: * forall peers associated with this interface
1766: * disconnect peer from this interface
1767: *
1768: * Phase 3:
1769: * attempt to re-assign interfaces to peers
1770: *
1771: */
1772:
1773: static int
1774: update_interfaces(
1775: u_short port,
1776: interface_receiver_t receiver,
1777: void * data
1778: )
1779: {
1780: isc_mem_t * mctx = (void *)-1;
1781: interface_info_t ifi;
1782: isc_interfaceiter_t * iter;
1783: isc_result_t result;
1784: isc_interface_t isc_if;
1785: int new_interface_found;
1786: int refresh_peers;
1787: unsigned int family;
1788: endpt enumep;
1789: endpt * ep;
1790: endpt * next_ep;
1791:
1792: DPRINTF(3, ("update_interfaces(%d)\n", port));
1793:
1794: /*
1795: * phase one - scan interfaces
1796: * - create those that are not found
1797: * - update those that are found
1798: */
1799:
1800: new_interface_found = FALSE;
1801: refresh_peers = FALSE;
1802: iter = NULL;
1803: result = isc_interfaceiter_create(mctx, &iter);
1804:
1805: if (result != ISC_R_SUCCESS)
1806: return 0;
1807:
1808: /*
1809: * Toggle system interface scan phase to find untouched
1810: * interfaces to be deleted.
1811: */
1812: sys_interphase ^= 0x1;
1813:
1814: for (result = isc_interfaceiter_first(iter);
1815: ISC_R_SUCCESS == result;
1816: result = isc_interfaceiter_next(iter)) {
1817:
1818: result = isc_interfaceiter_current(iter, &isc_if);
1819:
1820: if (result != ISC_R_SUCCESS)
1821: break;
1822:
1823: /* See if we have a valid family to use */
1824: family = isc_if.address.family;
1825: if (AF_INET != family && AF_INET6 != family)
1826: continue;
1827: if (AF_INET == family && !ipv4_works)
1828: continue;
1829: if (AF_INET6 == family && !ipv6_works)
1830: continue;
1831:
1832: /* create prototype */
1833: init_interface(&enumep);
1834:
1835: convert_isc_if(&isc_if, &enumep, port);
1836:
1837: /*
1838: * Check if and how we are going to use the interface.
1839: */
1840: switch (interface_action(enumep.name, &enumep.sin,
1841: enumep.flags)) {
1842:
1843: case ACTION_IGNORE:
1844: continue;
1845:
1846: case ACTION_LISTEN:
1847: enumep.ignore_packets = ISC_FALSE;
1848: break;
1849:
1850: case ACTION_DROP:
1851: enumep.ignore_packets = ISC_TRUE;
1852: break;
1853: }
1854:
1855: DPRINT_INTERFACE(4, (&enumep, "examining ", "\n"));
1856:
1857: /* interfaces must be UP to be usable */
1858: if (!(enumep.flags & INT_UP)) {
1859: DPRINTF(4, ("skipping interface %s (%s) - DOWN\n",
1860: enumep.name, stoa(&enumep.sin)));
1861: continue;
1862: }
1863:
1864: /*
1865: * skip any interfaces UP and bound to a wildcard
1866: * address - some dhcp clients produce that in the
1867: * wild
1868: */
1869: if (is_wildcard_addr(&enumep.sin))
1870: continue;
1871:
1872: if (is_anycast(&enumep.sin, isc_if.name))
1873: continue;
1874:
1875: /*
1876: * map to local *address* in order to map all duplicate
1877: * interfaces to an endpt structure with the appropriate
1878: * socket. Our name space is (ip-address), NOT
1879: * (interface name, ip-address).
1880: */
1881: ep = getinterface(&enumep.sin, INT_WILDCARD);
1882:
1883: if (ep != NULL && refresh_interface(ep)) {
1884: /*
1885: * found existing and up to date interface -
1886: * mark present.
1887: */
1888: if (ep->phase != sys_interphase) {
1889: /*
1890: * On a new round we reset the name so
1891: * the interface name shows up again if
1892: * this address is no longer shared.
1893: * We reset ignore_packets from the
1894: * new prototype to respect any runtime
1895: * changes to the nic rules.
1896: */
1897: strncpy(ep->name, enumep.name,
1898: sizeof(ep->name));
1899: if (ep->ignore_packets !=
1900: enumep.ignore_packets) {
1901: ep->ignore_packets =
1902: enumep.ignore_packets;
1903: refresh_peers = TRUE;
1904: DPRINTF(4, ("refreshing peers due to %s ignore_packets change to %d\n",
1905: stoa(&ep->sin),
1906: ep->ignore_packets));
1907: }
1908: } else {
1909: /* name collision - rename interface */
1910: strncpy(ep->name, "*multiple*",
1911: sizeof(ep->name));
1912: }
1913:
1914: DPRINT_INTERFACE(4, (ep, "updating ",
1915: " present\n"));
1916:
1917: if (ep->ignore_packets !=
1918: enumep.ignore_packets) {
1919: /*
1920: * We have conflicting configurations
1921: * for the interface address. This is
1922: * caused by using -I <interfacename>
1923: * for an interface that shares its
1924: * address with other interfaces. We
1925: * can not disambiguate incoming
1926: * packets delivered to this socket
1927: * without extra syscalls/features.
1928: * These are not (commonly) available.
1929: * Note this is a more unusual
1930: * configuration where several
1931: * interfaces share an address but
1932: * filtering via interface name is
1933: * attempted. We resolve the
1934: * configuration conflict by disabling
1935: * the processing of received packets.
1936: * This leads to no service on the
1937: * interface address where the conflict
1938: * occurs.
1939: */
1940: msyslog(LOG_ERR,
1941: "WARNING: conflicting enable configuration for interfaces %s and %s for address %s - unsupported configuration - address DISABLED",
1942: enumep.name, ep->name,
1943: stoa(&enumep.sin));
1944:
1945: ep->ignore_packets = ISC_TRUE;
1946: }
1947:
1948: ep->phase = sys_interphase;
1949:
1950: ifi.action = IFS_EXISTS;
1951: ifi.ep = ep;
1952: if (receiver != NULL)
1953: (*receiver)(data, &ifi);
1954: } else {
1955: /*
1956: * This is new or refreshing failed - add to
1957: * our interface list. If refreshing failed we
1958: * will delete the interface structure in phase
1959: * 2 as the interface was not marked current.
1960: * We can bind to the address as the refresh
1961: * code already closed the offending socket
1962: */
1963: ep = create_interface(port, &enumep);
1964:
1965: if (ep != NULL) {
1966: ifi.action = IFS_CREATED;
1967: ifi.ep = ep;
1968: if (receiver != NULL)
1969: (*receiver)(data, &ifi);
1970:
1971: new_interface_found = TRUE;
1972: refresh_peers = TRUE;
1973: DPRINTF(4, ("refreshing peers due to new addr %s\n",
1974: stoa(&ep->sin)));
1975: DPRINT_INTERFACE(3,
1976: (ep, "updating ",
1977: " new - created\n"));
1978: } else {
1979: DPRINT_INTERFACE(3,
1980: (&enumep, "updating ",
1981: " new - creation FAILED"));
1982:
1983: msyslog(LOG_INFO,
1984: "failed to init interface for address %s",
1985: stoa(&enumep.sin));
1986: continue;
1987: }
1988: }
1989: }
1990:
1991: isc_interfaceiter_destroy(&iter);
1992:
1993: /*
1994: * phase 2 - delete gone interfaces - reassigning peers to
1995: * other interfaces
1996: */
1997: for (ep = ep_list; ep != NULL; ep = next_ep) {
1998: next_ep = ep->elink;
1999:
2000: /*
2001: * if phase does not match sys_phase this interface was
2002: * not enumerated during the last interface scan - so it
2003: * is gone and will be deleted here unless it did not
2004: * originate from interface enumeration (INT_WILDCARD,
2005: * INT_MCASTIF).
2006: */
2007: if (((INT_WILDCARD | INT_MCASTIF) & ep->flags) ||
2008: ep->phase == sys_interphase)
2009: continue;
2010:
2011: DPRINT_INTERFACE(3, (ep, "updating ",
2012: "GONE - deleting\n"));
2013: remove_interface(ep);
2014: refresh_peers = TRUE;
2015: DPRINTF(4, ("refreshing peers due to deleted addr %s",
2016: stoa(&ep->sin)));
2017:
2018: ifi.action = IFS_DELETED;
2019: ifi.ep = ep;
2020: if (receiver != NULL)
2021: (*receiver)(data, &ifi);
2022:
2023: /* disconnect peers from deleted endpt. */
2024: while (ep->peers != NULL)
2025: set_peerdstadr(ep->peers, NULL);
2026:
2027: /*
2028: * update globals in case we lose
2029: * a loopback interface
2030: */
2031: if (ep == loopback_interface)
2032: loopback_interface = NULL;
2033:
2034: delete_interface(ep);
2035: }
2036:
2037: /*
2038: * phase 3 - re-configure as the world has changed if necessary
2039: */
2040: if (refresh_peers) {
2041: refresh_all_peerinterfaces();
2042: msyslog(LOG_INFO, "peers refreshed");
2043: }
2044:
2045: return new_interface_found;
2046: }
2047:
2048:
2049: /*
2050: * create_sockets - create a socket for each interface plus a default
2051: * socket for when we don't know where to send
2052: */
2053: static int
2054: create_sockets(
2055: u_short port
2056: )
2057: {
2058: #ifndef HAVE_IO_COMPLETION_PORT
2059: /*
2060: * I/O Completion Ports don't care about the select and FD_SET
2061: */
2062: maxactivefd = 0;
2063: FD_ZERO(&activefds);
2064: #endif
2065:
2066: DPRINTF(2, ("create_sockets(%d)\n", port));
2067:
2068: create_wildcards(port);
2069:
2070: update_interfaces(port, NULL, NULL);
2071:
2072: /*
2073: * Now that we have opened all the sockets, turn off the reuse
2074: * flag for security.
2075: */
2076: set_reuseaddr(0);
2077:
2078: DPRINTF(2, ("create_sockets: Total interfaces = %d\n", ninterfaces));
2079:
2080: return ninterfaces;
2081: }
2082:
2083: /*
2084: * create_interface - create a new interface for a given prototype
2085: * binding the socket.
2086: */
2087: static struct interface *
2088: create_interface(
2089: u_short port,
2090: struct interface * protot
2091: )
2092: {
2093: sockaddr_u resmask;
2094: endpt * iface;
2095: #if defined(MCAST) && defined(MULTICAST_NONEWSOCKET)
2096: remaddr_t * entry;
2097: remaddr_t * next_entry;
2098: #endif
2099: DPRINTF(2, ("create_interface(%s#%d)\n", stoa(&protot->sin),
2100: port));
2101:
2102: /* build an interface */
2103: iface = new_interface(protot);
2104:
2105: /*
2106: * create socket
2107: */
2108: iface->fd = open_socket(&iface->sin, 0, 0, iface);
2109:
2110: if (iface->fd != INVALID_SOCKET)
2111: log_listen_address(iface);
2112:
2113: if ((INT_BROADCAST & iface->flags)
2114: && iface->bfd != INVALID_SOCKET)
2115: msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
2116: stoa((&iface->bcast)), port);
2117:
2118: if (INVALID_SOCKET == iface->fd
2119: && INVALID_SOCKET == iface->bfd) {
2120: msyslog(LOG_ERR, "unable to create socket on %s (%d) for %s#%d",
2121: iface->name,
2122: iface->ifnum,
2123: stoa((&iface->sin)),
2124: port);
2125: delete_interface(iface);
2126: return NULL;
2127: }
2128:
2129: /*
2130: * Blacklist our own addresses, no use talking to ourself
2131: */
2132: SET_HOSTMASK(&resmask, AF(&iface->sin));
2133: hack_restrict(RESTRICT_FLAGS, &iface->sin, &resmask,
2134: RESM_NTPONLY | RESM_INTERFACE, RES_IGNORE);
2135:
2136: /*
2137: * set globals with the first found
2138: * loopback interface of the appropriate class
2139: */
2140: if (NULL == loopback_interface && AF_INET == iface->family
2141: && (INT_LOOPBACK & iface->flags))
2142: loopback_interface = iface;
2143:
2144: /*
2145: * put into our interface list
2146: */
2147: add_addr_to_list(&iface->sin, iface);
2148: add_interface(iface);
2149:
2150: #if defined(MCAST) && defined(MULTICAST_NONEWSOCKET)
2151: /*
2152: * Join any previously-configured compatible multicast groups.
2153: */
2154: if (INT_MULTICAST & iface->flags &&
2155: !((INT_LOOPBACK | INT_WILDCARD) & iface->flags) &&
2156: !iface->ignore_packets) {
2157: for (entry = remoteaddr_list;
2158: entry != NULL;
2159: entry = next_entry) {
2160: next_entry = entry->link;
2161: if (AF(&iface->sin) != AF(&entry->addr) ||
2162: !IS_MCAST(&entry->addr))
2163: continue;
2164: if (socket_multicast_enable(iface,
2165: &entry->addr))
2166: msyslog(LOG_INFO,
2167: "Joined %s socket to multicast group %s",
2168: stoa(&iface->sin),
2169: stoa(&entry->addr));
2170: else
2171: msyslog(LOG_ERR,
2172: "Failed to join %s socket to multicast group %s",
2173: stoa(&iface->sin),
2174: stoa(&entry->addr));
2175: }
2176: }
2177: #endif /* MCAST && MCAST_NONEWSOCKET */
2178:
2179: DPRINT_INTERFACE(2, (iface, "created ", "\n"));
2180: return iface;
2181: }
2182:
2183:
2184: #ifdef SO_EXCLUSIVEADDRUSE
2185: static void
2186: set_excladdruse(
2187: SOCKET fd
2188: )
2189: {
2190: int one = 1;
2191: int failed;
2192: #ifdef SYS_WINNT
2193: DWORD err;
2194: #endif
2195:
2196: failed = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
2197: (char *)&one, sizeof(one));
2198:
2199: if (!failed)
2200: return;
2201:
2202: #ifdef SYS_WINNT
2203: /*
2204: * Prior to Windows XP setting SO_EXCLUSIVEADDRUSE can fail with
2205: * error WSAINVAL depending on service pack level and whether
2206: * the user account is in the Administrators group. Do not
2207: * complain if it fails that way on versions prior to XP (5.1).
2208: */
2209: err = GetLastError();
2210:
2211: if (isc_win32os_versioncheck(5, 1, 0, 0) < 0 /* < 5.1/XP */
2212: && WSAEINVAL == err)
2213: return;
2214:
2215: SetLastError(err);
2216: #endif
2217: msyslog(LOG_ERR,
2218: "setsockopt(%d, SO_EXCLUSIVEADDRUSE, on): %m",
2219: (int)fd);
2220: }
2221: #endif /* SO_EXCLUSIVEADDRUSE */
2222:
2223:
2224: /*
2225: * set_reuseaddr() - set/clear REUSEADDR on all sockets
2226: * NB possible hole - should we be doing this on broadcast
2227: * fd's also?
2228: */
2229: static void
2230: set_reuseaddr(
2231: int flag
2232: )
2233: {
2234: #ifndef SO_EXCLUSIVEADDRUSE
2235: endpt *ep;
2236:
2237: for (ep = ep_list; ep != NULL; ep = ep->elink) {
2238: if (ep->flags & INT_WILDCARD)
2239: continue;
2240:
2241: /*
2242: * if ep->fd is INVALID_SOCKET, we might have a adapter
2243: * configured but not present
2244: */
2245: DPRINTF(4, ("setting SO_REUSEADDR on %.16s@%s to %s\n",
2246: ep->name, stoa(&ep->sin),
2247: flag ? "on" : "off"));
2248:
2249: if (ep->fd != INVALID_SOCKET) {
2250: if (setsockopt(ep->fd, SOL_SOCKET, SO_REUSEADDR,
2251: (char *)&flag, sizeof(flag))) {
2252: msyslog(LOG_ERR, "set_reuseaddr: setsockopt(%s, SO_REUSEADDR, %s) failed: %m",
2253: stoa(&ep->sin), flag ? "on" : "off");
2254: }
2255: }
2256: }
2257: #endif /* ! SO_EXCLUSIVEADDRUSE */
2258: }
2259:
2260: /*
2261: * This is just a wrapper around an internal function so we can
2262: * make other changes as necessary later on
2263: */
2264: void
2265: enable_broadcast(
2266: struct interface * iface,
2267: sockaddr_u * baddr
2268: )
2269: {
2270: #ifdef OPEN_BCAST_SOCKET
2271: socket_broadcast_enable(iface, iface->fd, baddr);
2272: #endif
2273: }
2274:
2275: #ifdef OPEN_BCAST_SOCKET
2276: /*
2277: * Enable a broadcast address to a given socket
2278: * The socket is in the inter_list all we need to do is enable
2279: * broadcasting. It is not this function's job to select the socket
2280: */
2281: static isc_boolean_t
2282: socket_broadcast_enable(
2283: struct interface * iface,
2284: SOCKET fd,
2285: sockaddr_u * baddr
2286: )
2287: {
2288: #ifdef SO_BROADCAST
2289: int on = 1;
2290:
2291: if (IS_IPV4(baddr)) {
2292: /* if this interface can support broadcast, set SO_BROADCAST */
2293: if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
2294: (char *)&on, sizeof(on)))
2295: msyslog(LOG_ERR,
2296: "setsockopt(SO_BROADCAST) enable failure on address %s: %m",
2297: stoa(baddr));
2298: else
2299: DPRINTF(2, ("Broadcast enabled on socket %d for address %s\n",
2300: fd, stoa(baddr)));
2301: }
2302: iface->flags |= INT_BCASTOPEN;
2303: broadcast_client_enabled = ISC_TRUE;
2304: return ISC_TRUE;
2305: #else
2306: return ISC_FALSE;
2307: #endif /* SO_BROADCAST */
2308: }
2309:
2310: /*
2311: * Remove a broadcast address from a given socket
2312: * The socket is in the inter_list all we need to do is disable
2313: * broadcasting. It is not this function's job to select the socket
2314: */
2315: static isc_boolean_t
2316: socket_broadcast_disable(
2317: struct interface * iface,
2318: sockaddr_u * baddr
2319: )
2320: {
2321: #ifdef SO_BROADCAST
2322: int off = 0; /* This seems to be OK as an int */
2323:
2324: if (IS_IPV4(baddr) && setsockopt(iface->fd, SOL_SOCKET,
2325: SO_BROADCAST, (char *)&off, sizeof(off)))
2326: msyslog(LOG_ERR,
2327: "setsockopt(SO_BROADCAST) disable failure on address %s: %m",
2328: stoa(baddr));
2329:
2330: iface->flags &= ~INT_BCASTOPEN;
2331: broadcast_client_enabled = ISC_FALSE;
2332: return ISC_TRUE;
2333: #else
2334: return ISC_FALSE;
2335: #endif /* SO_BROADCAST */
2336: }
2337:
2338: #endif /* OPEN_BCAST_SOCKET */
2339:
2340: /*
2341: * return the broadcast client flag value
2342: */
2343: isc_boolean_t
2344: get_broadcastclient_flag(void)
2345: {
2346: return (broadcast_client_enabled);
2347: }
2348: /*
2349: * Check to see if the address is a multicast address
2350: */
2351: static isc_boolean_t
2352: addr_ismulticast(
2353: sockaddr_u *maddr
2354: )
2355: {
2356: isc_boolean_t result;
2357:
2358: #ifndef INCLUDE_IPV6_MULTICAST_SUPPORT
2359: /*
2360: * If we don't have IPV6 support any IPV6 addr is not multicast
2361: */
2362: if (IS_IPV6(maddr))
2363: result = ISC_FALSE;
2364: else
2365: #endif
2366: result = IS_MCAST(maddr);
2367:
2368: if (!result)
2369: DPRINTF(4, ("address %s is not multicast\n",
2370: stoa(maddr)));
2371:
2372: return result;
2373: }
2374:
2375: /*
2376: * Multicast servers need to set the appropriate Multicast interface
2377: * socket option in order for it to know which interface to use for
2378: * send the multicast packet.
2379: */
2380: void
2381: enable_multicast_if(
2382: struct interface * iface,
2383: sockaddr_u * maddr
2384: )
2385: {
2386: #ifdef MCAST
2387: TYPEOF_IP_MULTICAST_LOOP off = 0;
2388:
2389: NTP_REQUIRE(AF(maddr) == AF(&iface->sin));
2390:
2391: switch (AF(&iface->sin)) {
2392:
2393: case AF_INET:
2394: #ifdef IP_MULTICAST_LOOP
2395: /*
2396: * Don't send back to itself, but allow failure to set
2397: */
2398: if (setsockopt(iface->fd, IPPROTO_IP,
2399: IP_MULTICAST_LOOP,
2400: SETSOCKOPT_ARG_CAST &off,
2401: sizeof(off))) {
2402:
2403: msyslog(LOG_ERR,
2404: "setsockopt IP_MULTICAST_LOOP failed: %m on socket %d, addr %s for multicast address %s",
2405: iface->fd, stoa(&iface->sin),
2406: stoa(maddr));
2407: }
2408: #endif
2409: break;
2410:
2411: case AF_INET6:
2412: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2413: #ifdef IPV6_MULTICAST_LOOP
2414: /*
2415: * Don't send back to itself, but allow failure to set
2416: */
2417: if (setsockopt(iface->fd, IPPROTO_IPV6,
2418: IPV6_MULTICAST_LOOP,
2419: (char *) &off, sizeof(off))) {
2420:
2421: msyslog(LOG_ERR,
2422: "setsockopt IP_MULTICAST_LOOP failed: %m on socket %d, addr %s for multicast address %s",
2423: iface->fd, stoa(&iface->sin),
2424: stoa(maddr));
2425: }
2426: #endif
2427: break;
2428: #else
2429: return;
2430: #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
2431: }
2432: return;
2433: #endif
2434: }
2435:
2436: /*
2437: * Add a multicast address to a given socket
2438: * The socket is in the inter_list all we need to do is enable
2439: * multicasting. It is not this function's job to select the socket
2440: */
2441: #if defined(MCAST)
2442: static isc_boolean_t
2443: socket_multicast_enable(
2444: endpt * iface,
2445: sockaddr_u * maddr
2446: )
2447: {
2448: struct ip_mreq mreq;
2449: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2450: struct ipv6_mreq mreq6;
2451: #endif
2452: switch (AF(maddr)) {
2453:
2454: case AF_INET:
2455: memset(&mreq, 0, sizeof(mreq));
2456: mreq.imr_multiaddr = SOCK_ADDR4(maddr);
2457: mreq.imr_interface.s_addr = htonl(INADDR_ANY);
2458: if (setsockopt(iface->fd,
2459: IPPROTO_IP,
2460: IP_ADD_MEMBERSHIP,
2461: (char *)&mreq,
2462: sizeof(mreq))) {
2463: msyslog(LOG_ERR,
2464: "setsockopt IP_ADD_MEMBERSHIP failed: %m on socket %d, addr %s for %x / %x (%s)",
2465: iface->fd, stoa(&iface->sin),
2466: mreq.imr_multiaddr.s_addr,
2467: mreq.imr_interface.s_addr,
2468: stoa(maddr));
2469: return ISC_FALSE;
2470: }
2471: DPRINTF(4, ("Added IPv4 multicast membership on socket %d, addr %s for %x / %x (%s)\n",
2472: iface->fd, stoa(&iface->sin),
2473: mreq.imr_multiaddr.s_addr,
2474: mreq.imr_interface.s_addr, stoa(maddr)));
2475: break;
2476:
2477: case AF_INET6:
2478: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2479: /*
2480: * Enable reception of multicast packets.
2481: * If the address is link-local we can get the
2482: * interface index from the scope id. Don't do this
2483: * for other types of multicast addresses. For now let
2484: * the kernel figure it out.
2485: */
2486: memset(&mreq6, 0, sizeof(mreq6));
2487: mreq6.ipv6mr_multiaddr = SOCK_ADDR6(maddr);
2488: mreq6.ipv6mr_interface = iface->ifindex;
2489:
2490: if (setsockopt(iface->fd, IPPROTO_IPV6,
2491: IPV6_JOIN_GROUP, (char *)&mreq6,
2492: sizeof(mreq6))) {
2493: msyslog(LOG_ERR,
2494: "setsockopt IPV6_JOIN_GROUP failed: %m on socket %d, addr %s for interface %u (%s)",
2495: iface->fd, stoa(&iface->sin),
2496: mreq6.ipv6mr_interface, stoa(maddr));
2497: return ISC_FALSE;
2498: }
2499: DPRINTF(4, ("Added IPv6 multicast group on socket %d, addr %s for interface %u (%s)\n",
2500: iface->fd, stoa(&iface->sin),
2501: mreq6.ipv6mr_interface, stoa(maddr)));
2502: #else
2503: return ISC_FALSE;
2504: #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
2505: }
2506: iface->flags |= INT_MCASTOPEN;
2507: iface->num_mcast++;
2508:
2509: return ISC_TRUE;
2510: }
2511: #endif /* MCAST */
2512:
2513:
2514: /*
2515: * Remove a multicast address from a given socket
2516: * The socket is in the inter_list all we need to do is disable
2517: * multicasting. It is not this function's job to select the socket
2518: */
2519: #ifdef MCAST
2520: static isc_boolean_t
2521: socket_multicast_disable(
2522: struct interface * iface,
2523: sockaddr_u * maddr
2524: )
2525: {
2526: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2527: struct ipv6_mreq mreq6;
2528: #endif
2529: struct ip_mreq mreq;
2530:
2531: memset(&mreq, 0, sizeof(mreq));
2532:
2533: if (find_addr_in_list(maddr) == NULL) {
2534: DPRINTF(4, ("socket_multicast_disable(%s): not found\n",
2535: stoa(maddr)));
2536: return ISC_TRUE;
2537: }
2538:
2539: switch (AF(maddr)) {
2540:
2541: case AF_INET:
2542: mreq.imr_multiaddr = SOCK_ADDR4(maddr);
2543: mreq.imr_interface = SOCK_ADDR4(&iface->sin);
2544: if (setsockopt(iface->fd, IPPROTO_IP,
2545: IP_DROP_MEMBERSHIP, (char *)&mreq,
2546: sizeof(mreq))) {
2547:
2548: msyslog(LOG_ERR,
2549: "setsockopt IP_DROP_MEMBERSHIP failed: %m on socket %d, addr %s for %x / %x (%s)",
2550: iface->fd, stoa(&iface->sin),
2551: SRCADR(maddr), SRCADR(&iface->sin),
2552: stoa(maddr));
2553: return ISC_FALSE;
2554: }
2555: break;
2556: case AF_INET6:
2557: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2558: /*
2559: * Disable reception of multicast packets
2560: * If the address is link-local we can get the
2561: * interface index from the scope id. Don't do this
2562: * for other types of multicast addresses. For now let
2563: * the kernel figure it out.
2564: */
2565: mreq6.ipv6mr_multiaddr = SOCK_ADDR6(maddr);
2566: mreq6.ipv6mr_interface = iface->ifindex;
2567:
2568: if (setsockopt(iface->fd, IPPROTO_IPV6,
2569: IPV6_LEAVE_GROUP, (char *)&mreq6,
2570: sizeof(mreq6))) {
2571:
2572: msyslog(LOG_ERR,
2573: "setsockopt IPV6_LEAVE_GROUP failure: %m on socket %d, addr %s for %d (%s)",
2574: iface->fd, stoa(&iface->sin),
2575: iface->ifindex, stoa(maddr));
2576: return ISC_FALSE;
2577: }
2578: break;
2579: #else
2580: return ISC_FALSE;
2581: #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
2582: }
2583:
2584: iface->num_mcast--;
2585: if (!iface->num_mcast)
2586: iface->flags &= ~INT_MCASTOPEN;
2587:
2588: return ISC_TRUE;
2589: }
2590: #endif /* MCAST */
2591:
2592: /*
2593: * io_setbclient - open the broadcast client sockets
2594: */
2595: void
2596: io_setbclient(void)
2597: {
2598: #ifdef OPEN_BCAST_SOCKET
2599: struct interface * interf;
2600: int nif;
2601: isc_boolean_t jstatus;
2602: SOCKET fd;
2603:
2604: nif = 0;
2605: set_reuseaddr(1);
2606:
2607: for (interf = ep_list;
2608: interf != NULL;
2609: interf = interf->elink) {
2610:
2611: if (interf->flags & (INT_WILDCARD | INT_LOOPBACK))
2612: continue;
2613:
2614: /* use only allowed addresses */
2615: if (interf->ignore_packets)
2616: continue;
2617:
2618:
2619: /* Need a broadcast-capable interface */
2620: if (!(interf->flags & INT_BROADCAST))
2621: continue;
2622:
2623: /* Only IPv4 addresses are valid for broadcast */
2624: NTP_REQUIRE(IS_IPV4(&interf->sin));
2625:
2626: /* Do we already have the broadcast address open? */
2627: if (interf->flags & INT_BCASTOPEN) {
2628: /*
2629: * account for already open interfaces to avoid
2630: * misleading warning below
2631: */
2632: nif++;
2633: continue;
2634: }
2635:
2636: /*
2637: * Try to open the broadcast address
2638: */
2639: interf->family = AF_INET;
2640: interf->bfd = open_socket(&interf->bcast, 1, 0, interf);
2641:
2642: /*
2643: * If we succeeded then we use it otherwise enable
2644: * broadcast on the interface address
2645: */
2646: if (interf->bfd != INVALID_SOCKET) {
2647: fd = interf->bfd;
2648: jstatus = ISC_TRUE;
2649: } else {
2650: fd = interf->fd;
2651: jstatus = socket_broadcast_enable(interf, fd,
2652: &interf->sin);
2653: }
2654:
2655: /* Enable Broadcast on socket */
2656: if (jstatus) {
2657: nif++;
2658: msyslog(LOG_INFO,
2659: "io_setbclient: Opened broadcast client on interface #%d %s",
2660: interf->ifnum, interf->name);
2661: interf->addr_refid = addr2refid(&interf->sin);
2662: }
2663: }
2664: set_reuseaddr(0);
2665: if (nif > 0)
2666: DPRINTF(1, ("io_setbclient: Opened broadcast clients\n"));
2667: else if (!nif)
2668: msyslog(LOG_ERR,
2669: "Unable to listen for broadcasts, no broadcast interfaces available");
2670: #else
2671: msyslog(LOG_ERR,
2672: "io_setbclient: Broadcast Client disabled by build");
2673: #endif /* OPEN_BCAST_SOCKET */
2674: }
2675:
2676: /*
2677: * io_unsetbclient - close the broadcast client sockets
2678: */
2679: void
2680: io_unsetbclient(void)
2681: {
2682: endpt *ep;
2683:
2684: for (ep = ep_list; ep != NULL; ep = ep->elink) {
2685: if (INT_WILDCARD & ep->flags)
2686: continue;
2687: if (!(INT_BCASTOPEN & ep->flags))
2688: continue;
2689: socket_broadcast_disable(ep, &ep->sin);
2690: }
2691: }
2692:
2693: /*
2694: * io_multicast_add() - add multicast group address
2695: */
2696: void
2697: io_multicast_add(
2698: sockaddr_u *addr
2699: )
2700: {
2701: #ifdef MCAST
2702: endpt * ep;
2703: endpt * one_ep;
2704:
2705: /*
2706: * Check to see if this is a multicast address
2707: */
2708: if (!addr_ismulticast(addr))
2709: return;
2710:
2711: /* If we already have it we can just return */
2712: if (NULL != find_flagged_addr_in_list(addr, INT_MCASTOPEN)) {
2713: msyslog(LOG_INFO,
2714: "Duplicate request found for multicast address %s",
2715: stoa(addr));
2716: return;
2717: }
2718:
2719: #ifndef MULTICAST_NONEWSOCKET
2720: ep = new_interface(NULL);
2721:
2722: /*
2723: * Open a new socket for the multicast address
2724: */
2725: ep->sin = *addr;
2726: SET_PORT(&ep->sin, NTP_PORT);
2727: ep->family = AF(&ep->sin);
2728: AF(&ep->mask) = ep->family;
2729: SET_ONESMASK(&ep->mask);
2730:
2731: set_reuseaddr(1);
2732: ep->bfd = INVALID_SOCKET;
2733: ep->fd = open_socket(&ep->sin, 0, 0, ep);
2734: if (ep->fd != INVALID_SOCKET) {
2735: ep->ignore_packets = ISC_FALSE;
2736: ep->flags |= INT_MCASTIF;
2737:
2738: strncpy(ep->name, "multicast", sizeof(ep->name));
2739: DPRINT_INTERFACE(2, (ep, "multicast add ", "\n"));
2740: add_interface(ep);
2741: log_listen_address(ep);
2742: } else {
2743: /* bind failed, re-use wildcard interface */
2744: delete_interface(ep);
2745:
2746: if (IS_IPV4(addr))
2747: ep = wildipv4;
2748: else if (IS_IPV6(addr))
2749: ep = wildipv6;
2750: else
2751: ep = NULL;
2752:
2753: if (ep != NULL) {
2754: /* HACK ! -- stuff in an address */
2755: /* because we don't bind addr? DH */
2756: ep->bcast = *addr;
2757: msyslog(LOG_ERR,
2758: "multicast address %s using wildcard interface #%d %s",
2759: stoa(addr), ep->ifnum, ep->name);
2760: } else {
2761: msyslog(LOG_ERR,
2762: "No multicast socket available to use for address %s",
2763: stoa(addr));
2764: return;
2765: }
2766: }
2767: { /* in place of the { following for in #else clause */
2768: one_ep = ep;
2769: #else /* MULTICAST_NONEWSOCKET follows */
2770: /*
2771: * For the case where we can't use a separate socket (Windows)
2772: * join each applicable endpoint socket to the group address.
2773: */
2774: if (IS_IPV4(addr))
2775: one_ep = wildipv4;
2776: else
2777: one_ep = wildipv6;
2778: for (ep = ep_list; ep != NULL; ep = ep->elink) {
2779: if (ep->ignore_packets || AF(&ep->sin) != AF(addr) ||
2780: !(INT_MULTICAST & ep->flags) ||
2781: (INT_LOOPBACK | INT_WILDCARD) & ep->flags)
2782: continue;
2783: one_ep = ep;
2784: #endif /* MULTICAST_NONEWSOCKET */
2785: if (socket_multicast_enable(ep, addr))
2786: msyslog(LOG_INFO,
2787: "Joined %s socket to multicast group %s",
2788: stoa(&ep->sin),
2789: stoa(addr));
2790: else
2791: msyslog(LOG_ERR,
2792: "Failed to join %s socket to multicast group %s",
2793: stoa(&ep->sin),
2794: stoa(addr));
2795: }
2796:
2797: add_addr_to_list(addr, one_ep);
2798: #else /* !MCAST follows*/
2799: msyslog(LOG_ERR,
2800: "Can not add multicast address %s: no multicast support",
2801: stoa(addr));
2802: #endif
2803: return;
2804: }
2805:
2806:
2807: /*
2808: * io_multicast_del() - delete multicast group address
2809: */
2810: void
2811: io_multicast_del(
2812: sockaddr_u * addr
2813: )
2814: {
2815: #ifdef MCAST
2816: endpt *iface;
2817:
2818: /*
2819: * Check to see if this is a multicast address
2820: */
2821: if (!addr_ismulticast(addr)) {
2822: msyslog(LOG_ERR, "invalid multicast address %s",
2823: stoa(addr));
2824: return;
2825: }
2826:
2827: /*
2828: * Disable reception of multicast packets
2829: */
2830: while ((iface = find_flagged_addr_in_list(addr, INT_MCASTOPEN))
2831: != NULL)
2832: socket_multicast_disable(iface, addr);
2833:
2834: delete_addr_from_list(addr);
2835:
2836: #else /* not MCAST */
2837: msyslog(LOG_ERR,
2838: "Can not delete multicast address %s: no multicast support",
2839: stoa(addr));
2840: #endif /* not MCAST */
2841: }
2842:
2843:
2844: /*
2845: * init_nonblocking_io() - set up descriptor to be non blocking
2846: */
2847: static void init_nonblocking_io(
2848: SOCKET fd
2849: )
2850: {
2851: /*
2852: * set non-blocking,
2853: */
2854:
2855: #ifdef USE_FIONBIO
2856: /* in vxWorks we use FIONBIO, but the others are defined for old systems, so
2857: * all hell breaks loose if we leave them defined
2858: */
2859: #undef O_NONBLOCK
2860: #undef FNDELAY
2861: #undef O_NDELAY
2862: #endif
2863:
2864: #if defined(O_NONBLOCK) /* POSIX */
2865: if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
2866: msyslog(LOG_ERR,
2867: "fcntl(O_NONBLOCK) fails on fd #%d: %m", fd);
2868: exit(1);
2869: }
2870: #elif defined(FNDELAY)
2871: if (fcntl(fd, F_SETFL, FNDELAY) < 0) {
2872: msyslog(LOG_ERR, "fcntl(FNDELAY) fails on fd #%d: %m",
2873: fd);
2874: exit(1);
2875: }
2876: #elif defined(O_NDELAY) /* generally the same as FNDELAY */
2877: if (fcntl(fd, F_SETFL, O_NDELAY) < 0) {
2878: msyslog(LOG_ERR, "fcntl(O_NDELAY) fails on fd #%d: %m",
2879: fd);
2880: exit(1);
2881: }
2882: #elif defined(FIONBIO)
2883: {
2884: int on = 1;
2885:
2886: if (ioctl(fd, FIONBIO, &on) < 0) {
2887: msyslog(LOG_ERR,
2888: "ioctl(FIONBIO) fails on fd #%d: %m",
2889: fd);
2890: exit(1);
2891: }
2892: }
2893: #elif defined(FIOSNBIO)
2894: if (ioctl(fd, FIOSNBIO, &on) < 0) {
2895: msyslog(LOG_ERR,
2896: "ioctl(FIOSNBIO) fails on fd #%d: %m", fd);
2897: exit(1);
2898: }
2899: #else
2900: # include "Bletch: Need non-blocking I/O!"
2901: #endif
2902: }
2903:
2904: /*
2905: * open_socket - open a socket, returning the file descriptor
2906: */
2907:
2908: static SOCKET
2909: open_socket(
2910: sockaddr_u * addr,
2911: int bcast,
2912: int turn_off_reuse,
2913: endpt * interf
2914: )
2915: {
2916: SOCKET fd;
2917: int errval;
2918: char scopetext[16];
2919: /*
2920: * int is OK for REUSEADR per
2921: * http://www.kohala.com/start/mcast.api.txt
2922: */
2923: int on = 1;
2924: int off = 0;
2925:
2926: if (IS_IPV6(addr) && !ipv6_works)
2927: return INVALID_SOCKET;
2928:
2929: /* create a datagram (UDP) socket */
2930: fd = socket(AF(addr), SOCK_DGRAM, 0);
2931: if (INVALID_SOCKET == fd) {
2932: errval = socket_errno();
2933: msyslog(LOG_ERR,
2934: "socket(AF_INET%s, SOCK_DGRAM, 0) failed on address %s: %m",
2935: IS_IPV6(addr) ? "6" : "", stoa(addr));
2936:
2937: if (errval == EPROTONOSUPPORT ||
2938: errval == EAFNOSUPPORT ||
2939: errval == EPFNOSUPPORT)
2940: return (INVALID_SOCKET);
2941:
2942: errno = errval;
2943: msyslog(LOG_ERR,
2944: "unexpected socket() error %m code %d (not EPROTONOSUPPORT nor EAFNOSUPPORT nor EPFNOSUPPORT) - exiting",
2945: errno);
2946: exit(1);
2947: }
2948:
2949: #ifdef SYS_WINNT
2950: connection_reset_fix(fd, addr);
2951: #endif
2952: /*
2953: * Fixup the file descriptor for some systems
2954: * See bug #530 for details of the issue.
2955: */
2956: fd = move_fd(fd);
2957:
2958: /*
2959: * set SO_REUSEADDR since we will be binding the same port
2960: * number on each interface according to turn_off_reuse.
2961: * This is undesirable on Windows versions starting with
2962: * Windows XP (numeric version 5.1).
2963: */
2964: #ifdef SYS_WINNT
2965: if (isc_win32os_versioncheck(5, 1, 0, 0) < 0) /* before 5.1 */
2966: #endif
2967: if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
2968: (char *)((turn_off_reuse)
2969: ? &off
2970: : &on),
2971: sizeof(on))) {
2972:
2973: msyslog(LOG_ERR,
2974: "setsockopt SO_REUSEADDR %s fails for address %s: %m",
2975: (turn_off_reuse)
2976: ? "off"
2977: : "on",
2978: stoa(addr));
2979: closesocket(fd);
2980: return INVALID_SOCKET;
2981: }
2982: #ifdef SO_EXCLUSIVEADDRUSE
2983: /*
2984: * setting SO_EXCLUSIVEADDRUSE on the wildcard we open
2985: * first will cause more specific binds to fail.
2986: */
2987: if (!(interf->flags & INT_WILDCARD))
2988: set_excladdruse(fd);
2989: #endif
2990:
2991: /*
2992: * IPv4 specific options go here
2993: */
2994: if (IS_IPV4(addr)) {
2995: #if defined(HAVE_IPTOS_SUPPORT)
2996: if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *)&qos,
2997: sizeof(qos)))
2998: msyslog(LOG_ERR,
2999: "setsockopt IP_TOS (%02x) fails on address %s: %m",
3000: qos, stoa(addr));
3001: #endif /* HAVE_IPTOS_SUPPORT */
3002: if (bcast)
3003: socket_broadcast_enable(interf, fd, addr);
3004: }
3005:
3006: /*
3007: * IPv6 specific options go here
3008: */
3009: if (IS_IPV6(addr)) {
3010: #ifdef IPV6_V6ONLY
3011: if (isc_net_probe_ipv6only() == ISC_R_SUCCESS
3012: && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
3013: (char*)&on, sizeof(on)))
3014: msyslog(LOG_ERR,
3015: "setsockopt IPV6_V6ONLY on fails on address %s: %m",
3016: stoa(addr));
3017: #endif
3018: #ifdef IPV6_BINDV6ONLY
3019: if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
3020: (char*)&on, sizeof(on)))
3021: msyslog(LOG_ERR,
3022: "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
3023: stoa(addr));
3024: #endif
3025: }
3026:
3027: #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
3028: /*
3029: * some OSes don't allow binding to more specific
3030: * addresses if a wildcard address already bound
3031: * to the port and SO_REUSEADDR is not set
3032: */
3033: if (!is_wildcard_addr(addr))
3034: set_wildcard_reuse(AF(addr), 1);
3035: #endif
3036:
3037: /*
3038: * bind the local address.
3039: */
3040: errval = bind(fd, &addr->sa, SOCKLEN(addr));
3041:
3042: #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
3043: if (!is_wildcard_addr(addr))
3044: set_wildcard_reuse(AF(addr), 0);
3045: #endif
3046:
3047: if (errval < 0) {
3048: /*
3049: * Don't log this under all conditions
3050: */
3051: if (turn_off_reuse == 0
3052: #ifdef DEBUG
3053: || debug > 1
3054: #endif
3055: ) {
3056: if (SCOPE(addr))
3057: snprintf(scopetext, sizeof(scopetext),
3058: "%%%d", SCOPE(addr));
3059: else
3060: scopetext[0] = 0;
3061:
3062: msyslog(LOG_ERR,
3063: "bind(%d) AF_INET%s %s%s#%d%s flags 0x%x failed: %m",
3064: fd, IS_IPV6(addr) ? "6" : "",
3065: stoa(addr), scopetext, SRCPORT(addr),
3066: IS_MCAST(addr) ? " (multicast)" : "",
3067: interf->flags);
3068: }
3069:
3070: closesocket(fd);
3071:
3072: return INVALID_SOCKET;
3073: }
3074:
3075: #ifdef HAVE_TIMESTAMP
3076: {
3077: if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP,
3078: (char*)&on, sizeof(on)))
3079: msyslog(LOG_DEBUG,
3080: "setsockopt SO_TIMESTAMP on fails on address %s: %m",
3081: stoa(addr));
3082: else
3083: DPRINTF(4, ("setsockopt SO_TIMESTAMP enabled on fd %d address %s\n",
3084: fd, stoa(addr)));
3085: }
3086: #endif
3087: DPRINTF(4, ("bind(%d) AF_INET%s, addr %s%%%d#%d, flags 0x%x\n",
3088: fd, IS_IPV6(addr) ? "6" : "", stoa(addr),
3089: SCOPE(addr), SRCPORT(addr), interf->flags));
3090:
3091: init_nonblocking_io(fd);
3092:
3093: #ifdef HAVE_SIGNALED_IO
3094: init_socket_sig(fd);
3095: #endif /* not HAVE_SIGNALED_IO */
3096:
3097: add_fd_to_list(fd, FD_TYPE_SOCKET);
3098:
3099: #if !defined(SYS_WINNT) && !defined(VMS)
3100: DPRINTF(4, ("flags for fd %d: 0x%x\n", fd,
3101: fcntl(fd, F_GETFL, 0)));
3102: #endif /* SYS_WINNT || VMS */
3103:
3104: #if defined (HAVE_IO_COMPLETION_PORT)
3105: /*
3106: * Add the socket to the completion port
3107: */
3108: if (io_completion_port_add_socket(fd, interf)) {
3109: msyslog(LOG_ERR, "unable to set up io completion port - EXITING");
3110: exit(1);
3111: }
3112: #endif
3113: return fd;
3114: }
3115:
3116:
3117: #ifdef SYS_WINNT
3118: #define sendto(fd, buf, len, flags, dest, destsz) \
3119: io_completion_port_sendto(fd, buf, len, (sockaddr_u *)(dest))
3120: #endif
3121:
3122: /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
3123: /*
3124: * sendpkt - send a packet to the specified destination. Maintain a
3125: * send error cache so that only the first consecutive error for a
3126: * destination is logged.
3127: */
3128: void
3129: sendpkt(
3130: sockaddr_u * dest,
3131: struct interface * ep,
3132: int ttl,
3133: struct pkt * pkt,
3134: int len
3135: )
3136: {
3137: endpt * src;
3138: int ismcast;
3139: int cc;
3140: int rc;
3141: u_char cttl;
3142:
3143: ismcast = IS_MCAST(dest);
3144: if (!ismcast)
3145: src = ep;
3146: else
3147: src = (IS_IPV4(dest))
3148: ? mc4_list
3149: : mc6_list;
3150:
3151: if (NULL == src) {
3152: /*
3153: * unbound peer - drop request and wait for better
3154: * network conditions
3155: */
3156: DPRINTF(2, ("%ssendpkt(dst=%s, ttl=%d, len=%d): no interface - IGNORED\n",
3157: ismcast ? "\tMCAST\t***** " : "",
3158: stoa(dest), ttl, len));
3159: return;
3160: }
3161:
3162: do {
3163: DPRINTF(2, ("%ssendpkt(%d, dst=%s, src=%s, ttl=%d, len=%d)\n",
3164: ismcast ? "\tMCAST\t***** " : "", src->fd,
3165: stoa(dest), stoa(&src->sin), ttl, len));
3166: #ifdef MCAST
3167: /*
3168: * for the moment we use the bcast option to set multicast ttl
3169: */
3170: if (ismcast && ttl > 0 && ttl != src->last_ttl) {
3171: /*
3172: * set the multicast ttl for outgoing packets
3173: */
3174: switch (AF(&src->sin)) {
3175:
3176: case AF_INET :
3177: cttl = (u_char)ttl;
3178: rc = setsockopt(src->fd, IPPROTO_IP,
3179: IP_MULTICAST_TTL,
3180: (void *)&cttl,
3181: sizeof(cttl));
3182: break;
3183:
3184: # ifdef INCLUDE_IPV6_SUPPORT
3185: case AF_INET6 :
3186: rc = setsockopt(src->fd, IPPROTO_IPV6,
3187: IPV6_MULTICAST_HOPS,
3188: (void *)&ttl,
3189: sizeof(ttl));
3190: break;
3191: # endif /* INCLUDE_IPV6_SUPPORT */
3192:
3193: default:
3194: rc = 0;
3195: }
3196:
3197: if (!rc)
3198: src->last_ttl = ttl;
3199: else
3200: msyslog(LOG_ERR,
3201: "setsockopt IP_MULTICAST_TTL/IPV6_MULTICAST_HOPS fails on address %s: %m",
3202: stoa(&src->sin));
3203: }
3204: #endif /* MCAST */
3205:
3206: #ifdef SIM
3207: cc = simulate_server(dest, src, pkt);
3208: #else
3209: cc = sendto(src->fd, (char *)pkt, (u_int)len, 0,
3210: &dest->sa, SOCKLEN(dest));
3211: #endif
3212: if (cc == -1) {
3213: src->notsent++;
3214: packets_notsent++;
3215: } else {
3216: src->sent++;
3217: packets_sent++;
3218: }
3219: if (ismcast)
3220: src = src->mclink;
3221: } while (ismcast && src != NULL);
3222: }
3223:
3224:
3225: #if !defined(HAVE_IO_COMPLETION_PORT)
3226: /*
3227: * fdbits - generate ascii representation of fd_set (FAU debug support)
3228: * HFDF format - highest fd first.
3229: */
3230: static char *
3231: fdbits(
3232: int count,
3233: fd_set *set
3234: )
3235: {
3236: static char buffer[256];
3237: char * buf = buffer;
3238:
3239: count = min(count, 255);
3240:
3241: while (count >= 0) {
3242: *buf++ = FD_ISSET(count, set) ? '#' : '-';
3243: count--;
3244: }
3245: *buf = '\0';
3246:
3247: return buffer;
3248: }
3249:
3250: /*
3251: * Routine to read the refclock packets for a specific interface
3252: * Return the number of bytes read. That way we know if we should
3253: * read it again or go on to the next one if no bytes returned
3254: */
3255: static inline int
3256: read_refclock_packet(SOCKET fd, struct refclockio *rp, l_fp ts)
3257: {
3258: int i;
3259: int buflen;
3260: register struct recvbuf *rb;
3261:
3262: rb = get_free_recv_buffer();
3263:
3264: if (NULL == rb) {
3265: /*
3266: * No buffer space available - just drop the packet
3267: */
3268: char buf[RX_BUFF_SIZE];
3269:
3270: buflen = read(fd, buf, sizeof buf);
3271: packets_dropped++;
3272: return (buflen);
3273: }
3274:
3275: i = (rp->datalen == 0
3276: || rp->datalen > sizeof(rb->recv_space))
3277: ? sizeof(rb->recv_space)
3278: : rp->datalen;
3279: buflen = read(fd, (char *)&rb->recv_space, (unsigned)i);
3280:
3281: if (buflen < 0) {
3282: if (errno != EINTR && errno != EAGAIN)
3283: msyslog(LOG_ERR, "clock read fd %d: %m", fd);
3284: freerecvbuf(rb);
3285: return (buflen);
3286: }
3287:
3288: /*
3289: * Got one. Mark how and when it got here,
3290: * put it on the full list and do bookkeeping.
3291: */
3292: rb->recv_length = buflen;
3293: rb->recv_srcclock = rp->srcclock;
3294: rb->dstadr = 0;
3295: rb->fd = fd;
3296: rb->recv_time = ts;
3297: rb->receiver = rp->clock_recv;
3298:
3299: if (rp->io_input) {
3300: /*
3301: * have direct input routine for refclocks
3302: */
3303: if (rp->io_input(rb) == 0) {
3304: /*
3305: * data was consumed - nothing to pass up
3306: * into block input machine
3307: */
3308: freerecvbuf(rb);
3309: return (buflen);
3310: }
3311: }
3312:
3313: add_full_recv_buffer(rb);
3314:
3315: rp->recvcount++;
3316: packets_received++;
3317: return (buflen);
3318: }
3319:
3320:
3321: #ifdef HAVE_TIMESTAMP
3322: /*
3323: * extract timestamps from control message buffer
3324: */
3325: static l_fp
3326: fetch_timestamp(
3327: struct recvbuf * rb,
3328: struct msghdr * msghdr,
3329: l_fp ts
3330: )
3331: {
3332: #ifdef USE_TIMESTAMP_CMSG
3333: struct cmsghdr *cmsghdr;
3334:
3335: cmsghdr = CMSG_FIRSTHDR(msghdr);
3336: while (cmsghdr != NULL) {
3337: switch (cmsghdr->cmsg_type)
3338: {
3339: case SCM_TIMESTAMP:
3340: {
3341: struct timeval *tvp;
3342: double dtemp;
3343: l_fp nts;
3344:
3345: tvp = (struct timeval *)CMSG_DATA(cmsghdr);
3346: DPRINTF(4, ("fetch_timestamp: system network time stamp: %ld.%06ld\n",
3347: tvp->tv_sec, tvp->tv_usec));
3348: nts.l_i = tvp->tv_sec + JAN_1970;
3349: dtemp = (tvp->tv_usec
3350: + (ntp_random() * 2. / FRAC)) / 1e6;
3351: nts.l_uf = (u_int32)(dtemp * FRAC);
3352: #ifdef DEBUG_TIMING
3353: {
3354: l_fp dts;
3355:
3356: dts = ts;
3357: L_SUB(&dts, &nts);
3358: collect_timing(rb,
3359: "input processing delay",
3360: 1, &dts);
3361: DPRINTF(4, ("fetch_timestamp: timestamp delta: %s (incl. prec fuzz)\n",
3362: lfptoa(&dts, 9)));
3363: }
3364: #endif
3365: ts = nts; /* network time stamp */
3366: break;
3367: }
3368: default:
3369: DPRINTF(4, ("fetch_timestamp: skipping control message 0x%x\n",
3370: cmsghdr->cmsg_type));
3371: }
3372: cmsghdr = CMSG_NXTHDR(msghdr, cmsghdr);
3373: }
3374: #endif
3375: return ts;
3376: }
3377: #endif
3378:
3379:
3380: /*
3381: * Routine to read the network NTP packets for a specific interface
3382: * Return the number of bytes read. That way we know if we should
3383: * read it again or go on to the next one if no bytes returned
3384: */
3385: static inline int
3386: read_network_packet(
3387: SOCKET fd,
3388: struct interface * itf,
3389: l_fp ts
3390: )
3391: {
3392: GETSOCKNAME_SOCKLEN_TYPE fromlen;
3393: int buflen;
3394: register struct recvbuf *rb;
3395: #ifdef HAVE_TIMESTAMP
3396: struct msghdr msghdr;
3397: struct iovec iovec;
3398: char control[TIMESTAMP_CTLMSGBUF_SIZE];
3399: #endif
3400:
3401: /*
3402: * Get a buffer and read the frame. If we
3403: * haven't got a buffer, or this is received
3404: * on a disallowed socket, just dump the
3405: * packet.
3406: */
3407:
3408: rb = get_free_recv_buffer();
3409: if (NULL == rb || itf->ignore_packets) {
3410: char buf[RX_BUFF_SIZE];
3411: sockaddr_u from;
3412:
3413: if (rb != NULL)
3414: freerecvbuf(rb);
3415:
3416: fromlen = sizeof(from);
3417: buflen = recvfrom(fd, buf, sizeof(buf), 0,
3418: &from.sa, &fromlen);
3419: DPRINTF(4, ("%s on (%lu) fd=%d from %s\n",
3420: (itf->ignore_packets)
3421: ? "ignore"
3422: : "drop",
3423: free_recvbuffs(), fd, stoa(&from)));
3424: if (itf->ignore_packets)
3425: packets_ignored++;
3426: else
3427: packets_dropped++;
3428: return (buflen);
3429: }
3430:
3431: fromlen = sizeof(rb->recv_srcadr);
3432:
3433: #ifndef HAVE_TIMESTAMP
3434: rb->recv_length = recvfrom(fd, (char *)&rb->recv_space,
3435: sizeof(rb->recv_space), 0,
3436: &rb->recv_srcadr.sa, &fromlen);
3437: #else
3438: iovec.iov_base = &rb->recv_space;
3439: iovec.iov_len = sizeof(rb->recv_space);
3440: msghdr.msg_name = &rb->recv_srcadr;
3441: msghdr.msg_namelen = fromlen;
3442: msghdr.msg_iov = &iovec;
3443: msghdr.msg_iovlen = 1;
3444: msghdr.msg_control = (void *)&control;
3445: msghdr.msg_controllen = sizeof(control);
3446: msghdr.msg_flags = 0;
3447: rb->recv_length = recvmsg(fd, &msghdr, 0);
3448: #endif
3449:
3450: buflen = rb->recv_length;
3451:
3452: if (buflen == 0 || (buflen == -1 &&
3453: (EWOULDBLOCK == errno
3454: #ifdef EAGAIN
3455: || EAGAIN == errno
3456: #endif
3457: ))) {
3458: freerecvbuf(rb);
3459: return (buflen);
3460: } else if (buflen < 0) {
3461: msyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
3462: stoa(&rb->recv_srcadr), fd);
3463: DPRINTF(5, ("read_network_packet: fd=%d dropped (bad recvfrom)\n",
3464: fd));
3465: freerecvbuf(rb);
3466: return (buflen);
3467: }
3468:
3469: DPRINTF(3, ("read_network_packet: fd=%d length %d from %s\n",
3470: fd, buflen, stoa(&rb->recv_srcadr)));
3471:
3472: /*
3473: * Got one. Mark how and when it got here,
3474: * put it on the full list and do bookkeeping.
3475: */
3476: rb->dstadr = itf;
3477: rb->fd = fd;
3478: #ifdef HAVE_TIMESTAMP
3479: /* pick up a network time stamp if possible */
3480: ts = fetch_timestamp(rb, &msghdr, ts);
3481: #endif
3482: rb->recv_time = ts;
3483: rb->receiver = receive;
3484:
3485: add_full_recv_buffer(rb);
3486:
3487: itf->received++;
3488: packets_received++;
3489: return (buflen);
3490: }
3491:
3492:
3493: /*
3494: * input_handler - receive packets asynchronously
3495: */
3496: void
3497: input_handler(
3498: l_fp *cts
3499: )
3500: {
3501: int buflen;
3502: int n;
3503: int doing;
3504: SOCKET fd;
3505: struct timeval tvzero;
3506: l_fp ts; /* Timestamp at BOselect() gob */
3507: #ifdef DEBUG_TIMING
3508: l_fp ts_e; /* Timestamp at EOselect() gob */
3509: #endif
3510: fd_set fds;
3511: int select_count = 0;
3512: endpt *ep;
3513: #if defined(HAS_ROUTING_SOCKET)
3514: struct asyncio_reader *asyncio_reader;
3515: #endif
3516:
3517: handler_calls++;
3518:
3519: /*
3520: * If we have something to do, freeze a timestamp.
3521: * See below for the other cases (nothing left to do or error)
3522: */
3523: ts = *cts;
3524:
3525: /*
3526: * Do a poll to see who has data
3527: */
3528:
3529: fds = activefds;
3530: tvzero.tv_sec = tvzero.tv_usec = 0;
3531:
3532: n = select(maxactivefd + 1, &fds, (fd_set *)0, (fd_set *)0,
3533: &tvzero);
3534:
3535: /*
3536: * If there are no packets waiting just return
3537: */
3538: if (n < 0) {
3539: int err = errno;
3540: /*
3541: * extended FAU debugging output
3542: */
3543: if (err != EINTR)
3544: msyslog(LOG_ERR,
3545: "select(%d, %s, 0L, 0L, &0.0) error: %m",
3546: maxactivefd + 1,
3547: fdbits(maxactivefd, &activefds));
3548: if (err == EBADF) {
3549: int j, b;
3550: fds = activefds;
3551: for (j = 0; j <= maxactivefd; j++)
3552: if ((FD_ISSET(j, &fds)
3553: && (read(j, &b, 0) == -1)))
3554: msyslog(LOG_ERR,
3555: "Bad file descriptor %d",
3556: j);
3557: }
3558: return;
3559: }
3560: else if (n == 0)
3561: return;
3562:
3563: ++handler_pkts;
3564:
3565: #ifdef REFCLOCK
3566: /*
3567: * Check out the reference clocks first, if any
3568: */
3569:
3570: if (refio != NULL) {
3571: register struct refclockio *rp;
3572:
3573: for (rp = refio; rp != NULL; rp = rp->next) {
3574: fd = rp->fd;
3575:
3576: if (FD_ISSET(fd, &fds))
3577: do {
3578: ++select_count;
3579: buflen = read_refclock_packet(
3580: fd, rp, ts);
3581: } while (buflen > 0);
3582: }
3583: }
3584: #endif /* REFCLOCK */
3585:
3586: /*
3587: * Loop through the interfaces looking for data to read.
3588: */
3589: for (ep = ep_list; ep != NULL; ep = ep->elink) {
3590: for (doing = 0; doing < 2; doing++) {
3591: if (!doing) {
3592: fd = ep->fd;
3593: } else {
3594: if (!(ep->flags & INT_BCASTOPEN))
3595: break;
3596: fd = ep->bfd;
3597: }
3598: if (fd < 0)
3599: continue;
3600: if (FD_ISSET(fd, &fds))
3601: do {
3602: ++select_count;
3603: buflen = read_network_packet(
3604: fd, ep, ts);
3605: } while (buflen > 0);
3606: /* Check more interfaces */
3607: }
3608: }
3609:
3610: #ifdef HAS_ROUTING_SOCKET
3611: /*
3612: * scan list of asyncio readers - currently only used for routing sockets
3613: */
3614: asyncio_reader = asyncio_reader_list;
3615:
3616: while (asyncio_reader != NULL) {
3617: if (FD_ISSET(asyncio_reader->fd, &fds)) {
3618: ++select_count;
3619: (asyncio_reader->receiver)(asyncio_reader);
3620: }
3621: asyncio_reader = asyncio_reader->link;
3622: }
3623: #endif /* HAS_ROUTING_SOCKET */
3624:
3625: /*
3626: * Done everything from that select.
3627: */
3628:
3629: /*
3630: * If nothing to do, just return.
3631: * If an error occurred, complain and return.
3632: */
3633: if (select_count == 0) { /* We really had nothing to do */
3634: #ifdef DEBUG
3635: if (debug)
3636: msyslog(LOG_DEBUG, "input_handler: select() returned 0");
3637: #endif
3638: return;
3639: }
3640: /* We've done our work */
3641: #ifdef DEBUG_TIMING
3642: get_systime(&ts_e);
3643: /*
3644: * (ts_e - ts) is the amount of time we spent
3645: * processing this gob of file descriptors. Log
3646: * it.
3647: */
3648: L_SUB(&ts_e, &ts);
3649: collect_timing(NULL, "input handler", 1, &ts_e);
3650: if (debug > 3)
3651: msyslog(LOG_DEBUG,
3652: "input_handler: Processed a gob of fd's in %s msec",
3653: lfptoms(&ts_e, 6));
3654: #endif
3655: /* just bail. */
3656: return;
3657: }
3658: #endif
3659:
3660: /*
3661: * findinterface - find local interface corresponding to address
3662: */
3663: endpt *
3664: findinterface(
3665: sockaddr_u *addr
3666: )
3667: {
3668: endpt *iface;
3669:
3670: iface = findlocalinterface(addr, INT_WILDCARD, 0);
3671:
3672: if (NULL == iface) {
3673: DPRINTF(4, ("Found no interface for address %s - returning wildcard\n",
3674: stoa(addr)));
3675:
3676: iface = ANY_INTERFACE_CHOOSE(addr);
3677: } else
3678: DPRINTF(4, ("Found interface #%d %s for address %s\n",
3679: iface->ifnum, iface->name, stoa(addr)));
3680:
3681: return iface;
3682: }
3683:
3684: /*
3685: * findlocalinterface - find local interface corresponding to addr,
3686: * which does not have any of flags set. If bast is nonzero, addr is
3687: * a broadcast address.
3688: *
3689: * This code attempts to find the local sending address for an outgoing
3690: * address by connecting a new socket to destinationaddress:NTP_PORT
3691: * and reading the sockname of the resulting connect.
3692: * the complicated sequence simulates the routing table lookup
3693: * for to first hop without duplicating any of the routing logic into
3694: * ntpd. preferably we would have used an API call - but its not there -
3695: * so this is the best we can do here short of duplicating to entire routing
3696: * logic in ntpd which would be a silly and really unportable thing to do.
3697: *
3698: */
3699: static endpt *
3700: findlocalinterface(
3701: sockaddr_u * addr,
3702: int flags,
3703: int bcast
3704: )
3705: {
3706: GETSOCKNAME_SOCKLEN_TYPE sockaddrlen;
3707: endpt * iface;
3708: sockaddr_u saddr;
3709: SOCKET s;
3710: int rtn;
3711: int on;
3712:
3713: DPRINTF(4, ("Finding interface for addr %s in list of addresses\n",
3714: stoa(addr)));
3715:
3716: s = socket(AF(addr), SOCK_DGRAM, 0);
3717: if (INVALID_SOCKET == s)
3718: return NULL;
3719:
3720: /*
3721: * If we are looking for broadcast interface we need to set this
3722: * socket to allow broadcast
3723: */
3724: if (bcast) {
3725: on = 1;
3726: setsockopt(s, SOL_SOCKET, SO_BROADCAST,
3727: (char *)&on, sizeof(on));
3728: }
3729:
3730: rtn = connect(s, &addr->sa, SOCKLEN(addr));
3731: if (SOCKET_ERROR == rtn) {
3732: closesocket(s);
3733: return NULL;
3734: }
3735:
3736: sockaddrlen = sizeof(saddr);
3737: rtn = getsockname(s, &saddr.sa, &sockaddrlen);
3738: closesocket(s);
3739: if (SOCKET_ERROR == rtn)
3740: return NULL;
3741:
3742: DPRINTF(4, ("findlocalinterface: kernel maps %s to %s\n",
3743: stoa(addr), stoa(&saddr)));
3744:
3745: iface = getinterface(&saddr, flags);
3746:
3747: /*
3748: * if we didn't find an exact match on saddr, find the closest
3749: * available local address. This handles the case of the
3750: * address suggested by the kernel being excluded by nic rules
3751: * or the user's -I and -L options to ntpd.
3752: * See http://bugs.ntp.org/1184 and http://bugs.ntp.org/1683
3753: * for more background.
3754: */
3755: if (NULL == iface || iface->ignore_packets)
3756: iface = findclosestinterface(&saddr,
3757: flags | INT_LOOPBACK);
3758:
3759: /* Don't use an interface which will ignore replies */
3760: if (iface != NULL && iface->ignore_packets)
3761: iface = NULL;
3762:
3763: return iface;
3764: }
3765:
3766:
3767: /*
3768: * findclosestinterface
3769: *
3770: * If there are -I/--interface or -L/novirtualips command-line options,
3771: * or "nic" or "interface" rules in ntp.conf, findlocalinterface() may
3772: * find the kernel's preferred local address for a given peer address is
3773: * administratively unavailable to ntpd, and punt to this routine's more
3774: * expensive search.
3775: *
3776: * Find the numerically closest local address to the one connect()
3777: * suggested. This matches an address on the same subnet first, as
3778: * needed by Bug 1184, and provides a consistent choice if there are
3779: * multiple feasible local addresses, regardless of the order ntpd
3780: * enumerated them.
3781: */
3782: static endpt *
3783: findclosestinterface(
3784: sockaddr_u * addr,
3785: int flags
3786: )
3787: {
3788: endpt * ep;
3789: endpt * winner;
3790: sockaddr_u addr_dist;
3791: sockaddr_u min_dist;
3792:
3793: winner = NULL;
3794:
3795: for (ep = ep_list; ep != NULL; ep = ep->elink) {
3796: if (ep->ignore_packets ||
3797: AF(addr) != ep->family ||
3798: flags & ep->flags)
3799: continue;
3800:
3801: calc_addr_distance(&addr_dist, addr, &ep->sin);
3802: if (NULL == winner ||
3803: -1 == cmp_addr_distance(&addr_dist, &min_dist)) {
3804: min_dist = addr_dist;
3805: winner = ep;
3806: }
3807: }
3808: if (NULL == winner)
3809: DPRINTF(4, ("findclosestinterface(%s) failed\n",
3810: stoa(addr)));
3811: else
3812: DPRINTF(4, ("findclosestinterface(%s) -> %s\n",
3813: stoa(addr), stoa(&winner->sin)));
3814:
3815: return winner;
3816: }
3817:
3818:
3819: /*
3820: * calc_addr_distance - calculate the distance between two addresses,
3821: * the absolute value of the difference between
3822: * the addresses numerically, stored as an address.
3823: */
3824: static void
3825: calc_addr_distance(
3826: sockaddr_u * dist,
3827: const sockaddr_u * a1,
3828: const sockaddr_u * a2
3829: )
3830: {
3831: u_int32 a1val;
3832: u_int32 a2val;
3833: u_int32 v4dist;
3834: int found_greater;
3835: int a1_greater;
3836: int i;
3837:
3838: NTP_REQUIRE(AF(a1) == AF(a2));
3839:
3840: memset(dist, 0, sizeof(*dist));
3841: AF(dist) = AF(a1);
3842:
3843: /* v4 can be done a bit simpler */
3844: if (IS_IPV4(a1)) {
3845: a1val = SRCADR(a1);
3846: a2val = SRCADR(a2);
3847: v4dist = (a1val > a2val)
3848: ? a1val - a2val
3849: : a2val - a1val;
3850: SET_ADDR4(dist, v4dist);
3851:
3852: return;
3853: }
3854:
3855: found_greater = FALSE;
3856: a1_greater = FALSE; /* suppress pot. uninit. warning */
3857: for (i = 0; i < sizeof(NSRCADR6(a1)); i++) {
3858: if (!found_greater &&
3859: NSRCADR6(a1)[i] != NSRCADR6(a2)[i]) {
3860: found_greater = TRUE;
3861: a1_greater = (NSRCADR6(a1)[i] > NSRCADR6(a2)[i]);
3862: }
3863: if (!found_greater) {
3864: NSRCADR6(dist)[i] = 0;
3865: } else {
3866: if (a1_greater)
3867: NSRCADR6(dist)[i] = NSRCADR6(a1)[i] -
3868: NSRCADR6(a2)[i];
3869: else
3870: NSRCADR6(dist)[i] = NSRCADR6(a2)[i] -
3871: NSRCADR6(a1)[i];
3872: }
3873: }
3874: }
3875:
3876:
3877: /*
3878: * cmp_addr_distance - compare two address distances, returning -1, 0,
3879: * 1 to indicate their relationship.
3880: */
3881: static int
3882: cmp_addr_distance(
3883: const sockaddr_u * d1,
3884: const sockaddr_u * d2
3885: )
3886: {
3887: int i;
3888:
3889: NTP_REQUIRE(AF(d1) == AF(d2));
3890:
3891: if (IS_IPV4(d1)) {
3892: if (SRCADR(d1) < SRCADR(d2))
3893: return -1;
3894: else if (SRCADR(d1) == SRCADR(d2))
3895: return 0;
3896: else
3897: return 1;
3898: }
3899:
3900: for (i = 0; i < sizeof(NSRCADR6(d1)); i++) {
3901: if (NSRCADR6(d1)[i] < NSRCADR6(d2)[i])
3902: return -1;
3903: else if (NSRCADR6(d1)[i] > NSRCADR6(d2)[i])
3904: return 1;
3905: }
3906:
3907: return 0;
3908: }
3909:
3910:
3911:
3912: /*
3913: * fetch an interface structure the matches the
3914: * address and has the given flags NOT set
3915: */
3916: static endpt *
3917: getinterface(
3918: sockaddr_u * addr,
3919: u_int32 flags
3920: )
3921: {
3922: endpt *iface;
3923:
3924: iface = find_addr_in_list(addr);
3925:
3926: if (iface != NULL && (iface->flags & flags))
3927: iface = NULL;
3928:
3929: return iface;
3930: }
3931:
3932:
3933: /*
3934: * findbcastinter - find broadcast interface corresponding to address
3935: */
3936: endpt *
3937: findbcastinter(
3938: sockaddr_u *addr
3939: )
3940: {
3941: #if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
3942: struct interface *iface;
3943:
3944:
3945: DPRINTF(4, ("Finding broadcast/multicast interface for addr %s in list of addresses\n",
3946: stoa(addr)));
3947:
3948: iface = findlocalinterface(addr, INT_LOOPBACK | INT_WILDCARD,
3949: 1);
3950: if (iface != NULL) {
3951: DPRINTF(4, ("Easily found bcast-/mcast- interface index #%d %s\n",
3952: iface->ifnum, iface->name));
3953: return iface;
3954: }
3955:
3956: /*
3957: * plan B - try to find something reasonable in our lists in
3958: * case kernel lookup doesn't help
3959: */
3960: for (iface = ep_list; iface != NULL; iface = iface->elink) {
3961: if (iface->flags & INT_WILDCARD)
3962: continue;
3963:
3964: /* Don't bother with ignored interfaces */
3965: if (iface->ignore_packets)
3966: continue;
3967:
3968: /*
3969: * First look if this is the correct family
3970: */
3971: if(AF(&iface->sin) != AF(addr))
3972: continue;
3973:
3974: /* Skip the loopback addresses */
3975: if (iface->flags & INT_LOOPBACK)
3976: continue;
3977:
3978: /*
3979: * If we are looking to match a multicast address and
3980: * this interface is one...
3981: */
3982: if (addr_ismulticast(addr)
3983: && (iface->flags & INT_MULTICAST)) {
3984: #ifdef INCLUDE_IPV6_SUPPORT
3985: /*
3986: * ...it is the winner unless we're looking for
3987: * an interface to use for link-local multicast
3988: * and its address is not link-local.
3989: */
3990: if (IS_IPV6(addr)
3991: && IN6_IS_ADDR_MC_LINKLOCAL(PSOCK_ADDR6(addr))
3992: && !IN6_IS_ADDR_LINKLOCAL(PSOCK_ADDR6(&iface->sin)))
3993: continue;
3994: #endif
3995: break;
3996: }
3997:
3998: /*
3999: * We match only those interfaces marked as
4000: * broadcastable and either the explicit broadcast
4001: * address or the network portion of the IP address.
4002: * Sloppy.
4003: */
4004: if (IS_IPV4(addr)) {
4005: if (SOCK_EQ(&iface->bcast, addr))
4006: break;
4007:
4008: if ((NSRCADR(&iface->sin) & NSRCADR(&iface->mask))
4009: == (NSRCADR(addr) & NSRCADR(&iface->mask)))
4010: break;
4011: }
4012: #ifdef INCLUDE_IPV6_SUPPORT
4013: else if (IS_IPV6(addr)) {
4014: if (SOCK_EQ(&iface->bcast, addr))
4015: break;
4016:
4017: if (SOCK_EQ(netof(&iface->sin), netof(addr)))
4018: break;
4019: }
4020: #endif
4021: }
4022: #endif /* SIOCGIFCONF */
4023: if (NULL == iface) {
4024: DPRINTF(4, ("No bcast interface found for %s\n",
4025: stoa(addr)));
4026: iface = ANY_INTERFACE_CHOOSE(addr);
4027: } else
4028: DPRINTF(4, ("Found bcast-/mcast- interface index #%d %s\n",
4029: iface->ifnum, iface->name));
4030: return iface;
4031: }
4032:
4033:
4034: /*
4035: * io_clr_stats - clear I/O module statistics
4036: */
4037: void
4038: io_clr_stats(void)
4039: {
4040: packets_dropped = 0;
4041: packets_ignored = 0;
4042: packets_received = 0;
4043: packets_sent = 0;
4044: packets_notsent = 0;
4045:
4046: handler_calls = 0;
4047: handler_pkts = 0;
4048: io_timereset = current_time;
4049: }
4050:
4051:
4052: #ifdef REFCLOCK
4053: /*
4054: * io_addclock - add a reference clock to the list and arrange that we
4055: * get SIGIO interrupts from it.
4056: */
4057: int
4058: io_addclock(
4059: struct refclockio *rio
4060: )
4061: {
4062: BLOCKIO();
4063:
4064: /*
4065: * Stuff the I/O structure in the list and mark the descriptor
4066: * in use. There is a harmless (I hope) race condition here.
4067: */
4068: rio->next = refio;
4069:
4070: # ifdef HAVE_SIGNALED_IO
4071: if (init_clock_sig(rio)) {
4072: UNBLOCKIO();
4073: return 0;
4074: }
4075: # elif defined(HAVE_IO_COMPLETION_PORT)
4076: if (io_completion_port_add_clock_io(rio)) {
4077: UNBLOCKIO();
4078: return 0;
4079: }
4080: # endif
4081:
4082: /*
4083: * enqueue
4084: */
4085: refio = rio;
4086:
4087: /*
4088: * register fd
4089: */
4090: add_fd_to_list(rio->fd, FD_TYPE_FILE);
4091:
4092: UNBLOCKIO();
4093: return 1;
4094: }
4095:
4096: /*
4097: * io_closeclock - close the clock in the I/O structure given
4098: */
4099: void
4100: io_closeclock(
4101: struct refclockio *rio
4102: )
4103: {
4104: register struct refclockio *rp;
4105:
4106: BLOCKIO();
4107:
4108: /*
4109: * Remove structure from the list
4110: */
4111: if (refio == rio)
4112: refio = rio->next;
4113: else {
4114: for (rp = refio; rp != NULL; rp = rp->next)
4115: if (rp->next == rio) {
4116: rp->next = rio->next;
4117: break;
4118: }
4119:
4120: if (NULL == rp) {
4121: UNBLOCKIO();
4122: return;
4123: }
4124: }
4125:
4126: /*
4127: * Close the descriptor.
4128: */
4129: close_and_delete_fd_from_list(rio->fd);
4130: UNBLOCKIO();
4131: }
4132: #endif /* REFCLOCK */
4133:
4134: /*
4135: * On NT a SOCKET is an unsigned int so we cannot possibly keep it in
4136: * an array. So we use one of the ISC_LIST functions to hold the
4137: * socket value and use that when we want to enumerate it.
4138: *
4139: * This routine is called by the forked intres child process to close
4140: * all open sockets. On Windows there's no need as intres runs in
4141: * the same process as a thread.
4142: */
4143: #ifndef SYS_WINNT
4144: void
4145: kill_asyncio(int startfd)
4146: {
4147: BLOCKIO();
4148:
4149: /*
4150: * In the child process we do not maintain activefds and
4151: * maxactivefd. Zeroing maxactivefd disables code which
4152: * maintains it in close_and_delete_fd_from_list().
4153: */
4154: maxactivefd = 0;
4155:
4156: while (fd_list != NULL)
4157: close_and_delete_fd_from_list(fd_list->fd);
4158:
4159: UNBLOCKIO();
4160: }
4161: #endif /* !SYS_WINNT */
4162:
4163: /*
4164: * Add and delete functions for the list of open sockets
4165: */
4166: static void
4167: add_fd_to_list(
4168: SOCKET fd,
4169: enum desc_type type
4170: )
4171: {
4172: vsock_t *lsock = emalloc(sizeof(*lsock));
4173:
4174: lsock->fd = fd;
4175: lsock->type = type;
4176:
4177: LINK_SLIST(fd_list, lsock, link);
4178: /*
4179: * I/O Completion Ports don't care about the select and FD_SET
4180: */
4181: #ifndef HAVE_IO_COMPLETION_PORT
4182: if (fd < 0 || fd >= FD_SETSIZE) {
4183: msyslog(LOG_ERR,
4184: "Too many sockets in use, FD_SETSIZE %d exceeded",
4185: FD_SETSIZE);
4186: exit(1);
4187: }
4188: /*
4189: * keep activefds in sync
4190: */
4191: maxactivefd = max(fd, maxactivefd);
4192:
4193: FD_SET(fd, &activefds);
4194: #endif
4195: }
4196:
4197: static void
4198: close_and_delete_fd_from_list(
4199: SOCKET fd
4200: )
4201: {
4202: vsock_t *lsock;
4203:
4204: UNLINK_EXPR_SLIST(lsock, fd_list, fd ==
4205: UNLINK_EXPR_SLIST_CURRENT()->fd, link, vsock_t);
4206:
4207: if (lsock != NULL) {
4208: switch (lsock->type) {
4209: case FD_TYPE_SOCKET:
4210: closesocket(lsock->fd);
4211: break;
4212:
4213: case FD_TYPE_FILE:
4214: close(lsock->fd);
4215: break;
4216:
4217: default:
4218: msyslog(LOG_ERR,
4219: "internal error - illegal descriptor type %d - EXITING",
4220: (int)lsock->type);
4221: exit(1);
4222: }
4223:
4224: free(lsock);
4225: /*
4226: * I/O Completion Ports don't care about select and fd_set
4227: */
4228: #ifndef HAVE_IO_COMPLETION_PORT
4229: /*
4230: * remove from activefds
4231: */
4232: FD_CLR(fd, &activefds);
4233:
4234: if (fd == maxactivefd && maxactivefd) {
4235: int i;
4236: NTP_INSIST(maxactivefd - 1 < FD_SETSIZE);
4237: for (i = maxactivefd - 1; i >= 0; i--)
4238: if (FD_ISSET(i, &activefds)) {
4239: maxactivefd = i;
4240: break;
4241: }
4242: NTP_INSIST(fd != maxactivefd);
4243: }
4244: #endif
4245: }
4246: }
4247:
4248: static void
4249: add_addr_to_list(
4250: sockaddr_u * addr,
4251: endpt * ep
4252: )
4253: {
4254: remaddr_t *laddr;
4255:
4256: #ifdef DEBUG
4257: if (find_addr_in_list(addr) == NULL) {
4258: #endif
4259: /* not there yet - add to list */
4260: laddr = emalloc(sizeof(*laddr));
4261: laddr->addr = *addr;
4262: laddr->ep = ep;
4263:
4264: LINK_SLIST(remoteaddr_list, laddr, link);
4265:
4266: DPRINTF(4, ("Added addr %s to list of addresses\n",
4267: stoa(addr)));
4268: #ifdef DEBUG
4269: } else
4270: DPRINTF(4, ("WARNING: Attempt to add duplicate addr %s to address list\n",
4271: stoa(addr)));
4272: #endif
4273: }
4274:
4275:
4276: static void
4277: delete_addr_from_list(
4278: sockaddr_u *addr
4279: )
4280: {
4281: remaddr_t *unlinked;
4282:
4283: UNLINK_EXPR_SLIST(unlinked, remoteaddr_list, SOCK_EQ(addr,
4284: &(UNLINK_EXPR_SLIST_CURRENT()->addr)), link, remaddr_t);
4285:
4286: if (unlinked != NULL) {
4287: DPRINTF(4, ("Deleted addr %s from list of addresses\n",
4288: stoa(addr)));
4289: free(unlinked);
4290: }
4291: }
4292:
4293:
4294: static void
4295: delete_interface_from_list(
4296: endpt *iface
4297: )
4298: {
4299: remaddr_t *unlinked;
4300:
4301: do {
4302: UNLINK_EXPR_SLIST(unlinked, remoteaddr_list, iface ==
4303: UNLINK_EXPR_SLIST_CURRENT()->ep, link,
4304: remaddr_t);
4305:
4306: if (unlinked != NULL) {
4307: DPRINTF(4, ("Deleted addr %s for interface #%d %s from list of addresses\n",
4308: stoa(&unlinked->addr), iface->ifnum,
4309: iface->name));
4310: free(unlinked);
4311: }
4312: } while (unlinked != NULL);
4313: }
4314:
4315:
4316: static struct interface *
4317: find_addr_in_list(
4318: sockaddr_u *addr
4319: )
4320: {
4321: remaddr_t *entry;
4322:
4323: DPRINTF(4, ("Searching for addr %s in list of addresses - ",
4324: stoa(addr)));
4325:
4326: for (entry = remoteaddr_list;
4327: entry != NULL;
4328: entry = entry->link)
4329: if (SOCK_EQ(&entry->addr, addr)) {
4330: DPRINTF(4, ("FOUND\n"));
4331: return entry->ep;
4332: }
4333:
4334: DPRINTF(4, ("NOT FOUND\n"));
4335: return NULL;
4336: }
4337:
4338:
4339: /*
4340: * Find the given address with the all given flags set in the list
4341: */
4342: static endpt *
4343: find_flagged_addr_in_list(
4344: sockaddr_u * addr,
4345: u_int32 flags
4346: )
4347: {
4348: remaddr_t *entry;
4349:
4350: DPRINTF(4, ("Finding addr %s with flags %d in list: ",
4351: stoa(addr), flags));
4352:
4353: for (entry = remoteaddr_list;
4354: entry != NULL;
4355: entry = entry->link)
4356:
4357: if (SOCK_EQ(&entry->addr, addr)
4358: && (entry->ep->flags & flags) == flags) {
4359:
4360: DPRINTF(4, ("FOUND\n"));
4361: return entry->ep;
4362: }
4363:
4364: DPRINTF(4, ("NOT FOUND\n"));
4365: return NULL;
4366: }
4367:
4368:
4369: const char *
4370: localaddrtoa(
4371: endpt *la
4372: )
4373: {
4374: return (NULL == la)
4375: ? "<null>"
4376: : stoa(&la->sin);
4377: }
4378:
4379:
4380: #ifdef HAS_ROUTING_SOCKET
4381: # ifndef UPDATE_GRACE
4382: # define UPDATE_GRACE 2 /* wait UPDATE_GRACE seconds before scanning */
4383: # endif
4384:
4385: static void
4386: process_routing_msgs(struct asyncio_reader *reader)
4387: {
4388: char buffer[5120];
4389: int cnt, msg_type;
4390: #ifdef HAVE_RTNETLINK
4391: struct nlmsghdr *nh;
4392: #else
4393: struct rt_msghdr *rtm;
4394: char *p;
4395: #endif
4396:
4397: if (disable_dynamic_updates) {
4398: /*
4399: * discard ourselves if we are not needed any more
4400: * usually happens when running unprivileged
4401: */
4402: remove_asyncio_reader(reader);
4403: delete_asyncio_reader(reader);
4404: return;
4405: }
4406:
4407: cnt = read(reader->fd, buffer, sizeof(buffer));
4408:
4409: if (cnt < 0) {
4410: msyslog(LOG_ERR,
4411: "i/o error on routing socket %m - disabling");
4412: remove_asyncio_reader(reader);
4413: delete_asyncio_reader(reader);
4414: return;
4415: }
4416:
4417: /*
4418: * process routing message
4419: */
4420: #ifdef HAVE_RTNETLINK
4421: for (nh = (struct nlmsghdr *)buffer;
4422: NLMSG_OK(nh, cnt);
4423: nh = NLMSG_NEXT(nh, cnt)) {
4424: msg_type = nh->nlmsg_type;
4425: #else
4426: for (p = buffer;
4427: (p + sizeof(struct rt_msghdr)) <= (buffer + cnt);
4428: p += rtm->rtm_msglen) {
4429: rtm = (struct rt_msghdr *)p;
4430: if (rtm->rtm_version != RTM_VERSION) {
4431: msyslog(LOG_ERR,
4432: "version mismatch (got %d - expected %d) on routing socket - disabling",
4433: rtm->rtm_version, RTM_VERSION);
4434:
4435: remove_asyncio_reader(reader);
4436: delete_asyncio_reader(reader);
4437: return;
4438: }
4439: msg_type = rtm->rtm_type;
4440: #endif
4441: switch (msg_type) {
4442: #ifdef RTM_NEWADDR
4443: case RTM_NEWADDR:
4444: #endif
4445: #ifdef RTM_DELADDR
4446: case RTM_DELADDR:
4447: #endif
4448: #ifdef RTM_ADD
4449: case RTM_ADD:
4450: #endif
4451: #ifdef RTM_DELETE
4452: case RTM_DELETE:
4453: #endif
4454: #ifdef RTM_REDIRECT
4455: case RTM_REDIRECT:
4456: #endif
4457: #ifdef RTM_CHANGE
4458: case RTM_CHANGE:
4459: #endif
4460: #ifdef RTM_LOSING
4461: case RTM_LOSING:
4462: #endif
4463: #ifdef RTM_IFINFO
4464: case RTM_IFINFO:
4465: #endif
4466: #ifdef RTM_IFANNOUNCE
4467: case RTM_IFANNOUNCE:
4468: #endif
4469: #ifdef RTM_NEWLINK
4470: case RTM_NEWLINK:
4471: #endif
4472: #ifdef RTM_DELLINK
4473: case RTM_DELLINK:
4474: #endif
4475: #ifdef RTM_NEWROUTE
4476: case RTM_NEWROUTE:
4477: #endif
4478: #ifdef RTM_DELROUTE
4479: case RTM_DELROUTE:
4480: #endif
4481: /*
4482: * we are keen on new and deleted addresses and
4483: * if an interface goes up and down or routing
4484: * changes
4485: */
4486: DPRINTF(3, ("routing message op = %d: scheduling interface update\n",
4487: msg_type));
4488: timer_interfacetimeout(current_time + UPDATE_GRACE);
4489: break;
4490: #ifdef HAVE_RTNETLINK
4491: case NLMSG_DONE:
4492: /* end of multipart message */
4493: return;
4494: #endif
4495: default:
4496: /*
4497: * the rest doesn't bother us.
4498: */
4499: DPRINTF(4, ("routing message op = %d: ignored\n",
4500: msg_type));
4501: break;
4502: }
4503: }
4504: }
4505:
4506: /*
4507: * set up routing notifications
4508: */
4509: static void
4510: init_async_notifications()
4511: {
4512: struct asyncio_reader *reader;
4513: #ifdef HAVE_RTNETLINK
4514: int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
4515: struct sockaddr_nl sa;
4516: #else
4517: int fd = socket(PF_ROUTE, SOCK_RAW, 0);
4518: #endif
4519: if (fd < 0) {
4520: msyslog(LOG_ERR,
4521: "unable to open routing socket (%m) - using polled interface update");
4522: return;
4523: }
4524:
4525: fd = move_fd(fd);
4526: #ifdef HAVE_RTNETLINK
4527: memset(&sa, 0, sizeof(sa));
4528: sa.nl_family = PF_NETLINK;
4529: sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR
4530: | RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_ROUTE
4531: | RTMGRP_IPV4_MROUTE | RTMGRP_IPV6_ROUTE
4532: | RTMGRP_IPV6_MROUTE;
4533: if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
4534: msyslog(LOG_ERR,
4535: "bind failed on routing socket (%m) - using polled interface update");
4536: return;
4537: }
4538: #endif
4539: init_nonblocking_io(fd);
4540: #if defined(HAVE_SIGNALED_IO)
4541: init_socket_sig(fd);
4542: #endif /* HAVE_SIGNALED_IO */
4543:
4544: reader = new_asyncio_reader();
4545:
4546: reader->fd = fd;
4547: reader->receiver = process_routing_msgs;
4548:
4549: add_asyncio_reader(reader, FD_TYPE_SOCKET);
4550: msyslog(LOG_INFO,
4551: "Listening on routing socket on fd #%d for interface updates",
4552: fd);
4553: }
4554: #else
4555: /* HAS_ROUTING_SOCKET not defined */
4556: static void
4557: init_async_notifications(void)
4558: {
4559: }
4560: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>