ntp-4.2.6p1-bcast.patch 2.7 KB

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