diff -up ntp-4.2.4p7/ntpd/ntp_io.c.bcast ntp-4.2.4p7/ntpd/ntp_io.c --- ntp-4.2.4p7/ntpd/ntp_io.c.bcast 2009-05-18 16:53:05.000000000 +0200 +++ ntp-4.2.4p7/ntpd/ntp_io.c 2009-05-18 16:54:19.000000000 +0200 @@ -150,6 +150,8 @@ int ninterfaces; /* Total number of in volatile int disable_dynamic_updates; /* when set to != 0 dynamic updates won't happen */ +static int pktinfo_status = 0; /* is IP_PKTINFO on wildipv4 iface enabled? */ + #ifdef REFCLOCK /* * Refclock stuff. We keep a chain of structures with data concerning @@ -1611,6 +1613,18 @@ set_reuseaddr(int flag) { #endif /* ! SO_EXCLUSIVEADDRUSE */ } +static void +set_pktinfo(int flag) +{ + if (wildipv4 == NULL) + return; + if (setsockopt(wildipv4->fd, SOL_IP, IP_PKTINFO, &flag, sizeof (flag))) { + if (debug > 1) + printf("setsockopt(IP_PKTINFO) failed: %s\n", strerror(errno)); + } else + pktinfo_status = flag; +} + /* * This is just a wrapper around an internal function so we can * make other changes as necessary later on @@ -2027,6 +2041,7 @@ io_setbclient(void) #else netsyslog(LOG_ERR, "io_setbclient: Broadcast Client disabled by build"); #endif + set_pktinfo(1); } /* @@ -2049,6 +2064,7 @@ io_unsetbclient(void) continue; lstatus = socket_broadcast_disable(interf, &interf->sin); } + set_pktinfo(0); } /* @@ -2957,7 +2973,8 @@ read_network_packet(SOCKET fd, struct in #ifdef HAVE_TIMESTAMP struct msghdr msghdr; struct iovec iovec; - char control[TIMESTAMP_CTLMSGBUF_SIZE]; /* pick up control messages */ + char control[sizeof (struct cmsghdr) * 2 + sizeof (struct timeval) + + sizeof (struct in_pktinfo) + 32]; /* pick up control messages */ #endif /* @@ -2969,7 +2986,7 @@ read_network_packet(SOCKET fd, struct in rb = get_free_recv_buffer(); - if (rb == NULL || itf->ignore_packets == ISC_TRUE) + if (rb == NULL || (itf->ignore_packets == ISC_TRUE && !(pktinfo_status && itf == wildipv4))) { char buf[RX_BUFF_SIZE]; struct sockaddr_storage from; @@ -3031,6 +3048,34 @@ read_network_packet(SOCKET fd, struct in return (buflen); } + if (pktinfo_status && itf->ignore_packets == ISC_TRUE && itf == wildipv4) { + /* check for broadcast on 255.255.255.255, exception allowed on wildipv4 */ + struct cmsghdr *cmsg; + struct in_pktinfo *pktinfo = NULL; + + if ((cmsg = CMSG_FIRSTHDR(&msghdr))) + do { + if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO) + pktinfo = (struct in_pktinfo *) CMSG_DATA(cmsg); + } while ((cmsg = CMSG_NXTHDR(&msghdr, cmsg))); + if (pktinfo && pktinfo->ipi_addr.s_addr == INADDR_BROADCAST) { +#ifdef DEBUG + if (debug > 3) { + printf("INADDR_BROADCAST\n"); + } +#endif + } else { +#ifdef DEBUG + if (debug > 3) + printf("%s on (%lu) fd=%d from %s\n", "ignore", + free_recvbuffs(), fd, stoa(&rb->recv_srcadr)); +#endif + packets_ignored++; + freerecvbuf(rb); + return (buflen); + } + } + #ifdef DEBUG if (debug > 2) { if(rb->recv_srcadr.ss_family == AF_INET) diff -up ntp-4.2.4p7/ntpd/ntp_peer.c.bcast ntp-4.2.4p7/ntpd/ntp_peer.c --- ntp-4.2.4p7/ntpd/ntp_peer.c.bcast 2008-08-10 13:02:40.000000000 +0200 +++ ntp-4.2.4p7/ntpd/ntp_peer.c 2009-05-18 16:53:05.000000000 +0200 @@ -709,7 +709,8 @@ select_peerinterface(struct peer *peer, * as our (network) source address would be undefined and * crypto will not work without knowing the own transmit address */ - if (interface != NULL && interface->flags & INT_WILDCARD) + if (interface != NULL && interface->flags & INT_WILDCARD && + !(cast_flags & MDF_BCAST)) #ifdef SYS_WINNT if ( !accept_wildcard_if_for_winnt ) #endif