前回はブロードキャストのパケットを送受信する場合を考えてみましたが、今回はマルチキャストの場合です。前回同様、C言語でプログラミングしています。
マルチキャストの場合
ブロードキャストと同様に、マルチキャストのパケットを送れるのはUDPのみです。ですので、マルチキャストパケットを送るプログラミングを行うにはUDPのユニキャストの手順をマルチキャスト用に修正します。修正点は以下の3つです。ユニキャストの手順については前回説明しています。
- 送信側で送信パケットのTTLを設定する。
- 送信先IPアドレスにマルチキャストアドレスを指定する。
- 受信側でマルチキャストグループに参加する。
送信パケットのTTLを設定するには、setsockopt()でIPPROTO_IPのIP_MULTICAST_TTLに値を設定します。TTLとはパケットの生存時間です。パケットがルーターを通過するごとに値が減算され、0になった時点でパケットは破棄されます。
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, *optVal, optLen);
socketはソケットディスクリプタ、*optValはTTLとして設定する値のポインタ、optLenはoptValの長さ、を示します。ブロードキャストの場合は送信パケットのTTLを設定しませんでしたが、これはブロードキャストパケットはルーターを超えることがないためTTLを設定しても意味がない(TTLが減らない)からです。
送信先アドレスにはマルチキャストアドレスを指定しますが、マルチキャストアドレスには範囲があり、以下の範囲内のIPアドレスを指定します。
マルチキャストアドレスの範囲
224.0.0.0 〜 239.255.255.255
受信側の設定の方ですが、受信側ではマルチキャストグループに参加します。マルチキャストグループに参加するには、setsockopt()でIPPROTO_IPのIP_ADD_MEMBERSHIPにマルチキャストグループ(つまり、送信側が送信パケットに指定したマルチキャストのIPアドレス)を設定します。
setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, *optVal, optLen);
TTLの設定と同様に、socketはソケットディスクリプタ、*optValはマルチキャストグループのポインタ、optLenはoptValの長さ、を示します。
マルチキャストパケットを送受信する手順をまとめると以下となります。
プログラムの手順は上図に示した通りですが、マルチキャストパケットが各ホストに届くにはネットワークのほうで「お膳立て」のようなことを先にやっています。それについて書いておきます(以下)。
まず、マルチキャストパケットを届けるためにはルーターのマルチキャストルーティングを有効にしておく必要があります。これによりPIM(Protocol-Independent Multicast)というプロトコルがマルチキャスト専用のルーティングテーブルをルーター間で共有します。PIMはマルチキャスト専用のルーティングプロトコルです(代表的なルーティングプロトコルとしてRIPやOSPFなどがあります)。マルチキャストパケットはこのルーティングテーブルをもとにルーター間を転送されていきます。
また受信ホストがマルチキャストグループへの参加をすることによりNICがマルチキャストパケットを受信するようになります。通常NICは自身のIPアドレスのパケットかブロードキャストパケットしか受信しませんが、マルチキャストグループへの参加を行うことによりマルチキャストパケットも受信するようになります。
もう一点、受信ホストがマルチキャストグループへの参加を行うと、ホストからネットワークにIGMP(Internet Group Management Protocol)というプロトコルが送られます。IGMPはそのホストが属するセグメントのルーターに届き、ルーターは自分の属するセグメント内にマルチキャストグループに参加しているホスト(つまり、マルチキャストパケットを転送するホスト)があることを知ります。これによりルーターはマルチキャストパケットをそのホストが属するセグメントに転送します(通常のルーターはマルチキャストグループに属するホストがいなければマルチキャストパケットを転送しません)。
なおNICにはプロミスキャスモードというすべてのパケットを受信するモードがあります。プロミスキャスモードにすることによりマルチキャストパケットを含むすべてのパケットを受信しますが、プロミスキャスモードにするだけではIGMPによるルーターへの通知は行われません。
実際に、送信側ホストから受信側ホストにマルチキャストパケットが転送されていく際のイメージの絵です。
マルチキャストパケットはマルチキャスト用のルーティングテーブルをもとにルーター間を転送され、宛先ネットワークまで届けられます。宛先ネットワークに届いたパケットはイーサーネットのフレームに乗りますが、その際の宛先MACアドレスはマルチキャスト用のMACアドレスとなります。マルチキャスト用のMACアドレスはOUI(前半の24ビット)が「01-00-5E」となります。このパケットはブロードキャストパケットと同じくスイッチでは全ポートにフラッディングされます(正確に言うと、宛先MACアドレスのI/Gビットが「1」のものがフラッディングされます)。これによりマルチキャストグループに参加していないホストにまでマルチキャストパケットは届いてしまいますが、マルチキャストグループに参加していないホストのNICはマルチキャストパケットを無視します。
なお、不要なホストにまでマルチキャストパケットが届いてしまうとネットワークの帯域を圧迫するのでスイッチには「IGMPスヌーピング」という機能を持つものがあります。これは、受信側ホストがマルチキャストグループの参加を示したときに送られるIGMPをスイッチが盗み見しておいて、マルチキャストパケットが届いたときに必要なポートにのみマルチキャストパケットを送る機能です。