<!--Chapter 10 Networks-->
<sect>ネットワーク<label id="chapter_net">
<p>
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/penguin2.gif">
</figure>

<!--
Networking and Linux are terms that are almost synonymous. In a very real
sense Linux is a product of the Internet or World Wide Web (WWW). Its
developers and users use the web to exchange information ideas, code, and
Linux itself is often used to support the networking needs of organizations.
This chapter describes how Linux supports the network protocols known
collectively as TCP/IP. 
-->
<p>ネットワーキングと Linux とはほとんど同義語である。本当の意味で、Linux は
インターネットもしくは World Wide Web(WWW) の産物である。開発者やユーザたち
はウェブを使って情報やアイデアやコードを交換しているし、Linux そのものが組織に
おけるネットワークへの要求を満たすために利用されている。この章では、TCP/IP と
総称されるネットワークプロトコルを Linux がどのようにサポートしているかを
解説する。

<!--
The TCP/IP protocols were designed to support communications between
computers connected to the ARPANET, an American research network
funded by the US government. The ARPANET pioneered networking
concepts such as packet switching and protocol layering where one protocol
uses the services of another. ARPANET was retired in 1988 but its
successors (NSF1 NET and the Internet) have grown even larger. What is
now known as the World Wide Web grew from the ARPANET and is itself
supported by the TCP/IP protocols. Unix TM was extensively used on the
ARPANET and the first released networking version of Unix TM was 4.3
BSD. Linux's networking implementation is modeled on 4.3 BSD in that it
supports BSD sockets (with some extensions) and the full range of TCP/IP
networking. This programming interface was chosen because of its
popularity and to help applications be portable between Linux and other Unix
TM platforms. 
-->
<p>TCP/IP プロトコルが設計されたのは、ARPANET に接続されたコンピュータ間
での通信をサポートするためであった。合衆国政府によって設立されたアメリカ
の研究用ネットワークである ARPANET は、ネットワークの基本概念を作り出した
パイオニアであり、その中には、パケットスイッチング(packet switching)や、ある
プロトコルが別のプロトコルのサービスを利用するというプロトコル層(protocol 
layer)といった概念がある。
ARPANET は 1988 年に解散されたが、その後継者(NSF(<ref id="chapter_net_fn" 
name="脚注 1">) NET やインターネット)はそれ以上のものに成長した。
今日 World Wide Web と呼ばれるものは、ARPANET から発展しており、それ自体が 
TCP/IP プロトコルによってサポートされている。Unix は ARPANET 上で広範囲に
使用されが、最初にリリースされたネットワークバージョンの Unix は 4.3 BSD 
であった。Linux におけるネットワークの実装は、(いくつかの拡張機能とともに)BSD 
ソケットと TCP/IP 全般をサポートしている点で、4.3 BSD をモデルとするものであ
る。BSD ソケットというプログラミングインターフェイスが
採用されたのは、その人気ゆえであり、Linux とその他の Unix プラットフォーム間
でのアプリケーションの移植を容易にするためであった。

<!--10.1  An Overview of TCP/IP Networking-->
<sect1>TCP/IP ネットワーキングの概要<label id="chapter_net_sect1">

<!--
This section gives an overview of the main principles of TCP/IP networking.
It is not meant to be an exhaustive description, for that I suggest that you
read . In an IP network every machine is assigned an IP address, this is a 32
bit number that uniquely identifies the machine. The WWW is a very large,
and growing, IP network and every machine that is connected to it has to
have a unique IP address assigned to it. IP addresses are represented by
four numbers separated by dots, for example, 16.42.0.9. This IP address
is actually in two parts, the network address and the host address. The
sizes of these parts may vary (there are several classes of IP addresses)
but using 16.42.0.9 as an example, the network address would be 16.42
and the host address 0.9. The host address is further subdivided into a
subnetwork and a host address. Again, using 16.42.0.9 as an example,
the subnetwork address would be 16.42.0 and the host address 16.42.0.9.
This subdivision of the IP address allows organizations to subdivide their
networks. For example, 16.42 could be the network address of the ACME
Computer Company; 16.42.0 would be subnet 0 and 16.42.1 would be
subnet 1. These subnets might be in separate buildings, perhaps connected
by leased telephone lines or even microwave links. IP addresses are
assigned by the network administrator and having IP subnetworks is a good
way of distributing the administration of the network. IP subnet
administrators are free to allocate IP addresses within their IP subnetworks.
-->
<p>この章では、TCP/IP ネットワーキングにおける基本原則を概説する。
しかし、本書のテーマからして、徹底した記述というわけではない。
IP ネットワークでは、すべてのマシンが IP アドレスを割り当てられる。これはマシン
をユニークに識別する 32 ビットの数である。WWW は広大で今も成長過程にあり、そ
れに接続された IP ネットワークとすべてのマシンはユニークな IP アドレスを割り当
てられなければならない。
IP アドレスは、たとえば 16.42.0.9 のようにドットで区切られた 4 つの
数字で表現される。この IP アドレスは実際には、ネットワークアドレスとホスト
アドレスのふたつの部分に分かれる。( IP アドレスにはいくつかのクラスがあるので)
それらの部分のサイズは定まっていないが、仮に 16.42.0.9 を例に取り、ネットワー
クアドレスを 16.42 とし、ホストアドレスを 0.9 であるとする。ホストアドレスは
さらにサブネットとホストアドレスとに再分割できる。ここでも 16.42.0.9 を例に
取ると、サブネットアドレスは 16.42.0 であり、ホストアドレスは 9 となるだろう。
IP アドレスの細分化により、組織はネットワークを再分割できる。
たとえば、16.42 が ACME コンピュータ会社のネットワークアドレスであるとすると、
16.42.0 はサブネット 0 であり、16.42.1 はサブネット 1 となる。これらのサブ
ネットは、異なる建物の中にあり、おそらく専用線かもしくは無線によっ
て接続されているだろう。IP アドレスはネットワーク管理者によって割り当てられる
ので、IP サブネットを持つことはネットワーク管理を分散するよい方法である。IP 
サブネットの管理者は、その IP サブネットワーク内で自由に IP アドレスを割り当
てることができるからである。

<!--
Generally though, IP addresses are somewhat hard to remember. Names are
much easier. linux.acme.com is much easier to remember than
16.42.0.9 but there must be some mechanism to convert the network
names into an IP address. These names can be statically specified in the
/etc/hosts file or Linux can ask a Distributed Name Server 
(DNS server) to resolve the name for it. In this case the local host must
know the IP address of one or more DNS servers and these are specified in
/etc/resolv.conf. 
-->
<p>しかし、一般的に IP アドレスは覚えるのがやや困難である。名前のほうがより
簡単であり、linux.acme.com のほうが 16.42.0.9 よりもずっと覚えやすい。だが、
ネットワーク名を IP アドレスに変換するには多少の仕組みが必要となる。そうした
名前は、<tt>/etc/hosts</tt> ファイル内で静的に指定できるが、Linux は、
DNS (Domain Name System) サーバに問い合わせて、名前を IP アドレスに
変換することもできる。その場合、ローカルホストはひとつ以上の DNS サーバの IP 
アドレスを知る必要があり、それは <tt>/etc/resolv.conf</tt> で指定される。


<!--
Whenever you connect to another machine, say when reading a web page,
its IP address is used to exchange data with that machine. This data is
contained in IP packets each of which have an IP header containing the IP
addresses of the source and destination machine's IP addresses, a
checksum and other useful information. The checksum is derived from the
data in the IP packet and allows the receiver of IP packets to tell if the IP
packet was corrupted during transmission, perhaps by a noisy telephone
line. The data transmitted by an application may have been broken down into
smaller packets which are easier to handle. The size of the IP data packets
varies depending on the connection media; ethernet packets are generally
bigger than PPP packets. The destination host must reassemble the data
packets before giving the data to the receiving application. You can see this
fragmentation and reassembly of data graphically if you access a web page
containing a lot of graphical images via a moderately slow serial link. 
-->
<p>ウェブページを読む時などに他のマシンに接続する際はいつも、相手のマシンとの
データ交換に IP アドレスが使用される。このデータは IP パケットに含まれていて、
個々のパケットは、送信元の IP アドレスと送信先の IP アドレス、チェックサム
その他の情報を含んだ IP ヘッダを持っている。チェックサムは IP パケットの
データから導き出されるもので、それによって、おそらく電話回線上のノイズなどで、
転送中に IP パケットが壊れなかったかどうかを IP パケットの受信者が判断できる
ようになる。アプリケーションによって送信されるデータは、処理しやすいように、
より小さなパケットへと分割される。IP データパケットのサイズは接続
メディアによって異なり、イーサネットパケットは一般に PPP パケットよりも
サイズが大きい。送信先のホストはそのデータパケットを組み立て直して、それを受信
すべきアプリケーションに渡さなければならない。多くのグラフィックイメージを
含むウェブページに比較的低速なシリアル回線経由でアクセスする場合、このデータ
の分割と統合の過程を視覚的に理解することができる。

<!--
Hosts connected to the same IP subnet can send IP packets directly to each
other, all other IP packets will be sent to a special host, a gateway.
Gateways (or routers) are connected to more than one IP subnet and they
will resend IP packets received on one subnet, but destined for another
onwards. For example, if subnets 16.42.1.0 and 16.42.0.0 are
connected together by a gateway then any packets sent from subnet 0 to
subnet 1 would have to be directed to the gateway so that it could route
them. The local host builds up routing tables which allow it to route IP
packets to the correct machine. For every IP destination there is an entry in
the routing tables which tells Linux which host to send IP packets to in
order that they reach their destination. These routing tables are dynamic and
change over time as applications use the network and as the network
topology changes. 
-->
<p>同一の IP サブネットに接続されたホスト間ではお互いに直接 IP パケットを送信
することができるが、それ以外のすべてのパケットは特別なホストであるゲートウェイ
(gateway)に送信される。ゲートウェイ(あるいはルータ(router))は、複数の IP 
サブネットに接続されていて、あるサブネット上で受信した IP パケットが、別のサブ
ネット宛であった場合に、その IP パケットを送信先に向けて送りなおす。
たとえば、サブネット 16.42.1.0 と 16.42.0.0 がゲートウェイに
よって接続されている場合、サブネット 0 からサブネット 1 へと送信されるパケット
は、ルーティングが可能なゲートウェイに送られなければならない。ローカルホスト
はルーティングテーブルを設定し、それによって正しいマシンに IP パケットを
経路付けすることができる。すべての IP の送信先に関して、ルーティングテーブル
内にひとつのエントリがある。Linux は、それを参照することで、どのホストに送れば
よいかを判断して、IP パケットを宛先に届けている。
これらのルーティングテーブルは、複数のアプリケーションがネットワークを使用した
り、ネットワークトポロジーが変更された場合など、時間の経過によって動的に変化す
る。

<label id="figure10-1">
<!--               Figure 10.1: TCP/IP Protocol Layers-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure10-1.gif">
</figure>
</#if>
<#unless output="html">
<verb>
                     イーサネットフレーム
+----+------------+------------+------+---------//---+----------+
|PRE |送信先      |送信元      |プロ  |              |フレーム  |
|など|イーサネット|イーサネット|トコ  |    データ    |チェック  |
|    |アドレス    |アドレス    |ル    |              |シーケンス|
+----+------------+------------+------+---------//---+----------+
                                      |              |
+-------------------------------------+              +-----------+
|/                                                               |/
*                      IP データグラム                           *
+-+-+--------+-+-+-+------+--------+--------+--------+-------//--+
| | |パケット| | | |プロト|チェック|送信元  |送信先  |           |
| | |長      | | | |コル  |サム    |IP      |IP      |  データ   |
| | |        | | | |      |        |アドレス|アドレス|           |
+-+-+--------+-+-+-+------+--------+--------+--------+-------//--+
                                                     |           |
          +------------------------------------------+           |
          |/                                                     |/
          *                  TCP セグメント                      *
          +--------+--------+----------+----+-+-+---------//-----+
          |送信元  |送信先  |シーケンス|ACK | | |                |
          |TCP     |TCP     |番号      |番号| | |    データ      |
          |アドレス|アドレス|          |    | | |                |
          +--------+--------+----------+----+-+-+---------//-----+
</verb>
</#if>
<p>図表(10.1) TCP/IP プロトコル層

<!--
The IP protocol is a transport layer that is used by other protocols to carry
their data. The Transmission Control Protocol (TCP) is a reliable end to end
protocol that uses IP to transmit and receive its own packets. Just as IP
packets have their own header, TCP has its own header. TCP is a
connection based protocol where two networking applications are connected
by a single, virtual connection even though there may be many subnetworks,
gateways and routers between them. TCP reliably transmits and receives
data between the two applications and guarantees that there will be no lost
or duplicated data. When TCP transmits its packet using IP, the data
contained within the IP packet is the TCP packet itself. The IP layer on each
communicating host is responsible for transmitting and receiving IP packets.
User Datagram Protocol (UDP) also uses the IP layer to transport its
packets, unlike TCP, UDP is not a reliable protocol but offers a datagram
service. 
This use of IP by other protocols means that when IP packets are
received the receiving IP layer must know which upper protocol layer to give
the data contained in this IP packet to. To facilitate this every IP packet
header has a byte containing a protocol identifier. When TCP asks the IP
layer to transmit an IP packet , that IP packet's header states that it
contains a TCP packet. The receiving IP layer uses that protocol identifier to
decide which layer to pass the received data up to, in this case the TCP
layer. When applications communicate via TCP/IP they must specify not
only the target's IP address but also the port address of the application. A
port address uniquely identifies an application and standard network
applications use standard port addresses; for example, web servers use port
80. These registered port addresses can be seen in /etc/services. 
-->
<p>IP(Internet Protocol) プロトコルは、他のプロトコルがデータを運ぶために利用
する、転送のための層(layer)である。TCP (Transmission Control Protocol)は、エン
ドシステム間における信頼性のあるプロトコルで、自己のパケットを送受信するために 
IP を使用する。
IP が独自のヘッダを持つように、TCP も独自のヘッダを持つ。TCP はコネクション
(connection)に基づくプロトコルなので、両端のアプリケーションは、間に多くの
サブネットワークやゲートウェイ、ルータがある場合でも、単一の仮想的コネクション
によって接続される。TCP はふたつのアプリケーション間で信頼性をもってデータ
の受け渡しを行うので、データの喪失や重複が生じないことが保証される。TCP が IP 
を利用してパケットを転送するとき、IP パケット内に含まれるデータは TCP パケット
そのものである。
個々の通信ホスト上で IP 層は、IP パケットの送受信に関して責任を持つ。
UDP (User Datagram Protocol)も IP 層を使用して自分のパケットを転送するが、
TCP と異なり、UDP は信頼性のあるプロトコルではなく、単にデータグラム(datagram)
サービスを提供するだけである。
このように、IP は、他のプロトコルによって利用されている。したがって、IP パケッ
トを受け取った際、受信した IP 層は、どの上位プロトコル層に対してその IP パケッ
トに含まれるデータを渡すべきか認識できなければならない。これを簡単に実現するた
めに、すべての IP ヘッダには、プロトコル識別子が記述された 1 バイトの情報があ
る。TCP が IP 層に IP パケットの送信を依頼するとき、IP パケットのヘッダには、
そのパケットが TCP パケットを含むものであることを伝える情報が記述される。
受信した IP 層は、そのプロトコル識別子を使用して、どの上位層(この場合は、
TCP)に受信したデータを渡すべきかを判断する。
また、アプリケーションが TCP/IP 経由で通信を行うとき、それらは相手方の IP アド
レスだけでなく、アプリケーションのポート番号をも指定しなければならない。
ポート番号はアプリケーションをユニークに特定するものであり、標準的なネット
ワークアプリケーションは標準のポート番号を使用する。たとえば、ウェブサーバは 
80 番ポートを使用している。これら登録済みのポート番号は、<tt>/etc/services
</tt> ファイルで確認できる。

<!--
This layering of protocols does not stop with TCP, UDP and IP. The IP
protocol layer itself uses many different physical media to transport IP
packets to other IP hosts. These media may themselves add their own
protocol headers. One such example is the ethernet layer, but PPP and SLIP
are others. An ethernet network allows many hosts to be simultaneously
connected to a single physical cable. Every transmitted ethernet frame can
be seen by all connected hosts and so every ethernet device has a unique
address. Any ethernet frame transmitted to that address will be received by
the addressed host but ignored by all the other hosts connected to the
network. These unique addresses are built into each ethernet device when
they are manufactured and it is usually kept in an SROM2 on the ethernet
card. Ethernet addresses are 6 bytes long, an example would be
08-00-2b-00-49-A4. Some ethernet addresses are reserved for
multicast purposes and ethernet frames sent with these destination
addresses will be received by all hosts on the network. As ethernet frames
can carry many different protocols (as data) they, like IP packets, contain a
protocol identifier in their headers. This allows the ethernet layer to
correctly receive IP packets and to pass them onto the IP layer. 
-->
<p>このようなプロトコルの多層構造は、TCP, UDP や IP だけに留まらない。すなわ
ち、IP プロトコル自身が様々な異なる物理メディアを使用して IP パケットを他の IP 
ホストに転送している。したがって、それらの物理メディア自体も独自のプロトコル
ヘッダを付け加えている。イーサネット層がその一例であり、他にも PPP 層や SLIP 層
などがある。イーサネットのネットワークでは、多くのホストを同時に単一の物理ケー
ブルに接続することが可能である。(訳注: 10BASE5 など。現在、単一の物理ケーブルが
使われることは少なくなりました。) 送信されたイーサネットフレーム(frame)は、その
ケーブルに接続されたすべてのホストから見ることが出来るので、個々のイーサネット
デバイスはユニークな(ハードウェア)アドレスを持たなければならない。
特定の(ハードウェア)アドレスに対して送信されたイーサネットフレームはそのアドレ
スのホストに受信され、ネットワークに接続されたそれ以外のすべてのホストからは無
視される。こうしたユニークなアドレスはイーサネットデバイスの製造時にデバイスに
組み込まれていて、通常、イーサネットカードの SROM(<ref id="chapter_net_fn" 
name="脚注2">) に保存されている。
イーサネットのアドレスは 6 バイト長で、たとえば、08-00-2B-00-49-A4 といったもの
になっている。イーサネットのアドレスにはマルチキャスト(<ref id="multicast" 
name="訳注: 用語集(multicast)">)の目的に予約されたものがあり、そうした送信先
アドレスを設定されて送信されたイーサネットフレームは、そのネットワーク上のすべ
てのホストで受信される。
イーサネットフレームは、多種のプロトコルを(データとして)運ぶことができるので、
IP パケットの場合と同様に、イーサネットフレームのヘッダにはプロトコル識別子が
含まれている。これによって、イーサネット層は IP パケットを正確に受信して、それ
を IP 層に渡すことができる。

<!--
In order to send an IP packet via a multi-connection protocol such as
ethernet, the IP layer must find the ethernet address of the IP host. This is
because IP addresses are simply an addressing concept, the ethernet
devices themselves have their own physical addresses. IP addresses on the
other hand can be assigned and reassigned by network administrators at will
but the network hardware responds only to ethernet frames with its own
physical address or to special multicast addresses which all machines must
receive. Linux uses the Address Resolution Protocol (or ARP) to allow
machines to translate IP addresses into real hardware addresses such as
ethernet addresses. A host wishing to know the hardware address
associated with an IP address sends an ARP request packet containing the
IP address that it wishes translating to all nodes on the network by sending
it to a multicast address. The target host that owns the IP address,
responds with an ARP reply that contains its physical hardware address.
ARP is not just restricted to ethernet devices, it can resolve IP addresses
for other physical media, for example FDDI. Those network devices that
cannot ARP are marked so that Linux does not attempt to ARP. There is
also the reverse function, Reverse ARP or RARP, which translates phsyical
network addresses into IP addresses. This is used by gateways, which
respond to ARP requests on behalf of IP addresses that are in the remote
network. 
-->
<p>イーサネットのような(ケーブルに繋がったすべてのホストにフレームが流れる)
マルチコネクションのプロトコル経由で IP パケットを送信するためには、IP 層は、
IP ホストのイーサネットアドレスを知らなければならない。というのも、IP アドレス
は単にアドレス割り当ての概念にすぎず、イーサネットデバイス自体が独自の物理
アドレスを持っているからである。すなわち、IP アドレスはネットワーク管理者の
意志によって割り当てや再割り当てが可能であるのだが、ネットワークハードウェア
は、自分の物理アドレスが付加されたイーサネットフレームか、あるいはすべての
マシンで受信すべき特別なマルチキャストアドレスにしか反応しないからである。
Linux は、ARP (Address Resolution Protocol)を使用して、マシンが、IP アドレスを
イーサネットアドレスのような実際のハードウェアアドレスに変換できるようにしてい
る。
ある IP アドレスに関連付けられたハードウェアアドレスを知ろうとするホストは、
変換したい IP アドレスを含めた ARP リクエストパケットを、マルチキャストアドレス
を付けてネットワーク上のすべてのノード(node)に送信する。その IP アドレスを持つ
ターゲットホスト(target host)は、自分の物理アドレスを含めた ARP リプライによっ
てそれに応答する。ARP はイーサネットデバイスだけでしか利用できないわけではな
く、<ref id="FDDI" name="FDDI"> などのそれ以外の物理メディアに対しても IP アド
レスの解決が可能である。
ARP が利用できないネットワークデバイスはそれが出来ない旨マークされているので、
その場合、Linux がARP を試すことはない。ARP の逆の機能も存在しており、リバース 
ARP もしくは RARP は、ハードウェアアドレスを IP アドレスに変換する。これは
ゲートウェイによって利用されるもので、ゲートウェイは、リモートネットワークにあ
る IP アドレスが書かれた ARP リクエストに返答する際にそれを使用する。

<!--10.2  The Linux TCP/IP Networking Layers-->
<sect1>Linux の TCP/IP ネットワーク層<label id="chapter_net_sect2">
<p>

<label id="figure10-2">
<!--              Figure 10.2: Linux Networking Layers-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure10-2.gif">
</figure>
</#if>
<#unless output="html">
<verb>
                           ネットワーク
                          アプリケーション
                               /|
                                |                       User
--------------------------------+----------------------------
                                |                      Kernel
                                |/
                          +-----*------+
                          |    BSD     |
                          |  ソケット  |
                          +-----*------+
ソケット                       /|
インターフェイス                |/
                          +-----*------+
                          |    INET    |
                          |  ソケット  |
                          +--*--*--*---+
                            /| /| /|
                        +----+  |  +----+
                        |/      |       |/
                    +---*---+   |   +---*---+
                    |       |   |   |       |
                    |  TCP  |   |   |  UDP  |
                    +---*---+   |   +---*---+
プロトコル層           /|       |      /|
                        |       |       |
                        |/      |/      |/
                 +------*-------*-------*-------+
                 |                              |<-+
                 |              IP              |  |
                 +---*----------*----------*----+  |  +-------+
                    /|         /|         /|       +->|       |
                     |          |          |          |  ARP  |
                     |/         |/         |/      +->|       |
                 +---*---+  +---*---+  +---*----+  |  +-------+
ネットワーク     |       |  |       |  |        |<-+
デバイス         |  PPP  |  |  SLIP |  |Ethernet|
                 +-------+  +-------+  +--------+
</verb>
</#if>
<p>図表(10.2) Linux のネットワーク層

<!--
Just like the network protocols themselves, Figure  10.2 shows that Linux
implements the internet protocol address family as a series of connected
layers of software. BSD sockets are supported by a generic socket
management software concerned only with BSD sockets. Supporting this is
the INET socket layer, this manages the communication end points for the
IP based protocols TCP and UDP. UDP (User Datagram Protocol) is a
connectionless protocol whereas TCP (Transmission Control Protocol) is a
reliable end to end protocol. When UDP packets are transmitted, Linux
neither knows nor cares if they arrive safely at their destination. TCP
packets are numbered and both ends of the TCP connection make sure that
transmitted data is received correctly. The IP layer contains code
implementing the Internet Protocol. This code prepends IP headers to
transmitted data and understands how to route incoming IP packets to either
the TCP or UDP layers. Underneath the IP layer, supporting all of Linux's
networking are the network devices, for example PPP and ethernet. Network
devices do not always represent physical devices; some like the loopback
device are purely software devices. Unlike standard Linux devices that are
created via the mknod command, network devices appear only if the
underlying software has found and initialized them. You will only see
/dev/eth0 when you have built a kernel with the appropriate ethernet
device driver in it. The ARP protocol sits between the IP layer and the
protocols that support ARPing for addresses. 
-->
<p>ネットワークプロトコル自体が多層構造を持つのと同様に、図表(10.2)では、Linux 
がインターネットプロトコルアドレスファミリ(address family)をソフトウェアの多層
構造として実装していることが示されている。BSD ソケットは、BSD ソケットだけに関
する汎用のソケット管理ソフトウェアとしてサポートされている。
BSD ソケットをサポートするのが INET ソケット層で、これは、IP ベースの TCP や 
UDP プロトコルのためのエンドポイント通信を管理する。
UDP(User Datagram Protocol)はコネクション管理を行わないプロトコル
であるが、TCP(Transmission Control Protocol)は信頼性の高い一対一(end to end)の
プロトコルである。UDP パケットが送信されるとき、Linux はそれが安全に送信先に
届いたかどうか分からないし、気にもしない。TCP パケットは番号付けされている
ので、TCP コネクションの両方のエンド(end, 端)は、送信されたデータが正しく受信さ
れたかどうかを確認できる。
IP 層には、インターネットプロトコル(IP)を処理するためのコードが含まれている。
このコードは、受信したデータの IP ヘッダを取得し、その IP パケットが TCP か 
UDP のどちらかの上位層に宛てたものかを判断して、適切な上位層にルーティングす
る。IP 層の下で Linux のネットワーキングをサポートしているのが、PPP やイーサ
ネットといったネットワークデバイスである。ネットワークデバイスとは必ずしも物理
デバイスを意味するものではない。ループバックデバイス(loopback device)などは純粋
なソフトウェアデバイスだからである。
<tt>mknod</tt> で作成される Linux の標準的なデバイスファイルとは異なり、ネット
ワークデバイスはその基礎となるソフトウェアが物理デバイスを検出し初期化した場合
にだけ現れる。
カーネルに適切なイーサネットドライバを組み込んだ場合のみ、<tt>/dev/eth0</tt> 
を見ることができる。ARP プロトコルは、IP 層と ハードウェアアドレス解決のために
 ARP をサポートする下位のプロトコルとの間に位置している。

<!--10.3  The BSD Socket Interface-->
<sect1>BSD ソケットインターフェイス<label id="chapter_net_sect3">

<!--
This is a general interface which not only supports various forms of
networking but is also an inter-process communications mechanism. A
socket describes one end of a communications link, two communicating
processes would each have a socket describing their end of the
communication link between them. Sockets could be thought of as a special
case of pipes but, unlike pipes, sockets have no limit on the amount of data
that they can contain. Linux supports several classes of socket and these
are known as address families. This is because each class has its own
method of addressing its communications. Linux supports the following
socket address families or domains: 
-->
<p>BSD ソケットインターフェイスは、汎用インターフェイスであり、ネットワークの
様々な形態をサポートするだけでなく、プロセス間通信の仕組みでもある。
ソケットは通信リンクの一方のエンド(end, 端)を記述するもので、ふたつの通信プロセ
スが個別にソケットを持ち、両者の間の通信リンクのそれぞれのエンドを記述する。
ソケットはパイプの特殊なケースであると考えることも可能だが、パイプと異なり、
ソケットは保持できるデータ容量に制限がない。Linux は、いくつかのソケットクラス
(socket class)をサポートしており、それらはアドレスファミリ(address family)と
呼ばれている。これは、個々のクラスが独自の通信方式を持っているからである。
Linux は次のようなアドレスファミリもしくはドメイン(domain)をサポートしている。

<!--
 UNIX 
            Unix domain sockets, 
 INET 
            The Internet address family supports communications via 
            TCP/IP protocols 
 AX25 
            Amateur radio X25 
 IPX 
            Novell IPX 
 APPLETALK 
            Appletalk DDP 
 X25 
            X25
-->
<descrip>
<tag>UNIX</tag>Unix ドメインソケット。

<tag>INET</tag>インターネットアドレスファミリ(internet address family)は、
TCP/IP 経由の通信をサポートしている。

<tag>AX25</tag>アマチュア無線 X25。

<tag>IPX</tag>Novell IPX。

<tag>APPLETALK</tag>Appletalk DDP

<tag>X25</tag>X25。
</descrip>

<!--
There are several socket types and these represent the type of service that
supports the connection. Not all address families support all types of
service. Linux BSD sockets support a number of socket types: 
-->
<p>アドレスファミリもしくはドメインには、いくつかのソケットタイプ(socket type)
があり、それらはコネクションをサポートするサービスのタイプを表している。
すべてのサービスタイプをサポートしていないアドレスファミリもある。
Linux BSD ソケットは次のいくつかのソケットタイプをサポートしている。

<!--
Stream These sockets provide reliable two way sequenced data streams
      with a guarantee that data cannot be lost, corrupted or duplicated in
      transit. Stream sockets are supported by the TCP protocol of the
      Internet (INET) address family. 
-->
<descrip>
<tag>Stream</tag>
このソケットは、双方向で順次応答確認の行われる信頼性のあるデータストリーム
(data stream)であり、通信途上でのデータの喪失や破壊、複製が生じないよう保証され
たものである。Stream ソケットは、インターネット(INET)アドレスファミリの TCP 
プロトコルによってサポートされている。

<!--
Datagram
      These sockets also provide two way data transfer but, unlike stream
      sockets, there is no guarantee that the messages will arrive. Even if
      they do arrive there is no guarantee that they will arrive in order or
      even not be duplicated or corrupted. This type of socket is supported
      by the UDP protocol of the Internet address family. 
-->
<tag>Datagram</tag>
このソケットは、双方向でのデータ通信を提供するが、stream ソケットと異なり、
メッセージが到達する保証はない。到達した場合でも、順番通り届いたか、さらに
複製や破壊はないかといったことは保証されない。このタイプのソケットは、インター
ネットアドレスファミリの UDP プロトコルによってサポートされている。

<!--
Raw This allows processes direct (hence ``raw'') access to the
      underlying protocols. It is, for example, possible to open a raw
      socket to an ethernet device and see raw IP data traffic. 
-->
<tag>Raw</tag>
これは、プロセスが、下層のプロトコルに直接(それゆえ、生(raw))アクセスする
ものである。これを使うと、たとえば、raw ソケットをイーサネットデバイスに対して
オープンし、生(raw)の IP データトラフィックを見ることが可能になる。

<!--
Reliable Delivered Messages
      These are very like datagram sockets but the data is guaranteed to
      arrive. 
-->
<tag>Reliable Delivered Messages</tag>
これは、datagram ソケットと非常に類似しているが、データの到着は保証される。

<!--
Sequenced Packets
      These are like stream sockets except that the data packet sizes are
      fixed. 
-->
<tag>Sequenced Packets</tag>
これは、データパケットサイズが固定されていることを除いて、stream パケットと
同じである。

<!--
Packet This is not a standard BSD socket type, it is a Linux specific
      extension that allows processes to access packets directly at the
      device level. 
-->
<tag>Packet</tag>
これは、標準的な BSD ソケットタイプではない。Linux 固有の拡張であり、
これを使うと、プロセスがデバイスレベルで直接パケットにアクセスできる。
</descrip>

<!--
Processes that communicate using sockets use a client server model. A
server provides a service and clients make use of that service. One example
would be a Web Server, which provides web pages and a web client, or
browser, which reads those pages. A server using sockets, first creates a
socket and then binds a name to it. The format of this name is dependent on
the socket's address family and it is, in effect, the local address of the
server. The socket's name or address is specified using the sockaddr data
structure. An INET socket would have an IP port address bound to it. The
registered port numbers can be seen in /etc/services; for example, the
port number for a web server is 80. Having bound an address to the socket,
the server then listens for incoming connection requests specifying the
bound address. The originator of the request, the client, creates a socket
and makes a connection request on it, specifying the target address of the
server. For an INET socket the address of the server is its IP address and
its port number. These incoming requests must find their way up through the
various protocol layers and then wait on the server's listening socket. Once
the server has received the incoming request it either accepts or rejects it.
If the incoming request is to be accepted, the server must create a new
socket to accept it on. Once a socket has been used for listening for
incoming connection requests it cannot be used to support a connection.
With the connection established both ends are free to send and receive
data. Finally, when the connection is no longer needed it can be shutdown.
Care is taken to ensure that data packets in transit are correctly dealt with. 
-->
<p>ソケットを利用して通信を行うプロセスは、クライアントサーバモデル(client 
server model)を使用する。
サーバはサービスを提供し、クライアントがそのサービスを利用する。その典型が
ウェブサーバであり、サーバがウェブページを提供し、クライアント、もしくは
ブラウザがそのページを読み出す。ソケットを使うサーバは、まずソケットを作成
し、それに名前を結びつける(bind)。その名前のフォーマットはそのソケットアドレス
ファミリーに依存し、事実上サーバのローカルアドレスになる。ソケットの名前もしく
はアドレスは、<tt><ref id="sockaddr" name="sockaddr"></tt> データ構造体を使って
指定される。
INET ソケットは、IP ポート番号をそれに結びつける。登録済みポート番号は、
<tt>/etc/services</tt> ファイルで見ることができる。たとえば、ウェブサーバのポー
ト番号は 80 である。アドレスをソケットに結びつけたら、サーバは、そのアドレス
を指定したコネクションリクエストが来るまで待機している(listen)。リクエストの
発信者である
クライアントはソケットを作成し、サーバのターゲットアドレスを指定して、
ソケット上でコネクションリクエストを出す。INET ソケットの場合、サーバの
アドレスは、その IP アドレスとポート番号である。やって来たリクエストは、
様々なプロトコル層を
上昇して、サーバの待機中(listening)のソケット上で(処理されるのを)待つ。サーバ
がやって来たリクエストを受信した場合、サーバは、それを受け入れる(accept)か拒絶
するかのいずれかを行う。やって来たリクエストが受け入れられる場合、サーバは
受け入れるための新しいソケットを作成しなければならない。やって来る接続
リクエストのために、いったん待機状態(listening)に入ったソケットは、
コネクションをサポートするために使用することはできない。
コネクションが確立されたら、両者は自由にデータの送受信ができる。最後に、それ以
上コネクションが必要なくなったとき、コネクションは遮断(shutdown)できる。
その際、転送中のデータパケットがあっても正しく処理されるよう注意を払う
必要がある。

<!--
The exact meaning of operations on a BSD socket depends on its underlying
address family. Setting up TCP/IP connections is very different from setting
up an amateur radio X.25 connection. Like the virtual filesystem, Linux
abstracts the socket interface with the BSD socket layer being concerned
with the BSD socket interface to the application programs which is in turn
supported by independent address family specific software. At kernel
initialization time, the address families built into the kernel register
themselves with the BSD socket interface. Later on, as applications create
and use BSD sockets, an association is made between the BSD socket and
its supporting address family. This association is made via cross-linking
data structures and tables of address family specific support routines. For
example there is an address family specific socket creation routine which
the BSD socket interface uses when an application creates a new socket. 
-->
<p>BSD ソケット上での操作が厳密に何を意味するかは、その基礎となるアドレス
ファミリーによって異なる。TCP/IP コネクションの設定は、アマチュア無線 X.25 
コネクションの設定とは非常に異なる。仮想ファイルシステムの場合のように、Linux 
は、BSD ソケット層(layer)を使ってソケットインターフェイスを抽象化している。
BSD ソケット層側は、アプリケーションプログラムに対する BSD ソケットインター
フェイスと関係付けられ、アプリケーション側は、アドレスファミリーごとに独立した
固有のソフトウェアによりサポートされている。
カーネルに組み込まれたアドレスファミリは、カーネルの初期化時に、BSD ソケット
インターフェイスと伴に登録される。その後、アプリケーションが BSD ソケットを
作成して使用する場合、BSD ソケットとそれがサポートするアドレスファミリとの
間で関連付けがなされる。この関連付けは、データ構造体とアドレスファミリ固有の
サポートルーチンとをクロスリンクすることにより実現される。
たとえば、アドレスファミリ固有のソケット作成ルーチンがある場合、アプリケー
ションが新規にソケットを作成しようとする際には、BSD ソケットインターフェイス
は、そのルーチンを使用してソケットを作成する。

<!--
When the kernel is configured, a number of address families and protocols
are built into the protocols vector. Each is represented by its name, for
example ``INET'' and the address of its initialization routine. When the
socket interface is initialized at boot time each protocol's initialization
routine is called. For the socket address families this results in them
registering a set of protocol operations. This is a set of routines, each of
which performs a a particular operation specific to that address family. The
registered protocol operations are kept in the pops vector, a vector of
pointers to proto_ops data structures. 
The proto_ops data structure consists of the address family type and a
set of pointers to socket operation routines specific to a particular address
family. The pops vector is indexed by the address family identifier, for
example the Internet address family identifier (AF_INET is 2). 
-->
<p>一般に、カーネル設定の際には、いくつものアドレスファミリとプロトコルが 
ビルドされ、<tt><htmlurl url="./The-Linux-Kernel-images/linux/net/socket.c" 
name="protocols"></tt> 配列に組み込まれる。それらはそれぞれ、INET といった名前
とその初期化ルーチンのアドレスとによって表現される。ブート時にソケット
インターフェイスが初期化されるとき、個々のプロトコル初期化ルーチンが呼び出さ
れる。ソケットアドレスファミリーにとって、これは、一組のプロトコル操作
を登録することを意味する。これは、一組のルーチンであり、それぞれが
アドレスファミリ固有のプロトコル操作を実行する。登録されたプロトコル操作
ルーチンは、<tt><ref id="proto_ops" name="pops"></tt> 配列に保存されるが、
それは <tt><ref id="proto_ops" name="proto_ops"></tt>
 データ構造体へのポインタの配列である。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/net.h" 
name="include/linux/net.h">]<newline>
<tt>proto_ops</tt> データ構造体は、アドレスファミリタイプと、アドレス
ファミリ固有のソケット操作ルーチンに対する一連のポインタから構成されている。
<tt>pops</tt> 配列は、アドレスファミリ識別子によるインデックスが
付けられていて、たとえば、インターネットアドレスファミリの識別子(AF_INET)は
 2 である。


<!--           Figure 10.3: Linux BSD Socket Data Structures-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure10-3.gif">
</figure>
</#if>
<#unless output="html">
<verb>
files_struct
+-------------+
| count       |
|-------------|
|close_on_exec|
|-------------|
| open_fs     |
|-------------|
| fd[0]       |      file
|-------------|   +----------+
| fd[1]       |-->| f_mode   |
|-------------|   |----------|
|             |   | f_pos    |
|             |   |----------|
|             |   | f_flags  |
|-------------|   |----------|
| fd[255]     |   | f_count  |
+-------------+   |----------|
                  | f_owner  |
                  |----------|                    BSD Socket
                  | f_op     |------------------->File Operations
                  |----------|                    
                  | f_inode  |-+     inode        lseek,ioctl
                  |----------| |  +---------+     read, close
                  |f_version | +->|         |     write, fasync
                  +----------+    |         |     select
                              +-->| socket  |
                              |   |---------|SOCK_STREAM
                              |   | type    |------->Address Family
                              |   | ops     |----+   Socket
                              |   | data    |    |   Operations
                              |   +---------+    |
                              |    +-------------+
                              +----+-----------------+
                                   |       sock      |
                                   |   +----------+  |
                                   +-->| type     |SOCK_STREAM
                                       |----------|  |
                                       | protocol |  |
                                       |----------|  |
                                       | socket   |--+
                                       |----------|
                                       |          |
                                       |          |
                                       +----------+
</verb>
</#if>
<p>図表(10.3) Linux BSD ソケットデータ構造体

<!--10.4  The INET Socket Layer-->
<sect1>INET ソケット層<label id="chapter_net_sect4">

<!--
The INET socket layer supports the internet address family which contains
the TCP/IP protocols. As discussed above, these protocols are layered, one
protocol using the services of another. Linux's TCP/IP code and data
structures reflect this layering. Its interface with the BSD socket layer is
through the set of Internet address family socket operations which it
registers with the BSD socket layer during network initialization. These are
kept in the pops vector along with the other registered address families.
The BSD socket layer calls the INET layer socket support routines from the
registered INET proto_ops data structure to perform work for it. For
example a BSD socket create request that gives the address family as
INET will use the underlying INET socket create function. The BSD socket
layer passes the socket data structure representing the BSD socket to the
INET layer in each of these operations. Rather than clutter the BSD
socket wiht TCP/IP specific information, the INET socket layer uses its
own data structure, the sock which it links to the BSD socket data
structure. This linkage can be seen in Figure  10.3. It links the sock data
structure to the BSD socket data structure using the data pointer in the
BSD socket. This means that subsequent INET socket calls can easily
retrieve the sock data structure. The sock data structure's protocol
operations pointer is also set up at creation time and it depends on the
protocol requested. If TCP is requested, then the sock data structure's
protocol operations pointer will point to the set of TCP protocol operations
needed for a TCP connection. 
-->
<p>INET ソケット層は、TCP/IP を含むインターネットアドレスファミリをサポート
するものである。上記で説明したように、これらのプロトコルは多層構造になってい
て、ひとつのプロトコルが別のプロトコルのサービスを利用する。
Linux の TCP/IP のコードとデータ構造はその多層構造を反映している。BSD ソケット
層に対する INET ソケット層のインターフェイスは、一連のインターネットアドレス
ファミリーのソケット操作ルーチンを経由するものであり、Linux は、ネットワークの
初期化時にそれらのルーチンを BSD ソケット層と伴に登録する。
それらは、登録された他のアドレスファミリと一緒に <tt><ref id="proto_ops" 
name="pops"></tt> 配列に保存される。BSD ソケット層は、登録済みの INET <tt><ref 
id="proto_ops" name="proto_ops"></tt> データ構造体から、INET 層ソケットを
サポートするルーチンを呼び出して操作を実行する。
たとえば、アドレスファミリを INET と指定した BSD ソケット作成リクエストは、
その基礎にある INET ソケット作成関数を使用する。
BSD ソケット層は、それらの個々の操作をする際に、BSD ソケットを
表す <tt><ref id="socket" name="socket"></tt> データ構造体を INET 層に渡す。
BSD ソケットが TCP/IP 固有の情報でごちゃごちゃにならないように、INET ソケット
層は、独自のデータ構造体である <tt><ref id="sock" name="sock"></tt> を使用し、
この構造体を BSD ソケット層の <tt>socket</tt> データ構造体にリンクする。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/net/sock.h"
name="include/net/sock.h">]<newline>
このリンク関係は、図表(10.3)で示されている。
INET ソケット層は <tt>sock</tt> データ構造体を BSD <tt>socket</tt> データ構造体
にリンクする際、BSD <tt>socket</tt> の <tt>data</tt>ポインタを使用する。
これは、それ以降の INET ソケットの呼び出しで、簡単に <tt>sock</tt> データ構造体
が取り出せることを意味する。
<tt>sock</tt> データ構造体のプロトコル操作ルーチンへのポインタは、その構造体
作成時に設定されるが、設定の内容はリクエストされたプロトコルによって異なる。
TCP/IP がリクエストされた場合、<tt>sock</tt> データ構造体のプロトコル操作ルーチ
ンへのポインタは、TCP コネクションに必要な TCP プロトコル操作ルーチンのセットを
ポイントする。

<!--10.4.1  Creating a BSD Socket-->
<sect2>BSD ソケットの作成

<!--
The system call to create a new socket passes identifiers for its address
family, socket type and protocol. 
Firstly the requested address family is used to search the pops vector for a
matching address family. It may be that a particular address family is
implemented as a kernel module and, in this case, the kerneld daemon
must load the module before we can continue. A new socket data structure
is allocated to represent the BSD socket. Actually the socket data
structure is physically part of the VFS inode data structure and allocating
a socket really means allocating a VFS inode. This may seem strange
unless you consider that sockets can be operated on in just the same way
that ordinairy files can. As all files are represented by a VFS inode data
structure, then in order to support file operations, BSD sockets must also be
represented by a VFS inode data structure. 
-->
<p>システムコールで新規ソケットを作成する際は、アドレスファミリ、ソケットタイ
プ、プロトコルに関する識別子を渡す。
<newline>[see: sys_socket(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/socket.c" 
name="net/socket.c">]<newline>
まず、リクエストされたアドレスファミリを使って、<tt><ref id="proto_ops" 
name="pops"</tt> 配列内に合致するアドレスファミリがあるかどうか検索される。
たとえば、特定のアドレスファミリがカーネルモジュールとして実装されている場合
は、処理を継続する前に <tt>kerneld</tt> デーモンによって該当するモジュール
がロードされることになる。
新規の <tt><ref id="socket" name="socket"></tt> データ構造体が割り当てられて、
BSD ソケットが表現される。
実際、<tt>socket</tt> データ構造体は、物理的には VFS <tt><ref id="inode" 
name="inode"></tt> データ構造体の一部なので、<tt>socket</tt> の割り当ては、
VFS <tt>inode</tt> の割り当てを意味する。
これは奇妙に思われるかもしれないが、ソケットは、通常ファイルの操作と同じ方法で
操作され得ることを考えてほしい。すべてのファイルが VFS <tt>inode</tt> データ
構造体によって表現されるので、ファイル操作をサポートするには、BSD ソケットは 
VFS <tt>inode</tt> データ構造体によっても表現されなければならないのである。

<!--
The newly created BSD socket data structure contains a pointer to the
address family specific socket routines and this is set to the proto_ops
data structure retrieved from the pops vector. Its type is set to the sccket
type requested; one of SOCK_STREAM, SOCK_DGRAM and so on. The
address family specific creation routine is called using the address kept in
the proto_ops data structure. 
-->
<p>新規に作成された BSD <tt><ref id="socket" name="socket"></tt> データ構造体に
は、アドレスファミリ固有のソケットルーチンへのポインタが含まれていて、このルー
チンは、<tt><ref id="proto_ops" name="pops"></tt> 配列から取り出された <tt>
<ref id="proto_ops" name="proto_ops"></tt> データ構造体に設定される。そのタイプ
は、リクエストされたソケットタイプ、すなわち SOCK_STREAM, 
SOCK_DGRAM 等に設定される。アドレスファミリ固有の作成ルーチンは、<tt>proto_ops
</tt> データ構造体に保存されたアドレスを使用して呼び出される。

<!--
A free file descriptor is allocated from the current processes fd vector and
the file data structure that it points at is initialized. This includes setting
the file operations pointer to point to the set of BSD socket file operations
supported by the BSD socket interface. Any future operations will be
directed to the socket interface and it will in turn pass them to the
supporting address family by calling its address family operation routines. 
-->
<p>未使用のファイル記述子が、カレントプロセスの <tt><ref id="files_struct" 
name="fd"></tt> 配列から割り当てられて、それがポイントする <tt><ref 
id="file" name="file"></tt> データ構造体が初期化される。
この際に同時に為される処理として、そのファイル操作ポインタのポイント先が、
BSD ソケットインターフェイスによってサポートされる BSD ソケットファイル操作
ルーチン群へと設定される。それ以後の何らかの操作は、ソケットインターフェイス
へと誘導され、ソケットインターフェイスがさらにアドレスファミリ操作ルーチンを
呼び出すことで、それがサポートするアドレスファミリへと誘導される。

<!--10.4.2  Binding an Address to an INET BSD Socket-->
<sect2>アドレスを INET BSD ソケットに bind する

<!--
In order to be able to listen for incoming internet connection requests, each
server must create an INET BSD socket and bind its address to it. The bind
operation is mostly handled within the INET socket layer with some support
from the underlying TCP and UDP protocol layers. The socket having an
address bound to cannot be being used for any other communication. This
means that the socket's state must be TCP_CLOSE. The sockaddr pass
to the bind operation contains the IP address to be bound to and, optionally,
a port number. Normally the IP address bound to would be one that has been
assigned to a network device that supports the INET address family and
whose interface is up and able to be used. You can see which network
interfaces are currently active in the system by using the ifconfig command.
The IP address may also be the IP broadcast address of either all 1's or all
0's. These are special addresses that mean ``send to everybody''3. The IP
address could also be specified as any IP address if the machine is acting
as a transparent proxy or firewall, but only processes with superuser
privileges can bind to any IP address. The IP address bound to is saved in
the sock data structure in the recv_addr and saddr fields. These are
used in hash lookups and as the sending IP address respectively. The port
number is optional and if it is not specified the supporting network is asked
for a free one. By convention, port numbers less than 1024 cannot be used
by processes without superuser privileges. If the underlying network does
allocate a port number it always allocates ones greater than 1024. 
-->
<p>インターネット接続リクエストが送信されるのを待ち受ける(listen)ためには、
個々のサーバが INET BSD ソケットを作成して、それにアドレスを bind しなければ
ならない。bind 操作の大部分は、その基礎にある TCP と UDP プロトコル層の
サポートを受けた INET ソケット層内部で処理される。アドレスを bind された
ソケットは、それ以外の通信には使用できない。これは、ソケットの状態(state)が 
TCP_CLOSE でなければならないことを意味する。<tt><ref id="sockaddr" 
name="sockaddr"></tt> 構造体から bind 操作ルーチンに渡される情報の中には、
bind されるべき IP アドレスと、オプションとしてポート番号がある。
通常、bind された IP アドレスは、ネットワークデバイスに割り当てられたもので
あり、そのデバイスは INET アドレスファミリをサポートするもので、そのデバイス
のインターフェイスは起動されていて使用可能でなければならない。そのインターフェ
イスが現在アクティブであるかを確認するには、<tt>ifconfig</tt> コマンドを使用す
ればよい。
IP アドレスは、アドレス(のビット)をすべて 1 にするか、すべて 0 にするかい
ずれかによって、IP ブロードキャストアドレス(<ref id="broadcast" 
name="訳注:broadcast address">)にすることもできる。
それは特別なアドレスで、「全員に送信」(<ref id="chapter_net_fn" 
name="脚注3">)することを意味する。
マシンが透過的なプロキシかファイアウォールである場合、IP アドレスの指定を任意
の IP アドレスとしても構わないが、スーパーユーザの権限を持ったプロセスだけが任
意の IP アドレスを bind できる。bind された IP アドレスは <tt><ref id="sock" 
name="sock"></tt> データ構造体の <tt>recv_addr</tt>(訳注: <tt><ref 
id="sock" name="recv_saddr"></tt>?) と <tt><ref id="sock" name="saddr"></tt> 
に保存される。それらは、ハッシュへの問い合わせの際と、IP アドレスを互いに送信
しあう場合に使用される。ポート番号はオプションであり、指定されない場合、
サポートするネットワークに未使用の番号を割り当てるよう要請がなされる。
慣習では、1024 未満のポート番号は、スーパーユーザの特権がない
プロセスでは使用できない。基礎となるネットワークがポート番号を割り当てる場合、
1024 以上の番号を常に割り当てる。

<!--
As packets are being received by the underlying network devices they must
be routed to the correct INET and BSD sockets so that they can be
processed. For this reason UDP and TCP maintain hash tables which are
used to lookup the addresses within incoming IP messages and direct them
to the correct socket/sock pair. TCP is a connection oriented protocol and
so there is more information involved in processing TCP packets than there
is in processing UDP packets. 
-->
<p>パケットが基礎となるネットワークデバイスで受信されると、パケットは正しい 
INET ソケットと BSD ソケットへと伝達されて、処理されなければならない。
そのために、UDP と TCP は、ハッシュテーブルを管理していて、それを使って、到着
した IP パケット内にあるアドレスを問い合わせて、正しい <tt>
socket/sock</tt> ペアへと IP パケットを伝達する。TCP はコネクション指向の
プロトコルなので、UDP パケットの場合よりも TCP パケットを処理する場合のほうが
関係する情報量が多い。

<!--
UDP maintains a hash table of allocated UDP ports, the udp_hash table.
This consists of pointers to sock data structures indexed by a hash
function based on the port number. As the UDP hash table is much smaller
than the number of permissible port numbers (udp_hash is only 128 or
UDP_HTABLE_SIZE entries long) some entries in the table point to a chain
of sock data structures linked together using each sock's next pointer. 
-->
<p>UDP は、割り当てられた UDP ポートを <tt><ref id="udp_hash" name="udp_hash">
</tt> というハッシュテーブルで管理している。
そのハッシュテーブルは、<tt><ref id="sock" name="sock"></tt> データ構造体への
ポインタから構成されていて、<tt>sock</tt> 構造体はポート番号に基づいてハッシュ
関数によりインデックス付けされている。UDP のハッシュテーブルは、持ち得るポート
番号の数よりも小さい(<tt>udp_hash</tt> は 128 か、UDP_HTABLE_SIZE の数のエント
リしか持たない)ので、テーブル内のエントリのなかには、個々の <tt>sock</tt> が
次へのポインタを持つことでリンクされた <tt>sock</tt> データ構造体の連結リスト
をポイントしているものがある。

<!--
TCP is much more complex as it maintains several hash tables. However,
TCP does not actually add the binding sock data stucture into its hash
tables during the bind operation, it merely checks that the port number
requested is not currently being used. The sock data structure is added to
TCP's hash tables during the listen operation. 
-->
<p>TCP は、複数のハッシュテーブルを管理しているので、それよりずっと複雑である。
しかし、TCP は、bind 操作をする間、実際に bind すべき <tt><ref id="sock" 
name="sock"></tt> データ構造体をそのハッシュテーブルに付け加えるわけではなく、
要求されたのポート番号が現在使用されていないかどうかチェックするだけである。
<tt>sock</tt> データ構造体は、listen 操作の間に TCP のハッシュテーブルに付け加
えられる。

REVIEW NOTE: What about the route entered? 

<!--10.4.3  Making a Connection on an INET BSD Socket-->
<sect2>INET BSD ソケット上でコネクションを確立する。

<!--
Once a socket has been created and, provided it has not been used to listen
for inbound connection requests, it can be used to make outbound
connection requests. For connectionless protocols like UDP this socket
operation does not do a whole lot but for connection orientated protocols like
TCP it involves building a virtual circuit between two applications. 
-->
<p>ソケットが作成されると、そのソケットは、入って来る(inbound)コネクション
リクエストを待ち受ける(listen)ために使用されていない限り、出て行く(outbound)
コネクションリクエストのために使用できる。
UDP のようなコネクションレスのプロトコルの場合、このソケット操作は限定された
意味しか持たないのだが、TCP のようなコネクション指向のプロトコルの場合だと、
それはふたつのアプリケーション間で仮想サーキットを構築することを意味する。

<!--
An outbound connection can only be made on an INET BSD socket that is in
the right state; that is to say one that does not already have a connection
established and one that is not being used for listening for inbound
connections. This means that the BSD socket data structure must be in
state SS_UNCONNECTED. The UDP protocol does not establish virtual
connections between applications, any messages sent are datagrams, one
off messages that may or may not reach their destinations. It does,
however, support the connect BSD socket operation. A connection operation
on a UDP INET BSD socket simply sets up the addresses of the remote
application; its IP address and its IP port number. Additionally it sets up a
cache of the routing table entry so that UDP packets sent on this BSD
socket do not need to check the routing database again (unless this route
becomes invalid). The cached routing information is pointed at from the
ip_route_cache pointer in the INET sock data structure. If no
addressing information is given, this cached routing and IP addressing
information will be automatically be used for messages sent using this BSD
socket. UDP moves the sock's state to TCP_ESTABLISHED. 
-->
<p>出て行く(outbound)コネクションリクエストが可能となるのは、INET BSD ソケット
を使用し、しかも使用する INET BSD ソケットが適切な状態(state)にある場合だけで
ある。
すなわち、そのソケット上で既にコネクションが確立していないこと、およびそれが
入って来る(inbound)コネクションリクエストを待ち受けるために使用されていない
場合である。
これは、BSD <tt><ref id="socket" name="socket"></tt> データ構造体が 
SS_UNCONNECTED の状態になければならないことを意味する。
UDP プロトコルはアプリケーション間で仮想コネクションを確立することはなく、送信
されたメッセージはすべてデータグラム(datagram)であるので、送信メッセージが送信
先に届くかどうかは確定しない。しかし、UDP に関しても BSD ソケット操作である 
connect はサポートされている。UDP BSD ソケット上での connect 操作は、単にリモー
トアプリケーションのアドレスとして、その IP アドレスと IP ポート番号を設定
する。さらに、ルーティングテーブルのエントリのキャッシュを設定して、(当該ルート
が無効とならない限り)その BSD ソケットから送信された UDP パケットが再度ルーティ
ング情報をチェックする必要がないようにする。キャッシュされたルーティング情報
は、INET <tt><ref id="sock" name="sock"></tt> データ構造体内の <tt><ref 
id="sock" name="ip_route_cache"></tt> ポインタによってポイントされる。
アドレス情報が指定されない場合、このキャッシュされたルーティング情報と IP アド
レス情報が、その BSD ソケットを使って送信されるメッセージのために
自動的に使用される。そして、UDP は <tt>sock</tt> の状態(state)を 
TCP_ESTABLISHE に変更する。

<!--
For a connect operation on a TCP BSD socket, TCP must build a TCP
message containing the connection information and send it to IP destination
given. The TCP message contains information about the connection, a
unique starting message sequence number, the maximum sized message
that can be managed by the initiating host, the transmit and receive window
size and so on. Within TCP all messages are numbered and the initial
sequence number is used as the first message number. Linux chooses a
reasonably random value to avoid malicious protocol attacks. Every
message transmitted by one end of the TCP connection and successfully
received by the other is acknowledged to say that it arrived successfully
and uncorrupted. Unacknowledges messages will be retransmitted. The
transmit and receive window size is the number of outstanding messages
that there can be without an acknowledgement being sent. The maximum
message size is based on the network device that is being used at the
initiating end of the request. If the receiving end's network device supports
smaller maximum message sizes then the connection will use the minimum
of the two. The application making the outbound TCP connection request
must now wait for a response from the target application to accept or reject
the connection request. As the TCP sock is now expecting incoming
messages, it is added to the tcp_listening_hash so that incoming TCP
messages can be directed to this sock data structure. TCP also starts
timers so that the outbound connection request can be timed out if the target
application does not respond to the request. 
-->
<p>TCP BSD ソケット上での connect 操作の場合、TCP は、コネクション情報を含んだ 
TCP セグメント(segment)を作成して、指定された IP 送信先に送らなければならない。
TCP セグメントには、コネクション情報、開始セグメントのシーケンス番号(sequence 
number)、接続を開始したホスト側が処理できるセグメントの最大サイズ(maximum 
segment size, MSS)、送信および受信の際のウィンドウサイズ(window size)、等が含
まれる。
TCP では、すべてのセグメントに番号が付けられるので、シーケンス番号の初期値に
は、最初のセグメントの番号が利用される。Linux は、悪意のあるアタックを防ぐため
に、妥当な範囲の乱数値を選択している。TCP コネクションの一方から送信され、相手
側で問題なく受信されたセグメントに対してはすべて、データ破損なく成功裡に到達し
た旨の送達確認(acknowledgement)がなされる。送達確認のないセグメントは再送され
る。送信と受信のウィンドウサイズとは、送達確認が送信されないまま存在しうる未解
決セグメントの数である。最大セグメントサイズは、コネクションリクエストを発信し
た側で使用されているネットワークデバイスに依存する。受信側のネットワークデバイ
スがそれよりも小さい最大セグメントサイズしかサポートしていない場合、そのコネク
ションは小さい方を使用する。
出て行く(outbound) TCP コネクションリクエストを発したアプリケーションは、
相手側アプリケーションがコネクションリクエストを受け入れるか拒絶するかを返答す
るまで待たなければならない。
その場合、TCP ソケットは相手側からのメッセージを期待しているので、そのソケット
は <tt><ref id="tcp_listening_hash" name="tcp_listening_hash"></tt> に加えられ
て、それによって、相手側からの TCP セグメントはその <tt><ref id="sock" 
name="sock"></tt> データ構造体へと誘導される。また、TCP はタイマーをスタート
させて、送信先のアプリケーションがリクエストに対して応答しない場合、出て行く
(outbound)コネクションリクエストをタイムアウトさせる。

<!--10.4.4  Listening on an INET BSD Socket-->
<sect2>INET BSD ソケット上での待ち受け(listen)

<!--
Once a socket has had an address bound to it, it may listen for incoming
connection requests specifying the bound addresses. A network application
can listen on a socket without first binding an address to it; in this case the
INET socket layer finds an unused port number (for this protocol) and
automatically binds it to the socket. The listen socket function moves the
socket into state TCP_LISTEN and does any network specific work needed
to allow incoming connections. 
-->
<p>ソケットにアドレスが bind されると、そのソケットは、bind 
されたアドレスを指定した相手側からの接続要求を待ち受ける(listen)。ネットワーク
アプリケーションは、予めソケットにアドレスを bind しなくてもその
ソケット上で待つことができる。
その場合、INET ソケット層が(そのプロトコルに関して)未使用なポート番号を探して、
自動的にそのソケットにバインド bind する。ソケット関数 listen は、ソケット状態
(state)を TCP_LISTEN 状態へと変更し、相手側からの接続を許可するために必要とされ
るそのネットワーク固有のすべての処理を行う。

<!--
For UDP sockets, changing the socket's state is enough but TCP now adds
the socket's sock data structure into two hash tables as it is now active.
These are the tcp_bound_hash table and the tcp_listening_hash.
Both are indexed via a hash function based on the IP port number. 
-->
<p>UDP ソケットの場合、ソケット状態の変更で充分だが、TCP は、その際、アクティ
ブとなったことで、ソケットの <tt><ref id="sock" name="sock"></tt> データ構造体
をふたつのハッシュテーブルに付け加えなければならない。
それらは、<tt><ref id="tcp_listening_hash" name="tcp_bound_hash"></tt> テーブル
と <tt><ref id="tcp_listening_hash" name="tcp_listening_hash"></tt> である。
どちらも、IP ポート番号に基づくハッシュ関数を経由して、インデックス付けされる。

<!--
Whenever an incoming TCP connection request is received for an active
listening socket, TCP builds a new sock data structure to represent it. This
sock data structure will become the bottom half of the TCP connection
when it is eventually accepted. It also clones the incoming sk_buff
containing the connection request and queues it onto the receive_queue
for the listening sock data structure. The clone sk_buff contains a pointer
to the newly created sock data structure. 
-->
<p>入って来る(inbound) TCP コネクションリクエストがアクティブな接続待ち
(listening)ソケットで受信されたときはいつも、TCP は、それを表す新規の <tt>
<ref id="sock" name="sock"></tt> データ構造体を作成する。
この <tt>sock</tt> データ構造体は、コネクションリクエストが最終的に受け入れられ
たときに、TCP コネクションのボトムハーフ(bottom half)となる。また TCP は、
コネクションリクエストを含んでいる受信した <tt><ref id="sk_buff" 
name="sk_buff"></tt> をクローニング(cloning)して、それを、待ち受け(listen)状態
の <tt>sock</tt>データ構造体の <tt><ref id="sock" name="receive_queue"></tt> 
キューに登録する。
クローンの <tt>sk_buff</tt> 構造体には、新規に作成された <tt>sock</tt> 構造体
へのポインタが含まれる。

<!--10.4.5  Accepting Connection Requests-->
<sect2>コネクション要求を受け入れる(accept)

<!--
UDP does not support the concept of connections, accepting INET socket
connection requests only applies to the TCP protocol as an accept operation
on a listening socket causes a new socket data structure to be cloned from
the original listening socket. The accept operation is then passed to the
supporting protocol layer, in this case INET to accept any incoming
connection requests. The INET protocol layer will fail the accept operation
if the underlying protocol, say UDP, does not support connections.
Otherwise the accept operation is passed through to the real protocol, in
this case TCP. The accept operation can be either blocking or non-blocking.
In the non-blocking case if there are no incoming connections to accept, the
accept operation will fail and the newly created socket data structure will
be thrown away. In the blocking case the network application performing the
accept operation will be added to a wait queue and then suspended until a
TCP connection request is received. Once a connection request has been
received the sk_buff containing the request is discarded and the sock
data structure is returned to the INET socket layer where it is linked to the
new socket data structure created earlier. The file descriptor (fd) number
of the new socket is returned to the network application, and the
application can then use that file descriptor in socket operations on the
newly created INET BSD socket. 
-->
<p>UDP はコネクションの概念をサポートしていないので、INET ソケット上でのコネク
ションリクエストの受け入れ(accept)は、TCP プロトコルだけに適用される。
先ず、listen 状態のソケット上の accept 操作ルーチンによって、その <tt><ref 
id="socket" name="socket"></tt> データ構造体から、新規の <tt>socket</tt> データ
構造体がクローニングされる。
次に accept 操作ルーチンは、入って来る(inbound)コネクションリクエストを受け入
れる(accept)ために、サポートするプロトコル層(layer)、すなわちこの場合 INET 層に
渡される。
INET プロトコル層は、その下位層のプロトコルがコネクションをサポートしていない
場合、たとえば UDP であった場合は、受け入れ操作に失敗する。
下位層がコネクションをサポートしている場合、accept 操作ルーチンは、実(real)
プロトコル(この場合、TCP)へと渡される。
accept 操作は、ブロックするかしないかのいずれかで行える。
ブロックしない場合で、受け入れるべきコネクションがない場合、accept 操作ルーチン
は失敗し、新規に作成された <tt>socket</tt> データ構造体は破棄される。
ブロックする場合、accept 操作ルーチンを実行しているネットワークアプリケーション
は、待ち行列に加えられ、何らかの TCP コネクションリクエストが受信されるまでサス
ペンドする。
コネクションリクエストが受信されたら、そのリクエストを含む <tt><ref 
id="sk_buff" name="sk_buff"></tt> は破棄され、<tt>sock</tt> データ構造体が 
INET ソケット層へと返されて、それより前に新規作成された <tt>socket</tt> データ
構造体にリンクされる。
新規 <tt>socket</tt> のファイル記述子(<tt>fd</tt>)番号が、ネットワーク
アプリケーションに返されるので、アプリケーションは、新規に作成された INET BSD 
ソケットでのソケット操作を、そのファイル記述子を使用して行うことができるよう
になる。

<!--10.5  The IP Layer-->
<sect1>IP 層<label id="chapter_net_sect5">
<p>

<!--10.5.1  Socket Buffers-->
<sect2>ソケットバッファ(socket buffer)

<!--
One of the problems of having many layers of network protocols, each one
using the services of another, is that each protocol needs to add protocol
headers and tails to data as it is transmitted and to remove them as it
processes received data. This make passing data buffers between the
protocols difficult as each layer needs to find where its particular protocol
headers and tails are. One solution is to copy buffers at each layer but that
would be inefficient. Instead, Linux uses socket buffers or sk_buffs to
pass data between the protocol layers and the network device drivers.
sk_buffs contain pointer and length fields that allow each protocol layer to
manipulate the application data via standard functions or ``methods''. 
-->
<p>個々の層が他層のサービスを利用するという、多層構造のネットワークプロトコル
を持つことの問題点は、個々のプロトコルが、送信の際にはヘッダ(header)とテイル
(tail)をデータに付加し、受信データの処理の際にはそれを削除するといった操作が
必要になることである。
個々の層は自分のプロトコルヘッダとテイルがどこにあるのか探す
必要があるので、このことがプロトコル間でのデータバッファの受け渡しを
むずかしくしている。
個々の層でバッファをコピーすることはひとつの解決策であるが、それでは
非効率である。そこで、Linux は、ソケットバッファもしくは <tt><ref id="sk_buff"
 name="sk_buff"></tt> を使用してプロトコル間やネットワークデバイスとの間で
データを受け渡している。<tt>sk_buff</tt> には、ポインタとデータ長(length)の
フィールドが含まれているので、それによって、個々のプロトコル層は、標準関数
か「メソッド(methods)」経由でアプリケーションデータを操作できる。


<!--             Figure 10.4: The Socket Buffer (sk_buff)-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure10-4.gif">
</figure>
</#if>
<#unless output="html">
<verb>
                   sk_buff
              +-----------------+
              | next            |
              |-----------------|
              | prev            |
              |-----------------|
              | dev             |
              |-----------------|
              |                 |
              |                 |
              |-----------------|
              | head            |---+
              |-----------------|   |
              | data            |---+--+
              |-----------------|   |  |
              | tail            |---+--+--+
              |-----------------|   |  |  |
              | end             |---+--+--+---+
   *          |-----------------|<--+  |  |   |
  /|          |                 |      |  |   |
   |          |                 |      |  |   |
   |      *   |-----------------|<-----+  |   |
   |     /|   |                 |         |   |
truesize  |   | 送信されるべき  |         |   |
   |     len  | パケット        |         |   |
   |      |   |                 |         |   |
   |      |/  |                 |         |   |
   |      *   |-----------------|<--------+   |
   |          |                 |             |
   |/         |                 |             |
   *          +-----------------+<------------+
</verb>
</#if>
<p>図表(10.4) ソケットバッファ (sk_buff)

<!--
Figure  10.4 shows the sk_buff data structure; each sk_buff has a block
of data associated with it. The sk_buff has four data pointers, which are
used to manipulate and manage the socket buffer's data: 
-->
<p>図表(10.4)は、<tt><ref id="sk_buff" name="sk_buff"></tt> データ構造体を
示すものである。
個々の <tt>sk_buff</tt> には、一組のデータが関連付けられている。
<tt>sk_buff</tt> には、4 つのデータポインタがあり、それらを使ってソケット
バッファ内のデータ操作と管理がなされる。それら 4 つのポインタとは、次の
ものである。
<newline>[see <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/skbuff.h" 
name="include/linux/skbuff.h">]<newline>

<!--
head points to the start of the data area in memory. This is fixed when
      the sk_buff and its associated data block is allocated, 
data points at the current start of the protocol data. This pointer varies
      depending on the protocol layer that currently owns the sk_buff, 
tail points at the current end of the protocol data. Again, this pointer
      varies depending on the owning protocol layer, 
end points at the end of the data area in memory. This is fixed when the
      sk_buff is allocated. 
-->
<descrip>
<tag>head</tag>
メモリ内のデータ領域の始点を指す。これは、<tt><ref id="sk_buff" 
name="sk_buff"></tt> と関連するデータブロックが割り当てられたときに確定する。

<tag>data</tag>
プロトコルデータの現在の始点を指す。このポインタは、その時点で <tt>
sk_buff</tt> を所有するプロトコル層に依存するため、値は可変である。

<tag>tail</tag>
プロトコルデータの現在の終点を指す。このポインタも所有者たるプロトコル
層依存なので、値は可変である。

<tag>end</tag>
メモリ内のデータ領域の終点を指す。これは、<tt>sk_buff</tt> が
割り当てられたときに確定する。
</descrip>

<!--
There are two length fields len and truesize, which describe the length
of the current protocol packet and the total size of the data buffer
respectively. The sk_buff handling code provides standard mechanisms
for adding and removing protocol headers and tails to the application data.
These safely manipulate the data, tail and len fields in the sk_buff: 
-->
<p><tt><ref id="sk_buff" name="len"></tt> と <tt><ref id="sk_buff" 
name="truesize"></tt> のふたつのデータ長のフィールド(length field)があり、
それぞれ、現在のプロトコルパケットの長さとデータバッファ全体のサイズを
示している。<tt><ref id="sk_buff" name="sk_buff"></tt> 処理コードは、
アプリケーションデータに対するプロトコルヘッダとプロトコルテイルの付加および
削除に対する標準的な仕組みを提供する。
それらは、<tt>sk_buff</tt> 内のデータ、テイル、<tt>len</tt> フィールドを
安全に操作する。<tt>sk_buff</tt> 処理コードには、次のものがある。

<!--
push This moves the data pointer towards the start of the data area and
      increments the len field. This is used when adding data or protocol
      headers to the start of the data to be transmitted, 
-->
<descrip>
<tag>push</tag>
これは、data ポインタをデータ領域の始点方向に移動させ、<tt>len</tt> フィー
ルドを増加(increment)する。これが使用されるのは、送信されるべきデータの先頭に
データやプロトコルヘッダを付加するときである。
<newline>[see: skb_push(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/skbuff.h" 
name="include/linux/skbuff.h">]

<!--
pull This moves the data pointer away from the start, towards the end
      of the data area and decrements the len field. This is used when
      removing data or protocol headers from the start of the data that has
      been received, 
-->
<tag>pull</tag>
これは、data ポインタを始点とは反対側の、データ領域の終端方向へと移動させ
て、<tt>len</tt> フィールドを減少(decrement)する。これが使用されるのは、受信
したデータの先頭からデータやプロトコルヘッダを削除するときである。
<newline>[see: skb_pull(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/skbuff.h" 
name="include/linux/skbuff.h">]

<!--
put This moves the tail pointer towards the end of the data area and
      increments the len field. This is used when adding data or protocol
      information to the end of the data to be transmitted, 
-->
<tag>put</tag>
これは、tail ポインタをデータ領域の終端方向に移動させ、<tt>len</tt> 
フィールドを増加(increment)する。これが使用されるのは、送信されるべきデータの
終点にデータやプロトコル情報を付加するときである。
<newline>[see: skb_put(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/skbuff.h" 
name="include/linux/skbuff.h">]

<!--
trim This moves the tail pointer towards the start of the data area and
      decrements the len field. This is used when removing data or
      protocol tails from the received packet. 
-->
<tag>trim</tag>
これは、tail ポインタをデータ領域の始点方向に移動させ、<tt>len</tt> 
フィールドを減少(decrement)する。これが使用されるのは、受信したデータから
データやプロトコルテイルを削除するときである。
<newline>[see: skb_trim(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/skbuff.h" 
name="include/linux/skbuff.h">]

</descrip>

<!--
The sk_buff data structure also contains pointers that are used as it is
stored in doubly linked circular lists of sk_buff's during processing. There
are generic sk_buff routines for adding sk_buffs to the front and back of
these lists and for removing them. 
-->
<p><tt>sk_buff</tt> データ構造体には、さらにポインタが含まれている。
<tt>sk_buff</tt> は処理の最中に <tt>sk_buff</tt> の二重連結循環リストに保存
されるが、その際に使用されるポインタである。<tt>sk_buff</tt> をそのリストの
先頭や終端に加える際や、そこから削除する際には、そのための汎用的な <tt>
sk_buff</tt> ルーチンが用意されている。


<!--10.5.2  Receiving IP Packets-->
<sect2>IP パケットの受信

<!--
Chapter  dd-chapter described how Linux's network drivers built are into
the kernel and initialized. This results in a series of device data structures
linked together in the dev_base list. Each device data structure
describes its device and provides a set of callback routines that the network
protocol layers call when they need the network driver to perform work.
These functions are mostly concerned with transmitting data and with the
network device's addresses. When a network device receives packets from
its network it must convert the received data into sk_buff data structures.
These received sk_buff's are added onto the backlog queue by the
network drivers as they are received. 
If the backlog queue grows too large, then the received sk_buff's are
discarded. The network bottom half is flagged as ready to run as there is
work to do. 
-->
<p><ref id="chapter_dd_sect6" name="「デバイスドライバ」">の章では、Linux の
ネットワークドライバがカーネルに組み込まれて、初期化される方法を説明した。
それによって、一連の <tt><ref id="device" name="device"></tt> データ構造体が
<tt><ref id="dev_base" name="dev_base"></tt> リストにリンクされた。個々の 
<tt>device</tt> データ構造体は、そのデバイスを記述するとともに、ネットワーク
層がネットワークドライバに処理を実行させる必要があるときに呼び出すことができる
コールバックルーチンのセットを提供する。
これらの関数の大部分はデータ送信とネットワークデバイスのアドレスに関するもの
である。ネットワークデバイスがそのネットワークからパケットを受信したとき、
受信したデータを <tt><ref id="sk_buff" name="sk_buff"></tt> データ構造体に変換
しなければならない。
ネットワークドライバは、それらを受信すると、受信したパケットから作成された 
<tt>sk_buff</tt> を <tt><ref id="sk_buff_head" name="backlog"></tt> キューに
付け加える。
<newline>[see: netif_rr(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/core/dev.c" 
name="net/core/dev.c">]<newline>
もし <tt>backlog</tt> キューが大きくなりすぎた場合、受信した <tt>sk_buff</tt> 
は破棄される。ネットワークのボトムハーフ(bottom half)は、仕事ができたので、実行
準備完了(ready to run)のフラグが立つ。

<!--
When the network bottom half handler is run by the scheduler it processes
any network packets waiting to be transmitted before processing the
backlog queue of sk_buff's determining which protocol layer to pass the
received packets to. 
As the Linux networking layers were initialized, each protocol registered
itself by adding a packet_type data structure onto either the ptype_all
list or into the ptype_base hash table. The packet_type data structure
contains the protocol type, a pointer to a network device, a pointer to the
protocol's receive data processing routine and, finally, a pointer to the next
packet_type data structure in the list or hash chain. The ptype_all
chain is used to snoop all packets being received from any network device
and is not normally used. The ptype_base hash table is hashed by protocol
identifier and is used to decide which protocol should receive the incoming
network packet. The network bottom half matches the protocol types of
incoming sk_buff's against one or more of the packet_type entries in
either table. The protocol may match more than one entry, for example when
snooping all network traffic, and in this case the sk_buff will be cloned.
The sk_buff is passed to the matching protocol's handling routine. 
-->
<p>ネットワークボトムハーフハンドラがスケジューラによって実行されるとき、
そのハンドラーは、まず送信待ちになっているネットワークパケットをすべて処理
した後に、どのプロトコル層に受信したパケットを渡すか判断して、<tt><ref 
id="sk_buff" name="sk_buff"></tt> の <tt><ref id="sk_buff_head" 
name="backlog"></tt> キューを処理する。
<newline>[see: net_bh(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/core/dev.c" 
name="net/core/dev.c">]<newline>
Linux のネットワーク層が初期化されると、個々のプロトコルが登録され、<tt><ref 
id="packet_type" name="packet_type"></tt> データ構造体を <tt>
<ref id="packet_type" name="ptype_all"></tt> リストか <tt><ref 
id="packet_type" name="ptype_base"></tt> ハッシュテーブルに付け加える。
<tt>packet_type</tt> データ構造体には、プロトコルタイプ、ネットワークデバイス
へのポインタ、プロトコルの受信データ処理ルーチンへのポインタ、最後にそのリスト
かハッシュ配列内の次の <tt>packet_type</tt> データ構造体へのポインタが
含まれる。<tt>ptype_all</tt> 配列は、すべてのネットワークデバイス上で
受信された全パケットを探すために利用されるもので、したがって通常は使用されな
い。<tt>ptype_base</tt> ハッシュテーブルはプロトコル識別子をハッシュインデッ
クスとするもので、どのプロトコルが送られて来たネットワークパケットを受信すべき
かを決定するために利用される。ネットワークボトムハーフは、送られて来た <tt>
sk_buff</tt> のプロトコルタイプが、上記いずれかのテーブルにあるひとつ以上の
 <tt>packet_type</tt> エントリと合致するかどうか調べる。たとえば、すべてのネッ
トワークトラフィックを調査して、そのプロトコルがひとつ以上のエントリにマッチし
た場合、その際には <tt>sk_buff</tt> は複製される。そして、その <tt>
sk_buff</tt> は、合致したプロトコルの処理ルーチンへと送られる。
<newline>[see: ip_recv(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/ipv4/ip_input.c" 
name="net/ipv4/ip_input.c">]<newline>

<!--10.5.3  Sending IP Packets-->
<sect2>IP パケットの送信

<!--
Packets are transmitted by applications exchanging data or else they are
generated by the network protocols as they support established connections
or connections being established. Whichever way the data is generated, an
sk_buff is built to contain the data and various headers are added by the
protocol layers as it passes through them. 
-->
<p>パケットは、データ交換をしようとするアプリケーションによって送信される他に、
確立されたコネクションを維持したりコネクションを確立したりするときに、
ネットワークプロトコルによって生成される。しかし、データの生成方法が
どのようなものであっても、そのデータを保持するために <tt><ref id="sk_buff" 
name="sk_buff"></tt> が作成され、プロトコル層を通過する際に、種々のヘッダが
個々のプロトコル層によって付加される。

<!--
The sk_buff needs to be passed to a network device to be transmitted.
First though the protocol, for example IP, needs to decide which network
device to use. This depends on the best route for the packet. For computers
connected by modem to a single network, say via the PPP protocol, the
routing choice is easy. The packet should either be sent to the local host via
the loopback device or to the gateway at the end of the PPP modem
connection. For computers connected to an ethernet the choices are harder
as there are many computers connected to the network. 
-->
<p><tt><ref id="sk_buff" name="sk_buff"></tt> が送信されるには、ネットワーク
デバイスに渡される必要がある。
しかし、それにはまず、IP 等のプロトコルが、どのネットワークデバイスを使用すべき
か判断する必要がある。この判断は、そのパケットにとって何が最適なルートなのかに
よって決まる。たとえば、PPP プロトコル経由で、モデムによって単一のネットワーク
に接続されているコンピュータの場合、ルートの選択は容易である。パケットは、
ループバックデバイス経由でローカルホストに送られるか、PPP によるモデムの
コネクションの反対側にあるゲートウェイに送られるかのいずれかである。
イーサネットで接続されたコンピュータの場合、そのネットワークには多くのコン
ピュータが接続されているので、選択はそれよりも難しくなる。

<!--
For every IP packet transmitted, IP uses the routing tables to resolve the
route for the destination IP address. Each IP destination successfully
looked up in the routing tables returns a rtable 
data structure describing the route to use. This includes the source IP
address to use, the address of the network device data structure and,
sometimes, a prebuilt hardware header. This hardware header is network
device specific and contains the source and destination physical addresses
and other media specific information. If the network device is an ethernet
device, the hardware header would be as shown in Figure  10.1 and the
source and destination addresses would be physical ethernet addresses.
The hardware header is cached with the route because it must be appended
to each IP packet transmitted on this route and constructing it takes time.
The hardware header may contain physical addresses that have to be
resolved using the ARP protocol. In this case the outgoing packet is stalled
until the address has been resolved. Once it has been resolved and the
hardware header built, the hardware header is cached so that future IP
packets sent using this interface do not have to ARP. 
-->
<p>送信されるすべての IP パケットについては、IP がルーティングテーブルを使用
して送信先の IP アドレスに対するルートの解決をする。ルーティングテーブル内で
の個々の IP 送信先の問い合わせが成功した場合、使用すべきルートを示した 
<tt><ref id="rtable" name="rtable"></tt> データ構造体が返される。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/net/route.h" 
name="include/net/route.h">]<newline>
これには、使用すべき送信元 IP アドレス、そのネットワークの <tt><ref 
id="device" name="device"></tt> データ構造体のアドレス、また時には予め
組み込まれたハードウェアヘッダが含まれる。このハードウェアヘッダはネットワーク
デバイス固有のもので、それには送信元と送信先の物理アドレスと、それ以外の
メディア固有の情報が含まれている。ネットワークデバイスがイーサネットデバイスの
場合、ハードウェアヘッダは<ref id="figure10-1" name="図表(10.1)">で示されるよう
なものとなり、送信元と送信先のアドレスはイーサネットの物理アドレスとなる。
ハードウェアヘッダはそのルートとともにキャッシュされるが、それは、そのルート
上で送信されるべき個々の IP パケットにはそのハードウェアのヘッダが付加されなけ
ればならず、その作成には時間がかかるからである。ハードウェアヘッダに
物理アドレスが含まれる場合、そのアドレスは ARP プロトコルを使用して解決
されなければならない。その場合、出て行く(outgoing)パケットは、
その物理アドレスが解決されるまで送信されない。アドレスが解決されてハードウェア
ヘッダが組み込まれたら、ハードウェアヘッダはキャッシュされ、当該インターフェ
イスを使用して送信されるそれ以降の IP パケットは、ARP を使う必要がなくなる。

<!--10.5.4  Data Fragmentation-->
<sect2>データの断片化(fragmentation)

<!--
Every network device has a maximum packet size and it cannot transmit or
receive a data packet bigger than this. The IP protocol allows for this and
will fragment data into smaller units to fit into the packet size that the
network device can handle. The IP protocol header includes a fragment field
which contains a flag and the fragment offset. 
-->
<p>すべてのネットワークデバイスには最大パケットサイズ(maximum packet size)が
あり、それより大きなデータパケットは送信も受信もできない。IP プロトコルはこれに
対処しており、データを小さな断片(fragment)に分割することで、ネットワーク
デバイスが処理できるパケットサイズに合わせるようになっている。
IP プロトコルヘッダにはフラグメント(fragment)フィールドがあり、そこにはフラグ
(flag)とフラグメントオフセット(fragment offset)が含まれている。

<!--
When an IP packet is ready to be transmited, 
IP finds the network device to send the IP packet out on. This device is
found from the IP routing tables. Each device has a field describing its
maximum transfer unit (in bytes), this is the mtu field. If the device's mtu is
smaller than the packet size of the IP packet that is waiting to be
transmitted, then the IP packet must be broken down into smaller (mtu
sized) fragments. Each fragment is represented by an sk_buff; its IP
header marked to show that it is a fragment and what offset into the data
this IP packet contains. The last packet is marked as being the last IP
fragment. If, during the fragmentation, IP cannot allocate an sk_buff, the
transmit will fail. 
-->
<p>IP パケットの送信準備ができたとき、IP はそのパケットを外に送信するネット
ワークデバイスを探す。そのデバイスは IP ルーティングテーブルで見つかる。
<newline>[see: ip_build_xmit(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/ipv4/ip_output.c" 
name="net/ipv4/ip_output.c">]<newline>
個々の <tt><ref id="device" name="device"></tt> 構造体には、その最大転送単位 
(単位はバイト) を示すフィールドがあり、これは原語の maximum transfer unit を
略し <tt>mtu</tt> フィールドと呼ばれる。
デバイスの <tt>mtu</tt> が、送信を待つ IP パケットのパケットサイズよりも
小さい場合、IP パケットはより小さな(<tt>mtu</tt> サイズの)フラグメントへと
分割されなければならない。個々のフラグメントは <tt><ref id="sk_buff" 
name="sk_buff"></tt> によって表される。
その IP ヘッダは、そのパケットがフラグメントであること、そして
それに含まれるデータがどのようなオフセット値を持つかを示すためのマーク付けが
なされる。その最後のパケットは、最後の IP フラグメントである旨をマークされる。
細分化(fragmentation)の過程で、IP が <tt>sk_buff</tt> を割り当てられない場合
は、その送信は失敗となる。

<!--
Receiving IP fragments is a little more difficult than sending them because
the IP fragments can be received in any order and they must all be received
before they can be reassembled. Each time an IP packet is received it is
checked to see if it is an IP fragment. The first time that the fragment of a
message is received, IP creates a new ipq data structure, and this is linked
into the ipqueue list of IP fragments awaiting recombination. As more IP
fragments are received, the correct ipq data structure is found and a new
ipfrag data structure is created to describe this fragment. Each ipq data
structure uniquely describes a fragmented IP receive frame with its source
and destination IP addresses, the upper layer protocol identifier and the
identifier for this IP frame. When all of the fragments have been received,
they are combined into a single sk_buff and passed up to the next protocol
level to be processed. Each ipq contains a timer that is restarted each time
a valid fragment is received. If this timer expires, the ipq data structure and
its ipfrag's are dismantled and the message is presumed to have been
lost in transit. It is then up to the higher level protocols to retransmit the
message. 
-->
<p>IP フラグメントの受信は、その送信よりもやや面倒である。IP フラグメントは、
順序ばらばらに受信されるかもしれず、それらすべてが受信されてから組み立て直す
必要があるからである。
<newline>[see: ip_rcv(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/ipv4/ip_input.c" 
name="net/ipv4/ip_input.c">]<newline>
IP パケットが受信されるたびに、それが IP フラグメントか
否かのチェックがなされる。最初にメッセージのフラグメントが受信された際、IP 
は、新規に <tt><ref id="ipq" name="ipq"></tt> データ構造体を作成し、その構造体
が IP フラグメントの <tt><ref id="ipq" name="ipqueue"></tt> リストにリンクされ
て、再構成されるのを待つ。
より多くの IP フラグメントが受信されると、適切な <tt>ipq</tt> データ構造が
分かるので、新規に <tt><ref id="ipfrag" name="ipfrag"></tt> データ構造体が
作成されて、そのフラグメントを記述する。
個々の <tt>ipq</tt> データ構造体は、IP 受信フレームのフラグメントを一意的に
記述するが、その際には、送信元と送信先の IP アドレス、上層プロトコルの識別子、
その IP フレームの識別子が使用される。フラグメントがすべて受信されたとき、
それらは組み立てられて単一の <tt><ref id="sk_buff" name="sk_buff"></tt> とな
り、次の上層プロトコルへと渡され、処理される。個々の <tt>ipq</tt> にはタイマー
が含まれていて、それは有効なフラグメントが受信されるたびに再始動される。この
タイマーが時間切れになった場合、<tt>ipq</tt> データ構造体と <tt>ipfrag</tt> と
は破棄され、当該データは転送中に喪失したとの推定がなされる。
そのメッセージの再送は、上位層のプロトコルの役割である。

<!--10.6  The Address Resolution Protocol (ARP)-->
<sect1>Address Resolution Protocol (ARP)<label id="chapter_net_sect6">

<!--
The Address Resolution Protocol's role is to provide translations of IP
addresses into physical hardware addresses such as ethernet addresses. IP
needs this translation just before it passes the data (in the form of an
sk_buff) to the device driver for transmission. 
It performs various checks to see if this device needs a hardware header
and, if it does, if the hardware header for the packet needs to be rebuilt.
Linux caches hardware headers to avoid frequent rebuilding of them. If the
hardware header needs rebuilding, it calls the device specific hardware
header rebuilding routine. All ethernet devices use the same generic header
rebuilding routine which in turn uses the ARP services to translate the 
destination IP address into a physical address. 
-->
<p>ARP(Address Resolution Protocol)の役割は、IP アドレスをイーサネットアドレス
のような物理的なハードウェアのアドレスへと変換することである。IP がこの変換
を必要とするのは、送信のために(<tt><ref id="sk_buff" name="sk_buff"></tt> 形式
の)データをデバイスドライバに渡す直前である。
<newline>[see: ip_build_xmit(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/ipv4/ip_output.c" 
name="net/ipv4/ip_output.c">]<newline>
IP が実行する種々チェックの中には、そのデバイスがハードウェアヘッダを必要とする
か、必要とする場合はパケットのハードウェアヘッダを再構成(rebuild)する必要がある
かといった項目が存在する。
Linux は、ハードウェアヘッダをキャッシュすることで、それらを頻繁に再構成しない
で済むようにしている。
ハードウェアヘッダの再構成が必要な場合、Linux は、デバイス固有のハードウェア
ヘッダ再構成ルーチンを呼び出す。
<newline>[see: eth_rebuild_header(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/ethernet/eth.c" 
name="net/ethernet/eth.c">]<newline>
すべてのイーサネットデバイスは同一の汎用ヘッダ再構成ルーチンを使用するが、その
ルーチンが ARP サービスを利用して送信先 IP アドレスを物理アドレスに変換する。

<!--
The ARP protocol itself is very simple and consists of two message types,
an ARP request and an ARP reply. The ARP request contains the IP
address that needs translating and the reply (hopefully) contains the
translated IP address, the hardware address. The ARP request is broadcast
to all hosts connected to the network, so, for an ethernet network, all of the
machines connected to the ethernet will see the ARP request. The machine
that owns the IP address in the request will respond to the ARP request
with an ARP reply containing its own physical address. 
-->
<p>ARP プロトコルそのものは非常にシンプルであり、ARP リクエスト(request)と ARP 
応答(reply)のふたつのタイプのメッセージから成っている。
ARP リクエストには、変換に必要な IP アドレスが含まれ、応答には(上手くいけば)
その IP の変換後のアドレスであるハードウェアアドレスが含まれる。ARP リクエスト
は、ネットワークに接続されたすべてのホストにブロードキャストされるので、ある
イーサネットネットワークにおいては、そのイーサネットに繋がるすべてのマシンが 
ARP リクエストを見ることになる。
リクエストされた IP アドレスを所有するマシンがその ARP リクエストに応答し、
自分の物理アドレスを含めた ARP リプライを返す。

<!--
The ARP protocol layer in Linux is built around a table of arp_table data
structures which each describe an IP to physical address translation. These
entries are created as IP addresses need to be translated and removed as
they become stale over time. Each arp_table data structure has the
following fields: 
-->
<p>Linux 上の ARP プロトコル層は <tt><ref id="arp_table" name="arp_table">
</tt> データ構造体のテーブルを中心に構成されていて、個々の構造体が IP から物理
アドレスへの変換を記述している。
それらのエントリは、IP アドレスの変換が必要になったときに作成され、
それらが時間の経過で役に立たなくなったときに削除される。個々の <tt>arp_table
</tt> データ構造体は次のようなフィールドを持つ。

<!--
 last used 
               the time that this ARP entry was last used, 
 last updated 
               the time that this ARP entry was last updated, 
 flags 
               these describe this entry's state, if it is complete and
               so on, 
-->
<descrip>
<tag>last used</tag>
その ARP エントリが最後に使用された時間。

<tag>last update</tag>
その ARP エントリが最後に更新された時間。

<tag>flags</tag>
これらはそのエントリの状態を表す。それが解決済みでまだ有効なアドレスかどうか、
等である。

<!--
 IP address 
               The IP address that this entry describes 
 hardware address 
               The translated hardware address 
 hardware header 
               This is a pointer to a cached hardware header, 
 timer 
               This is a timer_list entry used to time out ARP
               requests 
               that do not get a response, 
-->
<tag>IP address</tag>
そのエントリが示す IP アドレス。

<tag>hardware address</tag>
変換されたハードウェアアドレス。

<tag>hardware header</tag>
これは、キャッシュされたハードウェアヘッダに対するポインタである。

<tag>timer</tag>
これは <tt><ref id="timer_list" name="timer_list"></tt> のエントリであり、
それは応答の返らない ARP リクエストをタイムアウトするために使用される。

<!--
 retries 
               The number of times that this ARP request has been 
               retried, 
 sk_buff queue 
               List of sk_buff entries waiting for this IP address 
               to be resolved
-->
<tag>retries</tag>
その ARP リクエストがリトライした回数。

<tag>sk_buff queue</tag>
IP アドレスの解決を待つ <tt><ref id="sk_buff" name="sk_buff"></tt> エントリの
リスト。
</descrip>

<!--
The ARP table consists of a table of pointers (the arp_tables vector) to
chains of arp_table entries. The entries are cached to speed up access to
them, each entry is found by taking the last two bytes of its IP address to
generate an index into the table and then following the chain of entries until
the correct one is found. Linux also caches prebuilt hardware headers off
the arp_table entries in the form of hh_cache data structures. 
-->
<p>ARP テーブルは、ポインタテーブル(<tt><ref id="arp_table" name="arp_table">
</tt> の配列)から構成され、そのポインタが <tt>arp_table</tt> エントリの連結
リストを指している。
エントリへのアクセス速度を上げるためにそれらはキャッシュされる。個々のエントリ
を探す場合、エントリは、IP アドレスの末尾 2 バイトを取り出してテーブル内で
インデックス付けされているので、そのインデックスを使ってエントリの連結リストを
辿れば、目的のエントリを見つけることができる。
Linux は、予め作成されたハードウェアヘッダもキャッシュしており、それは <tt>
arp_table</tt> エントリの中に <tt><ref id="hh_cache" name="hh_cache"></tt> 
データ構造体の形で入れられている。

<!--
When an IP address translation is requested and there is no corresponding
arp_table entry, ARP must send an ARP request message. It creates a
new arp_table entry in the table and queues the sk_buff containing the
network packet that needs the address translation on the sk_buff queue of
the new entry. It sends out an ARP request and sets the ARP expiry timer
running. If there is no response then ARP will retry the request a number of
times and if there is still no response ARP will remove the arp_table
entry. Any sk_buff data structures queued waiting for the IP address to be
translated will be notified and it is up to the protocol layer that is
transmitting them to cope with this failure. UDP does not care about lost
packets but TCP will attempt to retransmit on an established TCP link. If the
owner of the IP address responds with its hardware address, the
arp_table entry is marked as complete and any queued sk_buff's will
be removed from the queue and will go on to be transmitted. The hardware
address is written into the hardware header of each sk_buff. 
-->
<p>IP アドレス変換がリクエストされたが、適合する <tt><ref id="arp_table" 
name="arp_table"></tt> エントリが存在しないとき、ARP は ARP リクエスト
メッセージを送信しなければならない。
ARP は、新規に <tt>arp_table</tt> エントリをテーブル内に作成し、アドレス変換を
要するネットワークパケットを含んだ <tt><ref id="sk_buff" name="sk_buff"></tt> 
を 新規エントリの <tt>sk_buff</tt> キューに登録する。
ARP は ARP リクエストを送信し、ARP 時間切れタイマーを走らせる。
応答がない場合、ARP は何度かリクエストを再送してみるが、それでも応答がない場合
は、その <tt>arp_table</tt> のエントリを削除する。エントリの削除は、その 
IP アドレスの変換を待っているキュー上にあるすべての <tt>sk_buff</tt> に
通知される。そして、失敗を上位プロトコル層に送信するのは ARP プロトコル層の
役割である。
UDP はパケットが喪失しても気にしないが、TCP は確立された TCP リンク上で再送を
試みる。もし、IP アドレスの所有者がハードウェアアドレスを付して応答を返した
場合、その <tt>arp_table</tt> エントリは完成(complete)のマークが付けられ、
キュー上にある該当する <tt>sk_buff</tt> はキューから削除されて、送信処理の
過程にまわされる。ハードウェアアドレスは、個々の <tt>sk_buff</tt> の
ハードウェアヘッダの中に書き込まれる。

<!--
The ARP protocol layer must also respond to ARP requests that specfy its
IP address. It registers its protocol type (ETH_P_ARP), generating a
packet_type data structure. This means that it will be passed all ARP
packets that are received by the network devices. As well as ARP replies,
this includes ARP requests. It generates an ARP reply using the hardware
address kept in the receiving device's device data structure. 
-->
<p>ARP プロトコル層は、自身の IP アドレスを指定した ARP リクエストに対する応答
(respond)もしなければならない。ARP は、そのリクエストのプロトコルタイプ
(ETH_P_ARP)を登録し、<tt><ref id="packet_type" name="packet_type"></tt> データ
構造体を生成する。
これは、ネットワークデバイスが受信したすべての ARP パケットが ARP プロトコル層
に渡されることを意味する。このことは、ARP リプライ(reply)の場合だけでなく、ARP 
リクエスト(request)を発するときも同様である。
ARP が ARP リプライを生成するときは、リクエストを受信したデバイスの <tt><ref 
id="device" name="device"></tt> 構造体に保存されたハードウェアアドレスを使用
する。

<!--
Network topologies can change over time and IP addresses can be
reassigned to different hardware addresses. For example, some dial up
services assign an IP address as each connection is established. In order
that the ARP table contains up to date entries, ARP runs a periodic timer
which looks through all of the arp_table entries to see which have timed
out. It is very careful not to remove entries that contain one or more cached
hardware headers. Removing these entries is dangerous as other data
 structures rely on them. Some arp_table entries are permanent and these
are marked so that they will not be deallocated. The ARP table cannot be
allowed to grow too large; each arp_table entry consumes some kernel
memory. Whenever the a new entry needs to be allocated and the ARP table
has reached its maximum size the table is pruned by searching out the
oldest entries and removing them. 
-->
<p>ネットワークトポロジーは時間の経過によって変化することがあるので、IP アドレ
スが以前と異なるハードウェアアドレスに割り当てられることがある。たとえば、
ダイヤルアップサービスの中には、個々のコネクションが確立した時点で IP アドレス
を割り当てるものがある。ARP テーブルが最新の情報を保持するようにするために、
ARP は定期的に実行されて、<tt><ref id="arp_table" name="arp_table"></tt> の全
エントリを走査してタイムアウトになったものがないか確認がなされる。
その際、キャッシュされたハードウェアヘッダをひとつ以上含むエントリを削除してし
まわないよう注意が払われる。他のデータ構造がそれらのエントリに依存しているの
で、削除してしまうことは危険だからである。
ある種の <tt>arp_table</tt> エントリは永続的で、
それらが解放されないよう、その旨マークされている。ARP テーブルは
大きくなりすぎないよう制限されている。個々の <tt>arp_table</tt> エントリは
カーネルメモリを消費するからである。新規にエントリを割り当てる必要が生じたり、
ARP テーブルが最大サイズに達したときはいつも、一番古いエントリを探してそれらを
削除することでテーブルが適度な大きさに保たれる。

<!--10.7  IP Routing-->
<sect1>IP ルーティング<label id="chapter_net_sect7">

<!--
The IP routing function determines where to send IP packets destined for a
particular IP address. There are many choices to be made when transmitting
IP packets. Can the destination be reached at all? If it can be reached, which
network device should be used to transmit it? If there is more than one
network device that could be used to reach the destination, which is the
better one? The IP routing database maintains information that gives
answers to these questions. There are two databases, the most important
being the Forwarding Information Database. This is an exhaustive list of
known IP destinations and their best routes. A smaller and much faster
database, the route cache is used for quick lookups of routes for IP
destinations. Like all caches, it must contain only the frequently accessed
routes; its contents are derived from the Forwarding Information Database. 
-->
<p>IP ルーティング関数は、特定の IP アドレス宛の IP パケットをどこに送信すべき
かを決定する。IP パケットを送信する際は多くの選択肢がある。送信先には到達
可能だろうか？ 到達可能なら、送信のためにどのネットワークデバイスを
使用すべきか？ 送信先に到達し得る利用可能なデバイスが複数ある場合、よりよい
デバイスはどれか？ IP ルーティングデータベースは、それらの疑問に答えるための
情報を管理する。ふたつのデータベースが存在するが、最も重要なのは、フォワーディ
ング 情報データベース(Fowarding Information Database)である。
これは既知の IP 送信先とそこへの最良のルートを
漏れなく収めたリストである。それより小規模だが高速なデータベースとしてルート
キャッシュ(route cache)があり、それは IP 送信先に関するすばやいルート問い合わ
せのために使用される。
すべてのキャッシュと同様に、これには頻繁にアクセスされるルートしか含まれてお
らず、その内容は、フォワーディング情報データベースから取り込まれたものである。

<!--
Routes are added and deleted via IOCTL requests to the BSD socket
interface. These are passed onto the protocol to process. The INET protocol
layer only allows processes with superuser privileges to add and delete IP
routes. These routes can be fixed or they can be dynamic and change over
time. Most systems use fixed routes unless they themselves are routers.
Routers run routing protocols which constantly check on the availability of
routes to all known IP destinations. Systems that are not routers are known
as end systems. The routing protocols are implemented as daemons, for
example GATED, and they also add and delete routes via the IOCTL BSD
socket interface. 
-->
<p>ルート(route)は、BSD ソケットインターフェイスへの IOCTL リクエストを経由して
追加と削除がなされる。それらはプロトコルに渡されて、処理される。INET 
プロトコル層の場合、IP ルートの追加と削除ができるのは、スーパーユーザ権限を
持ったプロセスだけである。ルートは固定することも可能であり、あるいは、時間の
経過によって動的に変更することも可能である。ルータ(router)(訳注: ルータとは、
ネットワークから他のネットワークに、他のシステムが送信したパケットを送り出す
もの)でない限り、大部分の
システムでは固定されたルートが使用されている。ルータはルーティングプロトコルを
実行して、それが既知の送信先の全 IP に対してルーティングできるよう常時チェック
している。ルータでないシステムは、エンドシステム(end system)と呼ばれる。
ルーティングプロトコルは、たとえば GATED のようにデーモンとして実装されている
が、それらも IOCTL BSD ソケットインターフェイス経由でルートを追加したり削除した
りしている。

<!--10.7.1  The Route Cache-->
<sect2>ルートキャッシュ

<!--
Whenever an IP route is looked up, the route cache is first checked for a
matching route. If there is no matching route in the route cache the
Forwarding Information Database is searched for a route. If no route can be
found there, the IP packet will fail to be sent and the application notified. 
If a route is in the Forwarding Information Database and not in the route 
cache, then a new entry is generated and added into the route cache for this 
route. The route cache is a table (ip_rt_hash_table) that contains pointers to
chains of rtable data structures. The index into the route table is a hash
function based on the least significant two bytes of the IP address. These
are the two bytes most likely to be different between destinations and
provide the best spread of hash values. Each rtable entry contains
information about the route; the destination IP address, the network device
to use to reach that IP address, the maximum size of message that can be
used and so on. It also has a reference count, a usage count and a
timestamp of the last time that they were used (in jiffies). 
The reference
count is incremented each time the route is used to show the number of
network connections using this route. It is decremented as applications stop
using the route. The usage count is incremented each time the route is
looked up and is used to order the rtable entry in its chain of hash entries.
The last used timestamp for all of the entries in the route cache is
periodically checked to see if the rtable is too old . 
If the route has not 
been recently used, it is discarded from the route cache. If routes are kept 
in the route cache they are ordered so that the most used entries are at the 
front of the hash chains. This means that finding them will be quicker when 
routes are looked up. 
-->
<p>IP ルートの問い合わせがあるときはいつも、合致するルートがないか、まず
ルートキャッシュがチェックされる。ルートキャッシュに合致するルートがない場合、
ルートについてフォワーディング情報データベースが検索される。そこにもルートが
見つからない場合、IP パケットの送信は失敗し、アプリケーションにその旨通知が
なされる。
フォワーディング情報データベースに該当するルートがあり、ルートキャッシュに
はない場合、新規のエントリが生成され、ルートキャッシュにそのルートが付け加え
られる。
<p>ルートキャッシュは、<tt><ref id="rtable" name="rtable"></tt> データ構造体の
連結リスト(chain)へのポインタを含んだテーブル(<tt><ref id="rtable" 
name="ip_rt_hash_table"></tt>) である。ルートテーブルに対する
インデックスは、IP アドレスの最下位から 2 バイトを基準としてハッシュ関数
により生成される。これらの 2 バイト情報は、たいていの場合送信先によって異なって
いるので、ハッシュ値を散らすには最良である。個々の <tt>rtable</tt> エントリに
は、ルートに関する情報が含まれていて、それには、送信先 IP アドレス、その IP 
アドレスに到達するために使用するネットワークデバイス、使用可能なメッセージ
の最大サイズなどがある。またそれは、リファレンスカウント(reference count)、
ユーサージカウント(usage count)、(<tt>jiffies</tt> を使って表された)最終時間の
タイムスタンプ(timestamp of last time)といった情報も持っている。
リファレンスカウントは、そのルートが使用されるたびにインクリメントされ、そのル
ートを使用したネットワークコネクションの数を示す。そして、このルートを使用した
アプリケーションが終了することによりデクリメントされる。ユーサージカウントは
そのルートが問い合わせを受けるごとに加算され、ハッシュエントリの連結リスト内の 
<tt>rtable</tt> を処理するために使用される。ルートキャッシュ内のすべての
エントリは、「最後に使用された時間を示すタイムスタンプ」を持っていて、
それは <tt>rtable</tt> が古くなりすぎていないかの定期的なチェックに使用される。
<newline>[see ip_rt_check_expire(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/net/ipv4/route.c" 
name="net/ipv4/route.c">]<newline>
そのルートが最近使用されていない場合、それはルートキャッシュから
破棄される。ルートがルートキャッシュに保存されている場合、それらは、最も利用
頻度が多いものがハッシュ連結リストの先頭に来るよう並べ替えられる。これによっ
て、ルート問い合わせがあった際に、その発見が高速になる。


<!--10.7.2  The Forwarding Information Database-->
<sect2>フォワーディング情報データベース(Forwarding Information Database)
<p>

<!--          Figure 10.5: The Forwarding Information Database-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure10-5.gif">
</figure>
</#if>
<#unless output="html">
<verb>
fib_zones                                  fib_node
+-------+                                +----------+
|       |                             +->| fib_next |
|-------|                             |  |----------|
|       |                             |  | fib_dst  |
|-------|                             |  |----------|
|       |                             |  | fib_use  |    fib_info
|       |     fib_zone                |  |----------|  +-----------+
|-------|  +-------------+            |  | fib_info |->| fib_next  |
|       |->| fz_next     |            |  |----------|  |-----------|
|-------|  |-------------|  +-------+ |  |fib_metric|  | fib_prev  |
|       |  |fz_hash_table|->|       | |  |----------|  |-----------|
|       |  |-------------|  |-------| |  | fib_tos  |  |fib_gateway|
|       |  | fz_list     |  |       | |  +----------+  |-----------|
|       |  |-------------|  |-------| |                | fib_dev   |
|       |  | fz_nent     |  |       | |                |-----------|
|       |  |-------------|  |       | |                | fib_refcnt|
|       |  | fz_logmask  |  |-------| |                |-----------|
|       |  |-------------|  |       |-+                | fib_window|
|-------|  | fz_mask     |  |-------|                  |-----------|
|       |  +-------------+  |       |                  | fib_flags |
|-------|                   |       |      fib_node    |-----------|
|       |                   |-------|    +----------+  | fib_mtu   |
+-------+                   |       |--->| fib_next |  |-----------|
                            |-------|    |----------|  | fib_irtt  |
                            |       |    | fib_dst  |  +-----------+
                            |       |    |----------|
                            |       |    | fib_use  |    fib_info
                            |-------|    |----------|  +-----------+
                            |       |    | fib_info |->| fib_next  |
                            |-------|    |----------|  |-----------|
                            |       |    |fib_metric|  | fib_prev  |
                            +-------+    |----------|  |-----------|
                                         | fib_tos  |  |fib_gateway|
                                         +----------+  |-----------|
                                                       | fib_dev   |
                                                       |-----------|
                                                       | fib_refcnt|
                                                       |-----------|
                                                       | fib_window|
                                                       |-----------|
                                                       | fib_flags |
                                                       |-----------|
                                                       | fib_mtu   |
                                                       |-----------|
                                                       | fib_irtt  |
                                                       +-----------+
</verb>
</#if>
<p>図表(10.5) フォワーディング情報データベース


<!--
The forwarding information database (shown in Figure  10.5 contains IP's
view of the routes available to this system at this time. It is quite a
complicated data structure and, although it is reasonably efficiently
arranged, it is not a quick database to consult. In particular it would be very
slow to look up destinations in this database for every IP packet
transmitted. This is the reason that the route cache exists: to speed up IP
packet transmission using known good routes. The route cache is derived
from the forwarding database and represents its commonly used entries. 
-->
<p>フォワーディング情報データベース(図表(10.5)参照)には、IP アドレスから見た、
その時点においてシステム上で利用可能なルートの一覧が含まれる。
それは非常に複雑なデータ構造をしていて、妥当な効率を得られるようアレンジされて
はいるが、高速で問い合わせが可能なデータベースではない。
特に、送信されるべきすべての IP パケットについて送信先をこのデータベースに
問い合わせるとしたら、検索は非常に遅いものになるだろう。
ルートキャッシュが存在するのは、そのためである。既存の適切なルートを
使って IP パケットを高速に送信するわけである。ルートキャッシュはこの 
フォワーディング情報データベースから派生したもので、よく利用されるエントリを
表したものである。

<!--
Each IP subnet is represented by a fib_zone data structure. All of these
are pointed at from the fib_zones hash table. The hash index is derived
from the IP subnet mask. All routes to the same subnet are described by
pairs of fib_node and fib_info data structures queued onto the
fz_list of each fib_zone data structure. If the number of routes in this
subnet grows large, a hash table is generated to make finding the
fib_node data structures easier. 
-->
<p>個々の IP サブネットは <tt><ref id="fib_zone" name="fib_zone"></tt> データ
構造体によって表される。
それらのすべては <tt>fib_zones</tt> ハッシュテーブルからポインタ参照されて
いる。ハッシュのインデックスは、その IP サブネットのマスクから生成
されている。同一サブネットに対するすべてのルート(route)は、<tt><ref 
id="fib_node" name="fib_node"></tt> と <tt><ref id="fib_info" name="fib_info">
</tt> データ構造体のペアによって記述されていて、それらは、個々の <tt>fib_zone
</tt> データ構造体内の <tt><ref id="fib_zone" name="fz_list"></tt> キューに
登録されている。
そのサブネットのルートの数が増えた場合、ハッシュテーブルが
生成されて、<tt>fib_node</tt> データ構造体の発見を容易にする。

<!--
Several routes may exist to the same IP subnet and these routes can go
through one of several gateways. The IP routing layer does not allow more
than one route to a subnet using the same gateway. In other words, if there
are several routes to a subnet, then each route is guaranteed to use a
different gateway. Associated with each route is its metric. This is a
measure of how advantagious this route is. A route's metric is, essentially,
the number of IP subnets that it must hop across before it reaches the
destination subnet. The higher the metric, the worse the route. 
-->
<p>同一の IP サブネットに対していくつかのルートがある場合があり、それらの
ルートは複数のゲートウェイのひとつを通過できる。IP ルーティング層は、
同一サブネットへの複数のルートが同じゲートウェイを使用することは許さない。
言い換えると、あるサブネットへのルートが複数ある場合、個々のルートは
必ず異なるゲートウェイを使用することが保証される。個々のルートに関連付けられ
るのがメトリック(metric)である。これは、そのルートがどれだけ最短に近いかを示す
指標である。ルートのメトリックは、本質的には、宛先のサブネットに到達するまで
に経由しなければならない IP サブネットの数である。メトリックが大きくなるに
つれて、そのルートは最短ルートから遠くなる。


<!--
Footnotes:

1 National Science Foundation 

2 Synchronous Read Only Memory 

3 duh? What used for? 
-->
<label id="chapter_net_fn">
<footnote>
(脚注1) National Science Foundation<newline>

(脚注2) Serial Read Only Memory<newline>

(脚注3) で、何のために？<newline>
</footnote>