Multicast Extensions to Windows Sockets for Win32 -------------------------- About Multicast Extensions -------------------------- The multicast extensions to Windows Sockets for Win32 let an application send and receive Internet Protocol multicast datagrams. Multicast datagrams are similiar to broadcast datagrams. However, multicast datagrams are only received by hosts that have expressed interest in receiving them. In addition, if a network's routers are configured to route multicast packets, the packets are sent beyond the current subnet. The information in this document is excerpted and adapted from Sections 3 and 5 of the document "IP Multicast Extensions for 4.3BSD UNIX and related systems (MULTICAST 1.2 Release)", dated June 24, 1989, written by Steve Deering. You can obtain the most recent complete version of that document via anonymous FTP to gregorio.stanford.edu, directory /vmtp-ip. We gratefully acknowledge the author's kind permission to use this material. --------------------------------------------------------- Notes on the Win32 Implementation of Multicast Extensions --------------------------------------------------------- The Win32 implementation of multicast extensions follows the standards of the MULTICAST 1.2 release, with the following exceptions: There is no support for IP_MULTICAST_LOOP. An application must call the bind function for a socket before setting any multicast options -------------------------- Using Multicast Extensions -------------------------- The following sections discuss using multicast extensions. ------------------------------ Sending IP Multicast Datagrams ------------------------------ Internet Protocol multicasting is currently supported only on AF_INET sockets of type SOCK_DGRAM. 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. 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. Many multicast routers refuse 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 multicasting 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. 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. -------------------------------- 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. 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, 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. The definitions required for the new, multicast-related socket options are found in the file winsock.h that is supplied with the Win32 SDK for Windows NT 3.5. All IP addresses are passed in network byte-order. ------------------------------------------ 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 a WSAENETUNREACH 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: 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: 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 WSAENETUNREACH error.