Subject: multicasting problem?
To: None <tech-net@NetBSD.ORG>
From: Christos Zoulas <christos@deshaw.com>
List: tech-net
Date: 11/04/1996 19:46:52
I am trying to resolve a problem that occurs with routed on PPP [and other
point-to-point]. When you start up ppp, the following portion of code
inside routed fails:


		m.imr_multiaddr.s_addr = htonl(INADDR_RIP_GROUP);
		m.imr_interface.s_addr = ((ifp->int_if_flags & IFF_POINTOPOINT)
					  ? ifp->int_dstaddr
					  : ifp->int_addr);
		if (setsockopt(rip_sock,IPPROTO_IP, IP_ADD_MEMBERSHIP,
			       &m, sizeof(m)) < 0)

and produces syslog messages.


Looking at netinet/ip_output.c, in the IP_ADD_MEMBERSHIP portion:

                } else {
                        INADDR_TO_IFP(mreq->imr_interface, ifp);
                }
                /*
                 * See if we found an interface, and confirm that it
                 * supports multicast.
                 */
                if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
                        error = EADDRNOTAVAIL;
                        break;
                }


INADDR_TO_IFP() will fail finding an ifp appropriate for the dstaddr of the
ppp connection, and the setsockopt() call will fail.

In the source of routed, there is a PPP_MCAST_BUG define for systems that
that the multicasting code cannot add/remove memberships from point to point
interfaces when those are specified by their remote addresses.

Who is right? How can we fix this? Is the correct fix just to define:


#define INADDR_TO_IFP_REMOTE(addr, ifp) \
        /* struct in_addr addr; */ \
        /* struct ifnet *ifp; */ \
{ \
        register struct in_ifaddr *ia; \
\
        for (ia = in_ifaddr.tqh_first; ia != NULL; ia = ia->ia_list.tqe_next) \
                if (ia->ia_ifp->if_flags & IFF_POINTOPOINT) { \
                        if (ia->ia_dstaddr.sin_addr.s_addr == (addr).s_addr) \
                                break; \
                } else { \ 
                        if (ia->ia_addr.sin_addr.s_addr == (addr).s_addr) \
                                break; \
                } \
        (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
}


and use this in the add and remove cases? Or should we just define
PPP_MCAST_BUG? Where is the place to read about this stuff?

christos