Subject: Re: kern/23221: setsockopt IP_ADD_MEMBERSHIP arguments not honored
To: None <gnats-bugs@NetBSD.org>
From: William A.Carrel <william.a@carrel.org>
List: tech-net
Date: 10/24/2003 13:07:03
Updated patch.  The previous patch contained an error where in some 
situations inp->inp_moptions could be dereferenced while null.  This 
patch also has the effect of blocking multicast packets from reaching 
non-multicast programs.  Thanks to Bruce Fenner for pointing these two 
things out to me.  I've also paid homage to Dijkstra by removing the 
goto, which didn't really need to be there except on FreeBSD-CURRENT 
for consistencies sake.

Under the existing implementation, packets bound for "multicast 
address":2049 will be received by any process listening to udp4 *:2049 
if any other process on the host is subscribed to the multicast 
address.  The patch besides its other effect makes sure that processes 
really want to receive multicast traffic before it starts coming to 
them.

--- netbsd_udp_usrreq.c.orig	Fri Oct 24 12:35:01 2003
+++ netbsd_udp_usrreq.c	Fri Oct 24 12:48:04 2003
@@ -643,6 +643,26 @@
  				    inp->inp_fport != *sport)
  					continue;
  			}
+			/*
+			 * Check multicast packets to make sure they are only
+			 * sent to sockets with multicast memberships for the
+			 * packet's destination address and arrival interface
+			 */
+			if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
+			    inp->inp_moptions != NULL) {
+				int mshipno;
+				
+				for (mshipno = 0;
+				     mshipno <=
+				        inp->inp_moptions->imo_num_memberships;
+				     ++mshipno) {
+					if (ip->ip_dst.s_addr == 
inp->inp_moptions->imo_membership[mshipno]->inm_addr.s_addr && 
m->m_pkthdr.rcvif == 
inp->inp_moptions->imo_membership[mshipno]->inm_ifp)
+						break;
+				}
+				if (mshipno ==
+				    inp->inp_moptions->imo_num_memberships)
+					continue;
+			}

  			udp4_sendup(m, off, (struct sockaddr *)src,
  				inp->inp_socket);