Subject: kern/7302: multicast interface addr. with p2p inferfaces
To: None <gnats-bugs@gnats.netbsd.org>
From: None <salvet@ics.muni.cz>
List: netbsd-bugs
Date: 04/02/1999 11:10:34
>Number:         7302
>Category:       kern
>Synopsis:       cannot set multicast interface addr. of p2p interface
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Apr  2 01:20:00 1999
>Last-Modified:
>Originator:     Zdenek Salvet
>Organization:
Masaryk University
>Release:        current of Apr 1, 1999
>Environment:
MI

>Description:
   Code for multicast interface address manipulation does not check
   destination addresses of point-to-point interfaces.
   Because of this e.g. GateD's implementation of OSPF protocol does not work
   correctly with point-to-point interfaces (can't add membership).

>How-To-Repeat:
>Fix:
diff -u -r netinet.orig/in_var.h netinet/in_var.h
--- netinet.orig/in_var.h       Fri Apr  2 09:15:07 1999
+++ netinet/in_var.h    Fri Apr  2 11:04:02 1999
@@ -186,6 +186,27 @@
 }
 
 /*
+ * Macro for finding the interface (ifnet structure) corresponding to one
+ * of our IP addresses.  Looks at the remote address of POINTOPOINT
+ * interfaces.
+ */
+#define INDSTADDR_TO_IFP(addr, ifp) \
+       /* struct in_addr addr; */ \
+       /* struct ifnet *ifp; */ \
+{ \
+       register struct in_ifaddr *ia; \
+\
+       for (ia = in_ifaddr.tqh_first; \
+           ia != NULL && \
+                ((ia->ia_ifp->if_flags & IFF_POINTOPOINT) ? \
+               !in_hosteq(ia->ia_dstaddr.sin_addr, (addr)) : \
+               !in_hosteq(ia->ia_addr.sin_addr, (addr))); \
+           ia = ia->ia_list.tqe_next) \
+                continue; \
+       (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
+}
+
+/*
  * Macro for finding an internet address structure (in_ifaddr) corresponding
  * to a given interface (ifnet structure).
  */
diff -u -r netinet.orig/ip_output.c netinet/ip_output.c
--- netinet.orig/ip_output.c    Fri Apr  2 10:13:57 1999
+++ netinet/ip_output.c Fri Apr  2 10:19:07 1999
@@ -975,7 +975,11 @@
                 * IP address.  Find the interface and confirm that
                 * it supports multicasting.
                 */
-               INADDR_TO_IFP(addr, ifp);
+                INDSTADDR_TO_IFP(addr, ifp);
+                if (ifp == NULL) {
+                        INADDR_TO_IFP(addr, ifp);
+                }
+
                if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
                        error = EADDRNOTAVAIL;
                        break;
@@ -1040,7 +1044,10 @@
                        ifp = ro.ro_rt->rt_ifp;
                        rtfree(ro.ro_rt);
                } else {
-                       INADDR_TO_IFP(mreq->imr_interface, ifp);
+                        INDSTADDR_TO_IFP(mreq->imr_interface, ifp);
+                        if (ifp == NULL) {
+                              INADDR_TO_IFP(mreq->imr_interface, ifp);
+                        }
                }
                /*
                 * See if we found an interface, and confirm that it
@@ -1101,7 +1108,11 @@
                if (in_nullhost(mreq->imr_interface))
                        ifp = NULL;
                else {
-                       INADDR_TO_IFP(mreq->imr_interface, ifp);
+                        INDSTADDR_TO_IFP(mreq->imr_interface, ifp);
+                        if (ifp == NULL) {
+                                INADDR_TO_IFP(mreq->imr_interface, ifp);
+                        }
+
                        if (ifp == NULL) {
                                error = EADDRNOTAVAIL;
                                break;

>Audit-Trail:
>Unformatted: