|
|
473877 |
diff -up ntp-4.2.6p3/ntpd/ntp_io.c.bcast ntp-4.2.6p3/ntpd/ntp_io.c
|
|
|
473877 |
--- ntp-4.2.6p3/ntpd/ntp_io.c.bcast 2010-12-25 10:40:36.000000000 +0100
|
|
|
473877 |
+++ ntp-4.2.6p3/ntpd/ntp_io.c 2011-01-05 17:46:13.820049150 +0100
|
|
|
473877 |
@@ -151,6 +151,8 @@ int ninterfaces; /* Total number of in
|
|
|
473877 |
|
|
|
473877 |
int disable_dynamic_updates; /* scan interfaces once only */
|
|
|
473877 |
|
|
|
473877 |
+static int pktinfo_status = 0; /* is IP_PKTINFO on wildipv4 iface enabled? */
|
|
|
473877 |
+
|
|
|
473877 |
#ifdef REFCLOCK
|
|
|
473877 |
/*
|
|
|
473877 |
* Refclock stuff. We keep a chain of structures with data concerning
|
|
|
473877 |
@@ -2254,6 +2256,17 @@ set_reuseaddr(
|
|
|
473877 |
#endif /* ! SO_EXCLUSIVEADDRUSE */
|
|
|
473877 |
}
|
|
|
473877 |
|
|
|
473877 |
+static void
|
|
|
473877 |
+set_pktinfo(int flag)
|
|
|
473877 |
+{
|
|
|
473877 |
+ if (wildipv4 == NULL)
|
|
|
473877 |
+ return;
|
|
|
473877 |
+ if (setsockopt(wildipv4->fd, SOL_IP, IP_PKTINFO, &flag, sizeof (flag))) {
|
|
|
473877 |
+ msyslog(LOG_ERR, "set_pktinfo: setsockopt(IP_PKTINFO, %s) failed: %m", flag ? "on" : "off");
|
|
|
473877 |
+ } else
|
|
|
473877 |
+ pktinfo_status = flag;
|
|
|
473877 |
+}
|
|
|
473877 |
+
|
|
|
473877 |
/*
|
|
|
473877 |
* This is just a wrapper around an internal function so we can
|
|
|
473877 |
* make other changes as necessary later on
|
|
|
473877 |
@@ -2659,6 +2672,7 @@ io_setbclient(void)
|
|
|
473877 |
}
|
|
|
473877 |
}
|
|
|
473877 |
set_reuseaddr(0);
|
|
|
473877 |
+ set_pktinfo(1);
|
|
|
473877 |
if (nif > 0)
|
|
|
473877 |
DPRINTF(1, ("io_setbclient: Opened broadcast clients\n"));
|
|
|
473877 |
else if (!nif)
|
|
|
473877 |
@@ -2685,6 +2699,7 @@ io_unsetbclient(void)
|
|
|
473877 |
continue;
|
|
|
473877 |
socket_broadcast_disable(ep, &ep->sin);
|
|
|
473877 |
}
|
|
|
473877 |
+ set_pktinfo(0);
|
|
|
473877 |
}
|
|
|
473877 |
|
|
|
473877 |
/*
|
|
|
473877 |
@@ -3392,7 +3407,8 @@ read_network_packet(
|
|
|
473877 |
#ifdef HAVE_TIMESTAMP
|
|
|
473877 |
struct msghdr msghdr;
|
|
|
473877 |
struct iovec iovec;
|
|
|
473877 |
- char control[TIMESTAMP_CTLMSGBUF_SIZE];
|
|
|
473877 |
+ char control[sizeof (struct cmsghdr) * 2 + sizeof (struct timeval) +
|
|
|
473877 |
+ sizeof (struct in_pktinfo) + 32];
|
|
|
473877 |
#endif
|
|
|
473877 |
|
|
|
473877 |
/*
|
|
|
473877 |
@@ -3403,7 +3419,7 @@ read_network_packet(
|
|
|
473877 |
*/
|
|
|
473877 |
|
|
|
473877 |
rb = get_free_recv_buffer();
|
|
|
473877 |
- if (NULL == rb || itf->ignore_packets) {
|
|
|
473877 |
+ if (NULL == rb || (itf->ignore_packets && !(pktinfo_status && itf == wildipv4))) {
|
|
|
473877 |
char buf[RX_BUFF_SIZE];
|
|
|
473877 |
sockaddr_u from;
|
|
|
473877 |
|
|
|
473877 |
@@ -3463,6 +3479,27 @@ read_network_packet(
|
|
|
473877 |
return (buflen);
|
|
|
473877 |
}
|
|
|
473877 |
|
|
|
473877 |
+ if (pktinfo_status && itf->ignore_packets && itf == wildipv4) {
|
|
|
473877 |
+ /* check for broadcast on 255.255.255.255, exception allowed on wildipv4 */
|
|
|
473877 |
+ struct cmsghdr *cmsg;
|
|
|
473877 |
+ struct in_pktinfo *pktinfo = NULL;
|
|
|
473877 |
+
|
|
|
473877 |
+ if ((cmsg = CMSG_FIRSTHDR(&msghdr)))
|
|
|
473877 |
+ do {
|
|
|
473877 |
+ if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO)
|
|
|
473877 |
+ pktinfo = (struct in_pktinfo *) CMSG_DATA(cmsg);
|
|
|
473877 |
+ } while ((cmsg = CMSG_NXTHDR(&msghdr, cmsg)));
|
|
|
473877 |
+ if (pktinfo && pktinfo->ipi_addr.s_addr == INADDR_BROADCAST) {
|
|
|
473877 |
+ DPRINTF(4, ("INADDR_BROADCAST\n"));
|
|
|
473877 |
+ } else {
|
|
|
473877 |
+ DPRINTF(4, ("%s on (%lu) fd=%d from %s\n", "ignore",
|
|
|
473877 |
+ free_recvbuffs(), fd, stoa(&rb->recv_srcadr)));
|
|
|
473877 |
+ packets_ignored++;
|
|
|
473877 |
+ freerecvbuf(rb);
|
|
|
473877 |
+ return (buflen);
|
|
|
473877 |
+ }
|
|
|
473877 |
+ }
|
|
|
473877 |
+
|
|
|
473877 |
DPRINTF(3, ("read_network_packet: fd=%d length %d from %s\n",
|
|
|
473877 |
fd, buflen, stoa(&rb->recv_srcadr)));
|
|
|
473877 |
|