1. IGMP??

IGMP(Internet Group Management Protocol)? ??? ???? ????? ???
??? ?????? ??? ??? ???? ??? ??????. ?????? ?????
? ??? ???? ?? ??? ??? ?? ?????? ???? ?? ? ??? ????.

?????? ???? ??? ??? ????? ???? ?????, ?? ??? ???
??? ??? ??? ??, ??? ????? ?? ??? ?????? ?? ??? ??
????? ???? ??? ???? ????? ???? ?? ?? ?? ??? ? ??.

IGMP? ??? Multicast Group? join? ? ?? Client?? ???? ?? ???
Multicast ??? ????? ?? Multicast Group? ????? ??? Multicast
???? ??? ?? ??? ???? ?????? ???? ????? ???.
?? IGMP? ???? Multicast ???? ?? ?? ?? Query ??? ??.

IGMP? OSI ?? ???? ??? ??(Layer 3 - network layer)? ????.

2. IGMP Message ??
Head file ?? : /usr/include/netinet/igmp.h
....
#define IGMP_MEMBERSHIP_QUERY 0x11 /* membership query */
#define IGMP_V1_MEMBERSHIP_REPORT 0x12 /* Vers.1 membership report */
#define IGMP_V2_MEMBERSHIP_REPORT 0x16 /* Vers.2 membership report */
#define IGMP_V3_MEMBERSHIP_REPORT 0x22 /* Vers.3 membership report */
#define IGMP_V2_LEAVE_GROUP 0x17 /* Leave-group message */
#define IGMP_DVMRP 0x13 /* DVMRP routing message */
#define IGMP_PIM 0x14 /* PIM routing message */

0x11 Membership Query : ???? ????? Multicast Group?? ???? ???? ?? ???? ???.
0x12 IGMP version 1 Membership Report : Query? ?? ???? IGMP version 1? ??? ?? ? ????.
0x16 IGMP version 2 Membership Report : Query? ?? ???? IGMP version 2? ??? ?? ? ????.
.....
0x17 Leave Report : IGMP version 2?? ???? Message? ???? ?? ??? ?? ? ????.

3. IGMP & IPMP

IPMP Group??? NIC failover? ???? ??, System? router ?? switch???
??? interface? IGMP group? join ????? IGMP Membership Report request?
???? ??. ?? IGMP snooping? enable ?? ?? switch??, ??? interface?
switch?? IGMP Membership report? ?? ???, multicast applications? packet??
???? ?? ???.

Application ? switch ???? Network interface? failover ???? ?? ???
? ????, NIC failover?? switch? Membership Query? ??? ??? Network ???
Solution(IPMP)? IGMP membership report? switch?? ????, ????? multicast
applications? packet? ?? ? ??? ????? ??.

4. Example : IPMP failover?? IGMP Membership report ?? function
...
if (err == 0) {
err = ill_up_ipifs(ill_to_v4 == NULL ? ill_to_v6:ill_to_v4, q, mp);
}

if (err == 0) {
if (ill_to_v4 != NULL)
ilm_send_multicast_reqs(ill_from_v4, ill_to_v4);

if (ill_to_v6 != NULL)
ilm_send_multicast_reqs(ill_from_v6, ill_to_v6);
}
done:

if (ill_to_v4 != NULL) {
ill_refrele(ill_to_v4);
}

....

5. Example of Multicast Program
Sender Program

/*
* sender.c -- multicasts "hello, world!" to a multicast group once a second
*
* Antony Courtney, 25/11/94
*/

#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include time.h
#include string.h
#include stdio.h

#define HELLO_PORT 12345
#define HELLO_GROUP "225.0.0.37"

main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, cnt;
struct ip_mreq mreq;
char *message="Hello, World!";

/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}

/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(HELLO_GROUP);
addr.sin_port=htons(HELLO_PORT);

/* now just sendto() our destination! */
while (1) {
if (sendto(fd,message,sizeof(message),0,(struct sockaddr *) &addr,
sizeof(addr)) < 0) {
perror("sendto");
exit(1);
}
sleep(1);
}
}

Listener Program

/*
* listener.c -- joins a multicast group and echoes all data it receives from
* the group to its stdout...
*
* Antony Courtney, 25/11/94
* Modified by: Frédéric Bastien (25/03/04)
* to compile without warning and work correctly
*/

#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include time.h
#include string.h
#include stdio.h

#define HELLO_PORT 12345
#define HELLO_GROUP "225.0.0.37"
#define MSGBUFSIZE 256

main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes,addrlen;
struct ip_mreq mreq;
char msgbuf[MSGBUFSIZE];

u_int yes=1; /*** MODIFICATION TO ORIGINAL */

/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}

/**** MODIFICATION TO ORIGINAL */
/* allow multiple sockets to use the same PORT number */
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
/*** END OF MODIFICATION TO ORIGINAL */

/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */
addr.sin_port=htons(HELLO_PORT);

/* bind to receive address */
if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
perror("bind");
exit(1);
}

/* use setsockopt() to request that the kernel join a multicast group */
mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP);
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) {
perror("setsockopt");
exit(1);
}

/* now just enter a read-print loop */
while (1) {
addrlen=sizeof(addr);
if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0,
(struct sockaddr *) &addr,&addrlen)) < 0) {
perror("recvfrom");
exit(1);
}
puts(message);
}
}

6. Method of IGMP snooping When IPMP failover

# netstat -g
Group Memberships: IPv4
Interface Group RefCnt
--------- -------------------- ------
lo0 ALL-SYSTEMS.MCAST.NET 1
e1000g0 224.101.101.101 1

# if_mpadm -d e1000g0

# dtrace -n 'fbt::ill_recover_multicast:entry fbt::ip_ll_send_enabmulti_req:entry
fbt::igmp_joingroup:entry fbt::ipif_multicast_up:entry :: :entry mib::ip_wput_ire:ipIfStatsHCOutMcastPkts ::igmp_timeout_handler:entry'

# snoop -ta -r -d e1000g1
8:41:48.55063 x.x.x.x -> 224.101.10.101 IGMP v2 membership report
or
11:04:2.82520 x.x.x.x -> 224.0.1.1 IP D=224.101.101.101 S=x.x.x.x LEN=28, ID=1093, TOS=0x0, TTL=1

[/usr/local/sbin]# ./tcpdump -i e1000g1 host 224.101.101.101
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on e1000g1, link-type EN10MB (Ethernet), capture size 96 bytes

11:25:03.735562 IP x.x.x.x > 224.101.101.101: igmp v2 report 224.101.101.101
11:25:07.725934 IP x.x.x.x > 224.101.101.101: igmp v2 report 224.101.101.101

# if_mpadm -r e1000g0



More...