diff options
Diffstat (limited to 'ntpd/ntp_io.c')
-rw-r--r-- | ntpd/ntp_io.c | 113 |
1 files changed, 86 insertions, 27 deletions
diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index 0f335ea..1ee7098 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -217,7 +217,7 @@ static isc_boolean_t socket_multicast_disable(endpt *, sockaddr_u *); #ifdef DEBUG static void interface_dump (const endpt *); static void sockaddr_dump (const sockaddr_u *); -static void print_interface (const endpt *, char *, char *); +static void print_interface (const endpt *, const char *, const char *); #define DPRINT_INTERFACE(level, args) do { if (debug >= (level)) { print_interface args; } } while (0) #else #define DPRINT_INTERFACE(level, args) do {} while (0) @@ -269,7 +269,9 @@ static SOCKET open_socket (sockaddr_u *, int, int, endpt *); static char * fdbits (int, fd_set *); static void set_reuseaddr (int); static isc_boolean_t socket_broadcast_enable (struct interface *, SOCKET, sockaddr_u *); +#ifdef OS_MISSES_SPECIFIC_ROUTE_UPDATES static isc_boolean_t socket_broadcast_disable (struct interface *, sockaddr_u *); +#endif typedef struct remaddr remaddr_t; @@ -548,7 +550,7 @@ sockaddr_dump(const sockaddr_u *psau) * print_interface - helper to output debug information */ static void -print_interface(const endpt *iface, char *pfx, char *sfx) +print_interface(const endpt *iface, const char *pfx, const char *sfx) { printf("%sinterface #%d: fd=%d, bfd=%d, name=%s, flags=0x%x, ifindex=%u, sin=%s", pfx, @@ -714,7 +716,6 @@ is_ip_address( ) { struct in_addr in4; - struct in6_addr in6; struct addrinfo hints; struct addrinfo *result; struct sockaddr_in6 *resaddr6; @@ -1646,16 +1647,15 @@ set_wildcard_reuse( static isc_boolean_t -is_anycast( +check_flags6( sockaddr_u *psau, - const char *name + const char *name, + u_int32 flags6 ) { -#if defined(INCLUDE_IPV6_SUPPORT) && defined(SIOCGIFAFLAG_IN6) && \ - defined(IN6_IFF_ANYCAST) +#if defined(INCLUDE_IPV6_SUPPORT) && defined(SIOCGIFAFLAG_IN6) struct in6_ifreq ifr6; int fd; - u_int32 flags6; if (psau->sa.sa_family != AF_INET6) return ISC_FALSE; @@ -1669,13 +1669,45 @@ is_anycast( return ISC_FALSE; } close(fd); - flags6 = ifr6.ifr_ifru.ifru_flags6; - if ((flags6 & IN6_IFF_ANYCAST) != 0) + if ((ifr6.ifr_ifru.ifru_flags6 & flags6) != 0) return ISC_TRUE; -#endif /* INCLUDE_IPV6_SUPPORT && SIOCGIFAFLAG_IN6 && IN6_IFF_ANYCAST */ +#endif /* INCLUDE_IPV6_SUPPORT && SIOCGIFAFLAG_IN6 */ + return ISC_FALSE; +} + +static isc_boolean_t +is_anycast( + sockaddr_u *psau, + const char *name + ) +{ +#ifdef IN6_IFF_ANYCAST + return check_flags6(psau, name, IN6_IFF_ANYCAST); +#else return ISC_FALSE; +#endif } +static isc_boolean_t +is_valid( + sockaddr_u *psau, + const char *name + ) +{ + u_int32 flags6; + + flags6 = 0; +#ifdef IN6_IFF_DEPARTED + flags6 |= IN6_IFF_DEPARTED; +#endif +#ifdef IN6_IFF_DETACHED + flags6 |= IN6_IFF_DETACHED; +#endif +#ifdef IN6_IFF_TENTATIVE + flags6 |= IN6_IFF_TENTATIVE; +#endif + return check_flags6(psau, name, flags6) ? ISC_FALSE : ISC_TRUE; +} /* * update_interface strategy @@ -1809,6 +1841,12 @@ update_interfaces( continue; /* + * skip any address that is an invalid state to be used + */ + if (!is_valid(&enumep.sin, isc_if.name)) + continue; + + /* * map to local *address* in order to map all duplicate * interfaces to an endpt structure with the appropriate * socket. Our name space is (ip-address), NOT @@ -1968,6 +2006,9 @@ update_interfaces( if (broadcast_client_enabled) io_setbclient(); + if (sys_bclient) + io_setbclient(); + return new_interface_found; } @@ -2232,6 +2273,7 @@ socket_broadcast_enable( #endif /* SO_BROADCAST */ } +#ifdef OS_MISSES_SPECIFIC_ROUTE_UPDATES /* * Remove a broadcast address from a given socket * The socket is in the ep_list all we need to do is disable @@ -2258,6 +2300,7 @@ socket_broadcast_disable( return ISC_FALSE; #endif /* SO_BROADCAST */ } +#endif /* OS_MISSES_SPECIFIC_ROUTE_UPDATES */ #endif /* OPEN_BCAST_SOCKET */ @@ -2311,7 +2354,7 @@ enable_multicast_if( #ifdef IP_MULTICAST_LOOP TYPEOF_IP_MULTICAST_LOOP off = 0; #endif -#ifdef IPV6_MULTICAST_LOOP +#if defined(INCLUDE_IPV6_MULTICAST_SUPPORT) && defined(IPV6_MULTICAST_LOOP) u_int off6 = 0; #endif @@ -2792,7 +2835,6 @@ open_socket( { SOCKET fd; int errval; - char scopetext[16]; /* * int is OK for REUSEADR per * http://www.kohala.com/start/mcast.api.txt @@ -2942,16 +2984,10 @@ open_socket( || debug > 1 #endif ) { - if (SCOPE(addr)) - snprintf(scopetext, sizeof(scopetext), - "%%%d", SCOPE(addr)); - else - scopetext[0] = 0; - msyslog(LOG_ERR, - "bind(%d) AF_INET%s %s%s#%d%s flags 0x%x failed: %m", + "bind(%d) AF_INET%s %s#%d%s flags 0x%x failed: %m", fd, IS_IPV6(addr) ? "6" : "", - stoa(addr), scopetext, SRCPORT(addr), + stoa(addr), SRCPORT(addr), IS_MCAST(addr) ? " (multicast)" : "", interf->flags); } @@ -3195,8 +3231,8 @@ read_refclock_packet( } i = (rp->datalen == 0 - || rp->datalen > sizeof(rb->recv_space)) - ? sizeof(rb->recv_space) + || rp->datalen > (int)sizeof(rb->recv_space)) + ? (int)sizeof(rb->recv_space) : rp->datalen; do { buflen = read(fd, (char *)&rb->recv_space, (u_int)i); @@ -3318,8 +3354,8 @@ fetch_timestamp( tvp->tv_usec = (long)(ticks * 1e6 * sys_tick); } - DPRINTF(4, ("fetch_timestamp: system usec network time stamp: %ld.%06ld\n", - tvp->tv_sec, tvp->tv_usec)); + DPRINTF(4, ("fetch_timestamp: system usec network time stamp: %jd.%06ld\n", + (intmax_t)tvp->tv_sec, (long)tvp->tv_usec)); nts = tval_stamp_to_lfp(*tvp); break; #endif /* HAVE_TIMESTAMP */ @@ -3443,6 +3479,29 @@ read_network_packet( fd, buflen, stoa(&rb->recv_srcadr))); /* + ** Bug 2672: Some OSes (MacOSX and Linux) don't block spoofed ::1 + */ + + if (AF_INET6 == itf->family) { + DPRINTF(2, ("Got an IPv6 packet, from <%s> (%d) to <%s> (%d)\n", + stoa(&rb->recv_srcadr), + IN6_IS_ADDR_LOOPBACK(PSOCK_ADDR6(&rb->recv_srcadr)), + stoa(&itf->sin), + !IN6_IS_ADDR_LOOPBACK(PSOCK_ADDR6(&itf->sin)) + )); + + if ( IN6_IS_ADDR_LOOPBACK(PSOCK_ADDR6(&rb->recv_srcadr)) + && !IN6_IS_ADDR_LOOPBACK(PSOCK_ADDR6(&itf->sin)) + ) { + packets_dropped++; + DPRINTF(2, ("DROPPING that packet\n")); + freerecvbuf(rb); + return buflen; + } + DPRINTF(2, ("processing that packet\n")); + } + + /* * Got one. Mark how and when it got here, * put it on the full list and do bookkeeping. */ @@ -4010,7 +4069,7 @@ calc_addr_distance( found_greater = FALSE; a1_greater = FALSE; /* suppress pot. uninit. warning */ - for (i = 0; i < sizeof(NSRCADR6(a1)); i++) { + for (i = 0; i < (int)sizeof(NSRCADR6(a1)); i++) { if (!found_greater && NSRCADR6(a1)[i] != NSRCADR6(a2)[i]) { found_greater = TRUE; @@ -4053,7 +4112,7 @@ cmp_addr_distance( return 1; } - for (i = 0; i < sizeof(NSRCADR6(d1)); i++) { + for (i = 0; i < (int)sizeof(NSRCADR6(d1)); i++) { if (NSRCADR6(d1)[i] < NSRCADR6(d2)[i]) return -1; else if (NSRCADR6(d1)[i] > NSRCADR6(d2)[i]) |