[ Team LiB ] Previous Section Next Section

21.9 Receiving IP Multicast Infrastructure Session Announcements

The IP multicast infrastructure is the portion of the Internet with inter-domain multicast enabled. Multicast is not enabled on the entire Internet; the IP multicast infrastructure started life as the "MBone" in 1992 as an overlay network and moved toward being deployed as part of the Internet infrastructure in 1998. Multicast is widely deployed within enterprises, but being part of the inter-domain IP multicast infrastructure is less common.

To receive a multimedia conference on the IP multicast infrastructure, a site needs to know only the multicast address of the conference and the UDP ports for the conference's data streams (audio and video, for example). The Session Announcement Protocol, or SAP (RFC 2974 [Handley, Perkins, and Whelan 2000]), describes the way this is done (the packet headers and frequency with which these announcements are multicast to the IP multicast infrastructure), and the Session Description Protocol, or SDP (RFC 2327 [Handley and Jacobson 1998]), describes the contents of these announcements (how the multicast addresses and UDP port numbers are specified). A site wishing to announce a session on the IP multicast infrastructure periodically sends a multicast packet containing a description of the session to a well-known multicast group and UDP port. Sites on the IP multicast infrastructure run a program named sdr to receive these announcements. This program does a lot: Not only does it receive session announcements, but it also provides an interactive user interface that displays the information and lets the user send announcements.

In this section, we will develop a simple program that only receives these session announcements to show an example of a simple multicast receiving program. Our goal is to show the simplicity of a multicast receiver, not to delve into the details of this one application.

Figure 21.14 shows our main program that receives periodic SAP/SDP announcements.

Well-Known name and Well-Known port

2–3 The multicast address assigned for SAP announcements is 224.2.127.254 and its name is sap.mcast.net. All the well-known multicast addresses (see http://www.iana.org/assignments/multicast-addresses) appear in the DNS under the mcast.net hierarchy. The well-known UDP port is 9875.

Figure 21.14 main program to receive SAP/SDP announcements.

mysdr/main.c

 1 #include    "unp.h"

 2 #define SAP_NAME     "sap.mcast.net" /* default group name and port */
 3 #define SAP_PORT     "9875"

 4 void     loop(int, socklen_t);

 5 int
 6 main(int argc, char **argv)
 7 {
 8     int     sockfd;
 9     const int on = 1;
10     socklen_t salen;
11     struct sockaddr *sa;

12     if (argc == 1)
13         sockfd = Udp_client(SAP_NAME, SAP_PORT, (void **) &sa, &salen);
14     else if (argc == 4)
15         sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);
16     else
17         err_quit("usage: mysdr <mcast-addr> <port#> <interface-name>");

18     Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
19     Bind(sockfd, sa, salen);

20     Mcast_join(sockfd, sa, salen, (argc == 4) ? argv[3] : NULL, 0);

21     loop(sockfd, salen);        /* receive and print */

22     exit(0);
23 }

Create UDP socket

12–17 We call our udp_client function to look up the name and port, and it fills in the appropriate socket address structure. We use the defaults if no command-line arguments are specified; otherwise, we take the multicast address, port, and interface name from the command-line arguments.

bind port

18–19 We set the SO_REUSEADDR socket option to allow multiple instances of this program to run on a host, and bind the port to the socket. By binding the multicast address to the socket, we prevent the socket from receiving any other UDP datagrams that may be received for the port. Binding this multicast address is not required, but it provides filtering by the kernel of packets in which we are not interested.

Join multicast group

20 We call our mcast_join function to join the group. If the interface name was specified as a command-line argument, it is passed to our function; otherwise, we let the kernel choose the interface on which the group is joined.

21 We call our loop function, shown in Figure 21.15, to read and print all the announcements.

Figure 21.15 Loop that receives and prints SAP/SDP announcements.

mysdr/loop.c

 1 #include    "mysdr.h"

 2 void
 3 loop(int sockfd, socklen_t salen)
 4 {
 5     socklen_t len;
 6     ssize_t n;
 7     char   *p;
 8     struct sockaddr *sa;
 9     struct sap_packet {
10         uint32_t sap_header;
11         uint32_t sap_src;
12         char    sap_data[BUFFSIZE];
13     } buf;

14     sa = Malloc(salen);

15     for ( ; ; ) {
16         len = salen;
17         n = Recvfrom(sockfd, &buf, sizeof(buf) - 1, 0, sa, &len);
18         ((char *) &buf)[n] = 0; /* null terminate */
19         buf.sap_header = ntohl(buf.sap_header);

20         printf("From %s hash 0x%04x\n", Sock_ntop(sa, len),
21                buf.sap_header & SAP_HASH_MASK);
22         if (((buf.sap_header & SAP_VERSION_MASK) >> SAP_VERSION_SHIFT) > 1) {
23             err_msg("... version field not 1 (0x%08x)", buf.sap_header);
24             continue;
25         }
26         if (buf.sap_header & SAP_IPV6) {
27             err_msg("... IPv6");
28             continue;
29         }
30         if (buf.sap_header & (SAP_DELETE | SAP_ENCRYPTED | SAP_COMPRESSED)) {
31             err_msg("... can't parse this packet type (0x%08x)",
32                     buf.sap_header);
33             continue;
34         }
35         p = buf.sap_data + ((buf.sap_header & SAP_AUTHLEN_MASK)
36                             >> SAP_AUTHLEN_SHIFT);
37         if (strcmp(p, "application/sdp") == 0)
38             p += 16;
39         printf("%s\n", p);
40     }
41 }

Packet format

9–13 sap_packet describes the SDP packet: a 32-bit SAP header, followed by a 32-bit source address, followed by the actual announcement. The announcement is simply lines of ISO 8859–1 text and should not exceed 1,024 bytes. Only one session announcement is allowed in each UDP datagram.

Read UDP datagram, print sender and contents

15–21 recvfrom waits for the next UDP datagram destined to our socket. When one arrives, we place a null byte at the end of the buffer, fix the byte order of the header field, and print the source of the packet and SAP hash.

Check SAP header

22–34 We check the SAP header to see if it is a type that we handle. We don't handle SAP packets with IPv6 addresses in the header, or compressed or encrypted packets.

Find beginning of announcement and print

35–39 We skip over any authentication data that may be present, skip over the packet content type if it's present, and then print out the contents of the packet.

Figure 21.16 shows some typical output from our program.

Figure 21.16 Typical SAP/SDP announcement.
freebsd % mysdr
From 128.223.83.33:1028 hash 0x0000
v=0
o=- 60345 0 IN IP4 128.223.214.198
s=UO Broadcast - NASA Videos - 25 Years of Progress
i=25 Years of Progress, parts 1-13. Broadcast with Cisco System's
 IP/TV using MPEG1 codec (6 hours 5 Minutes; repeats) More information
 about IP/TV and the client needed to view this program is available
 from http://videolab.uoregon.edu/download.html
u=http://videolab.uoregon.edu/
e=Hans Kuhn <multicast@lists.uoregon.edu>
p=Hans Kuhn <541/346-1758>
b=AS:1000
t=0 0
a=type:broadcast
a=tool:IP/TV Content Manager 3.2.24
a=x-iptv-file:1 name y:25yop1234567890123.mpg
m=video 63096 RTP/AVP 32 31 96
c=IN IP4 224.2.245.25/127
a=framerate:30
a=rtpmap:96 WBIH/90000
a=x-iptv-svr:video blaster2.uoregon.edu file 1 loop
m=audio 31954 RTP/AVP 14 96 0 3 5 97 98 99 100 101 102 10 11 103 104 105 106
c=IN IP4 224.2.216.85/127
a=rtpmap:96 X-WAVE/8000
a=rtpmap:97 L8/8000/2
a=rtpmap:98 L8/8000
a=rtpmap:99 L8/22050/2
a=rtpmap:100 L8/22050
a=rtpmap:101 L8/11025/2
a=rtpmap:102 L8/11025
a=rtpmap:103 L16/22050/2
a=rtpmap:104 L16/22050
a=rtpmap:105 L16/22050/2
a=rtpmap:106 L16/11025
a=x-iptv-svr:audio blaster2.uoregon.edu file 1 loop

This announcement describes the NASA coverage on the IP Multicast Infrastructure of a space shuttle mission. The SDP session description consists of numerous lines of the form

type=value

where the type is always one character and is case-significant. The value is a structured text string that depends on the type. Spaces are not allowed around the equals sign. v=0 is the version.

0= is the origin. - indicates no particular username, 60345 is the session ID, 0 is the version number for this announcement, IN is the network type, IP4 is the address type, and 128.223.214.198 is the address. The five-tuple consisting of the username, session ID, network type, address type, and address form a globally unique identifier for the session.

s= defines the session name, and i= is information about the session. We have wrapped the latter every 80 characters. u= provides a Uniform Resource Identifier (URI) for more information about the session, and e= and p= provide the email address and phone number of the person responsible for the conference.

b= provides a measure of the expected bandwidth for this session. t= provides the starting time and stopping time, both in NTP units, which are seconds since January 1, 1900, UTC. In this case, this session is "permanent;" having no particular start or stop time, so both start and stop time are specified as 0.

The a= lines are attributes; either of the session, if they appear before any m= lines, or of the media, if they appear after a m= line.

The m= lines are the media announcements. The first of these two lines specifies that the video is on port 63096 and its format is RTP, using the Audio/Video Profile or AVP, with possible payload types 32, 31 or 96 (which are MPEG, H.261, and WBIH, respectively). The c= line that follows provides the connection information, which in this example, specifies that it is IP-based, using IPv4, with a multicast address of 224.2.245.25 and a TTL of 127. Although these are separated by a slash, like the CIDR prefix format, they are not meant to represent a prefix and a mask.

The next m= line specifies that the audio is on port 31954 and may be in any of a number of RTP/AVP payload types, some of which are standard and some of which are specified below using a=rtpmap: attributes. The c= line that follows provides the connection information for the audio, which in this example specifies that it is IP-based, using IPv4, with a multicast address of 224.2.216.85 and a TTL of 127.

    [ Team LiB ] Previous Section Next Section