Note: This file is from the README that accompanied Steve Deering's original IP multicast release. I have removed all of the kernel installation instructions, leaving only the information about the IP multicast API. ------------------------------------------------------------------------- IP Multicast Extensions for 4.3BSD UNIX and related systems (MULTICAST 1.2 Release) June 24, 1989 Steve Deering Stanford University 3. HOW TO USE THE MULTICAST EXTENSIONS Sending IP Multicast Datagrams IP multicasting is currently supported only on AF_INET sockets of type SOCK_DGRAM and SOCK_RAW, and only on subnetworks for which the interface driver has been modified to support multicasting. To send a multicast datagram, specify an IP multicast address in the range 224.0.0.0 to 239.255.255.255 as the destination address in a sendto() call. By default, IP multicast datagrams are sent with a time-to-live (TTL) of 1, which prevents them from being forwarded beyond a single subnetwork. A new socket option allows the TTL for subsequent multicast datagrams to be set to any value from 0 to 255, in order to control the scope of the multicasts: u_char ttl; setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) Multicast datagrams with a TTL of 0 will not be transmitted on any subnet, 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 one may be delivered to more than one subnet if there are one or more multicast routers attached to the first-hop subnet. To provide meaningful scope control, the multicast routers support the notion of TTL "thresholds", which prevent datagrams with less than a certain TTL from traversing certain subnets. The thresholds enforce the following convention: multicast datagrams with initial TTL 0 are restricted to the same host multicast datagrams with initial TTL 1 are restricted to the same subnet multicast datagrams with initial TTL 32 are restricted to the same site multicast datagrams with initial TTL 64 are restricted to the same region multicast datagrams with initial TTL 128 are restricted to the same continent multicast datagrams with initial TTL 255 are unrestricted in scope. "Sites" and "regions" are not strictly defined, and sites may be further subdivided into smaller administrative units, as a local matter. An application may choose an initial TTL other than the ones listed above. For example, an application might perform an "expanding-ring search" for a network resource by sending a multicast query, first with a TTL of 0, and then with larger and larger TTLs, until a reply is received, perhaps using the TTL sequence 0, 1, 2, 4, 8, 16, 32. The multicast router accompanying this release refuses to forward any multicast datagram with a destination address between 224.0.0.0 and 224.0.0.255, inclusive, regardless of its TTL. This range of addresses is reserved for the use of routing protocols and other low-level topology discovery or maintenance protocols, such as gateway discovery and group membership reporting. The current specification for IP multicasting requires this behavior only for addresses 224.0.0.0 and 224.0.0.1; the next revision of the specification is expected to contain this more general restriction. Each multicast transmission is sent from a single network interface, even if the host has more than one multicast-capable interface. (If the host is also serving as a multicast router, a multicast may be FORWARDED to interfaces other than originating interface, provided that the TTL is greater than 1.) The system manager establishes the default interface to be used for multicast- ing as part of the installation procedure, described below. A socket option is available to override the default for subsequent transmissions from a given socket: struct in_addr addr; setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr)) where "addr" is the local IP address of the desired outgoing interface. An address of INADDR_ANY may be used to revert to the default interface. The local IP address of an interface can be obtained via the SIOCGIFCONF ioctl. To determine if an interface supports multicasting, fetch the interface flags via the SIOCGIFFLAGS ioctl and see if the IFF_MULTICAST flag is set. (Normal applications should not need to use this option; it is intended primarily for multicast routers and other system services specifically concerned with internet topology.) 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. Another socket option gives the sender explicit control over whether or not subsequent datagrams are looped back: u_char loop; setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) where "loop" is 0 to disable loopback, and 1 to enable loopback. This option provides a performance benefit for applications that may have no more than one instance on a single host (such as a router or a mail demon), by eliminating the overhead of receiving their own transmissions. It should generally 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. Receiving IP Multicast Datagrams Before a host can receive IP multicast datagrams, it must become a member of one or more IP multicast groups. A process can ask the host to join a multicast group by using the following socket option: struct ip_mreq mreq; setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) where "mreq" is the following structure: struct ip_mreq { struct in_addr imr_multiaddr; /* multicast group to join */ struct in_addr imr_interface; /* interface to join on */ } Every membership is associated with a single interface, and it is possible to join the same group on more than one interface. "imr_interface" should be INADDR_ANY to choose the default multicast interface, or one of the host's local addresses to choose a particular (multicast-capable) interface. Up to IP_MAX_MEMBERSHIPS (currently 20) memberships may be added on a single socket. To drop a membership, use: struct ip_mreq mreq; setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) where "mreq" contains the same values as used to add the membership. The memberships associated with a socket are also dropped when the socket is closed or the process holding the socket is killed. However, more than one socket may claim a membership in a particular group, and the host will remain a member of that group until the last claim is dropped. The memberships associated with a socket do not necessarily determine which datagrams are received on that socket. Incoming multicast packets are accepted by the kernel IP layer if any socket has claimed a membership in the destination group of the datagram; however, delivery of a multicast datagram to a particular socket is based on the destination port (or protocol type, for raw sockets), just as with unicast datagrams. To receive multicast datagrams sent to a particular port, it is necessary to bind to that local port, leaving the local address unspecified (i.e., INADDR_ANY). More than one process may bind to the same SOCK_DGRAM UDP port if the bind() is preceded by: int one = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) In this case, every incoming multicast or broadcast UDP datagram destined to the shared port is delivered to all sockets bound to the port. For backwards compatibility reasons, THIS DOES NOT APPLY TO INCOMING UNICAST DATAGRAMS -- unicast datagrams are never delivered to more than one socket, regardless of how many sockets are bound to the datagram's destination port. SOCK_RAW sockets do not require the SO_REUSEADDR option to share a single IP protocol type. The definitions required for the new, multicast-related socket options are found in . All IP addresses are passed in network byte-order. A final multicast-related extension is independent of IP: two new ioctls, SIOCADDMULTI and SIOCDELMULTI, are available to add or delete link-level (e.g., Ethernet) multicast addresses accepted by a particular interface. The address to be added or deleted is passed as a sockaddr structure of family AF_UNSPEC, within the standard ifreq structure. These ioctls are for the use of protocols other than IP, and require superuser privileges. A link-level multicast address added via SIOCADDMULTI is not automatically deleted when the socket used to add it goes away; it must be explicitly deleted. It is inadvisable to delete a link-level address that may be in use by IP. (These ioctls already exist in SunOS and Ultrix; they are new to BSD Unix.) Drivers that have been modified to support multicasting also support the IFF_PROMISC and IFF_ALLMULTI interface flags, to the degree possible. The kernel modification required to support Van Jacobson's traceroute program is also included in this release. Examples of usage of the above facilities can be found in the programs accompanying this distribution, such as "ping", "mtest" and "rwhod". 5. ESTABLISHING A DEFAULT MULTICAST INTERFACE Selection of the default multicast interface is controlled via the kernel (unicast) routing table. If there is no multicast route in the table, all multicasts will, by default, be sent on the interface associated with the default gateway. If that interface does not support multicast, attempts to send will receive an ENETUNREACH error. A route may be added for a particular multicast address or for all multicast addresses, to direct them to a different default interface. For example, to specify that multicast datagrams addressed to 224.0.1.3 should, by default, be sent on the interface with local address 36.2.0.8, use the following: /etc/route add 224.0.1.3 36.2.0.8 0 To set the default for all multicast addresses, other than those with individual routes, to be the interface with local address 36.11.0.1, use: /etc/route add 224.0.0.0 36.11.0.1 0 If you point a multicast route at an interface that does not support multicasting, an attempt to multicast via that route will receive an ENETUNREACH error. If needed, these commands normally would be added to the /etc/rc.ip or /etc/rc.local file, to take effect every time the system is booted. 9. MTEST The mtest directory contains a small program for testing the multicast membership sockopts and ioctls. It accepts the following commands, interactively: j g.g.g.g i.i.i.i - join IP multicast group l g.g.g.g i.i.i.i - leave IP multicast group a ifname e.e.e.e.e.e - add ether multicast address d ifname e.e.e.e.e.e - del ether multicast address m ifname 1/0 - set/clear ether allmulti flag p ifname 1/0 - set/clear ether promisc flag q - quit where g.g.g.g is an IP multicast address, e.g., 224.0.2.1 i.i.i.i is the IP address of a local interface or 0.0.0.0 ifname is an interface name, e.g., qe0 e.e.e.e.e.e is an Ethernet address in hex, e.g., 1.0.5e.0.2.1 1/0 is a 1 or a 0, to turn the flag on or off The "p" command to change the promiscuous flag does not work under SunOS, because it uses a different ioctl for that purpose. Mtest is useful for establishing targets for multicast ping testing. The results of mtest filter manipulation can be seen by using the "netstat -nia" command (see next section).