Annotation of embedaddon/ntp/ntpd/ntp_io.c, revision 1.1.1.1.2.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: {
1.1.1.1.2.1! misho 1672: unsigned char zerobuf[8];
! 1673:
1.1 misho 1674: if (IS_IPV4(psau) && !NSRCADR(psau))
1675: return 1;
1676:
1677: #ifdef INCLUDE_IPV6_SUPPORT
1678: if (IS_IPV6(psau) && S_ADDR6_EQ(psau, &in6addr_any))
1679: return 1;
1.1.1.1.2.1! misho 1680: bzero(zerobuf, sizeof(zerobuf));
! 1681: // If the host portion is all 0, then assume it's a router's anycast address.
! 1682: if (IS_IPV6(psau) && memcmp((char*)(&((struct sockaddr_in6*)psau)->sin6_addr) + 8, zerobuf, 8) == 0)
! 1683: return 1;
1.1 misho 1684: #endif
1685:
1686: return 0;
1687: }
1688:
1689:
1690: #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
1691: /*
1692: * enable/disable re-use of wildcard address socket
1693: */
1694: static void
1695: set_wildcard_reuse(
1696: u_short family,
1697: int on
1698: )
1699: {
1700: struct interface *any;
1701: SOCKET fd = INVALID_SOCKET;
1702:
1703: any = ANY_INTERFACE_BYFAM(family);
1704: if (any != NULL)
1705: fd = any->fd;
1706:
1707: if (fd != INVALID_SOCKET) {
1708: if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1709: (char *)&on, sizeof(on)))
1710: msyslog(LOG_ERR,
1711: "set_wildcard_reuse: setsockopt(SO_REUSEADDR, %s) failed: %m",
1712: on ? "on" : "off");
1713:
1714: DPRINTF(4, ("set SO_REUSEADDR to %s on %s\n",
1715: on ? "on" : "off",
1716: stoa(&any->sin)));
1717: }
1718: }
1719: #endif /* OS_NEEDS_REUSEADDR_FOR_IFADDRBIND */
1720:
1721:
1722: static isc_boolean_t
1723: is_anycast(
1724: sockaddr_u *psau,
1725: const char *name
1726: )
1727: {
1728: #if defined(INCLUDE_IPV6_SUPPORT) && defined(SIOCGIFAFLAG_IN6) && \
1729: defined(IN6_IFF_ANYCAST)
1730: struct in6_ifreq ifr6;
1731: int fd;
1732: u_int32 flags6;
1733:
1734: if (psau->sa.sa_family != AF_INET6)
1735: return ISC_FALSE;
1736: if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
1737: return ISC_FALSE;
1738: memset(&ifr6, 0, sizeof(ifr6));
1739: memcpy(&ifr6.ifr_addr, &psau->sa6, sizeof(ifr6.ifr_addr));
1740: strncpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name));
1741: if (ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
1742: close(fd);
1743: return ISC_FALSE;
1744: }
1745: close(fd);
1746: flags6 = ifr6.ifr_ifru.ifru_flags6;
1747: if ((flags6 & IN6_IFF_ANYCAST) != 0)
1748: return ISC_TRUE;
1749: #endif /* INCLUDE_IPV6_SUPPORT && SIOCGIFAFLAG_IN6 && IN6_IFF_ANYCAST */
1750: return ISC_FALSE;
1751: }
1752:
1753:
1754: /*
1755: * update_interface strategy
1756: *
1757: * toggle configuration phase
1758: *
1759: * Phase 1:
1760: * forall currently existing interfaces
1761: * if address is known:
1762: * drop socket - rebind again
1763: *
1764: * if address is NOT known:
1765: * attempt to create a new interface entry
1766: *
1767: * Phase 2:
1768: * forall currently known non MCAST and WILDCARD interfaces
1769: * if interface does not match configuration phase (not seen in phase 1):
1770: * remove interface from known interface list
1771: * forall peers associated with this interface
1772: * disconnect peer from this interface
1773: *
1774: * Phase 3:
1775: * attempt to re-assign interfaces to peers
1776: *
1777: */
1778:
1779: static int
1780: update_interfaces(
1781: u_short port,
1782: interface_receiver_t receiver,
1783: void * data
1784: )
1785: {
1786: isc_mem_t * mctx = (void *)-1;
1787: interface_info_t ifi;
1788: isc_interfaceiter_t * iter;
1789: isc_result_t result;
1790: isc_interface_t isc_if;
1791: int new_interface_found;
1792: int refresh_peers;
1793: unsigned int family;
1794: endpt enumep;
1795: endpt * ep;
1796: endpt * next_ep;
1797:
1798: DPRINTF(3, ("update_interfaces(%d)\n", port));
1799:
1800: /*
1801: * phase one - scan interfaces
1802: * - create those that are not found
1803: * - update those that are found
1804: */
1805:
1806: new_interface_found = FALSE;
1807: refresh_peers = FALSE;
1808: iter = NULL;
1809: result = isc_interfaceiter_create(mctx, &iter);
1810:
1811: if (result != ISC_R_SUCCESS)
1812: return 0;
1813:
1814: /*
1815: * Toggle system interface scan phase to find untouched
1816: * interfaces to be deleted.
1817: */
1818: sys_interphase ^= 0x1;
1819:
1820: for (result = isc_interfaceiter_first(iter);
1821: ISC_R_SUCCESS == result;
1822: result = isc_interfaceiter_next(iter)) {
1823:
1824: result = isc_interfaceiter_current(iter, &isc_if);
1825:
1826: if (result != ISC_R_SUCCESS)
1827: break;
1828:
1829: /* See if we have a valid family to use */
1830: family = isc_if.address.family;
1831: if (AF_INET != family && AF_INET6 != family)
1832: continue;
1833: if (AF_INET == family && !ipv4_works)
1834: continue;
1835: if (AF_INET6 == family && !ipv6_works)
1836: continue;
1837:
1838: /* create prototype */
1839: init_interface(&enumep);
1840:
1841: convert_isc_if(&isc_if, &enumep, port);
1842:
1843: /*
1844: * Check if and how we are going to use the interface.
1845: */
1846: switch (interface_action(enumep.name, &enumep.sin,
1847: enumep.flags)) {
1848:
1849: case ACTION_IGNORE:
1850: continue;
1851:
1852: case ACTION_LISTEN:
1853: enumep.ignore_packets = ISC_FALSE;
1854: break;
1855:
1856: case ACTION_DROP:
1857: enumep.ignore_packets = ISC_TRUE;
1858: break;
1859: }
1860:
1861: DPRINT_INTERFACE(4, (&enumep, "examining ", "\n"));
1862:
1863: /* interfaces must be UP to be usable */
1864: if (!(enumep.flags & INT_UP)) {
1865: DPRINTF(4, ("skipping interface %s (%s) - DOWN\n",
1866: enumep.name, stoa(&enumep.sin)));
1867: continue;
1868: }
1869:
1870: /*
1871: * skip any interfaces UP and bound to a wildcard
1872: * address - some dhcp clients produce that in the
1873: * wild
1874: */
1875: if (is_wildcard_addr(&enumep.sin))
1876: continue;
1877:
1878: if (is_anycast(&enumep.sin, isc_if.name))
1879: continue;
1880:
1881: /*
1882: * map to local *address* in order to map all duplicate
1883: * interfaces to an endpt structure with the appropriate
1884: * socket. Our name space is (ip-address), NOT
1885: * (interface name, ip-address).
1886: */
1887: ep = getinterface(&enumep.sin, INT_WILDCARD);
1888:
1889: if (ep != NULL && refresh_interface(ep)) {
1890: /*
1891: * found existing and up to date interface -
1892: * mark present.
1893: */
1894: if (ep->phase != sys_interphase) {
1895: /*
1896: * On a new round we reset the name so
1897: * the interface name shows up again if
1898: * this address is no longer shared.
1899: * We reset ignore_packets from the
1900: * new prototype to respect any runtime
1901: * changes to the nic rules.
1902: */
1903: strncpy(ep->name, enumep.name,
1904: sizeof(ep->name));
1905: if (ep->ignore_packets !=
1906: enumep.ignore_packets) {
1907: ep->ignore_packets =
1908: enumep.ignore_packets;
1909: refresh_peers = TRUE;
1910: DPRINTF(4, ("refreshing peers due to %s ignore_packets change to %d\n",
1911: stoa(&ep->sin),
1912: ep->ignore_packets));
1913: }
1914: } else {
1915: /* name collision - rename interface */
1916: strncpy(ep->name, "*multiple*",
1917: sizeof(ep->name));
1918: }
1919:
1920: DPRINT_INTERFACE(4, (ep, "updating ",
1921: " present\n"));
1922:
1923: if (ep->ignore_packets !=
1924: enumep.ignore_packets) {
1925: /*
1926: * We have conflicting configurations
1927: * for the interface address. This is
1928: * caused by using -I <interfacename>
1929: * for an interface that shares its
1930: * address with other interfaces. We
1931: * can not disambiguate incoming
1932: * packets delivered to this socket
1933: * without extra syscalls/features.
1934: * These are not (commonly) available.
1935: * Note this is a more unusual
1936: * configuration where several
1937: * interfaces share an address but
1938: * filtering via interface name is
1939: * attempted. We resolve the
1940: * configuration conflict by disabling
1941: * the processing of received packets.
1942: * This leads to no service on the
1943: * interface address where the conflict
1944: * occurs.
1945: */
1946: msyslog(LOG_ERR,
1947: "WARNING: conflicting enable configuration for interfaces %s and %s for address %s - unsupported configuration - address DISABLED",
1948: enumep.name, ep->name,
1949: stoa(&enumep.sin));
1950:
1951: ep->ignore_packets = ISC_TRUE;
1952: }
1953:
1954: ep->phase = sys_interphase;
1955:
1956: ifi.action = IFS_EXISTS;
1957: ifi.ep = ep;
1958: if (receiver != NULL)
1959: (*receiver)(data, &ifi);
1960: } else {
1961: /*
1962: * This is new or refreshing failed - add to
1963: * our interface list. If refreshing failed we
1964: * will delete the interface structure in phase
1965: * 2 as the interface was not marked current.
1966: * We can bind to the address as the refresh
1967: * code already closed the offending socket
1968: */
1969: ep = create_interface(port, &enumep);
1970:
1971: if (ep != NULL) {
1972: ifi.action = IFS_CREATED;
1973: ifi.ep = ep;
1974: if (receiver != NULL)
1975: (*receiver)(data, &ifi);
1976:
1977: new_interface_found = TRUE;
1978: refresh_peers = TRUE;
1979: DPRINTF(4, ("refreshing peers due to new addr %s\n",
1980: stoa(&ep->sin)));
1981: DPRINT_INTERFACE(3,
1982: (ep, "updating ",
1983: " new - created\n"));
1984: } else {
1985: DPRINT_INTERFACE(3,
1986: (&enumep, "updating ",
1987: " new - creation FAILED"));
1988:
1989: msyslog(LOG_INFO,
1990: "failed to init interface for address %s",
1991: stoa(&enumep.sin));
1992: continue;
1993: }
1994: }
1995: }
1996:
1997: isc_interfaceiter_destroy(&iter);
1998:
1999: /*
2000: * phase 2 - delete gone interfaces - reassigning peers to
2001: * other interfaces
2002: */
2003: for (ep = ep_list; ep != NULL; ep = next_ep) {
2004: next_ep = ep->elink;
2005:
2006: /*
2007: * if phase does not match sys_phase this interface was
2008: * not enumerated during the last interface scan - so it
2009: * is gone and will be deleted here unless it did not
2010: * originate from interface enumeration (INT_WILDCARD,
2011: * INT_MCASTIF).
2012: */
2013: if (((INT_WILDCARD | INT_MCASTIF) & ep->flags) ||
2014: ep->phase == sys_interphase)
2015: continue;
2016:
2017: DPRINT_INTERFACE(3, (ep, "updating ",
2018: "GONE - deleting\n"));
2019: remove_interface(ep);
2020: refresh_peers = TRUE;
2021: DPRINTF(4, ("refreshing peers due to deleted addr %s",
2022: stoa(&ep->sin)));
2023:
2024: ifi.action = IFS_DELETED;
2025: ifi.ep = ep;
2026: if (receiver != NULL)
2027: (*receiver)(data, &ifi);
2028:
2029: /* disconnect peers from deleted endpt. */
2030: while (ep->peers != NULL)
2031: set_peerdstadr(ep->peers, NULL);
2032:
2033: /*
2034: * update globals in case we lose
2035: * a loopback interface
2036: */
2037: if (ep == loopback_interface)
2038: loopback_interface = NULL;
2039:
2040: delete_interface(ep);
2041: }
2042:
2043: /*
2044: * phase 3 - re-configure as the world has changed if necessary
2045: */
2046: if (refresh_peers) {
2047: refresh_all_peerinterfaces();
2048: msyslog(LOG_INFO, "peers refreshed");
2049: }
2050:
2051: return new_interface_found;
2052: }
2053:
2054:
2055: /*
2056: * create_sockets - create a socket for each interface plus a default
2057: * socket for when we don't know where to send
2058: */
2059: static int
2060: create_sockets(
2061: u_short port
2062: )
2063: {
2064: #ifndef HAVE_IO_COMPLETION_PORT
2065: /*
2066: * I/O Completion Ports don't care about the select and FD_SET
2067: */
2068: maxactivefd = 0;
2069: FD_ZERO(&activefds);
2070: #endif
2071:
2072: DPRINTF(2, ("create_sockets(%d)\n", port));
2073:
2074: create_wildcards(port);
2075:
2076: update_interfaces(port, NULL, NULL);
2077:
2078: /*
2079: * Now that we have opened all the sockets, turn off the reuse
2080: * flag for security.
2081: */
2082: set_reuseaddr(0);
2083:
2084: DPRINTF(2, ("create_sockets: Total interfaces = %d\n", ninterfaces));
2085:
2086: return ninterfaces;
2087: }
2088:
2089: /*
2090: * create_interface - create a new interface for a given prototype
2091: * binding the socket.
2092: */
2093: static struct interface *
2094: create_interface(
2095: u_short port,
2096: struct interface * protot
2097: )
2098: {
2099: sockaddr_u resmask;
2100: endpt * iface;
2101: #if defined(MCAST) && defined(MULTICAST_NONEWSOCKET)
2102: remaddr_t * entry;
2103: remaddr_t * next_entry;
2104: #endif
2105: DPRINTF(2, ("create_interface(%s#%d)\n", stoa(&protot->sin),
2106: port));
2107:
2108: /* build an interface */
2109: iface = new_interface(protot);
2110:
2111: /*
2112: * create socket
2113: */
2114: iface->fd = open_socket(&iface->sin, 0, 0, iface);
2115:
2116: if (iface->fd != INVALID_SOCKET)
2117: log_listen_address(iface);
2118:
2119: if ((INT_BROADCAST & iface->flags)
2120: && iface->bfd != INVALID_SOCKET)
2121: msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
2122: stoa((&iface->bcast)), port);
2123:
2124: if (INVALID_SOCKET == iface->fd
2125: && INVALID_SOCKET == iface->bfd) {
2126: msyslog(LOG_ERR, "unable to create socket on %s (%d) for %s#%d",
2127: iface->name,
2128: iface->ifnum,
2129: stoa((&iface->sin)),
2130: port);
2131: delete_interface(iface);
2132: return NULL;
2133: }
2134:
2135: /*
2136: * Blacklist our own addresses, no use talking to ourself
2137: */
2138: SET_HOSTMASK(&resmask, AF(&iface->sin));
2139: hack_restrict(RESTRICT_FLAGS, &iface->sin, &resmask,
2140: RESM_NTPONLY | RESM_INTERFACE, RES_IGNORE);
2141:
2142: /*
2143: * set globals with the first found
2144: * loopback interface of the appropriate class
2145: */
2146: if (NULL == loopback_interface && AF_INET == iface->family
2147: && (INT_LOOPBACK & iface->flags))
2148: loopback_interface = iface;
2149:
2150: /*
2151: * put into our interface list
2152: */
2153: add_addr_to_list(&iface->sin, iface);
2154: add_interface(iface);
2155:
2156: #if defined(MCAST) && defined(MULTICAST_NONEWSOCKET)
2157: /*
2158: * Join any previously-configured compatible multicast groups.
2159: */
2160: if (INT_MULTICAST & iface->flags &&
2161: !((INT_LOOPBACK | INT_WILDCARD) & iface->flags) &&
2162: !iface->ignore_packets) {
2163: for (entry = remoteaddr_list;
2164: entry != NULL;
2165: entry = next_entry) {
2166: next_entry = entry->link;
2167: if (AF(&iface->sin) != AF(&entry->addr) ||
2168: !IS_MCAST(&entry->addr))
2169: continue;
2170: if (socket_multicast_enable(iface,
2171: &entry->addr))
2172: msyslog(LOG_INFO,
2173: "Joined %s socket to multicast group %s",
2174: stoa(&iface->sin),
2175: stoa(&entry->addr));
2176: else
2177: msyslog(LOG_ERR,
2178: "Failed to join %s socket to multicast group %s",
2179: stoa(&iface->sin),
2180: stoa(&entry->addr));
2181: }
2182: }
2183: #endif /* MCAST && MCAST_NONEWSOCKET */
2184:
2185: DPRINT_INTERFACE(2, (iface, "created ", "\n"));
2186: return iface;
2187: }
2188:
2189:
2190: #ifdef SO_EXCLUSIVEADDRUSE
2191: static void
2192: set_excladdruse(
2193: SOCKET fd
2194: )
2195: {
2196: int one = 1;
2197: int failed;
2198: #ifdef SYS_WINNT
2199: DWORD err;
2200: #endif
2201:
2202: failed = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
2203: (char *)&one, sizeof(one));
2204:
2205: if (!failed)
2206: return;
2207:
2208: #ifdef SYS_WINNT
2209: /*
2210: * Prior to Windows XP setting SO_EXCLUSIVEADDRUSE can fail with
2211: * error WSAINVAL depending on service pack level and whether
2212: * the user account is in the Administrators group. Do not
2213: * complain if it fails that way on versions prior to XP (5.1).
2214: */
2215: err = GetLastError();
2216:
2217: if (isc_win32os_versioncheck(5, 1, 0, 0) < 0 /* < 5.1/XP */
2218: && WSAEINVAL == err)
2219: return;
2220:
2221: SetLastError(err);
2222: #endif
2223: msyslog(LOG_ERR,
2224: "setsockopt(%d, SO_EXCLUSIVEADDRUSE, on): %m",
2225: (int)fd);
2226: }
2227: #endif /* SO_EXCLUSIVEADDRUSE */
2228:
2229:
2230: /*
2231: * set_reuseaddr() - set/clear REUSEADDR on all sockets
2232: * NB possible hole - should we be doing this on broadcast
2233: * fd's also?
2234: */
2235: static void
2236: set_reuseaddr(
2237: int flag
2238: )
2239: {
2240: #ifndef SO_EXCLUSIVEADDRUSE
2241: endpt *ep;
2242:
2243: for (ep = ep_list; ep != NULL; ep = ep->elink) {
2244: if (ep->flags & INT_WILDCARD)
2245: continue;
2246:
2247: /*
2248: * if ep->fd is INVALID_SOCKET, we might have a adapter
2249: * configured but not present
2250: */
2251: DPRINTF(4, ("setting SO_REUSEADDR on %.16s@%s to %s\n",
2252: ep->name, stoa(&ep->sin),
2253: flag ? "on" : "off"));
2254:
2255: if (ep->fd != INVALID_SOCKET) {
2256: if (setsockopt(ep->fd, SOL_SOCKET, SO_REUSEADDR,
2257: (char *)&flag, sizeof(flag))) {
2258: msyslog(LOG_ERR, "set_reuseaddr: setsockopt(%s, SO_REUSEADDR, %s) failed: %m",
2259: stoa(&ep->sin), flag ? "on" : "off");
2260: }
2261: }
2262: }
2263: #endif /* ! SO_EXCLUSIVEADDRUSE */
2264: }
2265:
2266: /*
2267: * This is just a wrapper around an internal function so we can
2268: * make other changes as necessary later on
2269: */
2270: void
2271: enable_broadcast(
2272: struct interface * iface,
2273: sockaddr_u * baddr
2274: )
2275: {
2276: #ifdef OPEN_BCAST_SOCKET
2277: socket_broadcast_enable(iface, iface->fd, baddr);
2278: #endif
2279: }
2280:
2281: #ifdef OPEN_BCAST_SOCKET
2282: /*
2283: * Enable a broadcast address to a given socket
2284: * The socket is in the inter_list all we need to do is enable
2285: * broadcasting. It is not this function's job to select the socket
2286: */
2287: static isc_boolean_t
2288: socket_broadcast_enable(
2289: struct interface * iface,
2290: SOCKET fd,
2291: sockaddr_u * baddr
2292: )
2293: {
2294: #ifdef SO_BROADCAST
2295: int on = 1;
2296:
2297: if (IS_IPV4(baddr)) {
2298: /* if this interface can support broadcast, set SO_BROADCAST */
2299: if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
2300: (char *)&on, sizeof(on)))
2301: msyslog(LOG_ERR,
2302: "setsockopt(SO_BROADCAST) enable failure on address %s: %m",
2303: stoa(baddr));
2304: else
2305: DPRINTF(2, ("Broadcast enabled on socket %d for address %s\n",
2306: fd, stoa(baddr)));
2307: }
2308: iface->flags |= INT_BCASTOPEN;
2309: broadcast_client_enabled = ISC_TRUE;
2310: return ISC_TRUE;
2311: #else
2312: return ISC_FALSE;
2313: #endif /* SO_BROADCAST */
2314: }
2315:
2316: /*
2317: * Remove a broadcast address from a given socket
2318: * The socket is in the inter_list all we need to do is disable
2319: * broadcasting. It is not this function's job to select the socket
2320: */
2321: static isc_boolean_t
2322: socket_broadcast_disable(
2323: struct interface * iface,
2324: sockaddr_u * baddr
2325: )
2326: {
2327: #ifdef SO_BROADCAST
2328: int off = 0; /* This seems to be OK as an int */
2329:
2330: if (IS_IPV4(baddr) && setsockopt(iface->fd, SOL_SOCKET,
2331: SO_BROADCAST, (char *)&off, sizeof(off)))
2332: msyslog(LOG_ERR,
2333: "setsockopt(SO_BROADCAST) disable failure on address %s: %m",
2334: stoa(baddr));
2335:
2336: iface->flags &= ~INT_BCASTOPEN;
2337: broadcast_client_enabled = ISC_FALSE;
2338: return ISC_TRUE;
2339: #else
2340: return ISC_FALSE;
2341: #endif /* SO_BROADCAST */
2342: }
2343:
2344: #endif /* OPEN_BCAST_SOCKET */
2345:
2346: /*
2347: * return the broadcast client flag value
2348: */
2349: isc_boolean_t
2350: get_broadcastclient_flag(void)
2351: {
2352: return (broadcast_client_enabled);
2353: }
2354: /*
2355: * Check to see if the address is a multicast address
2356: */
2357: static isc_boolean_t
2358: addr_ismulticast(
2359: sockaddr_u *maddr
2360: )
2361: {
2362: isc_boolean_t result;
2363:
2364: #ifndef INCLUDE_IPV6_MULTICAST_SUPPORT
2365: /*
2366: * If we don't have IPV6 support any IPV6 addr is not multicast
2367: */
2368: if (IS_IPV6(maddr))
2369: result = ISC_FALSE;
2370: else
2371: #endif
2372: result = IS_MCAST(maddr);
2373:
2374: if (!result)
2375: DPRINTF(4, ("address %s is not multicast\n",
2376: stoa(maddr)));
2377:
2378: return result;
2379: }
2380:
2381: /*
2382: * Multicast servers need to set the appropriate Multicast interface
2383: * socket option in order for it to know which interface to use for
2384: * send the multicast packet.
2385: */
2386: void
2387: enable_multicast_if(
2388: struct interface * iface,
2389: sockaddr_u * maddr
2390: )
2391: {
2392: #ifdef MCAST
2393: TYPEOF_IP_MULTICAST_LOOP off = 0;
2394:
2395: NTP_REQUIRE(AF(maddr) == AF(&iface->sin));
2396:
2397: switch (AF(&iface->sin)) {
2398:
2399: case AF_INET:
2400: #ifdef IP_MULTICAST_LOOP
2401: /*
2402: * Don't send back to itself, but allow failure to set
2403: */
2404: if (setsockopt(iface->fd, IPPROTO_IP,
2405: IP_MULTICAST_LOOP,
2406: SETSOCKOPT_ARG_CAST &off,
2407: sizeof(off))) {
2408:
2409: msyslog(LOG_ERR,
2410: "setsockopt IP_MULTICAST_LOOP failed: %m on socket %d, addr %s for multicast address %s",
2411: iface->fd, stoa(&iface->sin),
2412: stoa(maddr));
2413: }
2414: #endif
2415: break;
2416:
2417: case AF_INET6:
2418: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2419: #ifdef IPV6_MULTICAST_LOOP
2420: /*
2421: * Don't send back to itself, but allow failure to set
2422: */
2423: if (setsockopt(iface->fd, IPPROTO_IPV6,
2424: IPV6_MULTICAST_LOOP,
2425: (char *) &off, sizeof(off))) {
2426:
2427: msyslog(LOG_ERR,
2428: "setsockopt IP_MULTICAST_LOOP failed: %m on socket %d, addr %s for multicast address %s",
2429: iface->fd, stoa(&iface->sin),
2430: stoa(maddr));
2431: }
2432: #endif
2433: break;
2434: #else
2435: return;
2436: #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
2437: }
2438: return;
2439: #endif
2440: }
2441:
2442: /*
2443: * Add a multicast address to a given socket
2444: * The socket is in the inter_list all we need to do is enable
2445: * multicasting. It is not this function's job to select the socket
2446: */
2447: #if defined(MCAST)
2448: static isc_boolean_t
2449: socket_multicast_enable(
2450: endpt * iface,
2451: sockaddr_u * maddr
2452: )
2453: {
2454: struct ip_mreq mreq;
2455: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2456: struct ipv6_mreq mreq6;
2457: #endif
2458: switch (AF(maddr)) {
2459:
2460: case AF_INET:
2461: memset(&mreq, 0, sizeof(mreq));
2462: mreq.imr_multiaddr = SOCK_ADDR4(maddr);
2463: mreq.imr_interface.s_addr = htonl(INADDR_ANY);
2464: if (setsockopt(iface->fd,
2465: IPPROTO_IP,
2466: IP_ADD_MEMBERSHIP,
2467: (char *)&mreq,
2468: sizeof(mreq))) {
2469: msyslog(LOG_ERR,
2470: "setsockopt IP_ADD_MEMBERSHIP failed: %m on socket %d, addr %s for %x / %x (%s)",
2471: iface->fd, stoa(&iface->sin),
2472: mreq.imr_multiaddr.s_addr,
2473: mreq.imr_interface.s_addr,
2474: stoa(maddr));
2475: return ISC_FALSE;
2476: }
2477: DPRINTF(4, ("Added IPv4 multicast membership on socket %d, addr %s for %x / %x (%s)\n",
2478: iface->fd, stoa(&iface->sin),
2479: mreq.imr_multiaddr.s_addr,
2480: mreq.imr_interface.s_addr, stoa(maddr)));
2481: break;
2482:
2483: case AF_INET6:
2484: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2485: /*
2486: * Enable reception of multicast packets.
2487: * If the address is link-local we can get the
2488: * interface index from the scope id. Don't do this
2489: * for other types of multicast addresses. For now let
2490: * the kernel figure it out.
2491: */
2492: memset(&mreq6, 0, sizeof(mreq6));
2493: mreq6.ipv6mr_multiaddr = SOCK_ADDR6(maddr);
2494: mreq6.ipv6mr_interface = iface->ifindex;
2495:
2496: if (setsockopt(iface->fd, IPPROTO_IPV6,
2497: IPV6_JOIN_GROUP, (char *)&mreq6,
2498: sizeof(mreq6))) {
2499: msyslog(LOG_ERR,
2500: "setsockopt IPV6_JOIN_GROUP failed: %m on socket %d, addr %s for interface %u (%s)",
2501: iface->fd, stoa(&iface->sin),
2502: mreq6.ipv6mr_interface, stoa(maddr));
2503: return ISC_FALSE;
2504: }
2505: DPRINTF(4, ("Added IPv6 multicast group on socket %d, addr %s for interface %u (%s)\n",
2506: iface->fd, stoa(&iface->sin),
2507: mreq6.ipv6mr_interface, stoa(maddr)));
2508: #else
2509: return ISC_FALSE;
2510: #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
2511: }
2512: iface->flags |= INT_MCASTOPEN;
2513: iface->num_mcast++;
2514:
2515: return ISC_TRUE;
2516: }
2517: #endif /* MCAST */
2518:
2519:
2520: /*
2521: * Remove a multicast address from a given socket
2522: * The socket is in the inter_list all we need to do is disable
2523: * multicasting. It is not this function's job to select the socket
2524: */
2525: #ifdef MCAST
2526: static isc_boolean_t
2527: socket_multicast_disable(
2528: struct interface * iface,
2529: sockaddr_u * maddr
2530: )
2531: {
2532: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2533: struct ipv6_mreq mreq6;
2534: #endif
2535: struct ip_mreq mreq;
2536:
2537: memset(&mreq, 0, sizeof(mreq));
2538:
2539: if (find_addr_in_list(maddr) == NULL) {
2540: DPRINTF(4, ("socket_multicast_disable(%s): not found\n",
2541: stoa(maddr)));
2542: return ISC_TRUE;
2543: }
2544:
2545: switch (AF(maddr)) {
2546:
2547: case AF_INET:
2548: mreq.imr_multiaddr = SOCK_ADDR4(maddr);
2549: mreq.imr_interface = SOCK_ADDR4(&iface->sin);
2550: if (setsockopt(iface->fd, IPPROTO_IP,
2551: IP_DROP_MEMBERSHIP, (char *)&mreq,
2552: sizeof(mreq))) {
2553:
2554: msyslog(LOG_ERR,
2555: "setsockopt IP_DROP_MEMBERSHIP failed: %m on socket %d, addr %s for %x / %x (%s)",
2556: iface->fd, stoa(&iface->sin),
2557: SRCADR(maddr), SRCADR(&iface->sin),
2558: stoa(maddr));
2559: return ISC_FALSE;
2560: }
2561: break;
2562: case AF_INET6:
2563: #ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
2564: /*
2565: * Disable reception of multicast packets
2566: * If the address is link-local we can get the
2567: * interface index from the scope id. Don't do this
2568: * for other types of multicast addresses. For now let
2569: * the kernel figure it out.
2570: */
2571: mreq6.ipv6mr_multiaddr = SOCK_ADDR6(maddr);
2572: mreq6.ipv6mr_interface = iface->ifindex;
2573:
2574: if (setsockopt(iface->fd, IPPROTO_IPV6,
2575: IPV6_LEAVE_GROUP, (char *)&mreq6,
2576: sizeof(mreq6))) {
2577:
2578: msyslog(LOG_ERR,
2579: "setsockopt IPV6_LEAVE_GROUP failure: %m on socket %d, addr %s for %d (%s)",
2580: iface->fd, stoa(&iface->sin),
2581: iface->ifindex, stoa(maddr));
2582: return ISC_FALSE;
2583: }
2584: break;
2585: #else
2586: return ISC_FALSE;
2587: #endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
2588: }
2589:
2590: iface->num_mcast--;
2591: if (!iface->num_mcast)
2592: iface->flags &= ~INT_MCASTOPEN;
2593:
2594: return ISC_TRUE;
2595: }
2596: #endif /* MCAST */
2597:
2598: /*
2599: * io_setbclient - open the broadcast client sockets
2600: */
2601: void
2602: io_setbclient(void)
2603: {
2604: #ifdef OPEN_BCAST_SOCKET
2605: struct interface * interf;
2606: int nif;
2607: isc_boolean_t jstatus;
2608: SOCKET fd;
2609:
2610: nif = 0;
2611: set_reuseaddr(1);
2612:
2613: for (interf = ep_list;
2614: interf != NULL;
2615: interf = interf->elink) {
2616:
2617: if (interf->flags & (INT_WILDCARD | INT_LOOPBACK))
2618: continue;
2619:
2620: /* use only allowed addresses */
2621: if (interf->ignore_packets)
2622: continue;
2623:
2624:
2625: /* Need a broadcast-capable interface */
2626: if (!(interf->flags & INT_BROADCAST))
2627: continue;
2628:
2629: /* Only IPv4 addresses are valid for broadcast */
2630: NTP_REQUIRE(IS_IPV4(&interf->sin));
2631:
2632: /* Do we already have the broadcast address open? */
2633: if (interf->flags & INT_BCASTOPEN) {
2634: /*
2635: * account for already open interfaces to avoid
2636: * misleading warning below
2637: */
2638: nif++;
2639: continue;
2640: }
2641:
2642: /*
2643: * Try to open the broadcast address
2644: */
2645: interf->family = AF_INET;
2646: interf->bfd = open_socket(&interf->bcast, 1, 0, interf);
2647:
2648: /*
2649: * If we succeeded then we use it otherwise enable
2650: * broadcast on the interface address
2651: */
2652: if (interf->bfd != INVALID_SOCKET) {
2653: fd = interf->bfd;
2654: jstatus = ISC_TRUE;
2655: } else {
2656: fd = interf->fd;
2657: jstatus = socket_broadcast_enable(interf, fd,
2658: &interf->sin);
2659: }
2660:
2661: /* Enable Broadcast on socket */
2662: if (jstatus) {
2663: nif++;
2664: msyslog(LOG_INFO,
2665: "io_setbclient: Opened broadcast client on interface #%d %s",
2666: interf->ifnum, interf->name);
2667: interf->addr_refid = addr2refid(&interf->sin);
2668: }
2669: }
2670: set_reuseaddr(0);
2671: if (nif > 0)
2672: DPRINTF(1, ("io_setbclient: Opened broadcast clients\n"));
2673: else if (!nif)
2674: msyslog(LOG_ERR,
2675: "Unable to listen for broadcasts, no broadcast interfaces available");
2676: #else
2677: msyslog(LOG_ERR,
2678: "io_setbclient: Broadcast Client disabled by build");
2679: #endif /* OPEN_BCAST_SOCKET */
2680: }
2681:
2682: /*
2683: * io_unsetbclient - close the broadcast client sockets
2684: */
2685: void
2686: io_unsetbclient(void)
2687: {
2688: endpt *ep;
2689:
2690: for (ep = ep_list; ep != NULL; ep = ep->elink) {
2691: if (INT_WILDCARD & ep->flags)
2692: continue;
2693: if (!(INT_BCASTOPEN & ep->flags))
2694: continue;
2695: socket_broadcast_disable(ep, &ep->sin);
2696: }
2697: }
2698:
2699: /*
2700: * io_multicast_add() - add multicast group address
2701: */
2702: void
2703: io_multicast_add(
2704: sockaddr_u *addr
2705: )
2706: {
2707: #ifdef MCAST
2708: endpt * ep;
2709: endpt * one_ep;
2710:
2711: /*
2712: * Check to see if this is a multicast address
2713: */
2714: if (!addr_ismulticast(addr))
2715: return;
2716:
2717: /* If we already have it we can just return */
2718: if (NULL != find_flagged_addr_in_list(addr, INT_MCASTOPEN)) {
2719: msyslog(LOG_INFO,
2720: "Duplicate request found for multicast address %s",
2721: stoa(addr));
2722: return;
2723: }
2724:
2725: #ifndef MULTICAST_NONEWSOCKET
2726: ep = new_interface(NULL);
2727:
2728: /*
2729: * Open a new socket for the multicast address
2730: */
2731: ep->sin = *addr;
2732: SET_PORT(&ep->sin, NTP_PORT);
2733: ep->family = AF(&ep->sin);
2734: AF(&ep->mask) = ep->family;
2735: SET_ONESMASK(&ep->mask);
2736:
2737: set_reuseaddr(1);
2738: ep->bfd = INVALID_SOCKET;
2739: ep->fd = open_socket(&ep->sin, 0, 0, ep);
2740: if (ep->fd != INVALID_SOCKET) {
2741: ep->ignore_packets = ISC_FALSE;
2742: ep->flags |= INT_MCASTIF;
2743:
2744: strncpy(ep->name, "multicast", sizeof(ep->name));
2745: DPRINT_INTERFACE(2, (ep, "multicast add ", "\n"));
2746: add_interface(ep);
2747: log_listen_address(ep);
2748: } else {
2749: /* bind failed, re-use wildcard interface */
2750: delete_interface(ep);
2751:
2752: if (IS_IPV4(addr))
2753: ep = wildipv4;
2754: else if (IS_IPV6(addr))
2755: ep = wildipv6;
2756: else
2757: ep = NULL;
2758:
2759: if (ep != NULL) {
2760: /* HACK ! -- stuff in an address */
2761: /* because we don't bind addr? DH */
2762: ep->bcast = *addr;
2763: msyslog(LOG_ERR,
2764: "multicast address %s using wildcard interface #%d %s",
2765: stoa(addr), ep->ifnum, ep->name);
2766: } else {
2767: msyslog(LOG_ERR,
2768: "No multicast socket available to use for address %s",
2769: stoa(addr));
2770: return;
2771: }
2772: }
2773: { /* in place of the { following for in #else clause */
2774: one_ep = ep;
2775: #else /* MULTICAST_NONEWSOCKET follows */
2776: /*
2777: * For the case where we can't use a separate socket (Windows)
2778: * join each applicable endpoint socket to the group address.
2779: */
2780: if (IS_IPV4(addr))
2781: one_ep = wildipv4;
2782: else
2783: one_ep = wildipv6;
2784: for (ep = ep_list; ep != NULL; ep = ep->elink) {
2785: if (ep->ignore_packets || AF(&ep->sin) != AF(addr) ||
2786: !(INT_MULTICAST & ep->flags) ||
2787: (INT_LOOPBACK | INT_WILDCARD) & ep->flags)
2788: continue;
2789: one_ep = ep;
2790: #endif /* MULTICAST_NONEWSOCKET */
2791: if (socket_multicast_enable(ep, addr))
2792: msyslog(LOG_INFO,
2793: "Joined %s socket to multicast group %s",
2794: stoa(&ep->sin),
2795: stoa(addr));
2796: else
2797: msyslog(LOG_ERR,
2798: "Failed to join %s socket to multicast group %s",
2799: stoa(&ep->sin),
2800: stoa(addr));
2801: }
2802:
2803: add_addr_to_list(addr, one_ep);
2804: #else /* !MCAST follows*/
2805: msyslog(LOG_ERR,
2806: "Can not add multicast address %s: no multicast support",
2807: stoa(addr));
2808: #endif
2809: return;
2810: }
2811:
2812:
2813: /*
2814: * io_multicast_del() - delete multicast group address
2815: */
2816: void
2817: io_multicast_del(
2818: sockaddr_u * addr
2819: )
2820: {
2821: #ifdef MCAST
2822: endpt *iface;
2823:
2824: /*
2825: * Check to see if this is a multicast address
2826: */
2827: if (!addr_ismulticast(addr)) {
2828: msyslog(LOG_ERR, "invalid multicast address %s",
2829: stoa(addr));
2830: return;
2831: }
2832:
2833: /*
2834: * Disable reception of multicast packets
2835: */
2836: while ((iface = find_flagged_addr_in_list(addr, INT_MCASTOPEN))
2837: != NULL)
2838: socket_multicast_disable(iface, addr);
2839:
2840: delete_addr_from_list(addr);
2841:
2842: #else /* not MCAST */
2843: msyslog(LOG_ERR,
2844: "Can not delete multicast address %s: no multicast support",
2845: stoa(addr));
2846: #endif /* not MCAST */
2847: }
2848:
2849:
2850: /*
2851: * init_nonblocking_io() - set up descriptor to be non blocking
2852: */
2853: static void init_nonblocking_io(
2854: SOCKET fd
2855: )
2856: {
2857: /*
2858: * set non-blocking,
2859: */
2860:
2861: #ifdef USE_FIONBIO
2862: /* in vxWorks we use FIONBIO, but the others are defined for old systems, so
2863: * all hell breaks loose if we leave them defined
2864: */
2865: #undef O_NONBLOCK
2866: #undef FNDELAY
2867: #undef O_NDELAY
2868: #endif
2869:
2870: #if defined(O_NONBLOCK) /* POSIX */
2871: if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
2872: msyslog(LOG_ERR,
2873: "fcntl(O_NONBLOCK) fails on fd #%d: %m", fd);
2874: exit(1);
2875: }
2876: #elif defined(FNDELAY)
2877: if (fcntl(fd, F_SETFL, FNDELAY) < 0) {
2878: msyslog(LOG_ERR, "fcntl(FNDELAY) fails on fd #%d: %m",
2879: fd);
2880: exit(1);
2881: }
2882: #elif defined(O_NDELAY) /* generally the same as FNDELAY */
2883: if (fcntl(fd, F_SETFL, O_NDELAY) < 0) {
2884: msyslog(LOG_ERR, "fcntl(O_NDELAY) fails on fd #%d: %m",
2885: fd);
2886: exit(1);
2887: }
2888: #elif defined(FIONBIO)
2889: {
2890: int on = 1;
2891:
2892: if (ioctl(fd, FIONBIO, &on) < 0) {
2893: msyslog(LOG_ERR,
2894: "ioctl(FIONBIO) fails on fd #%d: %m",
2895: fd);
2896: exit(1);
2897: }
2898: }
2899: #elif defined(FIOSNBIO)
2900: if (ioctl(fd, FIOSNBIO, &on) < 0) {
2901: msyslog(LOG_ERR,
2902: "ioctl(FIOSNBIO) fails on fd #%d: %m", fd);
2903: exit(1);
2904: }
2905: #else
2906: # include "Bletch: Need non-blocking I/O!"
2907: #endif
2908: }
2909:
2910: /*
2911: * open_socket - open a socket, returning the file descriptor
2912: */
2913:
2914: static SOCKET
2915: open_socket(
2916: sockaddr_u * addr,
2917: int bcast,
2918: int turn_off_reuse,
2919: endpt * interf
2920: )
2921: {
2922: SOCKET fd;
2923: int errval;
2924: char scopetext[16];
2925: /*
2926: * int is OK for REUSEADR per
2927: * http://www.kohala.com/start/mcast.api.txt
2928: */
2929: int on = 1;
2930: int off = 0;
2931:
2932: if (IS_IPV6(addr) && !ipv6_works)
2933: return INVALID_SOCKET;
2934:
2935: /* create a datagram (UDP) socket */
2936: fd = socket(AF(addr), SOCK_DGRAM, 0);
2937: if (INVALID_SOCKET == fd) {
2938: errval = socket_errno();
2939: msyslog(LOG_ERR,
2940: "socket(AF_INET%s, SOCK_DGRAM, 0) failed on address %s: %m",
2941: IS_IPV6(addr) ? "6" : "", stoa(addr));
2942:
2943: if (errval == EPROTONOSUPPORT ||
2944: errval == EAFNOSUPPORT ||
2945: errval == EPFNOSUPPORT)
2946: return (INVALID_SOCKET);
2947:
2948: errno = errval;
2949: msyslog(LOG_ERR,
2950: "unexpected socket() error %m code %d (not EPROTONOSUPPORT nor EAFNOSUPPORT nor EPFNOSUPPORT) - exiting",
2951: errno);
2952: exit(1);
2953: }
2954:
2955: #ifdef SYS_WINNT
2956: connection_reset_fix(fd, addr);
2957: #endif
2958: /*
2959: * Fixup the file descriptor for some systems
2960: * See bug #530 for details of the issue.
2961: */
2962: fd = move_fd(fd);
2963:
2964: /*
2965: * set SO_REUSEADDR since we will be binding the same port
2966: * number on each interface according to turn_off_reuse.
2967: * This is undesirable on Windows versions starting with
2968: * Windows XP (numeric version 5.1).
2969: */
2970: #ifdef SYS_WINNT
2971: if (isc_win32os_versioncheck(5, 1, 0, 0) < 0) /* before 5.1 */
2972: #endif
2973: if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
2974: (char *)((turn_off_reuse)
2975: ? &off
2976: : &on),
2977: sizeof(on))) {
2978:
2979: msyslog(LOG_ERR,
2980: "setsockopt SO_REUSEADDR %s fails for address %s: %m",
2981: (turn_off_reuse)
2982: ? "off"
2983: : "on",
2984: stoa(addr));
2985: closesocket(fd);
2986: return INVALID_SOCKET;
2987: }
2988: #ifdef SO_EXCLUSIVEADDRUSE
2989: /*
2990: * setting SO_EXCLUSIVEADDRUSE on the wildcard we open
2991: * first will cause more specific binds to fail.
2992: */
2993: if (!(interf->flags & INT_WILDCARD))
2994: set_excladdruse(fd);
2995: #endif
2996:
2997: /*
2998: * IPv4 specific options go here
2999: */
3000: if (IS_IPV4(addr)) {
3001: #if defined(HAVE_IPTOS_SUPPORT)
3002: if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *)&qos,
3003: sizeof(qos)))
3004: msyslog(LOG_ERR,
3005: "setsockopt IP_TOS (%02x) fails on address %s: %m",
3006: qos, stoa(addr));
3007: #endif /* HAVE_IPTOS_SUPPORT */
3008: if (bcast)
3009: socket_broadcast_enable(interf, fd, addr);
3010: }
3011:
3012: /*
3013: * IPv6 specific options go here
3014: */
3015: if (IS_IPV6(addr)) {
3016: #ifdef IPV6_V6ONLY
3017: if (isc_net_probe_ipv6only() == ISC_R_SUCCESS
3018: && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
3019: (char*)&on, sizeof(on)))
3020: msyslog(LOG_ERR,
3021: "setsockopt IPV6_V6ONLY on fails on address %s: %m",
3022: stoa(addr));
3023: #endif
3024: #ifdef IPV6_BINDV6ONLY
3025: if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
3026: (char*)&on, sizeof(on)))
3027: msyslog(LOG_ERR,
3028: "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
3029: stoa(addr));
3030: #endif
3031: }
3032:
3033: #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
3034: /*
3035: * some OSes don't allow binding to more specific
3036: * addresses if a wildcard address already bound
3037: * to the port and SO_REUSEADDR is not set
3038: */
3039: if (!is_wildcard_addr(addr))
3040: set_wildcard_reuse(AF(addr), 1);
3041: #endif
3042:
3043: /*
3044: * bind the local address.
3045: */
3046: errval = bind(fd, &addr->sa, SOCKLEN(addr));
3047:
3048: #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
3049: if (!is_wildcard_addr(addr))
3050: set_wildcard_reuse(AF(addr), 0);
3051: #endif
3052:
3053: if (errval < 0) {
3054: /*
3055: * Don't log this under all conditions
3056: */
3057: if (turn_off_reuse == 0
3058: #ifdef DEBUG
3059: || debug > 1
3060: #endif
3061: ) {
3062: if (SCOPE(addr))
3063: snprintf(scopetext, sizeof(scopetext),
3064: "%%%d", SCOPE(addr));
3065: else
3066: scopetext[0] = 0;
3067:
3068: msyslog(LOG_ERR,
3069: "bind(%d) AF_INET%s %s%s#%d%s flags 0x%x failed: %m",
3070: fd, IS_IPV6(addr) ? "6" : "",
3071: stoa(addr), scopetext, SRCPORT(addr),
3072: IS_MCAST(addr) ? " (multicast)" : "",
3073: interf->flags);
3074: }
3075:
3076: closesocket(fd);
3077:
3078: return INVALID_SOCKET;
3079: }
3080:
3081: #ifdef HAVE_TIMESTAMP
3082: {
3083: if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP,
3084: (char*)&on, sizeof(on)))
3085: msyslog(LOG_DEBUG,
3086: "setsockopt SO_TIMESTAMP on fails on address %s: %m",
3087: stoa(addr));
3088: else
3089: DPRINTF(4, ("setsockopt SO_TIMESTAMP enabled on fd %d address %s\n",
3090: fd, stoa(addr)));
3091: }
3092: #endif
3093: DPRINTF(4, ("bind(%d) AF_INET%s, addr %s%%%d#%d, flags 0x%x\n",
3094: fd, IS_IPV6(addr) ? "6" : "", stoa(addr),
3095: SCOPE(addr), SRCPORT(addr), interf->flags));
3096:
3097: init_nonblocking_io(fd);
3098:
3099: #ifdef HAVE_SIGNALED_IO
3100: init_socket_sig(fd);
3101: #endif /* not HAVE_SIGNALED_IO */
3102:
3103: add_fd_to_list(fd, FD_TYPE_SOCKET);
3104:
3105: #if !defined(SYS_WINNT) && !defined(VMS)
3106: DPRINTF(4, ("flags for fd %d: 0x%x\n", fd,
3107: fcntl(fd, F_GETFL, 0)));
3108: #endif /* SYS_WINNT || VMS */
3109:
3110: #if defined (HAVE_IO_COMPLETION_PORT)
3111: /*
3112: * Add the socket to the completion port
3113: */
3114: if (io_completion_port_add_socket(fd, interf)) {
3115: msyslog(LOG_ERR, "unable to set up io completion port - EXITING");
3116: exit(1);
3117: }
3118: #endif
3119: return fd;
3120: }
3121:
3122:
3123: #ifdef SYS_WINNT
3124: #define sendto(fd, buf, len, flags, dest, destsz) \
3125: io_completion_port_sendto(fd, buf, len, (sockaddr_u *)(dest))
3126: #endif
3127:
3128: /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
3129: /*
3130: * sendpkt - send a packet to the specified destination. Maintain a
3131: * send error cache so that only the first consecutive error for a
3132: * destination is logged.
3133: */
3134: void
3135: sendpkt(
3136: sockaddr_u * dest,
3137: struct interface * ep,
3138: int ttl,
3139: struct pkt * pkt,
3140: int len
3141: )
3142: {
3143: endpt * src;
3144: int ismcast;
3145: int cc;
3146: int rc;
3147: u_char cttl;
3148:
3149: ismcast = IS_MCAST(dest);
3150: if (!ismcast)
3151: src = ep;
3152: else
3153: src = (IS_IPV4(dest))
3154: ? mc4_list
3155: : mc6_list;
3156:
3157: if (NULL == src) {
3158: /*
3159: * unbound peer - drop request and wait for better
3160: * network conditions
3161: */
3162: DPRINTF(2, ("%ssendpkt(dst=%s, ttl=%d, len=%d): no interface - IGNORED\n",
3163: ismcast ? "\tMCAST\t***** " : "",
3164: stoa(dest), ttl, len));
3165: return;
3166: }
3167:
3168: do {
3169: DPRINTF(2, ("%ssendpkt(%d, dst=%s, src=%s, ttl=%d, len=%d)\n",
3170: ismcast ? "\tMCAST\t***** " : "", src->fd,
3171: stoa(dest), stoa(&src->sin), ttl, len));
3172: #ifdef MCAST
3173: /*
3174: * for the moment we use the bcast option to set multicast ttl
3175: */
3176: if (ismcast && ttl > 0 && ttl != src->last_ttl) {
3177: /*
3178: * set the multicast ttl for outgoing packets
3179: */
3180: switch (AF(&src->sin)) {
3181:
3182: case AF_INET :
3183: cttl = (u_char)ttl;
3184: rc = setsockopt(src->fd, IPPROTO_IP,
3185: IP_MULTICAST_TTL,
3186: (void *)&cttl,
3187: sizeof(cttl));
3188: break;
3189:
3190: # ifdef INCLUDE_IPV6_SUPPORT
3191: case AF_INET6 :
3192: rc = setsockopt(src->fd, IPPROTO_IPV6,
3193: IPV6_MULTICAST_HOPS,
3194: (void *)&ttl,
3195: sizeof(ttl));
3196: break;
3197: # endif /* INCLUDE_IPV6_SUPPORT */
3198:
3199: default:
3200: rc = 0;
3201: }
3202:
3203: if (!rc)
3204: src->last_ttl = ttl;
3205: else
3206: msyslog(LOG_ERR,
3207: "setsockopt IP_MULTICAST_TTL/IPV6_MULTICAST_HOPS fails on address %s: %m",
3208: stoa(&src->sin));
3209: }
3210: #endif /* MCAST */
3211:
3212: #ifdef SIM
3213: cc = simulate_server(dest, src, pkt);
3214: #else
3215: cc = sendto(src->fd, (char *)pkt, (u_int)len, 0,
3216: &dest->sa, SOCKLEN(dest));
3217: #endif
3218: if (cc == -1) {
3219: src->notsent++;
3220: packets_notsent++;
3221: } else {
3222: src->sent++;
3223: packets_sent++;
3224: }
3225: if (ismcast)
3226: src = src->mclink;
3227: } while (ismcast && src != NULL);
3228: }
3229:
3230:
3231: #if !defined(HAVE_IO_COMPLETION_PORT)
3232: /*
3233: * fdbits - generate ascii representation of fd_set (FAU debug support)
3234: * HFDF format - highest fd first.
3235: */
3236: static char *
3237: fdbits(
3238: int count,
3239: fd_set *set
3240: )
3241: {
3242: static char buffer[256];
3243: char * buf = buffer;
3244:
3245: count = min(count, 255);
3246:
3247: while (count >= 0) {
3248: *buf++ = FD_ISSET(count, set) ? '#' : '-';
3249: count--;
3250: }
3251: *buf = '\0';
3252:
3253: return buffer;
3254: }
3255:
3256: /*
3257: * Routine to read the refclock packets for a specific interface
3258: * Return the number of bytes read. That way we know if we should
3259: * read it again or go on to the next one if no bytes returned
3260: */
3261: static inline int
3262: read_refclock_packet(SOCKET fd, struct refclockio *rp, l_fp ts)
3263: {
3264: int i;
3265: int buflen;
3266: register struct recvbuf *rb;
3267:
3268: rb = get_free_recv_buffer();
3269:
3270: if (NULL == rb) {
3271: /*
3272: * No buffer space available - just drop the packet
3273: */
3274: char buf[RX_BUFF_SIZE];
3275:
3276: buflen = read(fd, buf, sizeof buf);
3277: packets_dropped++;
3278: return (buflen);
3279: }
3280:
3281: i = (rp->datalen == 0
3282: || rp->datalen > sizeof(rb->recv_space))
3283: ? sizeof(rb->recv_space)
3284: : rp->datalen;
3285: buflen = read(fd, (char *)&rb->recv_space, (unsigned)i);
3286:
3287: if (buflen < 0) {
3288: if (errno != EINTR && errno != EAGAIN)
3289: msyslog(LOG_ERR, "clock read fd %d: %m", fd);
3290: freerecvbuf(rb);
3291: return (buflen);
3292: }
3293:
3294: /*
3295: * Got one. Mark how and when it got here,
3296: * put it on the full list and do bookkeeping.
3297: */
3298: rb->recv_length = buflen;
3299: rb->recv_srcclock = rp->srcclock;
3300: rb->dstadr = 0;
3301: rb->fd = fd;
3302: rb->recv_time = ts;
3303: rb->receiver = rp->clock_recv;
3304:
3305: if (rp->io_input) {
3306: /*
3307: * have direct input routine for refclocks
3308: */
3309: if (rp->io_input(rb) == 0) {
3310: /*
3311: * data was consumed - nothing to pass up
3312: * into block input machine
3313: */
3314: freerecvbuf(rb);
3315: return (buflen);
3316: }
3317: }
3318:
3319: add_full_recv_buffer(rb);
3320:
3321: rp->recvcount++;
3322: packets_received++;
3323: return (buflen);
3324: }
3325:
3326:
3327: #ifdef HAVE_TIMESTAMP
3328: /*
3329: * extract timestamps from control message buffer
3330: */
3331: static l_fp
3332: fetch_timestamp(
3333: struct recvbuf * rb,
3334: struct msghdr * msghdr,
3335: l_fp ts
3336: )
3337: {
3338: #ifdef USE_TIMESTAMP_CMSG
3339: struct cmsghdr *cmsghdr;
3340:
3341: cmsghdr = CMSG_FIRSTHDR(msghdr);
3342: while (cmsghdr != NULL) {
3343: switch (cmsghdr->cmsg_type)
3344: {
3345: case SCM_TIMESTAMP:
3346: {
3347: struct timeval *tvp;
3348: double dtemp;
3349: l_fp nts;
3350:
3351: tvp = (struct timeval *)CMSG_DATA(cmsghdr);
3352: DPRINTF(4, ("fetch_timestamp: system network time stamp: %ld.%06ld\n",
3353: tvp->tv_sec, tvp->tv_usec));
3354: nts.l_i = tvp->tv_sec + JAN_1970;
3355: dtemp = (tvp->tv_usec
3356: + (ntp_random() * 2. / FRAC)) / 1e6;
3357: nts.l_uf = (u_int32)(dtemp * FRAC);
3358: #ifdef DEBUG_TIMING
3359: {
3360: l_fp dts;
3361:
3362: dts = ts;
3363: L_SUB(&dts, &nts);
3364: collect_timing(rb,
3365: "input processing delay",
3366: 1, &dts);
3367: DPRINTF(4, ("fetch_timestamp: timestamp delta: %s (incl. prec fuzz)\n",
3368: lfptoa(&dts, 9)));
3369: }
3370: #endif
3371: ts = nts; /* network time stamp */
3372: break;
3373: }
3374: default:
3375: DPRINTF(4, ("fetch_timestamp: skipping control message 0x%x\n",
3376: cmsghdr->cmsg_type));
3377: }
3378: cmsghdr = CMSG_NXTHDR(msghdr, cmsghdr);
3379: }
3380: #endif
3381: return ts;
3382: }
3383: #endif
3384:
3385:
3386: /*
3387: * Routine to read the network NTP packets for a specific interface
3388: * Return the number of bytes read. That way we know if we should
3389: * read it again or go on to the next one if no bytes returned
3390: */
3391: static inline int
3392: read_network_packet(
3393: SOCKET fd,
3394: struct interface * itf,
3395: l_fp ts
3396: )
3397: {
3398: GETSOCKNAME_SOCKLEN_TYPE fromlen;
3399: int buflen;
3400: register struct recvbuf *rb;
3401: #ifdef HAVE_TIMESTAMP
3402: struct msghdr msghdr;
3403: struct iovec iovec;
3404: char control[TIMESTAMP_CTLMSGBUF_SIZE];
3405: #endif
3406:
3407: /*
3408: * Get a buffer and read the frame. If we
3409: * haven't got a buffer, or this is received
3410: * on a disallowed socket, just dump the
3411: * packet.
3412: */
3413:
3414: rb = get_free_recv_buffer();
3415: if (NULL == rb || itf->ignore_packets) {
3416: char buf[RX_BUFF_SIZE];
3417: sockaddr_u from;
3418:
3419: if (rb != NULL)
3420: freerecvbuf(rb);
3421:
3422: fromlen = sizeof(from);
3423: buflen = recvfrom(fd, buf, sizeof(buf), 0,
3424: &from.sa, &fromlen);
3425: DPRINTF(4, ("%s on (%lu) fd=%d from %s\n",
3426: (itf->ignore_packets)
3427: ? "ignore"
3428: : "drop",
3429: free_recvbuffs(), fd, stoa(&from)));
3430: if (itf->ignore_packets)
3431: packets_ignored++;
3432: else
3433: packets_dropped++;
3434: return (buflen);
3435: }
3436:
3437: fromlen = sizeof(rb->recv_srcadr);
3438:
3439: #ifndef HAVE_TIMESTAMP
3440: rb->recv_length = recvfrom(fd, (char *)&rb->recv_space,
3441: sizeof(rb->recv_space), 0,
3442: &rb->recv_srcadr.sa, &fromlen);
3443: #else
3444: iovec.iov_base = &rb->recv_space;
3445: iovec.iov_len = sizeof(rb->recv_space);
3446: msghdr.msg_name = &rb->recv_srcadr;
3447: msghdr.msg_namelen = fromlen;
3448: msghdr.msg_iov = &iovec;
3449: msghdr.msg_iovlen = 1;
3450: msghdr.msg_control = (void *)&control;
3451: msghdr.msg_controllen = sizeof(control);
3452: msghdr.msg_flags = 0;
3453: rb->recv_length = recvmsg(fd, &msghdr, 0);
3454: #endif
3455:
3456: buflen = rb->recv_length;
3457:
3458: if (buflen == 0 || (buflen == -1 &&
3459: (EWOULDBLOCK == errno
3460: #ifdef EAGAIN
3461: || EAGAIN == errno
3462: #endif
3463: ))) {
3464: freerecvbuf(rb);
3465: return (buflen);
3466: } else if (buflen < 0) {
3467: msyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
3468: stoa(&rb->recv_srcadr), fd);
3469: DPRINTF(5, ("read_network_packet: fd=%d dropped (bad recvfrom)\n",
3470: fd));
3471: freerecvbuf(rb);
3472: return (buflen);
3473: }
3474:
3475: DPRINTF(3, ("read_network_packet: fd=%d length %d from %s\n",
3476: fd, buflen, stoa(&rb->recv_srcadr)));
3477:
3478: /*
3479: * Got one. Mark how and when it got here,
3480: * put it on the full list and do bookkeeping.
3481: */
3482: rb->dstadr = itf;
3483: rb->fd = fd;
3484: #ifdef HAVE_TIMESTAMP
3485: /* pick up a network time stamp if possible */
3486: ts = fetch_timestamp(rb, &msghdr, ts);
3487: #endif
3488: rb->recv_time = ts;
3489: rb->receiver = receive;
3490:
3491: add_full_recv_buffer(rb);
3492:
3493: itf->received++;
3494: packets_received++;
3495: return (buflen);
3496: }
3497:
3498:
3499: /*
3500: * input_handler - receive packets asynchronously
3501: */
3502: void
3503: input_handler(
3504: l_fp *cts
3505: )
3506: {
3507: int buflen;
3508: int n;
3509: int doing;
3510: SOCKET fd;
3511: struct timeval tvzero;
3512: l_fp ts; /* Timestamp at BOselect() gob */
3513: #ifdef DEBUG_TIMING
3514: l_fp ts_e; /* Timestamp at EOselect() gob */
3515: #endif
3516: fd_set fds;
3517: int select_count = 0;
3518: endpt *ep;
3519: #if defined(HAS_ROUTING_SOCKET)
3520: struct asyncio_reader *asyncio_reader;
3521: #endif
3522:
3523: handler_calls++;
3524:
3525: /*
3526: * If we have something to do, freeze a timestamp.
3527: * See below for the other cases (nothing left to do or error)
3528: */
3529: ts = *cts;
3530:
3531: /*
3532: * Do a poll to see who has data
3533: */
3534:
3535: fds = activefds;
3536: tvzero.tv_sec = tvzero.tv_usec = 0;
3537:
3538: n = select(maxactivefd + 1, &fds, (fd_set *)0, (fd_set *)0,
3539: &tvzero);
3540:
3541: /*
3542: * If there are no packets waiting just return
3543: */
3544: if (n < 0) {
3545: int err = errno;
3546: /*
3547: * extended FAU debugging output
3548: */
3549: if (err != EINTR)
3550: msyslog(LOG_ERR,
3551: "select(%d, %s, 0L, 0L, &0.0) error: %m",
3552: maxactivefd + 1,
3553: fdbits(maxactivefd, &activefds));
3554: if (err == EBADF) {
3555: int j, b;
3556: fds = activefds;
3557: for (j = 0; j <= maxactivefd; j++)
3558: if ((FD_ISSET(j, &fds)
3559: && (read(j, &b, 0) == -1)))
3560: msyslog(LOG_ERR,
3561: "Bad file descriptor %d",
3562: j);
3563: }
3564: return;
3565: }
3566: else if (n == 0)
3567: return;
3568:
3569: ++handler_pkts;
3570:
3571: #ifdef REFCLOCK
3572: /*
3573: * Check out the reference clocks first, if any
3574: */
3575:
3576: if (refio != NULL) {
3577: register struct refclockio *rp;
3578:
3579: for (rp = refio; rp != NULL; rp = rp->next) {
3580: fd = rp->fd;
3581:
3582: if (FD_ISSET(fd, &fds))
3583: do {
3584: ++select_count;
3585: buflen = read_refclock_packet(
3586: fd, rp, ts);
3587: } while (buflen > 0);
3588: }
3589: }
3590: #endif /* REFCLOCK */
3591:
3592: /*
3593: * Loop through the interfaces looking for data to read.
3594: */
3595: for (ep = ep_list; ep != NULL; ep = ep->elink) {
3596: for (doing = 0; doing < 2; doing++) {
3597: if (!doing) {
3598: fd = ep->fd;
3599: } else {
3600: if (!(ep->flags & INT_BCASTOPEN))
3601: break;
3602: fd = ep->bfd;
3603: }
3604: if (fd < 0)
3605: continue;
3606: if (FD_ISSET(fd, &fds))
3607: do {
3608: ++select_count;
3609: buflen = read_network_packet(
3610: fd, ep, ts);
3611: } while (buflen > 0);
3612: /* Check more interfaces */
3613: }
3614: }
3615:
3616: #ifdef HAS_ROUTING_SOCKET
3617: /*
3618: * scan list of asyncio readers - currently only used for routing sockets
3619: */
3620: asyncio_reader = asyncio_reader_list;
3621:
3622: while (asyncio_reader != NULL) {
3623: if (FD_ISSET(asyncio_reader->fd, &fds)) {
3624: ++select_count;
3625: (asyncio_reader->receiver)(asyncio_reader);
3626: }
3627: asyncio_reader = asyncio_reader->link;
3628: }
3629: #endif /* HAS_ROUTING_SOCKET */
3630:
3631: /*
3632: * Done everything from that select.
3633: */
3634:
3635: /*
3636: * If nothing to do, just return.
3637: * If an error occurred, complain and return.
3638: */
3639: if (select_count == 0) { /* We really had nothing to do */
3640: #ifdef DEBUG
3641: if (debug)
3642: msyslog(LOG_DEBUG, "input_handler: select() returned 0");
3643: #endif
3644: return;
3645: }
3646: /* We've done our work */
3647: #ifdef DEBUG_TIMING
3648: get_systime(&ts_e);
3649: /*
3650: * (ts_e - ts) is the amount of time we spent
3651: * processing this gob of file descriptors. Log
3652: * it.
3653: */
3654: L_SUB(&ts_e, &ts);
3655: collect_timing(NULL, "input handler", 1, &ts_e);
3656: if (debug > 3)
3657: msyslog(LOG_DEBUG,
3658: "input_handler: Processed a gob of fd's in %s msec",
3659: lfptoms(&ts_e, 6));
3660: #endif
3661: /* just bail. */
3662: return;
3663: }
3664: #endif
3665:
3666: /*
3667: * findinterface - find local interface corresponding to address
3668: */
3669: endpt *
3670: findinterface(
3671: sockaddr_u *addr
3672: )
3673: {
3674: endpt *iface;
3675:
3676: iface = findlocalinterface(addr, INT_WILDCARD, 0);
3677:
3678: if (NULL == iface) {
3679: DPRINTF(4, ("Found no interface for address %s - returning wildcard\n",
3680: stoa(addr)));
3681:
3682: iface = ANY_INTERFACE_CHOOSE(addr);
3683: } else
3684: DPRINTF(4, ("Found interface #%d %s for address %s\n",
3685: iface->ifnum, iface->name, stoa(addr)));
3686:
3687: return iface;
3688: }
3689:
3690: /*
3691: * findlocalinterface - find local interface corresponding to addr,
3692: * which does not have any of flags set. If bast is nonzero, addr is
3693: * a broadcast address.
3694: *
3695: * This code attempts to find the local sending address for an outgoing
3696: * address by connecting a new socket to destinationaddress:NTP_PORT
3697: * and reading the sockname of the resulting connect.
3698: * the complicated sequence simulates the routing table lookup
3699: * for to first hop without duplicating any of the routing logic into
3700: * ntpd. preferably we would have used an API call - but its not there -
3701: * so this is the best we can do here short of duplicating to entire routing
3702: * logic in ntpd which would be a silly and really unportable thing to do.
3703: *
3704: */
3705: static endpt *
3706: findlocalinterface(
3707: sockaddr_u * addr,
3708: int flags,
3709: int bcast
3710: )
3711: {
3712: GETSOCKNAME_SOCKLEN_TYPE sockaddrlen;
3713: endpt * iface;
3714: sockaddr_u saddr;
3715: SOCKET s;
3716: int rtn;
3717: int on;
3718:
3719: DPRINTF(4, ("Finding interface for addr %s in list of addresses\n",
3720: stoa(addr)));
3721:
3722: s = socket(AF(addr), SOCK_DGRAM, 0);
3723: if (INVALID_SOCKET == s)
3724: return NULL;
3725:
3726: /*
3727: * If we are looking for broadcast interface we need to set this
3728: * socket to allow broadcast
3729: */
3730: if (bcast) {
3731: on = 1;
3732: setsockopt(s, SOL_SOCKET, SO_BROADCAST,
3733: (char *)&on, sizeof(on));
3734: }
3735:
3736: rtn = connect(s, &addr->sa, SOCKLEN(addr));
3737: if (SOCKET_ERROR == rtn) {
3738: closesocket(s);
3739: return NULL;
3740: }
3741:
3742: sockaddrlen = sizeof(saddr);
3743: rtn = getsockname(s, &saddr.sa, &sockaddrlen);
3744: closesocket(s);
3745: if (SOCKET_ERROR == rtn)
3746: return NULL;
3747:
3748: DPRINTF(4, ("findlocalinterface: kernel maps %s to %s\n",
3749: stoa(addr), stoa(&saddr)));
3750:
3751: iface = getinterface(&saddr, flags);
3752:
3753: /*
3754: * if we didn't find an exact match on saddr, find the closest
3755: * available local address. This handles the case of the
3756: * address suggested by the kernel being excluded by nic rules
3757: * or the user's -I and -L options to ntpd.
3758: * See http://bugs.ntp.org/1184 and http://bugs.ntp.org/1683
3759: * for more background.
3760: */
3761: if (NULL == iface || iface->ignore_packets)
3762: iface = findclosestinterface(&saddr,
3763: flags | INT_LOOPBACK);
3764:
3765: /* Don't use an interface which will ignore replies */
3766: if (iface != NULL && iface->ignore_packets)
3767: iface = NULL;
3768:
3769: return iface;
3770: }
3771:
3772:
3773: /*
3774: * findclosestinterface
3775: *
3776: * If there are -I/--interface or -L/novirtualips command-line options,
3777: * or "nic" or "interface" rules in ntp.conf, findlocalinterface() may
3778: * find the kernel's preferred local address for a given peer address is
3779: * administratively unavailable to ntpd, and punt to this routine's more
3780: * expensive search.
3781: *
3782: * Find the numerically closest local address to the one connect()
3783: * suggested. This matches an address on the same subnet first, as
3784: * needed by Bug 1184, and provides a consistent choice if there are
3785: * multiple feasible local addresses, regardless of the order ntpd
3786: * enumerated them.
3787: */
3788: static endpt *
3789: findclosestinterface(
3790: sockaddr_u * addr,
3791: int flags
3792: )
3793: {
3794: endpt * ep;
3795: endpt * winner;
3796: sockaddr_u addr_dist;
3797: sockaddr_u min_dist;
3798:
3799: winner = NULL;
3800:
3801: for (ep = ep_list; ep != NULL; ep = ep->elink) {
3802: if (ep->ignore_packets ||
3803: AF(addr) != ep->family ||
3804: flags & ep->flags)
3805: continue;
3806:
3807: calc_addr_distance(&addr_dist, addr, &ep->sin);
3808: if (NULL == winner ||
3809: -1 == cmp_addr_distance(&addr_dist, &min_dist)) {
3810: min_dist = addr_dist;
3811: winner = ep;
3812: }
3813: }
3814: if (NULL == winner)
3815: DPRINTF(4, ("findclosestinterface(%s) failed\n",
3816: stoa(addr)));
3817: else
3818: DPRINTF(4, ("findclosestinterface(%s) -> %s\n",
3819: stoa(addr), stoa(&winner->sin)));
3820:
3821: return winner;
3822: }
3823:
3824:
3825: /*
3826: * calc_addr_distance - calculate the distance between two addresses,
3827: * the absolute value of the difference between
3828: * the addresses numerically, stored as an address.
3829: */
3830: static void
3831: calc_addr_distance(
3832: sockaddr_u * dist,
3833: const sockaddr_u * a1,
3834: const sockaddr_u * a2
3835: )
3836: {
3837: u_int32 a1val;
3838: u_int32 a2val;
3839: u_int32 v4dist;
3840: int found_greater;
3841: int a1_greater;
3842: int i;
3843:
3844: NTP_REQUIRE(AF(a1) == AF(a2));
3845:
3846: memset(dist, 0, sizeof(*dist));
3847: AF(dist) = AF(a1);
3848:
3849: /* v4 can be done a bit simpler */
3850: if (IS_IPV4(a1)) {
3851: a1val = SRCADR(a1);
3852: a2val = SRCADR(a2);
3853: v4dist = (a1val > a2val)
3854: ? a1val - a2val
3855: : a2val - a1val;
3856: SET_ADDR4(dist, v4dist);
3857:
3858: return;
3859: }
3860:
3861: found_greater = FALSE;
3862: a1_greater = FALSE; /* suppress pot. uninit. warning */
3863: for (i = 0; i < sizeof(NSRCADR6(a1)); i++) {
3864: if (!found_greater &&
3865: NSRCADR6(a1)[i] != NSRCADR6(a2)[i]) {
3866: found_greater = TRUE;
3867: a1_greater = (NSRCADR6(a1)[i] > NSRCADR6(a2)[i]);
3868: }
3869: if (!found_greater) {
3870: NSRCADR6(dist)[i] = 0;
3871: } else {
3872: if (a1_greater)
3873: NSRCADR6(dist)[i] = NSRCADR6(a1)[i] -
3874: NSRCADR6(a2)[i];
3875: else
3876: NSRCADR6(dist)[i] = NSRCADR6(a2)[i] -
3877: NSRCADR6(a1)[i];
3878: }
3879: }
3880: }
3881:
3882:
3883: /*
3884: * cmp_addr_distance - compare two address distances, returning -1, 0,
3885: * 1 to indicate their relationship.
3886: */
3887: static int
3888: cmp_addr_distance(
3889: const sockaddr_u * d1,
3890: const sockaddr_u * d2
3891: )
3892: {
3893: int i;
3894:
3895: NTP_REQUIRE(AF(d1) == AF(d2));
3896:
3897: if (IS_IPV4(d1)) {
3898: if (SRCADR(d1) < SRCADR(d2))
3899: return -1;
3900: else if (SRCADR(d1) == SRCADR(d2))
3901: return 0;
3902: else
3903: return 1;
3904: }
3905:
3906: for (i = 0; i < sizeof(NSRCADR6(d1)); i++) {
3907: if (NSRCADR6(d1)[i] < NSRCADR6(d2)[i])
3908: return -1;
3909: else if (NSRCADR6(d1)[i] > NSRCADR6(d2)[i])
3910: return 1;
3911: }
3912:
3913: return 0;
3914: }
3915:
3916:
3917:
3918: /*
3919: * fetch an interface structure the matches the
3920: * address and has the given flags NOT set
3921: */
3922: static endpt *
3923: getinterface(
3924: sockaddr_u * addr,
3925: u_int32 flags
3926: )
3927: {
3928: endpt *iface;
3929:
3930: iface = find_addr_in_list(addr);
3931:
3932: if (iface != NULL && (iface->flags & flags))
3933: iface = NULL;
3934:
3935: return iface;
3936: }
3937:
3938:
3939: /*
3940: * findbcastinter - find broadcast interface corresponding to address
3941: */
3942: endpt *
3943: findbcastinter(
3944: sockaddr_u *addr
3945: )
3946: {
3947: #if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
3948: struct interface *iface;
3949:
3950:
3951: DPRINTF(4, ("Finding broadcast/multicast interface for addr %s in list of addresses\n",
3952: stoa(addr)));
3953:
3954: iface = findlocalinterface(addr, INT_LOOPBACK | INT_WILDCARD,
3955: 1);
3956: if (iface != NULL) {
3957: DPRINTF(4, ("Easily found bcast-/mcast- interface index #%d %s\n",
3958: iface->ifnum, iface->name));
3959: return iface;
3960: }
3961:
3962: /*
3963: * plan B - try to find something reasonable in our lists in
3964: * case kernel lookup doesn't help
3965: */
3966: for (iface = ep_list; iface != NULL; iface = iface->elink) {
3967: if (iface->flags & INT_WILDCARD)
3968: continue;
3969:
3970: /* Don't bother with ignored interfaces */
3971: if (iface->ignore_packets)
3972: continue;
3973:
3974: /*
3975: * First look if this is the correct family
3976: */
3977: if(AF(&iface->sin) != AF(addr))
3978: continue;
3979:
3980: /* Skip the loopback addresses */
3981: if (iface->flags & INT_LOOPBACK)
3982: continue;
3983:
3984: /*
3985: * If we are looking to match a multicast address and
3986: * this interface is one...
3987: */
3988: if (addr_ismulticast(addr)
3989: && (iface->flags & INT_MULTICAST)) {
3990: #ifdef INCLUDE_IPV6_SUPPORT
3991: /*
3992: * ...it is the winner unless we're looking for
3993: * an interface to use for link-local multicast
3994: * and its address is not link-local.
3995: */
3996: if (IS_IPV6(addr)
3997: && IN6_IS_ADDR_MC_LINKLOCAL(PSOCK_ADDR6(addr))
3998: && !IN6_IS_ADDR_LINKLOCAL(PSOCK_ADDR6(&iface->sin)))
3999: continue;
4000: #endif
4001: break;
4002: }
4003:
4004: /*
4005: * We match only those interfaces marked as
4006: * broadcastable and either the explicit broadcast
4007: * address or the network portion of the IP address.
4008: * Sloppy.
4009: */
4010: if (IS_IPV4(addr)) {
4011: if (SOCK_EQ(&iface->bcast, addr))
4012: break;
4013:
4014: if ((NSRCADR(&iface->sin) & NSRCADR(&iface->mask))
4015: == (NSRCADR(addr) & NSRCADR(&iface->mask)))
4016: break;
4017: }
4018: #ifdef INCLUDE_IPV6_SUPPORT
4019: else if (IS_IPV6(addr)) {
4020: if (SOCK_EQ(&iface->bcast, addr))
4021: break;
4022:
4023: if (SOCK_EQ(netof(&iface->sin), netof(addr)))
4024: break;
4025: }
4026: #endif
4027: }
4028: #endif /* SIOCGIFCONF */
4029: if (NULL == iface) {
4030: DPRINTF(4, ("No bcast interface found for %s\n",
4031: stoa(addr)));
4032: iface = ANY_INTERFACE_CHOOSE(addr);
4033: } else
4034: DPRINTF(4, ("Found bcast-/mcast- interface index #%d %s\n",
4035: iface->ifnum, iface->name));
4036: return iface;
4037: }
4038:
4039:
4040: /*
4041: * io_clr_stats - clear I/O module statistics
4042: */
4043: void
4044: io_clr_stats(void)
4045: {
4046: packets_dropped = 0;
4047: packets_ignored = 0;
4048: packets_received = 0;
4049: packets_sent = 0;
4050: packets_notsent = 0;
4051:
4052: handler_calls = 0;
4053: handler_pkts = 0;
4054: io_timereset = current_time;
4055: }
4056:
4057:
4058: #ifdef REFCLOCK
4059: /*
4060: * io_addclock - add a reference clock to the list and arrange that we
4061: * get SIGIO interrupts from it.
4062: */
4063: int
4064: io_addclock(
4065: struct refclockio *rio
4066: )
4067: {
4068: BLOCKIO();
4069:
4070: /*
4071: * Stuff the I/O structure in the list and mark the descriptor
4072: * in use. There is a harmless (I hope) race condition here.
4073: */
4074: rio->next = refio;
4075:
4076: # ifdef HAVE_SIGNALED_IO
4077: if (init_clock_sig(rio)) {
4078: UNBLOCKIO();
4079: return 0;
4080: }
4081: # elif defined(HAVE_IO_COMPLETION_PORT)
4082: if (io_completion_port_add_clock_io(rio)) {
4083: UNBLOCKIO();
4084: return 0;
4085: }
4086: # endif
4087:
4088: /*
4089: * enqueue
4090: */
4091: refio = rio;
4092:
4093: /*
4094: * register fd
4095: */
4096: add_fd_to_list(rio->fd, FD_TYPE_FILE);
4097:
4098: UNBLOCKIO();
4099: return 1;
4100: }
4101:
4102: /*
4103: * io_closeclock - close the clock in the I/O structure given
4104: */
4105: void
4106: io_closeclock(
4107: struct refclockio *rio
4108: )
4109: {
4110: register struct refclockio *rp;
4111:
4112: BLOCKIO();
4113:
4114: /*
4115: * Remove structure from the list
4116: */
4117: if (refio == rio)
4118: refio = rio->next;
4119: else {
4120: for (rp = refio; rp != NULL; rp = rp->next)
4121: if (rp->next == rio) {
4122: rp->next = rio->next;
4123: break;
4124: }
4125:
4126: if (NULL == rp) {
4127: UNBLOCKIO();
4128: return;
4129: }
4130: }
4131:
4132: /*
4133: * Close the descriptor.
4134: */
4135: close_and_delete_fd_from_list(rio->fd);
4136: UNBLOCKIO();
4137: }
4138: #endif /* REFCLOCK */
4139:
4140: /*
4141: * On NT a SOCKET is an unsigned int so we cannot possibly keep it in
4142: * an array. So we use one of the ISC_LIST functions to hold the
4143: * socket value and use that when we want to enumerate it.
4144: *
4145: * This routine is called by the forked intres child process to close
4146: * all open sockets. On Windows there's no need as intres runs in
4147: * the same process as a thread.
4148: */
4149: #ifndef SYS_WINNT
4150: void
4151: kill_asyncio(int startfd)
4152: {
4153: BLOCKIO();
4154:
4155: /*
4156: * In the child process we do not maintain activefds and
4157: * maxactivefd. Zeroing maxactivefd disables code which
4158: * maintains it in close_and_delete_fd_from_list().
4159: */
4160: maxactivefd = 0;
4161:
4162: while (fd_list != NULL)
4163: close_and_delete_fd_from_list(fd_list->fd);
4164:
4165: UNBLOCKIO();
4166: }
4167: #endif /* !SYS_WINNT */
4168:
4169: /*
4170: * Add and delete functions for the list of open sockets
4171: */
4172: static void
4173: add_fd_to_list(
4174: SOCKET fd,
4175: enum desc_type type
4176: )
4177: {
4178: vsock_t *lsock = emalloc(sizeof(*lsock));
4179:
4180: lsock->fd = fd;
4181: lsock->type = type;
4182:
4183: LINK_SLIST(fd_list, lsock, link);
4184: /*
4185: * I/O Completion Ports don't care about the select and FD_SET
4186: */
4187: #ifndef HAVE_IO_COMPLETION_PORT
4188: if (fd < 0 || fd >= FD_SETSIZE) {
4189: msyslog(LOG_ERR,
4190: "Too many sockets in use, FD_SETSIZE %d exceeded",
4191: FD_SETSIZE);
4192: exit(1);
4193: }
4194: /*
4195: * keep activefds in sync
4196: */
4197: maxactivefd = max(fd, maxactivefd);
4198:
4199: FD_SET(fd, &activefds);
4200: #endif
4201: }
4202:
4203: static void
4204: close_and_delete_fd_from_list(
4205: SOCKET fd
4206: )
4207: {
4208: vsock_t *lsock;
4209:
4210: UNLINK_EXPR_SLIST(lsock, fd_list, fd ==
4211: UNLINK_EXPR_SLIST_CURRENT()->fd, link, vsock_t);
4212:
4213: if (lsock != NULL) {
4214: switch (lsock->type) {
4215: case FD_TYPE_SOCKET:
4216: closesocket(lsock->fd);
4217: break;
4218:
4219: case FD_TYPE_FILE:
4220: close(lsock->fd);
4221: break;
4222:
4223: default:
4224: msyslog(LOG_ERR,
4225: "internal error - illegal descriptor type %d - EXITING",
4226: (int)lsock->type);
4227: exit(1);
4228: }
4229:
4230: free(lsock);
4231: /*
4232: * I/O Completion Ports don't care about select and fd_set
4233: */
4234: #ifndef HAVE_IO_COMPLETION_PORT
4235: /*
4236: * remove from activefds
4237: */
4238: FD_CLR(fd, &activefds);
4239:
4240: if (fd == maxactivefd && maxactivefd) {
4241: int i;
4242: NTP_INSIST(maxactivefd - 1 < FD_SETSIZE);
4243: for (i = maxactivefd - 1; i >= 0; i--)
4244: if (FD_ISSET(i, &activefds)) {
4245: maxactivefd = i;
4246: break;
4247: }
4248: NTP_INSIST(fd != maxactivefd);
4249: }
4250: #endif
4251: }
4252: }
4253:
4254: static void
4255: add_addr_to_list(
4256: sockaddr_u * addr,
4257: endpt * ep
4258: )
4259: {
4260: remaddr_t *laddr;
4261:
4262: #ifdef DEBUG
4263: if (find_addr_in_list(addr) == NULL) {
4264: #endif
4265: /* not there yet - add to list */
4266: laddr = emalloc(sizeof(*laddr));
4267: laddr->addr = *addr;
4268: laddr->ep = ep;
4269:
4270: LINK_SLIST(remoteaddr_list, laddr, link);
4271:
4272: DPRINTF(4, ("Added addr %s to list of addresses\n",
4273: stoa(addr)));
4274: #ifdef DEBUG
4275: } else
4276: DPRINTF(4, ("WARNING: Attempt to add duplicate addr %s to address list\n",
4277: stoa(addr)));
4278: #endif
4279: }
4280:
4281:
4282: static void
4283: delete_addr_from_list(
4284: sockaddr_u *addr
4285: )
4286: {
4287: remaddr_t *unlinked;
4288:
4289: UNLINK_EXPR_SLIST(unlinked, remoteaddr_list, SOCK_EQ(addr,
4290: &(UNLINK_EXPR_SLIST_CURRENT()->addr)), link, remaddr_t);
4291:
4292: if (unlinked != NULL) {
4293: DPRINTF(4, ("Deleted addr %s from list of addresses\n",
4294: stoa(addr)));
4295: free(unlinked);
4296: }
4297: }
4298:
4299:
4300: static void
4301: delete_interface_from_list(
4302: endpt *iface
4303: )
4304: {
4305: remaddr_t *unlinked;
4306:
4307: do {
4308: UNLINK_EXPR_SLIST(unlinked, remoteaddr_list, iface ==
4309: UNLINK_EXPR_SLIST_CURRENT()->ep, link,
4310: remaddr_t);
4311:
4312: if (unlinked != NULL) {
4313: DPRINTF(4, ("Deleted addr %s for interface #%d %s from list of addresses\n",
4314: stoa(&unlinked->addr), iface->ifnum,
4315: iface->name));
4316: free(unlinked);
4317: }
4318: } while (unlinked != NULL);
4319: }
4320:
4321:
4322: static struct interface *
4323: find_addr_in_list(
4324: sockaddr_u *addr
4325: )
4326: {
4327: remaddr_t *entry;
4328:
4329: DPRINTF(4, ("Searching for addr %s in list of addresses - ",
4330: stoa(addr)));
4331:
4332: for (entry = remoteaddr_list;
4333: entry != NULL;
4334: entry = entry->link)
4335: if (SOCK_EQ(&entry->addr, addr)) {
4336: DPRINTF(4, ("FOUND\n"));
4337: return entry->ep;
4338: }
4339:
4340: DPRINTF(4, ("NOT FOUND\n"));
4341: return NULL;
4342: }
4343:
4344:
4345: /*
4346: * Find the given address with the all given flags set in the list
4347: */
4348: static endpt *
4349: find_flagged_addr_in_list(
4350: sockaddr_u * addr,
4351: u_int32 flags
4352: )
4353: {
4354: remaddr_t *entry;
4355:
4356: DPRINTF(4, ("Finding addr %s with flags %d in list: ",
4357: stoa(addr), flags));
4358:
4359: for (entry = remoteaddr_list;
4360: entry != NULL;
4361: entry = entry->link)
4362:
4363: if (SOCK_EQ(&entry->addr, addr)
4364: && (entry->ep->flags & flags) == flags) {
4365:
4366: DPRINTF(4, ("FOUND\n"));
4367: return entry->ep;
4368: }
4369:
4370: DPRINTF(4, ("NOT FOUND\n"));
4371: return NULL;
4372: }
4373:
4374:
4375: const char *
4376: localaddrtoa(
4377: endpt *la
4378: )
4379: {
4380: return (NULL == la)
4381: ? "<null>"
4382: : stoa(&la->sin);
4383: }
4384:
4385:
4386: #ifdef HAS_ROUTING_SOCKET
4387: # ifndef UPDATE_GRACE
4388: # define UPDATE_GRACE 2 /* wait UPDATE_GRACE seconds before scanning */
4389: # endif
4390:
4391: static void
4392: process_routing_msgs(struct asyncio_reader *reader)
4393: {
4394: char buffer[5120];
4395: int cnt, msg_type;
4396: #ifdef HAVE_RTNETLINK
4397: struct nlmsghdr *nh;
4398: #else
4399: struct rt_msghdr *rtm;
4400: char *p;
4401: #endif
4402:
4403: if (disable_dynamic_updates) {
4404: /*
4405: * discard ourselves if we are not needed any more
4406: * usually happens when running unprivileged
4407: */
4408: remove_asyncio_reader(reader);
4409: delete_asyncio_reader(reader);
4410: return;
4411: }
4412:
4413: cnt = read(reader->fd, buffer, sizeof(buffer));
4414:
4415: if (cnt < 0) {
4416: msyslog(LOG_ERR,
4417: "i/o error on routing socket %m - disabling");
4418: remove_asyncio_reader(reader);
4419: delete_asyncio_reader(reader);
4420: return;
4421: }
4422:
4423: /*
4424: * process routing message
4425: */
4426: #ifdef HAVE_RTNETLINK
4427: for (nh = (struct nlmsghdr *)buffer;
4428: NLMSG_OK(nh, cnt);
4429: nh = NLMSG_NEXT(nh, cnt)) {
4430: msg_type = nh->nlmsg_type;
4431: #else
4432: for (p = buffer;
4433: (p + sizeof(struct rt_msghdr)) <= (buffer + cnt);
4434: p += rtm->rtm_msglen) {
4435: rtm = (struct rt_msghdr *)p;
4436: if (rtm->rtm_version != RTM_VERSION) {
4437: msyslog(LOG_ERR,
4438: "version mismatch (got %d - expected %d) on routing socket - disabling",
4439: rtm->rtm_version, RTM_VERSION);
4440:
4441: remove_asyncio_reader(reader);
4442: delete_asyncio_reader(reader);
4443: return;
4444: }
4445: msg_type = rtm->rtm_type;
4446: #endif
4447: switch (msg_type) {
4448: #ifdef RTM_NEWADDR
4449: case RTM_NEWADDR:
4450: #endif
4451: #ifdef RTM_DELADDR
4452: case RTM_DELADDR:
4453: #endif
4454: #ifdef RTM_ADD
4455: case RTM_ADD:
4456: #endif
4457: #ifdef RTM_DELETE
4458: case RTM_DELETE:
4459: #endif
4460: #ifdef RTM_REDIRECT
4461: case RTM_REDIRECT:
4462: #endif
4463: #ifdef RTM_CHANGE
4464: case RTM_CHANGE:
4465: #endif
4466: #ifdef RTM_LOSING
4467: case RTM_LOSING:
4468: #endif
4469: #ifdef RTM_IFINFO
4470: case RTM_IFINFO:
4471: #endif
4472: #ifdef RTM_IFANNOUNCE
4473: case RTM_IFANNOUNCE:
4474: #endif
4475: #ifdef RTM_NEWLINK
4476: case RTM_NEWLINK:
4477: #endif
4478: #ifdef RTM_DELLINK
4479: case RTM_DELLINK:
4480: #endif
4481: #ifdef RTM_NEWROUTE
4482: case RTM_NEWROUTE:
4483: #endif
4484: #ifdef RTM_DELROUTE
4485: case RTM_DELROUTE:
4486: #endif
4487: /*
4488: * we are keen on new and deleted addresses and
4489: * if an interface goes up and down or routing
4490: * changes
4491: */
4492: DPRINTF(3, ("routing message op = %d: scheduling interface update\n",
4493: msg_type));
4494: timer_interfacetimeout(current_time + UPDATE_GRACE);
4495: break;
4496: #ifdef HAVE_RTNETLINK
4497: case NLMSG_DONE:
4498: /* end of multipart message */
4499: return;
4500: #endif
4501: default:
4502: /*
4503: * the rest doesn't bother us.
4504: */
4505: DPRINTF(4, ("routing message op = %d: ignored\n",
4506: msg_type));
4507: break;
4508: }
4509: }
4510: }
4511:
4512: /*
4513: * set up routing notifications
4514: */
4515: static void
4516: init_async_notifications()
4517: {
4518: struct asyncio_reader *reader;
4519: #ifdef HAVE_RTNETLINK
4520: int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
4521: struct sockaddr_nl sa;
4522: #else
4523: int fd = socket(PF_ROUTE, SOCK_RAW, 0);
4524: #endif
4525: if (fd < 0) {
4526: msyslog(LOG_ERR,
4527: "unable to open routing socket (%m) - using polled interface update");
4528: return;
4529: }
4530:
4531: fd = move_fd(fd);
4532: #ifdef HAVE_RTNETLINK
4533: memset(&sa, 0, sizeof(sa));
4534: sa.nl_family = PF_NETLINK;
4535: sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR
4536: | RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_ROUTE
4537: | RTMGRP_IPV4_MROUTE | RTMGRP_IPV6_ROUTE
4538: | RTMGRP_IPV6_MROUTE;
4539: if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
4540: msyslog(LOG_ERR,
4541: "bind failed on routing socket (%m) - using polled interface update");
4542: return;
4543: }
4544: #endif
4545: init_nonblocking_io(fd);
4546: #if defined(HAVE_SIGNALED_IO)
4547: init_socket_sig(fd);
4548: #endif /* HAVE_SIGNALED_IO */
4549:
4550: reader = new_asyncio_reader();
4551:
4552: reader->fd = fd;
4553: reader->receiver = process_routing_msgs;
4554:
4555: add_asyncio_reader(reader, FD_TYPE_SOCKET);
4556: msyslog(LOG_INFO,
4557: "Listening on routing socket on fd #%d for interface updates",
4558: fd);
4559: }
4560: #else
4561: /* HAS_ROUTING_SOCKET not defined */
4562: static void
4563: init_async_notifications(void)
4564: {
4565: }
4566: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>