]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Bug 629 Check for broadcast mode was in wrong place
authorDanny Mayer <mayer@ntp.org>
Tue, 19 Jun 2007 12:37:26 +0000 (08:37 -0400)
committerDanny Mayer <mayer@ntp.org>
Tue, 19 Jun 2007 12:37:26 +0000 (08:37 -0400)
bk: 4677ce06dpko5f1HbkaIDm2he-p36g

ntpd/ntp_io.c
ports/winnt/ntpd/ntp_iocompletionport.c

index 06edfc7c8f5c13a487e6d816c5fc56acc233bb4e..7fbc4a82842fae9ec6a376846fc61baaf4130667 100644 (file)
@@ -268,7 +268,7 @@ static void create_wildcards        (u_short);
 static isc_boolean_t   address_okay    (isc_interface_t *);
 static void            convert_isc_if          (isc_interface_t *, struct interface *, u_short);
 static struct interface *getinterface  (struct sockaddr_storage *, int);
-static struct interface *findlocalinterface    (struct sockaddr_storage *, int);
+static struct interface *findlocalinterface    (struct sockaddr_storage *, int, int);
 static struct interface *findlocalcastinterface        (struct sockaddr_storage *, int);
 
 /*
@@ -2855,6 +2855,7 @@ read_network_packet(SOCKET fd, struct interface *itf, l_fp ts)
        GETSOCKNAME_SOCKLEN_TYPE fromlen;
        int buflen;
        isc_boolean_t ignore_this;
+       isc_boolean_t ignore_later = ISC_FALSE;
        register struct recvbuf *rb;
 #ifdef HAVE_TIMESTAMP
        struct msghdr msghdr;
@@ -2873,18 +2874,18 @@ read_network_packet(SOCKET fd, struct interface *itf, l_fp ts)
 
        /* For broadcast packet received on the IPv4 wildcard socket
         * we carve out an exception but only if the client has requested
-        * to receive wildcard sockets
+        * to receive wildcard sockets. The final check is later when we
+        * have read the packet.
         */
        ignore_this = itf->ignore_packets;
        if (ignore_this == ISC_TRUE && itf->family == AF_INET &&
-           itf->flags == (INT_BROADCAST | INT_WILDCARD) &&
-           get_packet_mode(rb) == MODE_BROADCAST &&
+           (itf->flags & (INT_BROADCAST | INT_WILDCARD)) &&
            get_broadcastclient_flag() == ISC_TRUE
            )
-           ignore_this = ISC_FALSE;
+           ignore_later = ISC_TRUE;
 
-       if (rb == NULL || ignore_this == ISC_TRUE)
-       {
+       if (rb == NULL ||
+           (ignore_this == ISC_TRUE && ignore_later == ISC_FALSE)) {
                char buf[RX_BUFF_SIZE];
                struct sockaddr_storage from;
                if (rb != NULL)
@@ -2943,6 +2944,19 @@ read_network_packet(SOCKET fd, struct interface *itf, l_fp ts)
                return (rb->recv_length);
        }
 
+       /*
+        * Make sure only a valide broadcast packet was received
+        * on the wildcard address
+        */
+       if (ignore_later == ISC_TRUE && get_packet_mode(rb) != MODE_BROADCAST) {
+               freerecvbuf(rb);
+               DPRINTF(4, ("%s on (%lu) fd=%d from %s\n",
+                       "ignore", free_recvbuffs(), fd, stoa(&rb->recv_srcadr)));
+               packets_ignored++;
+               return (rb->recv_length);
+       }
+
+
 #ifdef DEBUG
        if (debug > 2) {
                if(rb->recv_srcadr.ss_family == AF_INET)
@@ -3166,7 +3180,7 @@ findinterface(
 {
        struct interface *interface;
        
-       interface = findlocalinterface(addr, INT_LOOPBACK|INT_WILDCARD);
+       interface = findlocalinterface(addr, INT_LOOPBACK|INT_WILDCARD, 0);
 
        if (interface == NULL)
        {
@@ -3200,7 +3214,8 @@ findinterface(
 static struct interface *
 findlocalinterface(
        struct sockaddr_storage *addr,
-       int flags
+       int flags,
+       int bflag
        )
 {
        SOCKET s;
@@ -3208,6 +3223,7 @@ findlocalinterface(
        struct sockaddr_storage saddr;
        GETSOCKNAME_SOCKLEN_TYPE saddrlen = SOCKLEN(addr);
        struct interface *iface;
+       int on = 1;
 
        DPRINTF(4, ("Finding interface for addr %s in list of addresses\n",
                    stoa(addr));)
@@ -3232,6 +3248,14 @@ findlocalinterface(
        if (s == INVALID_SOCKET)
                return NULL;
 
+       /*
+        * If we are looking for broadcast interface we need to set this
+        * socket to allow broadcast
+        */
+       if (bflag & INT_BROADCAST)
+               setsockopt(s, SOL_SOCKET, SO_BROADCAST,
+                         (char *)&on, sizeof(on));
+
        rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr));
 #ifndef SYS_WINNT
        if (rtn < 0)
@@ -3304,7 +3328,7 @@ findlocalcastinterface(
        /*
         * see how kernel maps the mcast address
         */
-        nif = findlocalinterface(addr, 0);
+        nif = findlocalinterface(addr, 0, 0);
 
        if (nif) {
                DPRINTF(2, ("findlocalcastinterface: kernel recommends interface #%d %s\n", nif->ifnum, nif->name));
@@ -3393,7 +3417,7 @@ findbcastinter(
        DPRINTF(4, ("Finding broadcast/multicast interface for addr %s in list of addresses\n",
                    stoa(addr)));
 
-       interface = findlocalinterface(addr, INT_LOOPBACK|INT_WILDCARD);
+       interface = findlocalinterface(addr, INT_LOOPBACK|INT_WILDCARD, INT_BROADCAST);
        
        if (interface != NULL)
        {
index c2c4edb3c689ed0b01dea93fb17fb0b26b918f10..dbd324235f72dda3640e9ec72b3a49f2df0148af 100644 (file)
@@ -517,16 +517,22 @@ OnSocketRecv(DWORD i, IoCompletionInfo *lpo, DWORD Bytes, int errstatus)
 #endif
                ignore_this = inter->ignore_packets;
                if (ignore_this == ISC_TRUE && inter->family == AF_INET &&
-                   inter->flags == (INT_BROADCAST | INT_WILDCARD) &&
+                   (inter->flags & (INT_BROADCAST | INT_WILDCARD)) &&
                    get_packet_mode(buff) == MODE_BROADCAST &&
                    get_broadcastclient_flag() == ISC_TRUE
                    ) {
                        ignore_this = ISC_FALSE;
 #ifdef DEBUG
-                       if (debug > 3)
+                       if (debug > 1)
                                printf("****Accepting ignored packet on fd %d from %s\n", buff->fd, stoa(&buff->recv_srcadr));
 #endif
                }
+#ifdef DEBUG
+               else {
+                       if (debug > 3)
+                               printf(" Packet mode is %d\n", get_packet_mode(buff));
+               }
+#endif
 
                /*
                 * If we keep it add some info to the structure