]>
Commit | Line | Data |
---|---|---|
1 | diff -up ntp-4.2.6p1/ntpd/ntp_io.c.bcast ntp-4.2.6p1/ntpd/ntp_io.c | |
2 | --- ntp-4.2.6p1/ntpd/ntp_io.c.bcast 2009-12-09 08:36:37.000000000 +0100 | |
3 | +++ ntp-4.2.6p1/ntpd/ntp_io.c 2010-03-05 14:49:25.000000000 +0100 | |
4 | @@ -151,6 +151,8 @@ int ninterfaces; /* Total number of in | |
5 | ||
6 | int disable_dynamic_updates; /* scan interfaces once only */ | |
7 | ||
8 | +static int pktinfo_status = 0; /* is IP_PKTINFO on wildipv4 iface enabled? */ | |
9 | + | |
10 | #ifdef REFCLOCK | |
11 | /* | |
12 | * Refclock stuff. We keep a chain of structures with data concerning | |
13 | @@ -1937,6 +1939,17 @@ set_reuseaddr( | |
14 | #endif /* ! SO_EXCLUSIVEADDRUSE */ | |
15 | } | |
16 | ||
17 | +static void | |
18 | +set_pktinfo(int flag) | |
19 | +{ | |
20 | + if (wildipv4 == NULL) | |
21 | + return; | |
22 | + if (setsockopt(wildipv4->fd, SOL_IP, IP_PKTINFO, &flag, sizeof (flag))) { | |
23 | + msyslog(LOG_ERR, "set_pktinfo: setsockopt(IP_PKTINFO, %s) failed: %m", flag ? "on" : "off"); | |
24 | + } else | |
25 | + pktinfo_status = flag; | |
26 | +} | |
27 | + | |
28 | /* | |
29 | * This is just a wrapper around an internal function so we can | |
30 | * make other changes as necessary later on | |
31 | @@ -2374,6 +2387,7 @@ io_setbclient(void) | |
32 | } | |
33 | } | |
34 | set_reuseaddr(0); | |
35 | + set_pktinfo(1); | |
36 | if (nif > 0) | |
37 | DPRINTF(1, ("io_setbclient: Opened broadcast clients\n")); | |
38 | else if (!nif) | |
39 | @@ -2405,6 +2419,7 @@ io_unsetbclient(void) | |
40 | ||
41 | socket_broadcast_disable(interf, &interf->sin); | |
42 | } | |
43 | + set_pktinfo(0); | |
44 | } | |
45 | ||
46 | /* | |
47 | @@ -3130,7 +3145,8 @@ read_network_packet( | |
48 | #ifdef HAVE_TIMESTAMP | |
49 | struct msghdr msghdr; | |
50 | struct iovec iovec; | |
51 | - char control[TIMESTAMP_CTLMSGBUF_SIZE]; | |
52 | + char control[sizeof (struct cmsghdr) * 2 + sizeof (struct timeval) + | |
53 | + sizeof (struct in_pktinfo) + 32]; | |
54 | #endif | |
55 | ||
56 | /* | |
57 | @@ -3141,7 +3157,7 @@ read_network_packet( | |
58 | */ | |
59 | ||
60 | rb = get_free_recv_buffer(); | |
61 | - if (NULL == rb || itf->ignore_packets) { | |
62 | + if (NULL == rb || (itf->ignore_packets && !(pktinfo_status && itf == wildipv4))) { | |
63 | char buf[RX_BUFF_SIZE]; | |
64 | sockaddr_u from; | |
65 | ||
66 | @@ -3201,6 +3217,27 @@ read_network_packet( | |
67 | return (buflen); | |
68 | } | |
69 | ||
70 | + if (pktinfo_status && itf->ignore_packets && itf == wildipv4) { | |
71 | + /* check for broadcast on 255.255.255.255, exception allowed on wildipv4 */ | |
72 | + struct cmsghdr *cmsg; | |
73 | + struct in_pktinfo *pktinfo = NULL; | |
74 | + | |
75 | + if ((cmsg = CMSG_FIRSTHDR(&msghdr))) | |
76 | + do { | |
77 | + if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO) | |
78 | + pktinfo = (struct in_pktinfo *) CMSG_DATA(cmsg); | |
79 | + } while ((cmsg = CMSG_NXTHDR(&msghdr, cmsg))); | |
80 | + if (pktinfo && pktinfo->ipi_addr.s_addr == INADDR_BROADCAST) { | |
81 | + DPRINTF(4, ("INADDR_BROADCAST\n")); | |
82 | + } else { | |
83 | + DPRINTF(4, ("%s on (%lu) fd=%d from %s\n", "ignore", | |
84 | + free_recvbuffs(), fd, stoa(&rb->recv_srcadr))); | |
85 | + packets_ignored++; | |
86 | + freerecvbuf(rb); | |
87 | + return (buflen); | |
88 | + } | |
89 | + } | |
90 | + | |
91 | DPRINTF(3, ("read_network_packet: fd=%d length %d from %s\n", | |
92 | fd, buflen, stoa(&rb->recv_srcadr))); | |
93 |