SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

仮想ネットワークの実装で学ぶTCP/IP

仮想ネットワーク実装でTCP/IPを学ぼう(3)
― インターネット層の勘所

仮想ネットワークの実装で学ぶTCP/IP (3)


  • このエントリーをはてなブックマークに追加

 この連載では仮想的なLANを実装することにより、目に見えないTCP/IPプロトコル群を、手を動かして目で実際に確認しながら習得することを 目的としています。今回はインターネット層のプロトコルとそれに関係するネットワークインタフェース層のプロトコルARPについて解説します。

  • このエントリーをはてなブックマークに追加

はじめに

 この連載では仮想的なLANを実装することにより、目に見えないTCP/IPプロトコル群を、手を動かして目で実際に確認しながら習得することを目的としています。ただし、TCP/IPの全てを解説するのは分量上不可能ですし、余計に読者を混乱させてしまいますので、筆者が重要と考えている部分だけ解説します。またサンプルコードや本記事に出てくるIPアドレスとMACアドレスについては架空のものであり、実際にそのIPアドレスを取得した組織などを意識したものではありません。あらかじめご了承ください。

 今回はインターネット層のプロトコルとそれに関係するネットワークインタフェース層のプロトコルARPについて解説します。

ネットワーク層で使用するアドレス

 前回通信相手を特定するためにMACアドレスを使用することを説明しました。しかし、インターネット層では、IPアドレスという名前の別のアドレスを使用します。わざわざそんなことをする理由は、そうすることで柔軟性が得られるからです。分かりにくいと思いますのでこれから具体的に説明します。

 MACアドレスはNICなどの物理的なものに付与されているアドレスです。ですから、サーバーにこのアドレスを使用すると、NICを変更したらサーバにアクセスできなくなるので、その都度各種設定を変えねばなりません。機器を新しいものにしたり機器を移動したりする度に、関連しているソフトウェアの設定などを変えるのは大変な作業です。このような事態を防ぐためにインターネット層では別のアドレスを使用します。

 このネットワーク層のアドレスのことをIP(Internet Protocol)アドレスと呼びます。IPアドレスを使用することにより、異なるネットワーク同士で通信を行えるようになります。次節でネットワーク間の通信について簡潔に説明します。

ネットワーク間の通信

 ネットワーク間の通信は、専用の機器を使って、ネットワーク層独自のデータフォーマットのデータ(IPパケットと呼びます)をやり取りすることにより行います。このデータをやり取りする手順を定めたプロトコルをIP(Internet Protocol)と呼びます。

 前回LAN内で端末同士が通信をする際に機器が必要だと説明しました。ネットワーク層でもそれは同じで、ルータと呼ばれる専用の機器を使用してネットワーク間で通信をします。また、通信の際にMACフレームをやり取りして通信を行うことも解説しました。こちらについても同様で、ネットワーク層独自のフォーマットのデータを、MACフレーム(Ethernetフレーム)内のユーザーデータとします。独自のデータフォーマットをMACフレーム内に埋め込む点に注意して下さい。この方式が連載1回目で解説したカプセル化です。

 まずはデータフォーマットを紹介します。

IPヘッダ
IPヘッダ
データフォーマットの詳細
部位 説明
バージョン(4ビット) IPのバージョンです。現時点では4か6が設定されます。
ヘッダ長(4ビット) IPヘッダの長さです。IPパケット内のデータの位置を探すために使用します。
サービスタイプ(8ビット) このデータの優先度を表します。
パケット長(16ビット) IPヘッダとデータを合わせた全体の長さを表します。
識別子(16ビット) データを小分けにして送る際に使用するIDです。
フラグ(3ビット) IPデータの分割に関する情報です。
フラグフラグメントオフセット(13ビット) データを分割した際に設定する項目で、元のデータのどの部分にあったのかを表します。
生存時間(8ビット) このパケットの寿命を表します。宛先が見つからない時に、データが永遠にネットワーク経路内をループするのを防ぐために使用します。
プロトコル(8ビット) ネットワーク層よりも一つ上のトランスポート層で使用するプロトコルを表します。
ヘッダチェックサム(16ビット) データが壊れていないかチェックする際に使用する値です。
ソースアドレス(32ビット) 送信元のIPアドレスです。
ディスティネーションアドレス(32ビット) 送信先のIPアドレスです。
オプション IPの拡張機能を使用するために指定するフィールドです。通常はオプションを指定しません。
パディング(可変長) IPパケットが32ビットの整数倍でなければ、このデータを埋めて調節します。

 これでやり取りするデータの概要を解説しましたので、これからサンプルコードを用いてネットワーク間の通信について解説します。端末Aが違うネットワークに属する端末Bへデータを送りたいとします。IPでは、まず端末Bが同じネットワークに属していないかをルーティングテーブルで調べます。その結果同じネットワーク内に属していれば直接送り、違うネットワークに属している場合は、そのネットワークの場所を知っているルータに送ります。

インターネット上へデータを送信する動作の模倣(Routerクラス:C#)
/// <summary>
/// インターネット上へデータを送信します。
/// </summary>
/// <param name="data">送信するデータ</param>
public void Send ( Frame data )
{
    //準備
    if ( data.TypeOrLength == ( ushort ) EtherType.IP ) {
        IPv4 packet = ( IPv4 ) ( ( MacFrame ) data ).UsertData;

        //宛て先がLAN内に在るかどうかを判別して送信する
        if ( packet.DestinationAddress.NetworkAddress ==
            this.m_address.NetworkAddress ) {
            this.m_lan.Send ( data );
        } else {
            //宛て先がLAN外なので、適切なルータを選んでインターネット上にデータを送信。
            IPv4Address ruterAddress = null;
            try {
                ruterAddress = this.table.Find (
                    delegate ( RoutingElement element ) {
                        if ( element.Destination == packet.DestinationAddress )
                            return true;
                        else
                            return false;
                    }
                ).Gateway;
            } catch ( NullReferenceException ) {
                //指定されたホストに到達できないことを知らせる
                this.icmp.SendDestinationUnreachableMessage ( ( MacFrame ) data );
            }
            this.Send ( ruterAddress, data );
        }
    } else {
        this.m_lan.Send ( data );
    }
}
インターネット上へデータを送信する動作の模倣(Routerクラス:VB.NET)
''' <summary>
''' インターネット上へデータを送信します。
''' </summary>
''' <param name="data">送信するデータ</param>
Public Sub Send(ByVal data As Frame)

    '準備
    If data.TypeOrLength = CUShort(EtherType.IP) Then
        Dim packet As IPv4 = CType((CType(data, MacFrame)).UsertData, IPv4)

        '宛て先がLAN内に在るかどうかを判別して送信する
        If packet.DestinationAddress.NetworkAddress = Me.m_address.NetworkAddress Then
            Me.m_lan.Send(data)
        Else
            '宛て先がLAN外なので、適切なルータを選んでインターネット上にデータを送信。
            Dim ruterAddress As IPv4Address = Nothing
            ruterAddress = Me.SearchRoute(packet.DestinationAddress)
            If ruterAddress Is Nothing Then
                '指定されたホストに到達できないことを知らせる
                Me.icmp.SendDestinationUnreachableMessage(CType(data, MacFrame))
            Else
                Me.Send(ruterAddress, data)
            End If
        End If
    Else
        Me.m_lan.Send(data)
    End If
End Sub
注釈

 icmp.SendDestinationUnreachableMessageについては後で説明します。

 ネットワークとはどの範囲を指すのか気になる方がいると思いますが厳密な定義は複雑なので、現時点では同じLAN内に端末があれば同一ネットワーク、違えば異なるネットワークと考えて下さい。

 これがネットワーク間の通信の概要です。これ以降の節では、ネットワーク通信を実現するための要素をより詳しく説明していきます。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
IPアドレスについて

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
仮想ネットワークの実装で学ぶTCP/IP連載記事一覧

もっと読む

この記事の著者

インドリ(インドリ)

分析・設計・実装なんでもありのフリーエンジニア。ブログ「無差別に技術をついばむ鳥(http://indori.blog32.fc2.com/)」の作者です。アドバイザーをしたり、システム開発したり、情報処理技術を研究したりと色々しています。座右の銘は温故知新で、新旧関係なく必要だと考えたものは全て学...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3866 2010/04/27 12:06

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング