Professional Documents
Culture Documents
VIII Multicasting Options
VIII Multicasting Options
multicasting
contents
multicast address
multicasting versus broadcasting on a LAN
multicasting on a WAN
multicast socket option
mcast_join and related function
dg_cli function using multicasting
receiving MBone session announcements
sending and receiving
SNTP
MULTICASTING
TCP/IP Protocol
Suite
Multicasting starts with one single packet from the source that is duplicated by the
routers. The destination address in each packet is the same for all duplicates
In multiple unicasting, several packets start from the source with different
destination address. For example, when a person sends an e-mail message to a
group of people, this is multiple unicasting. The e-mail software creates replicas of
the message, each with a different destination address, and sends them one by one.
TCP/IP Protocol
Suite
Applications of Multicasting
Teleconferencing
Distance Learning
Dissemination of News
Access to distributed database
TCP/IP Protocol
Suite
Multicast Address
A multicast address is a destination address for a group of hosts
that have joined a multicast group.
A packet that uses a multicast address as a destination can reach
all members of the group unless there are some filtering
restriction by the receiver.
Multicast Address used in IPV4: In classful addressing,
multicast addresses occupied the only single block in class D. In
classless addressing the same block has been used for this
purpose.
In other words, the block assigned for multicasting is 224.0.0.0/4.
This means that the block has 2^28 = 268,435,456 addresses
(224.0.0.0 to 239,255.255.255).
TCP/IP Protocol
Suite
Because the IP packet has a multicast IP address, the ARP protocol cannot
find the corresponding MAC (physical) address to forward the packet at
the data link layer.
What happens next depends on whether or not the underlying data link
layer supports physical multicast addresses.
Most LANs support physical multicast addressing. Ethernet is one of them.
An Ethernet physical address (MAC address) is six octets (48 bits) long. If
the first 25 bits in an Ethernet address are 00000001 00000000 01011110
0, this identifies a physical multicast address for the TCP/IP protocol.
The remaining 23 bits can be used to define a group.
To convert an IP multicast address into an Ethernet address, the multicast
router extracts the least significant 23 bits of a multicast IP address and
inserts them into a multicast Ethernet physical address
TCP/IP Protocol
Suite
TCP/IP Protocol
Suite
Note:
An Ethernet multicast physical address
is in the range
01:00:5E:00:00:00
to
01:00:5E:7F:FF:FF.
TCP/IP Protocol
Suite
Example 2
01:00:5E:2B:0E:07
TCP/IP Protocol
Suite
10
Example 3
01:00:5E:54:18:09
TCP/IP Protocol
Suite
11
Unicast
a single interface
broadcast
multiple interfaces
LAN
multicast
a set of interfaces
LAN or WAN
Mbone
five socket opetions
multicast address
IPv4 class D address
224.0.0.0 ~ 239.255.255.255
(224.0.0.1: all hosts group), (224.0.0.2: all-routers group)
multicast address(2)
IPv6 multicast address
special IPv6 multicast address (flags)
ff02::1 => all-nodes group(all multicast-capable hosts on subnet
must join this group on all multicast-capable interfaces)
ff02::2 => all-routers group(all multicast-capable routers on subnet
must join this group on all multicast-capable interfaces)
Node-local (1)
link-local (2)
site-local (5)
organization-local (8)
global (14)
multicasting on a WAN
A host sends the audio packets and the multicast receivers are
waiting to receive
Struct ipv6_mreq{
struct in6_addr ipv6mr_multiaddr;
struct int ipv6mr_interface;
};
IP_DROP_MEMBERSHIP, IPV6_DROP_MEMBERSHIP
#include "unp.h"
#include <net/if.h>
int mcast_join(int sockfd, const SA *sa, socklen_t salen, const char *ifname, u_int ifindex)
{
switch (sa->sa_family) {
case AF_INET: {
struct ip_mreq mreq;
struct ifreq
ifreq;
memcpy(&mreq.imr_multiaddr, &((struct sockaddr_in *) sa)->sin_addr,
sizeof(struct in_addr));
if (ifindex > 0) {
if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {
errno = ENXIO; /* i/f index not found */
return(-1);
}
goto doioctl;
} else if (ifname != NULL) {
strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
doioctl:
if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)
return(-1);
memcpy(&mreq.imr_interface,
&((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,
sizeof(struct in_addr));
} else
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)));
}
#ifdef
IPV6
case AF_INET6: {
struct ipv6_mreq mreq6;
memcpy(&mreq6.ipv6mr_multiaddr, &((struct sockaddr_in6 *) sa)->sin6_addr,
sizeof(struct in6_addr));
if (ifindex > 0)
mreq6.ipv6mr_interface = ifindex;
else if (ifname != NULL)
if ( (mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) {
errno = ENXIO; /* i/f name not found */
return(-1);
}
else
mreq6.ipv6mr_interface = 0;
return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
&mreq6, sizeof(mreq6)));
}
#endif
default:
errno = EPROTONOSUPPORT;
return(-1);
}
}
#include "unp.h"
int mcast_set_loop(int sockfd, int onoff)
{
switch (sockfd_to_family(sockfd)) {
case AF_INET: {
u_char
flag;
flag = onoff;
return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
&flag, sizeof(flag)));
}
#ifdef
IPV6
case AF_INET6: {
u_int flag;
flag = onoff;
return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
sizeof(flag)));
}
#endif
default:
errno = EPROTONOSUPPORT;
return(-1);
}
&flag,
Sites on Mbone
run sdr program
receives these announcements
provides an interactive user interface that displays the information
lets user send announcements
A sample program
only receives these session announcements to show an example of a simple
multicast receiving program
if (argc == 1)
sockfd = Udp_client(SAP_NAME, SAP_PORT, (void **) &sa, &salen);
else if (argc == 4)
sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);
else err_quit("usage: mysdr <mcast-addr> <port#> <interface-name>");
#include "unp.h"
void loop(int sockfd, socklen_t salen)
{ char buf[MAXLINE+1];
socklen_t
len;
ssize_t
n;
struct sockaddr *sa;
struct sap_packet {
uint32_t
sap_header;
uint32_t
sap_src;
char sap_data[1];
} *sapptr;
sa = Malloc(salen);
for ( ; ; ) {
len = salen;
n = Recvfrom(sockfd, buf, MAXLINE, 0, sa, &len);
buf[n] = 0;
/* null terminate */
sapptr = (struct sap_packet *) buf;
if ( (n -= 2 * sizeof(uint32_t)) <= 0)
err_quit("n = %d", n);
printf("From %s\n%s\n", Sock_ntop(sa, len), sapptr->sap_data);
}
}
Second part
an infinite loop that joins the multicast group to
which the first part is sending and prints every
received datagrams
#include
void
void
"unp.h"
recv_all(int, socklen_t);
send_all(int, SA *, socklen_t);
if (Fork() == 0)
recv_all(recvfd, salen);
#include "unp.h"
#include <sys/utsname.h>
#define SENDRATE
void
send_all(int sendfd, SA *sadest, socklen_t salen)
{
static char
line[MAXLINE];
struct utsname myname;
if (uname(&myname) < 0)
err_sys("uname error");;
snprintf(line, sizeof(line), "%s, %d\n", myname.nodename, getpid());
for ( ; ; ) {
Sendto(sendfd, line, strlen(line), 0, sadest, salen);
sleep(SENDRATE);
}
}
#include "unp.h"
void
recv_all(int recvfd, socklen_t salen)
{
int
n;
char
line[MAXLINE+1];
socklen_t
len;
struct sockaddr
*safrom;
safrom = Malloc(salen);
for ( ; ; ) {
len = salen;
n = Recvfrom(recvfd, line, MAXLINE, 0, safrom, &len);
line[n] = 0;
/* null terminate */
printf("from %s: %s", Sock_ntop(safrom, len), line);
}
}
SNTP
NTP => so sophisticated protocol
SNTP => simplified version of NTP
hosts do not need the complexity of a complete NTP
implementation.
A client listening for NTP broadcast or multicasts on
all attached networks and then prints the time
difference between the NTP packet and the hosts
current time-of-day
VERSION_MASK
MODE_MASK
0x38
0x07
#define
#define
#define
MODE_CLIENT
3
MODE_SERVER
4
MODE_BROADCAST
#include "sntp.h"
int main(int argc, char **argv)
{
int
sockfd;
char
buf[MAXLINE];
ssize_t
n;
socklen_t
salen, len;
struct ifi_info
*ifi;
struct sockaddr
*mcastsa, *wild, *from;
struct timeval
now;
if (argc != 2)
#include "sntp.h
void sntp_proc(char *buf, ssize_t n, struct timeval *nowptr)
{
int version, mode;
uint32_t
nsec, useci;
double
usecf;
struct timeval curr, diff;
struct ntpdata *ntp;
if (n < sizeof(struct ntpdata)) {
printf("\npacket too small: %d bytes\n", n);
return;
}
ntp = (struct ntpdata *) buf;
version = (ntp->status & VERSION_MASK) >> 3;
mode = ntp->status & MODE_MASK;
printf("\nv%d, mode %d, strat %d, ", version, mode, ntp->stratum);
if (mode == MODE_CLIENT) {
printf("client\n");
return;
}
SNTP(2)
One socket per unicast address
One socket per broadcast address
One socket per interface on which the multicast group is joined