コンピュータ・ネットワーク(4) -ネットワーク層-
投稿日: | |
---|---|
編集日: | |
タグ: |
目次
ネットワーク層は5階層TCP/IPモデルの下から3番目の層である。
アプリケーション層 |
トランスポート層 |
ネットワーク層 |
データリンク層 |
物理層 |
サービス |
| |
---|---|---|
インタフェース | データ単位 | パケット |
アドレス | 論理アドレス | |
代表的なプロトコル |
|
IPパケット
IPでは、IPパケットというデータ単位で通信を行う。IPパケットは次のようなデータ構造である。ここで、各セルは基本的に1ビットを表す。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Version | IHL | TOS | Total Length | ||||||||||||||||||||||||||||
identification | VCF | Fragment Offset | |||||||||||||||||||||||||||||
TTL | Protocol | Header Checksum | |||||||||||||||||||||||||||||
Source Address | |||||||||||||||||||||||||||||||
Destination Address | |||||||||||||||||||||||||||||||
Options | |||||||||||||||||||||||||||||||
Data |
- Version
- IPのバージョン。IPv4ならば4。
- IHL: Internet Header Length
- IPヘッダの長さ。
- Type Of Service
-
パケットが転送される際に重視するサービスを指定するフィールド。
0 1 2 3 4 5 6 7 優先度 遅延度 転送量 信頼性 予備 6 7 ECT CE - ECT(Explicit Capable Transport)
- CE(Congestion Experience)
00 ECNを未サポート。 01 送信ホストはECNをサポート。 10 11 輻輳はルータにより経験。 - Total Length
- パケットの全長。1バイトが8ビットとした時のバイト数。
- identification
- 断片化した時にその断片がどのパケットのものかを表す。
- VCF: Various Control Flags
-
断片化の制御に用いるフィールド。
0 1 2 予備 禁止 継続 - Fragment Offset
- パケットを断片化した時に、パケット全体のどこの位置にあたるのかを示すフィールド。
- TTL: Time To Live
- ルーティング可能な回数。パケットを転送する度に1減らし、これが0になったらそのパケットを破棄する。
- Protocol
-
トランスポート層やネットワーク層の他のプロトコルなどでIPパケットを使用する場合にその種類を示すフィールド。
プロトコル番号 プロトコル名 1 ICMP 2 IGMP 4 IP 6 TCP 7 CBT 8 EGP 9 IGP 17 UDP 41 IPv6 43 IPv6-Route 44 IPv6-Flag 45 IDRP 46 RSVP 47 GRE 50 ESP 51 AH 55 MOBILE 58 IPv6-ICMP 59 IPV6-NoNxt 60 IPv6-Opts 88 EIGRP 89 OSPF 94 IPIP 103 PIM 112 VRRP 113 PGM 115 L2TP - Header Checksum
- IPヘッダの誤り検査のためのフィールド。ルーティングの度にTTLの値が変化するため、この値も変化する。なおIPではデータ内容のチェックは行われない。
- Source Address
- 送信元IPアドレス。
- Destination Address
- 宛先IPアドレス。
- Options
- セキュリティやルーティングなどの拡張情報。可変長のフィールドで、ないこと、すなわち5であることが多い。
IPアドレス
IPアドレスとは32ビットの論理アドレスのことである。データリンク層で使用されるMACアドレスが各ネットワークデバイスにそれぞれ割り当てられているのに対し、IPアドレスはソフトウェアによってMACアドレスに対応づけられる(厳密には1対1関係とはいえないがそれについては後述する)。それゆえノードに割り当てられるIPアドレスは、常に同じであるとは限らない。
MACアドレスが隣接するノード間の通信に使われるのに、IPアドレスは接続されたノード間の通信のために使用される。例えば、送信元IPアドレス"192.168.1.2"から宛先IPアドレス"64.4.11.37"への通信を行う場合、経路中のパケットやフレームで使用される各アドレス情報は、それぞれ図のようになる(実際にはプライベートアドレスと呼ばれる"192.168.1.2"からグローバルアドレス"64.4.11.37"には直接通信できない)。
ネットワークインタフェース
IPアドレスはMACアドレスに対応付けられると述べたが、厳密にはこれは正しくない。前述の通り、MACアドレスはネットワークデバイス毎に割り当てられている。しかしソフトウェアレベルでは、ネットワークデバイスを抽象化したネットワークインタフェースという単位で扱われ、IPアドレスはネットワークインタフェースに割り当てられる。そして、ネットワークインタフェースにはMACアドレスがないがIPアドレスを持つものや、1つのネットワークインタフェースで複数のIPアドレスを持つもの、いくつかのネットワークインタフェースで同じMACアドレスが使用されるようなものなど様々なタイプがある。例えばUNIX系OSでは、ローカルループバックと呼ばれる自分自身と通信するためのIPアドレスが割り当てられたネットワークインタフェースがある。これは実際のネットワークデバイスの有無に関係なく存在し、かつMACアドレスがない。
ネットワーククラス -RFC791-
RFC791では、IPアドレスは3つの要素から構成される。各フィールドは、クラスとネットワークアドレス、ホストアドレスに分けられる。
- クラス
- ネットワークの規模。
- ネットワークアドレス
- ネットワークの識別番号。
- ホストアドレス
- あるネットワーク内のノードの識別番号。
クラス | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
A | 0 | |||||||||||||||||||||||||||||||
B | 1 | 0 | ||||||||||||||||||||||||||||||
C | 1 | 1 | 0 | |||||||||||||||||||||||||||||
1 | 1 | 1 | 拡張アドレスモード |
サブネット -RFC950-
RFC950では、RFC791で出てきたネットワークを更に小さいネットワーク(サブネット)に分割できる。サブネットを指定するには、ネットワークマスクと呼ばれる32ビットの値を使用する。例えばクラスBのネットワークは次のようにしてサブネットを指定する。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
B | 1 | 0 | ネットワーク | ホスト | 1 | 0 | ネットワーク | サブネット | ホスト | |||||||||||||||||||||||
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
プライベートアドレス -RFC1918-
インターネットで使用されるIPアドレスをグローバルアドレスと呼ぶ。そして、これとは別に局所的なネットワークで使用されるアドレスがある。これをプライベートアドレスという。RFC1918ではプライベートアドレスの範囲を次のように定めた。
10.0.0.0〜10.255.255.255 | 10.0.0.0/8 |
172.16.0.0〜172.31.255.255 | 172.16.0.0/12 |
192.168.0.0〜192.168.255.255 | 192.168.0.0/16 |
このようなRFCで定められたグローバルアドレス以外の特別なアドレスのことを予約アドレスという。
予約アドレス
2014/02時点の予約アドレスは次の通りである。
アドレス | ネットワーク名 | RFC |
---|---|---|
0.0.0.0/8 | 現在のネットワーク | RFC1122 |
10.0.0.0/8 | PRIVATE-ADDRESS-ABLK-RFC1918-IANA-RESERVED | RFC1918 |
127.0.0.0/8 | SPECIAL-IPV4-LOOPBACK-IANA-RESERVED | RFC6598 |
169.254.0.0/16 | SHARED-ADDRESS-SPACE-RFCTBD-IANA-RESERVED | RFC3927 |
172.16.0.0/12 | PRIVATE-ADDRESS-ABLK-RFC1918-IANA-RESERVED | RFC1918 |
192.0.0.0/24 | SPECIAL-IPV4-REGISTRY-IANA-RESERVED | RFC5736 |
192.0.2.0/24 | IANA Special Use | RFC5737 |
192.88.99.0/24 | 6TO4-RELAY-ANYCAST-IANA-RESERVED | RFC1198 |
192.168.0.0/16 | PRIVATE-ADDRESS-ABLK-RFC1918-IANA-RESERVED | RFC1918 |
198.18.0.0/15 | SPECIAL-IPV4-BENCHMARK-TESTING-IANA-RESERVED | RFC2544 |
198.51.100.0/24 | TEST-NET-1 | RFC5737 |
203.0.113.0/24 | TEST-NET-3 | RFC5737 |
224.0.0.0/4 | マルチキャスト(クラスD) | RFC3171 |
240.0.0.0/4 | クラスE | RFC1112 |
255.255.255.255 | ブロードキャスト | RFC919,RFC922 |
UNIX系OSでは、いくつかの例外を除いてIPアドレスの情報をwhoisコマンドで調べることができる。例えば127.0.0.1のIPアドレスについて調べたい時、次のようにすれば良い。
user% whois 127.0.0.1
ドメイン
人間がIPアドレスを指定する際、多くの場合はIPアドレスを指定する代わりにドメイン名といわれるコンピュータ名を指定する。ドメイン名はICANN(Internet Corporation for AssignedNames andNumbers)と呼ばれる団体によって管理される。ドメイン名の情報は、アプリケーション層のWHOISプロトコルを使用して取得できる。UNIX系では、そのためのクライアントアプリとしてwhoisがある。
user% whois google.co.jp
ドメインは、アプリケーション層のDNSという仕組みによって成り立つ。ドメイン名はDNSサーバによって管理され、DNSクライアントでアクセスすることで、ドメイン名からIPアドレスへ変換することができる。
user% nslookup google.co.jp
ルーティング
ルーティングとは、パケットの経路制御のことである。ルーティングはルーティングテーブルに基づいてルート(経路)を探索する。ルーティングは次の2種類に分類できる。
- 静的ルーティング
- 手動でルーティングテーブルの中身を設定する方法。
- 動的ルーティング
- アルゴリズムに基づいて自動でルーティングテーブルの中身を設定する方法。経路決定アルゴリズムには次の2種類がある。
- 距離ベクトルアルゴリズム(DVA:Distance Vector Algorithm)
- リンク状態アルゴリズム(LSA:Link State Algorithm)
ここでルーティングの仕組みを紹介する。次のような3つのネットワークインタフェースを持つノードがあるとする。
- lo
- 127.0.0.1
- eth0
- 192.168.1.2/24
- eth1
- 173.194.117.183/16
ネットワーク/ノード | ゲートウェイ | インタフェース |
---|---|---|
デフォルト | 192.168.1.1 | eth0 |
192.168.1.0/24 | * | eth0 |
173.194.0.0/16 | * | eth1 |
127.0.0.1/8 | * | lo |
次のようなネットワークで前述のノードが通信を行うとする。
- 宛先のネットワークが不明のため、デフォルトルートを使用。eth0のネットワークインタフェースを使用し、192.168.1.1に送信。
- 203.216.243.243に送信。
- 64.4.11.37に送信。
ネットワークインタフェースの情報は、UNIX系OSではifconfig、Windowsではipconfigコマンドで、ルーティングテーブルの情報は、UNIX系OSもWindowsも、routeコマンドや、netstatコマンドの-rオプションで表示したり設定したりできる。また、パケットが辿った経路については、tracerouteコマンドで確認することができる。
関連コマンド
以下にネットワーク層に関するコマンドをいくつか紹介する。なおここで紹介するコマンドは、主にUNIX系OSを想定している。
- whois
-
IPアドレスやドメインの情報をRFC3912のデータベースより検索するコマンド。ドメインとはIPアドレスに対応づけた名前のことで、"google.co.jp"や"yahoo.co.jp"などがそれに該当する。whoisの使い方は次の通りである。
user% whois 173.194.117.166
これによりネットワークの大きさや名前、それを管理する団体の情報などを取得できる。また、ドメインを指定することでそのドメインの管理者や有効期限などの情報を取得できる。user% whois google.co.jp
- nslookup
- dig
- ドメインとIPアドレスを変換するにはnslookupやdigコマンドがある。nslookupコマンドはWindowsにもあり、基本的な使い方は同じである。nslookupコマンドの使い方は、コマンドの引数を指定する方法と対話する方法の2種類がある。
user% nslookup google.co.jp
user% nslookup > google.co.jp
- traceroute
-
パケットの経路を調査し、出力するコマンド。
user% traceroute google.co.jp
tracerouteのオプションをいくつか紹介する。- -p port
- ポート番号を指定。
- -i device
- デバイスを指定。
- ping
-
ICMP Echo Requestパケットを送信するコマンド。pingはUNIX系OSだけでなくWindowsでも使用可能である。以下にUNIX系OSのpingのオプションをいくつか紹介する。
- -v
- 詳細な情報を出力。
- -b
- ブロードキャストで行う。
- -R
- 経路を表示。
- -i wait
- 個々の送信間隔をwait秒分間を置く。標準では1秒。
user% ping google.co.jp
- netstat
-
ネットワークに関する情報や状態を表示・設定するコマンド。以下にいくつか例を示す。UNIX系OSにもWindowsにもあるコマンドだが、使い方(オプション)は異なる。
ルーティングテーブル
user% netstat -r
UNIX系OS、Windows共に-rは同じである。user% netstat --route
user% route
ネットワークインタフェース
user% netstat -i
user% netstat --interfaces
使用中のソケット情報を確認(つまりポートの状態も確認できる)
user% netstat -a
user% netstat --all
プロトコル毎のログの統計
user% netstat -s
user% netstat --statistics
なおオプション-nを指定することで、アドレスやポート番号をそのまま数字で表示する。 - route
-
ルーティングテーブルの表示・設定を行うコマンド。routeは基本的に処理とそれに対する引数を指定する。処理を指定しなければ現在のルーティングテーブルを表示する。
- add
-
ルーティングテーブルへの追加処理。
user% route add -net 192.168.1.0 netmask 255.255.255.0 dev eth0
user% route add -host 192.168.1.2 gw 192.168.1.1 dev eth0
user% route add -net default gw 192.168.1.1 dev eth0
- del
-
ルーティングテーブルからの削除処理。
user% route del -net 192.168.1.0 netmask 255.255.255.0 dev eth0
user% route del -host 192.168.1.2 gw 192.168.1.1 dev eth0
user% route del -net default
- ifconfig
- ipconfig
-
ネットワークインタフェースの情報を表示・設定するコマンド。UNIX系OSはifconfig、Windowsはipconfigであり、使い方も異なる。
user% ifconfig -a
user% ipconfig /all
設定にはルート権限が必要である。 例えばIPアドレスとネットワークマスクは次のようにして設定する。user% ifconfig eth0 192.168.1.100 netmask 255.255.255.128
これ以外にもさまざまな設定がある。例えば通常ネットワークデバイスは自分のIPアドレス以外のパケットは破棄する(データリンク層でユニキャストを実現する)が、プロミスキャスモードというモードを有効にすれば、それを受信できる。user% ifconfig eth0 promisc
DHCP
5階層TCP/IPモデルのアプリケーション層のDHCPによってIPアドレスを設定する場合、IPアドレスはサーバによって割り当てられる。そして多くのルータはDHCPサーバの機能を持つ。それゆえ多くのルータが使用される環境では、個々のノードが自身のIPアドレスを決めることはないだろう。UNIX系OSでは、DHCPクライアントにdhclientコマンドがある。以下に簡単な使い方を紹介する。user% dhclient eth0
- iwconfig
- iwspy
- 無線のネットワークインタフェースのためのコマンド。
- tcpdump
-
パケットスキャニングツール。5階層TCP/IPモデルのより上位の層のためにも活用できるコマンドで、指定したネットワークインタフェースが扱ったパケット情報を出力する。tcpdumpについてはアプリケーション層のところで詳述する。
user% tcpdump -i eth0
- -i interface
- ネットワークインタフェースを指定。
- -e
- イーサネットフレームのヘッダを表示。
- -x
- -X
- パケットの中身を16進数で表示。-Xの場合、それに加えてASCII文字に変換したものも表示。
- -n
- アドレス(IPアドレスやポート番号)を名前に変換しない。
- -N
- ホストを名前に変換しない。
- expression
-
パケットフィルタ機能。いかにいくつかの機能を紹介する。
- proto
- プロトコルを指定。
- src host
- 送信元アドレスを指定。
- src port port
- 送信元のポート番号を指定。
- dst host
- 宛先アドレスを指定。
- dst port port
- 宛先のポート番号を指定。
- and
- or
- not
- いくつかの条件を組み合わせる
パケットプログラミング
IPパケットの送信
ネットワーク層のサービスを利用してデータを送信する例を紹介する。IPパケットを生成して送信するプログラムのソースコードは、次のように記述できる。なおこのコードはエラー処理のコードを記述していない。
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char *argv[])
{
const int ON=1;
const char* DST_ADDR = "192.168.1.1";
const unsigned char IP_PACKET[] = {
0x45, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00,
0xFF, 0x04, 0x00, 0x00,
0xad, 0xc2, 0x7e, 0x0d, // src 173.194.126.13
0xc0, 0xa8, 0x01, 0x01, // dst 192.168.1.1
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07
};
int sock;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = PF_INET;
sin.sin_addr.s_addr = inet_addr(DST_ADDR);
sin.sin_port = 0;
sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &ON, sizeof(int));
sendto(sock, IP_PACKET, sizeof(IP_PACKET), 0, (struct sockaddr*)&sin, sizeof(sin));
return 0;
}
このコードは、IPパケットを送信するプログラムである。このプログラムを正常に実行するにはルート権限が必要である。
タイプがSOCK_RAWについては、マニュアル第7章のrawを参照されたい。
user% man 7 raw
マニュアルによると、IPヘッダの大きさやヘッダ・チェックサムは関数によって自動的に計算される。また、ソースアドレスとパケットIDは0の場合に変更される。
このプログラムを実行し、そのパケットをtcpdumpで見た結果を以下に示す。
15:43:32.732162 IP 173.194.126.13 > 192.168.1.1: IP0 [|ip] (ipip-proto-4) 0x0000: 4500 001c 0000 4000 ff04 8e64 adc2 7e0d 0x0010: c0a8 0101 0001 0203 0405 0607
IPパケットの受信
ICMPパケットを受信するようなプログラムのコードは次のように記述される。このコードも同様にエラー処理を省略している。
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
int sock;
unsigned char packet[0x54];
sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
while (1){
recv(sock, packet, sizeof(packet), 0);
for (i=0;i<0x54;i++){
if (i%4==0) putchar('\n');
printf("0x%.2x ", packet[i]);
}
putchar('\n');
}
close(sock);
return 0;
}
このプログラムもまた正常に実行するにはルート権限が必要である。
このプログラムを起動中に、127.0.0.1宛にpingをすると、次のように画面に出力されるだろう。
0x45 0x00 0x00 0x54 0x80 0x72 0x00 0x00 0x40 0x01 0xfc 0x34 0x7f 0x00 0x00 0x01 0x7f 0x00 0x00 0x01 0x00 0x00 0x19 0xed 0x18 0xaa 0x00 0x01 0xa9 0x65 0x07 0x53 0x2c 0xac 0x05 0x00 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37