`
`value?
`
`by the
`
`)n one
`tlticast
`
`of the
`
`aod to
`
`multi-
`
`~ce has
`)K?
`.tion is
`
`~sed to
`
`13
`
`IGMP: Internet Group
`Management Protocol
`
`13.1
`
`Introduction
`
`IGMP conveys group membership information between hosts and touters on a local
`network. Routers periodically multicast IGMP queries to the all-hosts group. Hosts
`respond to the queries by multicasting IGMP report messages. The IGMP specification
`appears in RFC 1112. Chapter 13 of Volume 1 describes the specification of IGMP and
`provides some examples.
`From an architecture perspective, IGMP is a transport protocol above IP. It has a
`protocol number (2) and its messages are carried in IP datagrams (as with ICMP).
`IGMP usually isn’t accessed directly by a process but, as with ICMP, a process can send
`and receive IGMP messages through an IGMP socket. This feature enables multicast
`routing daemons to be implemented as user-level processes.
`Figure 13.1 shows the overall organization of the IGMP protocol in Net/3.
`The key to IGMP processing is the collection of in_mul t i structures shown in the
`center of Figure 13.1. An incoming IGMP query causes igmp_input to initialize a
`countdown timer for each in_multi structure. The timers are updated by
`igmp_fasttimo, which calls igmp_sendreport as each timer expires.
`We saw in Chapter 12 that ip_setmopt ions calls igmp_j o ingroup when a new
`in_multi structure is created,
`calls
`igmp_joingroup
`igmp_sendreport
`announce the new group and enables the group’s timer to schedule a second announce-
`ment a short time later, igmp_sendreport takes care of formatting an IGMP message
`and passing it to ip_output.
`On the left and right of Figure 13.1 we see that a raw socket can send and receive
`IGMP messages directly.
`
`to
`
`381
`
`Ex.1013.407
`
`DELL
`
`
`
`382
`
`IGMP: Internet Group Management Protocol
`
`Chapter 13
`
`Secti~
`
`Figure 13.1 Summary of IGMP processing.
`
`13.2 Code Introduction
`
`The IGMP protocol is implemented in four files listed in Figure 13.2.
`
`Description
`File
`ne¢ ± ne¢ / J_gmp. h IGMP protocol definitions
`nee±n÷(cid:128) / ±gmp_var.h
`IGMP implementation definitions
`ne ~ ±net / ±n_var. h
`IP multicast data structures
`n e ~ ± ne ~ / ± ~mp. c
`IGMP protocol implementation
`
`Figure 13.2 Files discussed in this chapter.
`
`Global Variables
`
`Three new global variables, shown in Figure 13.3, are introduced in this chapter.
`
`Statistics
`
`SNMP
`
`IGMP statistics are maintained in the J_grapstat variables shown in Figure 13.4.
`
`Ex.1013.408
`
`DELL
`
`
`
`:r 13
`
`Section 13.2
`
`Code Introduction 383
`
`Variable
`igmp. all hosts_group
`igmp_timers_are_running
`igmpstat
`
`Data~pe
`u_long
`int
`struct igmpstat
`
`Description
`all-hosts group address in network byte order
`true if any IGMP timer is active, false otherwise
`IGMP statistics (Figure 13.4).
`
`Figure 13.3 Global variables introduced in this chapter.
`
`igmpstat member
`igps_rcv_badqueries
`igps_rcv_badreports
`igps_rcv_badsum
`igps_rcv_ourreports
`igps_rcv_queries
`igps_rcv_reports
`igps_rcv_tooshort
`igps_rcv_total
`igps_snd_reports
`
`Description
`#messages received as invalid queries
`#messages received as invalid reports
`#messages received with bad checksum
`#messages received as reports for local groups
`#messages received as membership queries
`#messages received as membership reports
`#messages received with too few bytes
`total #IGMP messages received
`#messages sent as membership reports
`
`Figure 13.4 IGMP statistics.
`
`Figure 13.5 shows some sample output of these statistics, from the nets¢a¢ -p
`igmp command on vangogh, cs. berkeley, edu.
`
`netstat -p igmp output
`18774 messages received
`0 messages received with too few bytes
`0 messages received with bad checksum
`18774 membership queries received
`0 membership queries received with invalid field(s)
`0 membership reports received
`0 membership reports received with invalid field(s)
`0 membership reports received for groups to which we belong
`0 membership reports sent
`
`igmps tat member
`igps_rcv_total
`igps_rcv_tooshort
`igps_rcv_badsum
`igps_rcv_queries
`igps_rcv_badqueries
`igps_rcv_reports
`igps_rcv_badreports
`igps_rcv_ourreports
`igps_snd_reports
`
`Figure 13.5 Sample IGMP statistics.
`
`From Figure 13.5 we can tell that vangogh is attached to a network where IGMP is
`being used, but that vangogh is not joining any multicast groups, since
`is 0.
`igps_snd_reporCs
`
`SNMP Variables
`
`There is no standard SNMP MIB for IGMP, but [McCloghrie and Farinacci 1994a]
`describes an experimental MIB for IGMP.
`
`Ex.1013.409
`
`DELL
`
`
`
`384
`
`IGMP: Internet Group Management Protocol
`
`Chapter 13
`
`13.3
`
`igmp Structure
`
`An IGMP message is only 8 bytes long. Figure 13.6 shows the ±gmp structure used by
`Net/3.
`
`43 struct igmp {
`/* version & type of IGMP message */
`u_char igmp_type;
`44
`/* unused, should be zero
`*/
`u_char igmp_code;
`45
`/* IP-style checksum
`*/
`u_short igmp_cksum;
`46
`struct in_addr igmp_group; /* group address being reported
`*/
`47
`/* (zero for queries)
`*/
`48 };
`
`igmp.h
`
`~mp.h
`
`Figure 13.6 igmp structure.
`
`43--44
`
`A 4-bit version code and a 4-bit type code are contained within
`ure 13.7 shows the standard values.
`
`igmp_type.
`
`Fig-
`
`Type
`1
`2
`3
`
`igmp_type
`Oxll (IGMP_HOST_MEMBERSHIP_QUERY)
`0x12 (IGMP_HOST_MEMBERSHIP_REPORT)
`0x13
`
`Description
`membership query
`membership report
`DVMRP message (Chapter 14)
`
`Version
`
`111
`
`Figure 13.7 IGMP message types.
`
`Only version 1 messages are used by Net/3. Multicast routers send type 1
`(IGMP_HOST_MEMBERSHI P_QUERY) messages to solicit membership reports from hosts
`on the local network. The response to a type 1 IGMP message is a type 2
`(IGMP_HOST_MEMBERSHIP_REPORT) message from the hosts reporting their multicast
`membership information. Type 3 messages transport multicast routing information
`between routers (Chapter 14). A host never processes type 3 messages. The remainder
`of this chapter discusses only type I and 2 messages.
`igmp_code is unused in IGMP version 1, and igmp_cksum is the familiar IP
`checksum computed over all 8 bytes of the IGMP message.
`igmp_group is 0 for queries. For replies, it contains the multicast group being
`reported.
`Figure 13.8 shows the structure of an IGMP message relative to an IP datagram.
`
`45--46
`
`47-48
`
`13.4
`
`IGMP protosw Structure
`
`Figure 13.9 describes the protosw structure for IGMP.
`
`Although it is possible for a process to send raw IP packets through the IGMP
`protosw entry, in this chapter we are concerned only with how the kernel processes
`IGMP messages. Chapter 32 discusses how a process can access IGMP using a raw
`socket.
`
`Ex.1013.410
`
`DELL
`
`
`
`,ter 13
`
`Section 13.4
`
`IGMP protosw Structure 385
`
`IGMP message
`
`cksum ]
`2 bytes
`
`group
`
`4 bytes
`
`IP header
`
`IP datagram
`
`
`
`Figure 13.8 An IGMP message (igmp_ omitted).
`
`inetsw[5]
`SOCK_RAW
`&inetdomain
`IPPROTO_IGMP (2)
`PR_ATOMIC[PR__ADDR
`igmp_input
`rip_output
`
`Description
`IGMP provides raw packet services
`IGMP is part of the Internet domain
`
`appears in the ip_p field of the IP header
`socket layer flags, not used by protocol processing
`receives messages from IP layer
`sends IGMP message to IP layer
`not used by IGMP
`respond to administrative requests from a process
`respond to communication requests from a process
`initialization for IGMP
`process pending membership reports
`not used by IGMP
`not used by IGMP
` I
`not used by IGMP
`
`0 r
`
`00o
`
`ip_ctloutput
`rip_usrreq
`igmp_init
`igmp_fasttimo
`
`_~d by
`
`!gmp.h
`
`igmp.h
`
`. Fig-
`
`rpe 1
`hosts
`zpe 2
`lticast
`~ation
`tinder
`
`iar IP
`
`being
`
`IGMP
`.cesses
`a raw
`
`Member
`Dr_type
`pr_domain
`Dr_protocol
`Dr_flags
`pr_input
`pr_output
`pr_ctlinput
`pr_ctloutput
`pr_usrreq
`pr_init
`Pr_fasttimo
`pr_slowtimo
`pr_drain
`pr_sysctl
`
`Figure 13.9 The IGMP protosw structure.
`
`There are three events that trigger IGMP processing:
`¯ a local interface has joined a new multicast group (Section 13.5),
`¯ an IGMP timer has expired (Section 13.6), and
`¯ an IGMP query is received (Section 13.7).
`There are also two events that trigger local IGMP processing but do not result
`any messages being sent:
`¯ an IGMP report is received (Section 13.7), and
`¯ a local interface leaves a multicast group (Section 13.8).
`These five events are discussed in the following sections.
`
`Ex.1013.411
`
`DELL
`
`
`
`386
`
`IGMP: Internet Group Management Protocol
`
`Chapter 13
`
`Sectio
`
`13.5
`
`Joining a Group: Kg~p_joKngroup Function
`
`is called by
`We saw in Chapter 12 that
`igmp_joingroup
`in_multi structure is created. Subsequent requests to join the same group only
`increase the reference count in the i n_mu 1 t i structure; igmp_J o ingroup is not called.
`igmp_j oingroup is shown in Figure 13.10
`
`igmp.c
`
`164 void
`165 igmp_j oingroup (inm)
`166 struct in_multi *inm;
`167 {
`168 int s = splnet();
`if (inm->inm_addr.s_addr == igmp_all_hosts_group I I
`inm->inm_ifP == &loif)
`
`into- >inm_t imer = 0;
`else {
`igmp_sendreport (inm) ;
`inm->inm_timer = IGMP_RANDOM_DELAY ( inm- >inm_addr) ;
`igmp_timers_are_running : 1 ;
`
`169
`170
`171
`172
`173
`174
`175
`176
`177
`178 }
`
`}
`splx (s) ;
`
`Figure 13.10 igmp_joingroup function.
`
`igmp.c
`
`13.6
`
`164--178
`
`into points to the new in_multi structure for the group. If the new group is the
`all-hosts group, or the membership request is for the loopback interface, inm_t imer is
`disabled and igmp_joingroup returns. Membership in the all-hosts group is never
`reported, since every multicast host is assumed to be a member of the group. Sending a
`membership report to the loopback interface is unnecessary, since the local host is the
`only system on the loopback network and it already knows its membership status.
`In the remaining cases, a report is sent immediately for the new group, and the
`group timer is set to a random value based on the group. The global flag
`igmp_timers_are_running is set to indicate that at least one timer is enabled.
`i gmp_f a st t imo (Section 13.6) examines this variable to avoid unnecessary processing.
`
`123--i~
`
`59--73
`
`When the timer for the new group expires, a second membership report is issued.
`The duplicate report is harmless, but it provides insurance in case the first report is lost
`or damaged. The report delay is computed by
`(Figure 13.11).
`IGMP_RANDOM_DELA¥
`According to RFC 1122, report timers should be set to a random time between 0 and
`154--i~
`10 (IGMP_MAX_HOST_REPORT_DELAY) seconds. Since IGMP timers are decremented
`five (PR_FASTHZ) times per second,
`IGMP_RANDOM_DELAY must pick a random value
`between 1 and 50. If r is the random number computed by adding the total number of
`IP packets received, the host’s primary IP address, and the multicast group, then
`0 < (r rood 50) < 49
`
`170-1;
`
`and
`
`1 < (r rood 50)+1 _< 50
`
`Ex.1013.412
`
`DELL
`
`
`
`Section 13.6
`
`igmp_fas t timo Function 387
`
`5 9 /* ~mp_vanh
`60 * Macro to compute a random timer value between 1 and (IGMP_MAX_REPORTING_
`61
`* DELAY * countdown frequency). We generate a "random" number by adding
`62
`* the total number of IP packets received, our primary IP address, and the
`63 * multicast address being timed-out. The 4.3 random() routine really
`64
`* ought to be available in the kernel!
`65 */
`66 #define IGMP_RANDOM_DELAY(multiaddr) \
`67
`/* struct in_addr multiaddr; */ \
`68
`( (ipstat.ips_total + \
`69
`ntohl(IA_SIN(in_ifaddr)->sin_addr.s_addr) + \
`70
`ntohl((multiaddr).s_addr) \
`71
`) \
`72
`% (IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ) + 1 \
`73
`
`)
`
`
`
`Figure 13.11 IGMP_RANDOM_DELAY function.
`
`igmp_var.h
`
`Zero is avoided because it would disable the timer and no report would be sent.
`
`13.6
`
`igmp_fastt imo Function
`
`Before looking at igmp_fasttimo, we need to describe the mechanism used to tra-
`
`verse the in_mul t i structures.
`To locate each in_multi structure, Net/3 must traverse the in_multi list for each
`interface. During a traversal, an in_multistep structure (shown in Figure ]3.12)
`records the position.
`
`123 struct in_multistep {
`124
`struct in_ifaddr *i_ia;
`125
`struct in_multi *i_inm;
`126
`
`;
`
`in_var.h
`
`in_var.h
`
`Figure 13.12 in_multistep function.
`
`123--126
`
`~__ia points to the next in_i faddr interface structure and i_inm points to the next
`
`
`in_mul t i structure for the current
`interface.
`
`154-169
`
`170-177
`
`The IN_FIRST_MULTI and IN_NEXT_MULTI macros (shown in Figure 13.13) tra-
`verse the lists.
`If the in_mult i list has more entries, i_inm is advanced to the next entry. When
`IN_NEXT_MULTI reaches the end of a multicast list, i_ia is advanced to the next inter-
`face and i_inm to the first in_multi structure associated with the interface. If the
`interface has no multicast structures, the while loop continues to advance through the
`interface list until a11 interfaces have been searched.
`The in_multistep array is initialized to point to the first in_i faddr structure in
`the in_ifaddr list and i_inm is set to null. IN_NEXT_MULTI finds the first
`i n_mu i t i structure.
`
`te
`
`.~r
`a
`te
`
`te
`Lg
`d.
`g.
`
`Ld
`
`le
`of
`
`Ex.1013.413
`
`DELL
`
`
`
`388
`
`IGMP: Internet Group Management Protocol
`
`Chapter 13
`
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157
`158
`159
`160
`161
`162
`163
`164
`165
`166
`167
`168
`169
`
`170
`171
`172
`173
`174
`175
`176
`177
`
`/*
`* Macro to step through all of the in_multi records, one at a time.
`
`* The current position is remembered in "step", which the caller must
`* provide. IN_FIRST_MULTI(), below, must be called to initialize "step"
`* and get the first record.
`Both macros return a NULL "inm" when there
`* are no remaining records.
`*/
`#define IN_NEXT_MULTI(step, inm) \
`/* struct in_multistep step; */ \
`/* struct in_multi *inm; */ \
`
`in vanh
`
`{ \
`
`if (((inm) = (step).i_inm) != NULL) \
`(step).i_inm : (inm)->inm_next; \
`else \
`while ((step).i_ia != NULL) { \
`(inm) = (step).i_ia->ia_multiaddrs; \
`(step) .i_ia = (step) .i_ia->ia_next; \
`if ((inm) != NULL) { \
`(step) .i_inm = (inm)->inm_next; \
`break; \
`
`} \
`
`} \
`
`#define IN_FIRST_MULTI(step,
`inm) \
`/* struct in_multistep step; */ \
`/* struct in_multi *inm; */ \
`
`{ \
`
`(step).i_ia : in_ifaddr; \
`(step).i_inm : NULL; \
`IN_NEXT_MULTI((step), (inm)); \
`
`Figure 13.13 IN_FIRST_MULTI and IN_NEXT_MULTI structures.
`
`in_var.h
`
`igmp_fasttimo is the fast timeout function for
`We know from Figure 13.9 that
`IGMP and is called five times per second, igmp_fasttimo (shown in Figure 13.14)
`decrements multicast report timers and sends a report when the timer expires.
`If igmp_timers_are_running is false, igmp_fasttimo returns immediately
`instead of wasting time examining each timer.
`igmp_fasttimo resets the running flag and then initializes step and into with
`
`
`IN_FIRST_MULTI. The igmp_fasttimo function locates each structure
`in_multi
`with the whi le loop and the IN_NEXT_MULTI macro. For each structure:
`
`187--198
`
`199--213
`
`If the timer is 0, there is nothing to be done.
`If the timer is nonzero, it is decremented. If it reaches 0, an IGMP membership
`report is sent for the group.
`If the timer is still nonzero, then at least one timer is still running, so
`is set to 1.
`igmp_timers_are_running
`
`2]
`
`23
`
`24~
`
`Ex.1013.414
`
`DELL
`
`
`
`ier 13
`
`Section 13.6
`
`±gmp_£ast t imo Function
`
`389
`
`igmp.c
`
`187 void
`188 igmp_fasttimo ( )
`189 {
`190
`191
`192
`
`struct in_multi *inm;
`int
`s;
`struct in_multistep step;
`
`* Quick check to see if any work needs to be done, in order
`* to minimize the overhead of fasttimo processing.
`*/
`if (!igmp_timers are running}
`return;
`s = splnet();
`igmp_timers_are_running : 0;
`IN_FIRST_MULTI(step, inm);
`while (inm != NULL) {
`if (inm->inm_timer -= 0)
`/* do nothing */
`} else if (--inm->inm_timer == 0)
`igmp_sendreport(inm);
`} else {
`igmp_timers_are_running = i;
`
`}I
`
`N_NEXT_MULTI(step, inm);
`
`splx(s);
`
`193
`194
`195
`196
`197
`198
`
`199
`2OO
`201
`202
`203
`204
`205
`206
`207
`208
`209
`210
`211
`212
`213
`
`z var.h
`
`)n for
`13.14)
`
`[iately
`
`with
`,tcture
`
`arship
`
`lg, so
`
`Figure 13.14 igmp_fast t imo
`
`function.
`
`igmp_sendreport Function
`
`214--232
`
`233-245
`
`246--260
`
`function (shown in Figure 13.15) constructs and sends an
`The igmp_sendreport
`IGMP report message for a single multicast group.
`The single argument into points to the in_multi structure for the group being
`reported, igmp_sendretoort allocates a new mbuf and prepares it for an IGMP mes-
`sage. igmp_sendreport leaves room for a link-layer header and sets the length of the
`mbuf and packet to the length of an IGMP message.
`The IP header and IGMP message is constructed one field at a time. The source
`address for the datagram is set to INADDR_ANY, and the destination address is the
`multicast group being reported,
`replaces INADDR_ANY with the unicast
`ip_output
`address of the outgoing interface. Every member of the group receives the report as
`does every multicast router (since multicast routers receive
`
`all IP multicasts).
`Finally, igmp_sendreport constructs an ip_mopt ions structure to go along with
`the message sent to ip_output. The interface associated with the in_mul t i structure
`is selected as the outgoing interface; the TTL is set to 1 to keep the report on the local
`network; and, if the local system is configured as a router, multicast loopback is enabled
`for this request.
`
`Ex.1013.415
`
`DELL
`
`
`
`390
`
`IGMP: Internet Group Management Protocol
`
`214 static void
`215 igmp_sendreport(inm)
`216 struct in_multi *inm;
`217 {
`218
`219
`220
`221
`222
`
`struct mbuf *m;
`struct igmp *igmp;
`struct ip *ip;
`struct ip_moptions *imo;
`struct ip_moptions simo;
`
`Chapter 13
`
`igmp.c
`
`223
`224
`225
`226
`227
`228
`229
`230
`231
`232
`
`233
`234
`235
`236
`237
`238
`239
`
`240
`241
`242
`243
`244
`245
`
`246
`247
`248
`249
`
`250
`251
`252
`253
`254
`255
`256
`257
`258
`
`259
`260
`
`MGETHDR(m, M_DONTWAIT, MT_HEADER) ;
`if (m == NULL)
`return;
`
`/*
`* Assume max_linkhdr + sizeof(struct ip) + IGMP_MINLEN
`* is smaller than mbuf size returned by MGETHDR.
`*/
`m->m_data += max_linkhdr;
`m->m_len = sizeof(struct ip) + IGMP_MINLEN;
`m->m~kthdr.len = sizeof(struct ip) + IGMP_MINLEN;
`
`ip : mtod(m, struct ip *);
`ip->ip_tos : 0;
`ip->ip_len = sizeof(struct ip) + IGMP_MINLEN;
`ip->ip_off = 0;
`ip->ip_p = IPPROTO_IGMP;
`ip->ip_src.s_addr = INADDR_ANY;
`ip->ip_dst = inm->inm_addr;
`
`igmp = (struct igmp *) (ip + i);
`igmp->igmp_type = IGMP_HOST_MEMBERSHIP_REPORT;
`igmp->igmp_code = 0;
`igmp->igmp_group = inm->inm_addr;
`igmp->igmp_cksum = 0;
`igmp->igmp_cksum = in_cksum(m, IGMP_MINLEN);
`
`imo = &simo;
`bzero((caddr_t) imo, sizeof(*imo));
`imo->imo_multicast_ifp = inm->inm_ifp;
`imo->imo_multicast_ttl = i;
`
`* Request loopback of the report if we are acting as a multicast
`* router, so that the process-level routing demon can hear it.
`*/
`
`extern struct socket *ip_mrouter;
`imo->imo_multicast_loop = (ip_mrouter != NULL);
`
`ip_output(m, NULL, NULL, 0, imo);
`
`++igmpstat.igps_snd_reports
`
`
`
`Figure 13.15 lgmp_sendreport function.
`
`igmp.c
`
`Ex.1013.416
`
`DELL
`
`
`
`Section 13.7
`
`
`
`Input Processing: igmp_input Function 391
`
`The process-level multicast router must hear the membership reports. In Section 12.14 we saw
`that IGMP datagrams are always accepted when the system is configured as a multicast router.
`Through the normal transport demultiplexing code, the messages are passed to igmp_inpu<
`the p r_i npu t function for IGMP (Figure 13.9).
`
`13.7 Input Processing: igmp_input
`
`Function
`
`In Section 12.14 we described the multicast processing portion of ipintr. We saw that
`a multicast router accepts any IGMP message, but a multicast host accepts only IGMP
`messages that arrive on an interface that is a member of the destination multicast group
`(i.e., queries and membership reports for which the receiving interface is a member).
`The accepted messages are passed to igmp_input by the standard protocol demul-
`tiplexing mechanism. The beginning and end of igmp_input are shown in Fig-
`ure 13.16. The code for each IGMP message type is described in following sections.
`Validate IGMP message
`The function
`ipintr passes ra, a pointer to the received packet (stored in an mbuf),
`and iphlen, the size of the IP header in the datagram.
`The datagram must be large enough to contain an IGMP message (IGMP MINLEN),
`must be contained within a standard mbuf header -(m_pu 1 lup), and must hav~ a correct
`IGMP checksum. If any errors are found, they are counted, the datagram is silently dis-
`carded, and igmp_input returns.
`The body of igmp_input processes the validated messages based on the code in
`igrap_type. Remember from Figure 13.6 that igmp_type includes a version code and
`a type code. The switch statement is based on the combined value stored in
`igmp_type (Figure 13.7). Each case is described separately in the following sections.
`Pass IGMP messages to raw IP
`There is no default case for the switch statement. Any valid message (i.e., one
`that is properly formed) is passed to rip_input where it is delivered to any process
`listening for IGMP messages. IGMP messages with versions or types that are unrecog-
`nized by the kernel can be processed or discarded by the listening processes.
`
`52--96
`
`157-163
`
`The mrouted program depends on this call to rip_input so that it receives membership
`queries and reports.
`Membership Query: IGMP_HOST_MEMBERSHIP_QUERY
`
`RFC 1075 recommends that multicast routers issue an IGMP membership query at least
`once every 120 seconds. The query is sent to group 224.0.0.1 (the all-hosts group). Fig-
`ure 13.17 shows how the message is processed by a host.
`
`Ex.1013.417
`
`DELL
`
`
`
`Chapter 13
`
`igmp.c
`
`97.
`
`Ex.1013.418
`
`392
`
`IGMP: Internet Group Management Protocol
`
`void
`igmp_input(m, iphlen)
`struct mbuf *m;
`int
`iphlen;
`
`struct igmp *igmp;
`struct ip *ip;
`int igmplen;
`struct ifnet *ifp = m->m_pkthdr.rcvif;
`int minlen;
`struct in_multi *inm;
`struct in_ifaddr *ia;
`struct in_multistep step;
`
`++igmpstat.igps_rcv_total;
`
`ip = mtod(m, struct ip *);
`igmplen = ip->ip_len;
`
`* Validate lengths
`
`if (igmplen < IGMP_MINLEN) {
`++igmpstat.igps_rcv_tooshort;
`m_freem{m);
`return;
`
`}m
`
`inlen = iphlen + IGMP_MINLEN;
`if ((m->m_flags & M_EXT I I m->m_len < minlen) &&
`(m = m_pullup(m, minlen)) == 0) {
`++igmpstat.igps_rcv_tooshort;
`return;
`
`]/
`
`**
`
` Validate checksum
`*/
`m->m_data += iphlen;
`m->m_len -= iphlen;
`igmp = mtod(m, struct igmp *);
`if (in_cksum{m, igmplen)) {
`++igmpstat.igps_rcv_badsum;
`m_freem(m);
`return;
`
`}m
`
`->m_data -: iphlen;
`m->m_ien +: iphlen;
`ip : mtod(m, struct ip *);
`
`switch
`
`52
`53
`54
`55
`56
`57
`58
`59
`60
`61
`62
`63
`64
`
`65
`
`66
`67
`
`68
`69
`70
`71
`72
`73
`74
`75
`76
`77
`78
`79
`80
`81
`82
`83
`84
`85
`86
`87
`88
`89
`9O
`91
`92
`93
`94
`95
`
`96
`
`157
`
`DELL
`
`
`
`Section 13.7
`
`Input Processing: igmp_input Function 393
`
`* Pass all valid IGMP packets up to any process(es)
`* on a raw IGMP socket.
`*/
`rip_input(m);
`
`listening
`
`Figure13.16 igmp_input function.
`
`case IGMP_HOST_MEMBERSHIP_QUERY:
`++igmpstat.igps_rcv_queries;
`
`if (ifp == &loif)
`break;
`
`igmp.c
`
`if (ip->ip_dst.s_addr !: igmp_all_hosts_group) {
`++igmpstat igps_rcv_badqueries;
`m_freem(m)
`return;
`
`}/
`
`* *
`
` Start the timers in all of our membership records for
`* the interface on which the query arrived, except those
`* that are already running and those that belong to the
`* "all-hosts" group.
`*/
`IN_FIRST_MULTI(step, inm);
`while (irtm !: NULL) {
`if (inm->inm_ifp := ifp && inm->inm_timer =- 0 &&
`inm->inm_addr.s_addr != igmp_all_hosts_group) {
`inm->inm_timer :
`IGMP_RANDOM_DELAY(inm->inm_addr);
`igmp_timers_are_running = i;
`
`}I
`
`N_NEXT_MULTI(step, inm);
`
`}
`break;
`
`158
`159
`160
`161
`162
`163 }
`
`97
`98
`
`99
`I00
`
`i01
`102
`103
`104
`105
`106
`107
`108
`109
`Ii0
`IIi
`112
`113
`114
`115
`116
`117
`118
`119
`120
`121
`
`122
`
`Figure 13.17 Input processing of the IGMP query message.
`
`igmp.c
`
`97--122
`
`Queries that arrive on the loopback interface are silently discarded (Exercise 13.1).
`Queries by definition are sent to the all-hosts group. If a query arrives addressed to a
`different address, it is counted in igps_rcv_badqueries and discarded.
`The receipt of a query message does not trigger an immediate flurry of IGMP mem-
`bership reports. Instead, igmp_input resets the membership timers for each group
`associated with the interface on which the query was received to a random value with
`IGMP_RANDOM_DELAY. When the timer for a group expires, igmp_fasttimo sends a
`membership report. Meanwhile, the same activity is occurring on all the other hosts
`that received the IGMP query. As soon as the random timer for a particular group
`expires on one host, it is multicast to that group. This report cancels the timers on the
`
`Ex.1013.419
`
`DELL
`
`
`
`. IGMP: Internet Group Management Protocol
`
`Chapter 13
`
`other hosts so that only one report is multicast to the network. The routers, as well as
`any other members of the group, receive the report.
`The one exception to this scenario is the all-hosts group. A timer is never set for this
`group and a report is never sent.
`
`Membership Report:
`IGMP_HOST_MEMBERSHIP_REPORT
`
`The receipt of an IGMP membership report is one of the two events we mentioned in
`Section 13.1 that does not result in an IGMP message. The effect of the message is local
`to the interface on which it was received. Figure 13.18 shows the message processing.
`
`case IGMP_HOST_MEMBERSHIP_REPORT:
`++igmpstat.igps_rcv_reports;
`
`if (ifp :: &loif)
`break;
`
`igrnp.c
`
`if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr))
`igmp->igmp_group.s_addr !: ip->ip_dst.s_addr)
`++igmpstat.igps_rcv_badreports;
`m_freem(m);
`return;
`
`II
`{
`
`]/
`
`*
`
`KLUDGE: if the IP source address of the report has an
`unspecified {i.e., zero) subnet number, as is allowed for
`a booting host, replace it with the correct subnet number
`so that a process-level multicast routing demon can
`* determine which subnet it arrived from. This is necessary
`* to compensate for the lack of any way for a process to
`* determine the arrival interface of an incoming packet.
`*/
`if
`
`((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) == 0) {
`IFP TO IA(ifp, ia);
`if (ia)
`ip->ip_src.s_addr = htonl(ia->ia_subnet);
`
`}/
`
`**
`
` If we belong to the group being reported, stop
`* our timer for that group.
`*/
`IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm);
`if (inm != NULL) {
`inm->inm_timer = 0;
`++igmpstat.igps_rcv_ourreports;
`
`Figure 13.18 Input processing of the IGMP report message.
`
`igmp.c
`
`Ex.1013.420
`
`}b
`
`reak;
`
`123
`124
`
`125
`126
`
`127
`128
`129
`130
`131
`132
`133
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`
`DELL
`
`
`
`13
`
`Section 13.8
`
`Leaving a Group: igmp_leavegroup Function
`
`395
`
`n
`
`Reports sent to the loopback interface are discarded, as are membership reports sent
`to the incorrect multicast group. That is, the message must be addressed to the group
`identified within the message.
`The source address of an incompletely initialized host might not include a network
`or host number (or both). ±gml~_report looks at the class A network portion of the
`address, which can only be 0 when the network and subnet portions of the address are
`0. If this is the case, the source address is set to the subnet address, which includes the
`network ID and subnet ID, of the receiving interface. The only reason for doing this is
`to inform a processqevel daemon of the receiving interface, which is identified by the
`subnet number.
`If the receiving interface belongs to the group being reported, the associated report
`timer is reset to 0. In this way the first report sent to the group stops any other hosts
`from issuing a report. It is only necessary for the router to know that at least one inter-
`face on the network is a member of the group. The router does not need to maintain an
`explicit membership list or even a counter.
`
`13.8 Leaving a Group: igmp_leavegroup
`
`Function
`
`We saw in Chapter 12 that in_delmulti calls igmp_leavegroup when the last refer-
`ence count in the associated in_mul t
`i structure drops
`to 0.
`
`179 void
`180 igmp_leavegroup(inm)
`181 struct in_multi *inm;
`182 {
`183
`184
`185
`186 )
`
`/*
`* No action required on leaving a group.
`*/
`
`Figure 13.19 igmp_leavegroup function.
`
`@mp.c
`
`¯ igmp.c
`
`179-:86 As we can see, IGMP takes no action when an interface leaves a group. No explicit
`notification is sent--the next time a multicast router issues an IGMP query, the interface
`does not generate an IGMP report for this group. If no report is generated for a group,
`the multicast router assumes that all the interfaces have left the group and stops for-
`warding multicast packets for the group to the network.
`If the interface leaves the group while a report is pending (i.e., the group’s report
`timer is running), the report is never sent, since the timer is discarded by in_delmul t i
`(Figure 12.36) along with the in_multi structure for the group when
`i cmp_l eavegroup returns.
`
`Ex.1013.421
`
`DELL
`
`
`
`396
`
`IGMP: Internet Group Management Protocol
`
`Chapter 13
`
`13.9
`
`Summary
`
`In this chapter we described IGMP, which communicates IP multicast membership
`information between hosts and routers on a single network. IGMP membership reports
`are generated when an interface joins a group, and on demand when multicast routers
`issue an IGMP report query message.
`The design of IGMP minimizes the number of messages required to communicate
`membership information:
`
`¯ Hosts announce their membership when they join a group.
`¯ Response to membership queries are delayed for a random interval, and the first
`response suppresses any others.
`¯ Hosts are silent when they leave a group.
`¯ Membership queries are sent no more than once per minute.
`
`Multicast routers share the IGMP information they collect with each other (Chapter 14)
`to route multicast datagrams toward remote members of the multicast destination
`group.
`
`Exercises
`
`13.1 Why isn’t it necessary to respond to an IGMP query on the loopback interface?
`13.2 Verify the assumption stated on lines 226 to 229 in Figure 13.15.
`13.3
`Is it necessary to set random delays for membership queries that arrive on a point-to-point
`network interface?
`
`14,"
`
`Ex.1013.422
`
`DELL
`
`
`
`r 13
`
`~hip
`orts
`tters
`
`.cate
`
`first
`
`..r 14)
`ation
`
`,-point
`
`ld
`
`IP Multicast Routing
`
`14.1
`
`Introduction
`
`The previous two chapters discussed multicasting on a single network. In this chapter
`we look at multicasting across an entire internet. We describe the operation of the
`mrou~ed program, which computes the multicast routing tables, and the kernel func-
`tions that forward multicast datagrams between networks.
`
`Technically, multicast packets are forwarded. In this chapter we assume that every multicast
`
`packet contains an entire datagram (i.e., there are no fragments), so we use the term datagram
`exclusively. Net/3 forwards IP fragments as well as IP datagrams.
`
`Figure 14.1 shows several versions of mroue÷d and how they correspond to the
`BSD releases. The m~vou~ed releases include both the user-level daemons and the
`kernel-level multicast code.
`
`mrouged
`version
`1.2
`2.0
`3.3
`
`Description
`
`modifies the 4.3BSD Tahoe release
`included with 4.4BSD and Net/3
`modifies SunOS 4.1.3
`
`Figure 14.1 mrou~ed and IP multicasting releases.
`
`IP multicast technology is an active area of research and development. This chapter
`discusses version 2.0 of the multicast software, which is included in Net/3 but is consid-
`ered an obsolete implementation. Version 3.3 was released too late to be discussed fully
`in this text, but we will point out various 3.3 features along the way.
`
`397
`
`Ex.1013.423
`
`DELL
`
`
`
`398
`
`IP Multicast Routing
`
`Chapter 14
`
`Because commercial multicast routers are not widely deployed, multicast networks
`are often constructed using multicast tunnels, which connect two multicast routers over
`a standard IP unicast internet. Multicast tunnels are supported by Net/3 and are con-
`structed with the Loose Source Record Route (LSRR) option (Section 9.6). An improved
`tunneling technique encapsulates the IP multicast datagram within an IP unicast data-
`gram and is supported by version 3.3 of the multicast code but is not supported by
`Net/3.
`As in Chapter 12, we use the generic term transport protocols to refer to the protocols
`
`that send and receive multicast datagrams, but UDP is the only Internet protocol that
`supports multicasting.
`
`14.2 Code Introduction
`
`The three files listed in Figure 14.2 are discussed in this chapter.
`
`Description
`File
`ne¢inet / ip mroute, h multicast structure definitions
`net±net / ip_mrou t e. c mulficast routing functions
`multicast routing options
`net ine t /
`raw_ip, c
`
`Figure 14.2 Files discussed in this chapter.
`
`Global Variables
`
`The global variables used by the multicast routing code are shown in Figure 14.3.
`
`Variable
`cached_mrt
`cached_origin
`cached_originmask
`mrtstat
`mrttable
`numvifs
`viftable
`
`DataWpe
`struct mrt
`u_long
`u_long
`struct mrtstat
`struct mrt *[]
`vifi_t
`struct vif[]
`
`Description
`one-behind cache for multicast routing
`multicast group for one-behind cache
`mask for multicast group for one-behind cache
`multicast routing statistics
`hash table of pointers to multicast routes
`number of enabled multicast interfaces
`array of virtual multicast interfaces
`
`Figure 14.3 Global variables introduced in this chapter.
`
`Statistics
`
`All the statistics collected by the multicast routing code are found in the mr t s t at struc-
`ture described by Figure 14.4. Figure 14.5 shows some sample output of these statistics,
`from the net s t at - g s command.
`
`Ex.1013.424
`
`DELL
`
`
`
`~ter 14
`
`Section 14.3
`
`Output Multicast Processing Revisited 399
`