Multicast packets sent to inappropriate sockets (patch)

William A. Carrel william.a at carrel.org
Sat Oct 25 10:24:59 PDT 2003


The FreeBSD folks have apparently had a some amount of trepidation 
surrounding the patch I presented on this issue.  The old behavior dates 
back to BSD4.3.  Tradition.

Anyway, I've made a new patch which I hope you'll consider.
(a) provides a sysctl to toggle between the traditional BSD4.3 handling 
and the Solaris-style strict membership handling implied by man ip(4) 
and UNPv1.
(b) solves a kernel panic in the first patch

And with the new behavior enabled with the sysctl this will prevent 
unicast listeners from getting multicast traffic delivered to them if 
they are not multicast-aware (i.e. if they don't actually have any mcast 
memberships).  This means that if some socket on your system is 
listening to a multicast address, this patch (when enabled) will prevent 
your nfsd from seeing traffic to multicast-address:2049, which it would 
otherwise receive.

The patch follows.  Be sure to let me know if you have any concerns or 
questions.  Thanks for reading.

--- freebsd_stable_udp_usrreq.c.orig   Fri Oct 24 12:35:46 2003
+++ freebsd_stable_udp_usrreq.c  Fri Oct 24 23:22:01 2003
@@ -102,6 +102,10 @@
 SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW,
   &blackhole, 0, "Do not send port unreachables for refused connects");
 
+static int strict_mcast_mship = 0;
+SYSCTL_INT(_net_inet_udp, OID_AUTO, strict_mcast_mship, CTLFLAG_RW,
+  &strict_mcast_mship, 0, "Only send multicast to member sockets");
+
 struct  inpcbhead udb;    /* from udp_var.h */
 #define udb6  udb  /* for KAME src sync over BSD*'s */
 struct  inpcbinfo udbinfo;
@@ -290,6 +294,27 @@
            if (inp->inp_faddr.s_addr !=
                ip->ip_src.s_addr ||
                inp->inp_fport != uh->uh_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 (strict_mcast_mship &&
+            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;
         }





More information about the Bugs mailing list