Greg Troxel wrote:
> All that said, I can see the merit in changing the API. Has FreeBSD
> withdraw struct mreq, and only has struct mreqn now?
ip_mreq still exists:
struct ip_mreq {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
> Well, to deal with this, someone will need to read the new documentation
> for FreeBSD about how to join/leave, and figure out how to write an
> autoconf test to turn on this behavior being extremely careful not to
> break any other platforms.
It appears that the manual was updated following this change:
--x--
IP(4)
Multicast Options
IP multicasting is supported only on AF_INET sockets of type SOCK_DGRAM
and SOCK_RAW, and only on networks where the interface driver supports
multicasting.
The IP_MULTICAST_TTL option changes the time-to-live (TTL) for outgoing
multicast datagrams in order to control the scope of the multicasts:
u_char ttl; /* range: 0 to 255, default = 1 */
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
Datagrams with a TTL of 1 are not forwarded beyond the local network.
Multicast datagrams with a TTL of 0 will not be transmitted on any net-
work, but may be delivered locally if the sending host belongs to the
destination group and if multicast loopback has not been disabled on the
sending socket (see below). Multicast datagrams with TTL greater than 1
may be forwarded to other networks if a multicast router is attached to
the local network.
For hosts with multiple interfaces, each multicast transmission is sent
from the primary network interface. The IP_MULTICAST_IF option overrides
the default for subsequent transmissions from a given socket:
struct in_addr addr;
setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr));
where "addr" is the local IP address of the desired interface or
INADDR_ANY to specify the default interface.
To specify an interface by index, an instance of ip_mreqn should be
passed instead. The imr_ifindex member should be set to the index of the
desired interface, or 0 to specify the default interface. The kernel
differentiates between these two structures by their size. An inter-
face's local IP address and multicast capability can be obtained via the
SIOCGIFCONF and SIOCGIFFLAGS ioctls. Normal applications should not need
to use this option.
If a multicast datagram is sent to a group to which the sending host
itself belongs (on the outgoing interface), a copy of the datagram is, by
default, looped back by the IP layer for local delivery. The
IP_MULTICAST_LOOP option gives the sender explicit control over whether
or not subsequent datagrams are looped back:
u_char loop; /* 0 = disable, 1 = enable (default) */
setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
This option improves performance for applications that may have no more
than one instance on a single host (such as a router daemon), by elimi-
nating the overhead of receiving their own transmissions. It should gen-
erally not be used by applications for which there may be more than one
instance on a single host (such as a conferencing program) or for which
the sender does not belong to the destination group (such as a time
querying program).
A multicast datagram sent with an initial TTL greater than 1 may be
delivered to the sending host on a different interface from that on which
it was sent, if the host belongs to the destination group on that other
interface. The loopback control option has no effect on such delivery.
A host must become a member of a multicast group before it can receive
datagrams sent to the group. To join a multicast group, use the
IP_ADD_MEMBERSHIP option:
struct ip_mreq mreq;
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
where mreq is the following structure:
struct ip_mreq {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
}
imr_interface should be set to INADDR_ANY to choose the default multicast
interface, or the IP address of a particular multicast-capable interface
if the host is multihomed. Since FreeBSD 4.4, if the imr_interface mem-
ber is within the network range 0.0.0.0/8, it is treated as an interface
index in the system interface MIB, as per the RIP Version 2 MIB Extension
(RFC-1724).
Up to IP_MAX_MEMBERSHIPS memberships may be added on a single socket.
Membership is associated with a single interface; programs running on
multihomed hosts may need to join the same group on more than one inter-
face.
The IGMP protocol uses the primary IP address of the interface as its
identifier for group membership. If multiple IP aliases are configured
on the same interface, they will be ignored. This shortcoming was
addressed in IPv6; MLDv2 requires that the unique link-local address for
an interface is used to identify an MLDv2 listener.
To drop a membership, use:
struct ip_mreq mreq;
setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
where mreq contains the same values as used to add the membership. Mem-
berships are dropped when the socket is closed or the process exits.
--x--
> It really seems broken that the current quagga code doesn't work - it
> seems to leave the address at 0 and store the index. Can you post which
> of the relevant configure tests fire? In particular, is the following
> defined?
>
> HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
#define HAVE_STRUCT_IP_MREQN_IMR_IFINDEX 1
For some reason this still triggers.
#define HAVE_BSD_STRUCT_IP_MREQ_HACK
Ian
--
Ian Freislich
_______________________________________________
Quagga-users mailing list
Quagga-users@lists.quagga.net
http://lists.quagga.net/mailman/listinfo/quagga-users