FreeBSD/sys/netinet/in_mcast.c
/*
 * Select the interface for transmitting IPv4 multicast datagrams.
 *
 * Either an instance of struct in_addr or an instance of struct ip_mreqn
 * may be passed to this socket option. An address of INADDR_ANY or an
 * interface index of 0 is used to remove a previous selection.
 * When no interface is selected, one is chosen for every send.
 */
Select the interface for transmitting IPv4 multicast datagrams.
Either an instance of struct in_addr or an instance of struct ip_mreqn
may be passed to this socket option. An address of INADDR_ANY or an
interface index of 0 is used to remove a previous selection.
When no interface is selected, one is chosen for every send.
Select the interface for transmitting IPv4 multicast datagrams . Either an instance of struct in_addr or an instance of struct ip_mreqn may be passed to this socket option . An address of INADDR_ANY or an interface index of 0 is used to remove a previous selection . When no interface is selected one is chosen for every send .
static int
inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
{
	struct in_addr		 addr;
	struct ip_mreqn		 mreqn;
	struct ifnet		*ifp;
	struct ip_moptions	*imo;
	int			 error;
	if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) {
		error = sooptcopyin(sopt, &mreqn, sizeof(struct ip_mreqn),
		    sizeof(struct ip_mreqn));
		if (error)
			return (error);
		if (mreqn.imr_ifindex < 0 || V_if_index < mreqn.imr_ifindex)
			return (EINVAL);
		if (mreqn.imr_ifindex == 0) {
			ifp = NULL;
		} else {
			ifp = ifnet_byindex(mreqn.imr_ifindex);
			if (ifp == NULL)
				return (EADDRNOTAVAIL);
		}
	} else {
		error = sooptcopyin(sopt, &addr, sizeof(struct in_addr),
		    sizeof(struct in_addr));
		if (error)
			return (error);
		if (in_nullhost(addr)) {
			ifp = NULL;
		} else {
			INADDR_TO_IFP(addr, ifp);
			if (ifp == NULL)
				return (EADDRNOTAVAIL);
		}
		CTR3(KTR_IGMPV3, "%s: ifp = %p, addr = %s", __func__, ifp,
		    inet_ntoa(addr));
	}
	if (ifp != NULL && (ifp->if_flags & IFF_MULTICAST) == 0)
		return (EOPNOTSUPP);
	imo = inp_findmoptions(inp);
	imo->imo_multicast_ifp = ifp;
	imo->imo_multicast_addr.s_addr = INADDR_ANY;
	INP_WUNLOCK(inp);
	return (0);
}
static int inp_set_multicast_if ( struct inpcb * inp , struct sockopt * sopt ) { struct in_addr addr ; struct ip_mreqn mreqn ; struct ifnet * ifp ; struct ip_moptions * imo ; int error ; if ( sopt -> sopt_valsize == sizeof ( struct ip_mreqn ) ) { error = sooptcopyin ( sopt , & mreqn , sizeof ( struct ip_mreqn ) , sizeof ( struct ip_mreqn ) ) ; if ( error ) return ( error ) ; if ( mreqn . imr_ifindex < 0 || V_if_index < mreqn . imr_ifindex ) return ( EINVAL ) ; if ( mreqn . imr_ifindex == 0 ) { ifp = NULL ; } else { ifp = ifnet_byindex ( mreqn . imr_ifindex ) ; if ( ifp == NULL ) return ( EADDRNOTAVAIL ) ; } } else { error = sooptcopyin ( sopt , & addr , sizeof ( struct in_addr ) , sizeof ( struct in_addr ) ) ; if ( error ) return ( error ) ; if ( in_nullhost ( addr ) ) { ifp = NULL ; } else { INADDR_TO_IFP ( addr , ifp ) ; if ( ifp == NULL ) return ( EADDRNOTAVAIL ) ; } CTR3 ( KTR_IGMPV3 , " " , __func__ , ifp , inet_ntoa ( addr ) ) ; } if ( ifp != NULL && ( ifp -> if_flags & IFF_MULTICAST ) == 0 ) return ( EOPNOTSUPP ) ; imo = inp_findmoptions ( inp ) ; imo -> imo_multicast_ifp = ifp ; imo -> imo_multicast_addr . s_addr = INADDR_ANY ; INP_WUNLOCK ( inp ) ; return ( 0 ) ; }
Select the interface for transmitting IPv4 multicast datagrams.
Select the interface for transmitting IPv4 multicast datagrams .
/*
		 * An interface index was specified using the
		 * Linux-derived ip_mreqn structure.
		 */ /*
		 * An interface was specified by IPv4 address.
		 * This is the traditional BSD usage.
		 */ /* Reject interfaces which do not support multicast. */