IPNG Working Group R.E. Gilligan INTERNET-DRAFT: draft-ietf-ipngwg-rfc2553bis-00.txt Freegate Obsoletes RFC 2553 S. Thomson Bellcore J. Bound Compaq W. R. Stevens Consultant May 2000 Basic Socket Interface Extensions for IPv6 Status of this Memo This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026. This document is a submission by the Internet Protocol IPv6 Working Group of the Internet Engineering Task Force (IETF). Comments should be submitted to the ipng@sunroof.eng.sun.com mailing list. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet- Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet- Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. 要約 TCP/IP アプリケーションのための事実上の標準アプリケーションプログラム インターフェイス (API) は、"ソケット" インターフェイスである。この API は 1980 年代はじめに UNIX 用に開発されたが、数多くの非 UNIX システム上でも 実装されている。ソケット API を使って書かれた TCP/IP アプリケーションは 高度な移植性を経験した。そして我々は、IPv6 アプリケーションでも同じような 移植性を好むだろう。しかし、ソケット API に IPv6 をサポートさせるには 変更が要求されるので、このメモはそれらの変更について記述する。それらは、 IPv6アドレスを運ぶための新しいソケットアドレス構造体、新しいアドレス変換 関数と、いくつかの新しいソケットオプションを含んでいる。これらの拡張は、 TCPと UDP アプリケーションによって要求されたマルチキャストを含む基本的な IPv6 の特徴へのアクセスを与えるために設計された。その上これらの拡張は、 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 1] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 システムへの変更を最小にし、今ある IPv4 アプリケーションとの完全な互換性を 提供する。高度な IPv6 の特徴に対する付加的な拡張 (生のソケットと IPv6 拡張ヘッダに対するアクセス) は別の文書 [4] で定義されている。 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 2] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 Table of Contents: 1. 導入.........................................................4 2. 設計上の留意点...............................................4 2.1 変更される必要のあるもの....................................4 2.2 データ型....................................................6 2.3 ヘッダ......................................................6 2.4 構造体......................................................6 3. ソケットインタフェース.......................................6 3.1 IPv6 アドレスファミリとプロトコルファミリ...................6 3.2 IPv6 アドレス構造体.........................................7 3.3 4.3BSD系システムのためのソケットアドレス構造体..............7 3.4 4.4BSD系システムのためのソケットアドレス構造体..............8 3.5 ソケット関数................................................9 3.6 IPv4 アプリケーションとの互換性............................10 3.7 IPv4 ノードとの互換性......................................10 3.8 IPv6 ワイルドカードアドレス................................11 3.9 IPv6 ループバックアドレス..................................12 3.10 移植性の追加..............................................12 4. インタフェース識別..........................................14 4.1 名前からインデックス.......................................14 4.2 インデックスから名前.......................................15 4.3 全インタフェース名とインデックスの返却.....................15 4.4 メモリ解放.................................................15 5. ソケットオプション..........................................16 5.1 ユニキャスト中継点限界数...................................16 5.2 マルチキャストパケットの送受信.............................17 6. ライブラリ関数..............................................18 6.1 ノード名からアドレス変換...................................18 6.2 アドレスからノード名変換...................................21 6.3 getipnodebynameおよびgetipnodebyaddr用メモリ解放...........22 6.4 プロトコル非依存なノード名およびサービス名変換.............23 6.5 ソケットアドレス構造体からノード名およびサービス名.........27 6.6 アドレス変換関数...........................................29 6.7 アドレス試験マクロ.........................................30 7. 新しい定義のまとめ..........................................30 8. セキュリティ考察............................................32 9. 2000年考察..................................................32 RFC 2553 から rfc2553bis-00 までの変更:........................32 謝辞...........................................................33 参考文献.......................................................33 著者のアドレス.................................................34 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 3] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 1. はじめに IPv4 アドレスは、32ビットの長さであるが、IPv6 のインターフェイスは 128 ビットのアドレスで識別される。ソケットインターフェイスは、明らかに アプリケーションに対して IP アドレスのサイズを作る。事実、BSD 系システム のすべての TCP/IP アプリケーションは IP アドレスのサイズに対する知識を 持っている。アドレスをさらしている API の部分は、より大きいIPv6の アドレスのサイズに対応するために変更されなければならない。IPv6 はまた 新しい特徴(例えばフローラベルと優先度)を導入した。そのいくつかは明らか に API を通してアプリケーションのために作られなければならない。このメモ はソケットインターフェイスに大きいアドレスサイズと IPv6 の新しい特徴を サポートさせるための拡張の集合を定義する。 2. 設計上の留意点 このよく使われた API の変更を設計する上でのいくつかの重要な考察である。 - API の変更は、元の API で書かれたプログラムのソースとバイナリの 両方について互換性を提供するべきである。すなわち、既存のプログラムの バイナリは、新しい API をサポートしたシステムが稼働した時にも動き 続けるべきである。それに加えて、再コンパイルされ、新 API をサポート したシステムの上で走る現存のアプリケーションは動き続けるべきである。 簡単にいうと、IPv6 のための API の変更は既存のプログラムを破壊 すべきではない。実装がこれを証明するための追加機構は、新しい シンボルが IEEE Std 1003.1 で記述される機能試験マクロによって 保護されることを証明する(このような機能試験マクロはこのRFCでは 定義されない)。 - 既存の IPv4 アプリケーションを IPv6 用に変える仕事を簡素化するために、 API の変更点は可能な限り少なくあるべきである。 - もしも可能ならば、アプリケーションは IPv6 と IPv4の両方のホストで このAPIを使えるべきである。アプリケーションは、通信している相手が どちらのタイプのホストか知る必要はない。 - データ構造体の中で運ばれる IPv6 アドレスは、64ビット境界で整列 されるべきである。これは、64 ビットマシンアーキテクチャにおいて 最適なパフォーマンスを得るために必要である。 API に IPv4 との互換性を与えることは重要なので、これらの拡張は、IPv4 とIPv6 の両方が完全にサポートされているマシンの上で使用するために 明示的に設計された。この API の下位集合は、IPv6 しかサポートしていない システムで使用するために多分設計されている。しかしこれはこの文書では 特定されていない。 2.1 変更される必要のあるもの ソケットインターフェイス API は、いくつかの異なった要素からなる。 - 中心的ソケット関数 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 4] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 - アドレスデータ構造 - 名前からアドレス変換関数 - アドレス変換関数 中心的なソケット関数 -- TCP コネクションの開設・解放や、UDP パケットの 送受信の処理を行なうこれらの関数 -- は、自由に運ぶために設計されている。 プロトコルアドレスが関数の引数として通過する場所では、不透明なポインタに よって運ばれる。プロトコル独自のアドレスデータ構造は、ソケット関数が サポートしている各プロトコルごとに定義されている。アプリケーションが ソケット関数を使う時、これらのプロトコル独自のアドレス構造体へのポインタ を一般的な "sockaddr" アドレス構造体へのポインタにキャストしなければ ならない。これらの関数は、IPv6 用の変更を必要としないが、IPv6 独自の アドレスデータ構造は必要である。 sockaddr_in 構造体は、IPv4 のプロトコル独自のデータ構造体である。この データ構造体は、実は8オクテットの未使用の領域を含んでいて、sockaddr_in 構造体を IPv6 に適用するために、このスペースを使うことを試してみたくなる。 不運にも、sockaddr_in 構造体は、必要な他の情報 (アドレスファミリやポート 番号) はもちろん 16 オクテットの IPv6 アドレスさえも保持するのに十分な 大きさではない。従って、新しいアドレス構造体が IPv6 用に定義された。 IPv6 アドレスは [2] で書かれているようにスコープされていて、リンクローカル、 サイト、組織、グローバルや今はまだ定義されていないスコープが可能である。 特定のスコープのためのインターフェイス集合の識別をしたいアプリケーションを サポートするためにIPv6 の sockaddr_in 構造体は、IPv6 アドレスのスコープを 識別するインターフェイスの集合を識別するための実装に使われるフィールドを サポートしなければならない。 ソケットインターフェイスの名前-アドレス変換関数は、gethostbyname() と gethostbyaddr() である。これらはそれとして残り、新しい関数が IPv4 と IPv6 をサポートするために定義された。それに加えて、POSIX 1003.g ドラフト [5] は、プロトコルに依存しない新しいノード名-アドレス変換関数を明確に 述べた。この関数は IPv4 でも IPv6 でも使うことが出来る。 アドレス変換関数 -- inet_ntoa() と inet_addr() -- は、バイナリ形式と 印字可能形式の IPv4 アドレスを変換する。これらの関数は完全に 32 ビットの IPv4 アドレスに特有の物である。我々は、IPv4 と IPv6 アドレスとの両方で 変換する二つの類似している関数を設計した。そして、それはアドレスタイプ パラメータを運んでいるので、同様に別のプロトコルファミリに対応させる ことができる。 最後に、IPv6 をサポートするにはいくつかの雑多な機能が必要とされている。 IPv6 のフローラベル、優先度、そして中継点限界数ヘッダフィールドをサポート するために新しいインターフェイスが必要とされる。IPv6 のマルチキャスト パケットの送受信を制御するために新しいソケットオプションが必要である。 ソケットインターフェイスは、近い将来、別のIPv6の機能へのアクセスを与える ために拡張されるだろう。これらの拡張は [4] に記述されている。 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 5] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 2.2 データ型 この文書で与えられる構造体の要素のデータタイプは、例のつもりであって 絶対的な要求ではない。可能なら、POSIX 1003.1g のドラフト 6.6 (1997年3月)の データタイプが使われる。uintN_t はちょうど N ビットの符号無し整数(例えば uint16_t)を意味する。我々はまた、可能なら 1003.1g による引数のデータ タイプとみなす (例えば setsockopt() の最後の引数は size_t の値である)。 バッファサイズが指定された時は POSIX 1003.1 size_t データタイプが使われる (例えば getnameinfo() の二つの長さの引数)。 2.3 ヘッダ 関数のプロトタイプや構造体が出現する時、我々は、項目が定義されるために #include されなければならないヘッダを示す。 2.4 構造体 構造体が記述中、メンバとして出現したメンバは実装に現れなければならない。 それに加え、実装によっては非標準のメンバも定義されるかも知れない。更に 用心のために、非標準のメンバは IEEE Std 1003.1 で記述される機能試験 マクロによって確かめられるだろう(このような機能試験マクロはこのRFCでは 定義されない)。 構造体のメンバは、マルチバイトメンバの境界を考慮して推奨される順序で 示されているが、実装はメンバを異なる順序で並べてもよい。 3. ソケットインタフェース この章では、IPv6 用ソケットインターフェイスの変更点を述べる。 3.1 IPv6 のアドレスファミリとプロトコルファミリ 新しいアドレスファミリ名 AF_INET6 は で定義されている。 この AF_INET6 の定義は、オリジナルの sockaddr_in アドレスデータ構造体と 新しい sockaddr_in6 データ構造体を区別する。 新しいプロトコルファミリ名 PF_INET6 は で定義されている。 他の多くのプロトコルファミリ名と同じように、これも通常アドレスファミリ名と 同じ値が定義されている。 #define PF_INET6 AF_INET6 PF_INET6 は、IPv6 ソケットが作られることを示すために socket() 関数の 最初の引数に使われる。 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 6] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 3.2 IPv6 アドレス構造体 新しい in6_addr 構造体は、一つの IPv6 アドレスを保持し、 をインクルードした結果定義される。 struct in6_addr { uint8_t s6_addr[16]; /* IPv6 address */ }; このデータ構造体は、8ビットの要素16個からなる配列を含んでおり、それが 128 ビットの IPv6 アドレスを作っている。IPv6 アドレスはネットワーク バイトオーダで格納される。 上の構造体 in6_addr は、普通 struct in_addr の BSD の実装と同じ風習の 境界をもったフィールドの共用体として実装される。 次に例を示す。 struct in6_addr { union { uint8_t _S6_u8[16]; uint32_t _S6_u32[4]; uint64_t _S6_u64[2]; } _S6_un; }; #define s6_addr _S6_un._S6_u8 3.3 4.3BSD 系システム用のソケットアドレス構造体 ソケットインターフェイスの中で、異なったプロトコル独自のデータ構造体が、 それぞれのプロトコル用のアドレスを運ぶために定義されている。各プロトコル 独自のデータ構造体は、プロトコル非依存のデータ構造体--"sockaddr"構造体--に キャストできるように設計されている。それぞれが、sockaddr データ構造体の "sa_family" を上塗りする "family" フィールドを持っている。このフィールドが データ構造体のタイプを識別する。 sockaddr_in 構造体は、IPv4 プロトコル独自のアドレスデータ構造体である。 それは、ソケット関数の中でアプリケーションとシステムとの間でアドレスを 伝えるのに使われている。次の sockaddr_in6 構造体は、IPv6 アドレスを保持 していて、 ヘッダをインクルードした結果定義される。 struct sockaddr_in6 { sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* トランスポート層のポート番号 */ uint32_t sin6_flowinfo; /* IPv6 トラヒッククラスとフロー情報 */ struct in6_addr sin6_addr; /* IPv6 アドレス */ uint32_t sin6_scope_id; /* スコープのためのインタフェース集合 */ }; この構造体は、4.3BSD release で使われている sockaddr データ構造体と 互換性があるように設計されている。 sin6_family フィールドは、これが sockaddr_in6 構造体であるということを draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 7] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 識別する。このフィールドは、バッファが sockaddr データ構造体にキャスト された時、sa_family フィールドを上塗りする。このフィールドの値は、AF_INET6 でなければならない。 sin6_port フィールドは、16 ビットの UDP か TCP のポート番号を持っている。 このフィールドは、sockaddr_in 構造体の sin_port フィールドと同じ方法で 使われる。ポート番号はネットワークバイトオーダで格納される。 sin6_flowinfo フィールドは、トラフィッククラスとフローラベルの二つの 情報を持った32ビットのフィールドである。そのメンバの内容と解釈は[1]で 記されている。sin6_flowinfo フィールドは、受信操作の時にアプリケーションに よって sockaddr_in6 構造体が使われるより前に実装によって0がセットされて いるべきである。 sin6_addr フィールドは、(前章で定義された)一つの in6_addr 構造体である。 このフィールドは 128 ビットの IPv6 アドレスを保持している。このアドレスは ネットワークバイトオーダで格納される。 この構造体の中の要素の並び方は明示的に設計されたので、sin6_addrフィールドが 64ビット境界で整列される時この構造体の先頭も64ビット境界で整列されている だろう。これは64ビットアーキテクチャ上で最適なパフォーマンスを得る。 sin6_scope_id フィールドは sin6_addr フィールドが運んでいるアドレスの スコープのための適当なインターフェイスの集合を識別する32ビット整数である [2,5,6,7]。リンクスコープの sin6_addr では sin6_scope_id はインタフェース インデックスになるだろう。サイトスコープの sin6_addrでは sin6_scope_id はサイト識別子になるだろう。sin6_scope_id のインターフェイスやその集合 へのマッピングは実装と将来の仕様に任されている。 sockaddr_in6 構造体は、通常一般的な sockaddr 構造体よりも大きくなる ことに注意せよ。多くの現存の実装では、sizeof(struct sockaddr_in) は sizeof(struct sockaddr) に等しく、どちらも 16 バイトである。こう仮定 しているいくつかの現存のコードを IPv6 用に変更する時は、注意深く試験 される必要がある。 3.4 4.4BSD 系システムのソケットアドレス構造体 4.4BSD release は、ソケットインターフェイスに対して小さいが互換性のない 変更を含んでいる。sockaddr データ構造体の "sa_family" フィールドは、16 ビット値から8ビット値に変更された。そして、空いた領域は "sa_len" という 名前で長さのフィールドを保持するために使われる。前章で与えられた sockaddr_in6 データ構造体は、新しい sockaddr データ構造体に正しくキャスト することができない。この理由から、4.4BSD 系のシステムでは次の代替 IPv6 アドレスデータ構造体が用意されている。これは ヘッダを インクルードした結果定義される。 struct sockaddr_in6 { uint8_t sin6_len; /* この構造体の長さ */ sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* トランスポート層のポート番号 */ uint32_t sin6_flowinfo; /* IPv6 フロー情報 */ struct in6_addr sin6_addr; /* IPv6 アドレス */ uint32_t sin6_scope_id; /* スコープのためのインタフェース集合 */ }; draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 8] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 このデータ構造体と 4.3BSD のそれとの違いは、長さのフィールドを含み、 ファミリフィールドが 8ビットデータタイプに変更になったことだけである。 他の全てのフィールドの宣言は、前章で定義した構造体を同様である。 このバージョンの sockaddr_in6 データ構造体を提供しているシステムでは、 ヘッダをインクルードした結果として SIN6_LEN も宣言 しなければならない。このマクロは、アプリケーションが 4.3BSD のデータ 構造体をサポートしているシステムの上で動くか、4.4BSD のそれの上で動くか どうかを決めることができる。 3.5 ソケット関数 アプリケーションは、通信のエンドポイントの代理をするソケットディスクリプタ を生成するために socket() 関数を呼ぶ。socket() 関数への引き数は、どの プロトコルを使うかとその後の関数でどの型のアドレス構造体が使われるのかを システムに知らせる。例えば、IPv4/TCP ソケットを生成したいならアプリ ケーションは次のようにする: s = socket(PF_INET, SOCK_STREAM, 0); IPv4/UDP ソケットを生成したいなら、アプリケーションは次のようにする: s = socket(PF_INET, SOCK_DGRAM, 0); アプリケーションは、最初の引数の PF_INET の代わりに単に定数 PF_INET6 を 使うだけで、IPv6/TCP や IPv6/UDP のソケットを生成できる。例えば、 IPv6/TCP ソケットを生成したいならアプリケーションは次のようにする: s = socket(PF_INET6, SOCK_STREAM, 0); IPv6/UDP ソケットを生成したいならアプリケーションは次のようにする: s = socket(PF_INET6, SOCK_DGRAM, 0); 一旦アプリケーションが PF_INET6 ソケットを生成したら、システムに アドレスを伝える時には sockaddr_in6 アドレス構造体を使わなければならない。 アプリケーションがシステムにアドレスを伝えるために使う関数は: bind() connect() sendmsg() sendto() システムは、PF_INET6 ソケットを使っているアプリケーションにアドレスを 返すために sockaddr_in6 アドレス構造体を使うだろう。システムから アプリケーションにアドレスを返す関数は: accept() recvfrom() recvmsg() getpeername() getsockname() 全ての"アドレスを運んでいる"関数は、不透明なアドレスポインタを使用して draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 9] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 いて、関数の引数としてアドレスの長さを運んでいるので、IPv6 をサポート するために、ソケット関数の文法に変更は必要ない。 3.6 IPv4 アプリケーションとの互換性 元の API を使ったアプリケーションの大きな基盤をサポートする目的で、 システムの実装は、元のAPIとのソースとバイナリでの完全な互換性を提供 しなければならない。これは、システムが PF_INET ソケットと sockaddr_in アドレス構造体のサポートを続けなければならないことを意味する。 アプリケーションは、前章で述べられたように socket() 関数で PF_INET 定数を用いて IPv4/TCP と IPv4/UDP ソケットを生成できなければならない。 アプリケーションは、同じプロセスの中で同時に IPv4/TCP、IPv4/UDP、 IPv6/TCP そして IPv6/UDP ソケットを保持できるべきである。 元の API を使っているアプリケーションは、IPv4 しかサポートしていない システム上でしていたように動作し続けるべきである。すなわち、それらは IPv4 ノードでも動作し続けるべきである。 3.7 IPv4 ノードとの互換性 API は、IPv6 アプリケーションが IPv4 アプリケーションとともに相互動作 する能力という違ったタイプの互換性を提供する。この特徴は、IPv6 アドレス アーキテクチャ仕様書[2] で定義された IPv4 射影 IPv6 アドレス形式を使って いる。このアドレス形式は、IPv4 ノードの IPv4 アドレスに対して、IPv6 アドレスの代理をすることを許している。Ipv4 アドレスは、IPv6 アドレスの 下位 32 ビットに置かれ、上位 96 ビットは固定プレフィックス 0:0:0:0:0:FFFF を持つ。IPv4 射影アドレスは次のように書かれる。 ::FFFF: これらのアドレスは、指定されたホストが IPv4 アドレスしか持たなかったとき、 (6.1節や6.4節で示されるように) getipnodebyname() や getaddrinfo() 関数に より自動的に生成されるかもしれない。 アプリケーションは、単に終点の IPv4 アドレスをIPv4 射影 IPv6 アドレスと してエンコードして、connect() や sendto() コールの中で sockaddr_in6 構造体 の中でそのアドレスを通すことによって、IPv4 ノードに TCP コネクションを オープンするためやIPv4 ノードに UDP パケットを送るために PF_INET6 ソケットを使うだろう。アプリケーションが IPv4 ノードからの TCP コネクションを accept するためや IPv4 ノードからの UDP パケットを受け 取るために PF_INET6 を使う時、システムは accept(), recvfrom() や getpeername() コールにおいてこの方法でエンコードされた sockaddr_in6 を 用いて peer アドレスをアプリケーションに返す。 いくつかのアプリケーションは、多分相互動作しているノードがどのタイプか 知る必要があるだろう。しかし、それを知りたいそれらのアプリケーションに 対して、6.7 節で定義される IN6_IS_ADDR_V4MAPPED() マクロが用意されている。 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 10] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 3.8 ワイルドカードアドレス bind() 関数は、アプリケーションが UDP パケットや TCP コネクションの 始点 IP アドレスを選ぶことを許している。アプリケーションはシステムに彼ら の始点アドレスを選ばせたがる。IPv4 では、bind() コールや単に bind() 全て を省略すると、一つのアドレスが、(ワイルドカードアドレスと呼ばれる) シンボル定数 INADDR_ANY として明確にされていた。 IPv6 アドレスタイプは構造体 (struct in6_addr) なので、シンボル定数は IPv6 アドレス変数を初期化に使うことはできたが、割り当てに使うことは出来ない。 それゆえにシステムは二つの形式で IPv6 ワイルドカードアドレスを提供する。 最初のバージョンは、in6_addr 構造体の "in6addr_any" という名前の グローバル変数である。この変数の外部宣言は で定義されている: extern const struct in6_addr in6addr_any; アプリケーションは、IPv4 で INADDR_ANY を使うのと同じ方法で in6addr_any を使う。例えば、始点アドレスをシステムに選ばせて、ポート番号23にソケットを バインドしたい場合は、アプリケーションは以下のコードを使うことができる: struct sockaddr_in6 sin6; . . . sin6.sin6_family = AF_INET6; sin6.sin6_flowinfo = 0; sin6.sin6_port = htons(23); sin6.sin6_addr = in6addr_any; /* 構造体の代入 */ . . . if (bind(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1) . . . 別のバージョンは、IN6ADDR_ANY_INIT という名前のシンボル定数で、 で定義されている。この定数は、in6_addr 構造体の初期化に 使うことができる: struct in6_addr anyaddr = IN6ADDR_ANY_INIT; この定数は、宣言時に*しか*使うことが出来ないことに注意せよ。これは、 既に宣言された in6_addr 構造体に対して割り当てることはできない。 例えば、次のコードは動かないだろう: /* これは未指定アドレスを代入する*誤った*方法である */ struct sockaddr_in6 sin6; . . . sin6.sin6_addr = IN6ADDR_ANY_INIT; /* コンパイル*できない*だろう */ IPv4 の INADDR_xxx 定数は全てホストバイトオーダで定義されていたが、 IPv6 の IN6ADDR_xxx 定数と IPv6 の in6addr_xxx 外部宣言は、ネットワーク バイトオーダで定義されていることに注意せよ。 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 11] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 3.9 IPv6 ループバックアドレス アプリケーションは、ローカルノードに備わっているサービスに UDP パケット を送ったり、TCP コネクションを張ったりする必要があるだろう。IPv4 では、 connect(), sendto() や sendmsg() コール中で IPv4 アドレス定数 INADDR_LOOPBACK を使うことで、これをしてきた。 IPv6 にもローカルの TCP や UDP サービスにコンタクトするためのループ バックアドレスが用意されている。未指定アドレスのように IPv6 ループバック アドレスは二つの形式が用意されており、それらはグローバル変数とシンボル 定数である。 グローバル変数は、"in6addr_loopback" という名前の in6_addr 構造体である。 この変数の外部宣言は で定義されている: extern const struct in6_addr in6addr_loopback; アプリケーションは、IPv4 で INADDR_LOOPBACK を使っていたように in6addr_loopback を使う(しかし、前節の終わりで述べたバイトオーダの違いに 注意せよ)。例えば、ローカルの telnet サーバに TCP コネクションを張るため に、アプリケーションは以下のコードを使うことが出来る: struct sockaddr_in6 sin6; . . . sin6.sin6_family = AF_INET6; sin6.sin6_flowinfo = 0; sin6.sin6_port = htons(23); sin6.sin6_addr = in6addr_loopback; /* 構造体の代入 */ . . . if (connect(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1) . . . シンボル定数は、IN6ADDR_LOOPBACK_INIT という名前で、 で 定義されている。これは、宣言時*しか*使うことができない。例えば: struct in6_addr loopbackaddr = IN6ADDR_LOOPBACK_INIT; IN6ADDR_ANY_INIT のように、この定数は前に宣言された IPv6 アドレス変数への 割り当てでは使うことが出来ない。 3.10 移植性の追加 アプリケーション制作者を助けるためのソケット API への簡単な追加は、 struct sockaddr_storage である。この構造体で複数のアドレスファミリや プラットフォーム間で移植可能なコードを書くことができる。この構造体は 次のような目標で設計された。 - 要求されたプロトコルに固有のソケットアドレス構造体を格納するのに 十分な大きさであること。 - それへのポインタはプロトコル特有のソケットアドレス構造体へのポインタに キャストすることができ、境界を問題にすることなくそれらの構造体に アクセスすることができるよう、適当な境界で整列されていること。 sockaddr_storage 構造体は sa_family_t 型の ss_family フィールドを持つ。 sockaddr_storage 構造体が sockaddr 構造体にキャストされたら、 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 12] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 sockaddr_storage構造体のss_familyフィールドはsockaddr構造体のsa_family フィールドに写像される。sockaddr_storage構造体がプロトコル固有アドレス 構造体としてキャストされたら、sa_family_t型でプロトコルのアドレス ファミリを同定する、その構造体のフィールドに写像される。 これらのデータ構造体の実装案の例は次のようになるだろう。 /* * 最大長と整列に望まれる設計 */ #define _SS_MAXSIZE 128 /* 実装依存な最大長 */ #define _SS_ALIGNSIZE (sizeof (int64_t)) /* 実装依存で要求された境界 */ /* * sockaddr_storage 構造体のパディング設計に使われる定義 */ #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (sa_family_t)) #define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (sa_family_t)+ _SS_PAD1SIZE + _SS_ALIGNSIZE)) struct sockaddr_storage { sa_family_t ss_family; /* アドレスファミリ */ /* 次のフィールドは実装固有 */ char __ss_pad1[_SS_PAD1SIZE]; /* 6 バイトパッド, これはデータ構造中明示的に続く */ /* パッドまでの実装依存なパッドを作るためである */ int64_t __ss_align; /* 保持構造に望まれる境界を強制するための */ /* フィールド */ char __ss_pad2[_SS_PAD2SIZE]; /* 望まれるサイズまでの 112 バイトのパッド */ /* _SS_MAXSIZE 値 引く ss_family のサイズ, */ /* __ss_pad1, __ss_align フィールドは 112 */ }; 上の例は64ビット境界で整列するデータ構造体を示している。実装固有な フィールド "__ss_pad1" に続く "__ss_align" は、sockaddr_in6 (IPv6) や sockaddr_in (IPv4) アドレスデータ構造に十分適切な 64 ビット境界を 強制するために用いられている。パディングフィールド __ss_pad1 の 大きさは選ばれた整列境界に依存する。パディングフィールド __ss_pad2 の 大きさは、この構造体の全体の大きさとして選ばれた全部の大きさに依存する。 この大きさと整列は上の例では実装固有の(必須でない)定数 _SS_MAXSIZE (選定値 128) と _SS_ALIGNMENT (選定値 8)として示されている。定数 _SS_PAD1SIZE (計算値 6)と _SS_PAD2SIZE (計算値 112) もまた図示のためで あり、必須ではない。上でアンダースコアで始まる実装固有の定義と構造体 フィールド名は実装だけの名前空間であることを示す。移植可能なコードは それらのフィールドや定数にアクセスしたり参照したりすることは期待されて いない。 sockaddrデータ構造体に "sa_len" を含む実装では、そのデータ構造体の フィールドは次のようになるだろう。 /* * 最大長と整列に望まれる設計 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 13] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 */ #define _SS_MAXSIZE 128 /* 実装依存な最大長 */ #define _SS_ALIGNSIZE (sizeof (int64_t)) /* 実装依存で要求された境界 */ /* * sockaddr_storage 構造体のパディング設計に使われる定義 */ #define _SS_PAD1SIZE (_SS_ALIGNSIZE - (sizeof (uint8_t) + sizeof (sa_family_t)) #define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (sa_family_t)+ _SS_PAD1SIZE + _SS_ALIGNSIZE)) struct sockaddr_storage { uint8_t ss_len; /* アドレス長 */ sa_family_t ss_family; /* アドレスファミリ */ /* 次のフィールドは実装固有 */ char __ss_pad1[_SS_PAD1SIZE]; /* 6 バイトパッド, これはデータ構造中明示的に続く /* パッドまでの実装依存なパッドを作るためである */ int64_t __ss_align; /* 保持構造に望まれる境界を強制するための */ /* フィールド */ char __ss_pad2[_SS_PAD2SIZE]; /* 望まれるサイズまでの 112 バイトのパッド */ /* _SS_MAXSIZE 値 引く ss_len, ss_family, */ /* __ss_pad1, __ss_align フィールドのサイズは 112 */ }; 4. インターフェイス識別子 この API は、マルチキャストグループに加えられているローカルインタフェースを 識別するためにインターフェイスインデックス (小さな正の整数値)を使う(5.3節)。 それに加えて、高度な API [4] は同じインターフェイスインデックスを、データ グラムが受け取られたインターフェイスを識別するためや、データグラムが送られる インターフェイスを指定するために使う。 インターフェイスは普通 "le0", "sl1", "ppp2" などのような名前で知られて いる。バークレイ派の実装では、インターフェイスがシステムに知らされた時、 カーネルが、そのインターフェイスに対して (インターフェイスインデックスと 呼ばれる) ユニークな正の整数値を割り当てる。それらは1から始まる小さな正の 整数値である。(0はインターフェイスインデックスには決して使われないことに 注意。)特定の正のインデックスに対して現在のインタフェースがないために それは間があくかもしれない。 この API は、インターフェイス名とインデックスとの間をマップする二つの 関数、全てのインターフェイス名とインデックスを返す三つ目の関数、それを 動的に確保されたメモリで返す四つ目の関数を定義している。どのようにして これらの関数が実装されるかは、実装による(?)。 4.4BSD の実装は、存在している sysctl() 関数に NET_RT_IFLIST コマンドを | 使ってこれらの関数を実装できる。他の実装は、この方法のために ioctl() を 使うことを望むかも知れない。 4.1 名前からインデックス 最初の関数は、インターフェイス名をそれに一致するインデックスに写像する。 #include unsigned int if_nametoindex(const char *ifname); draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 14] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 もし指定されたインターフェイスが存在しなければ、戻り値は 0 で、errnoには ENXIOがセットされる。もし(実行時のメモリ不足のような)システムエラーなら、 戻り値0でerrnoには適当な値がセットされる(例えばENOMEM)。 4.2 インデックスから名前 二つ目の関数は、インターフェイスインデックスをそれに一致する名前に写像する。 #include char *if_indextoname(unsigned int ifindex, char *ifname); ifname 引数は、指定されたインデックスに一致するインターフェイス名が返 されるための少なくとも IF_NAMESIZE バイトのバッファを指していなければなら ない。(IF_NAMESIZE も で定義されていて、その内容はインターフェ イス名の最後がヌルバイトで終わっている)。 このポインタは関数の戻り値で もある。指定されたインデックスに一致するインターフェイスがなければ、 NULL が返される。そして、もし(実行時メモリ不足のような)システムエラー ならerrnoにはENXIOがセットされる。if_indextoname はNULLを返し、errnoに は適当な値(例えばENOMEM)がセットされるだろう。 4.3 全てのインターフェイス名とインデックスの返却 if_nameindex 構造体は、一つのインターフェイスについての情報を持っており、 それは ヘッダをインクルードした結果定義される。 struct if_nameindex { unsigned int if_index; /* 1, 2, ... */ char *if_name; /* null 終端名: "le0", ... */ }; 最後の関数は、if_nameindex 構造体の配列を返す。一つのインターフェイスに つき、一つの構造体である。 struct if_nameindex *if_nameindex(void); 構造体の配列の最後は、if_index が 0 で if_name が NULL の構造体によって 示される。エラーが起きるとNULLポインタを返し、errnoには適当な値がセット されるだろう。 if_nameメンバによって指されるインターフェイス名と一緒にこの構造体の配列に よって使われるメモリは、動的に確保されている。このメモリは次の関数によって 解放される。 4.4 メモリ解放 次の関数は if_nameindex() で確保した動的メモリを解放する。 #include draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 15] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 void if_freenameindex(struct if_nameindex *ptr); この関数への引数は if_nameindex() で返されるポインタでなければならない。 現在のところ、net/if.hには関数のプロトタイプ宣言はないが、if_nameindex{} 構造体と同様、これらの宣言はnet/if.hで宣言されることが推奨される。 5. ソケットオプション いくつかの新しいソケットオプションが IPv6 用に定義された。これらの 全ての新しいオプションは IPPROTO_IPV6 レベルである。すなわち、これらの オプションが使われる時の getsockopt() と setsockopt() コールの "レベル" パラメータは IPPROTO_IPV6 である。定数名プレフィックス IPV6_ は全ての 新しいソケットオプションで使われる。これは IPv6 に適用するときに 明らかにこれらのオプションを識別するのに役立つ(?)。 この章で定義されている IPPROTO_IPV6 の宣言、新しい IPv6 ソケット オプションと、関係する定数は、 ヘッダをインクルードする ことによって得られる。 5.1 ユニキャスト中継点限界数 新しい setsockopt() オプションは、出ていくユニキャスト IPv6 パケットに 使われている中継点限界数を制御する。このオプションの名前は IPV6_UNICAST_HOPS で、IPPROTO_IPV6 層で使われる。次の例は使い方を 示している: int hoplimit = 10; if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (char *) &hoplimit, sizeof(hoplimit)) == -1) perror("setsockopt IPV6_UNICAST_HOPS"); setsockopt() で IPV6_UNICAST_HOPS オプションがセットされると、与えられた オプションの値は、ソケットを通して送られるその後の全てのユニキャスト パケットの中継点限界数として使われる。もしオプションがセットされなければ、 システムはデフォルト値を選ぶ。整数の中継点限界数(ここでは x) は次のよう に解釈される: x < -1: エラーEINVALを返す x == -1: カーネル既定値を使用 0 <= x <= 255: xを使用 x >= 256: エラーEINVALを返す IPV6_UNICAST_HOPS オプションは getsockopt() で、その後のソケットを 通して送られるユニキャストパケットの中継点限界数をシステムが決定する のに使われるだろう。例えば: int hoplimit; size_t len = sizeof(hoplimit); if (getsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 16] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 (char *) &hoplimit, &len) == -1) perror("getsockopt IPV6_UNICAST_HOPS"); else printf("Using %d for hop limit.\n", hoplimit); 5.2 マルチキャストパケットの送受信 IPv6 アプリケーションは、sendto() 関数のアドレス引数にIPv6 マルチ キャストアドレスを指定するだけで、UDP マルチキャストパケットを送るだろう。 IPPROTO_IPV6 層の三つのソケットオプションは、マルチキャストパケットを 送る際のいくつかのパラメータを制御する。これらのオプションを設定すること は要求されていない。アプリケーションはこれらのオプションを使わずにマルチ キャストパケットを送ってもよい。マルチキャストパケットの送信を制御する setsockopt() のオプションは、以下で要約されている。これら三つのオプション | は getsockopt() でも使うことが出来る。 IPV6_MULTICAST_IF マルチキャストパケットが出ていくようにインターフェイスを設定する。 引数は、使うインターフェイスのインデックスである。 引数の型: unsigned int IPV6_MULTICAST_HOPS 出ていくマルチキャストパケットの中継点限界数を設定する (別の オプション - IPV6_UNICAST_HOPS - が出ていくユニキャストパケットの 中継点限界数を設定するために用意されていることに注意せよ)。引数の 解釈は、IPV6_UNICAST_HOPS オプションと同様である。 x < -1: エラーEINVALを返す x == -1: カーネル既定値を使用 0 <= x <= 255: xを使用 x >= 256: エラーEINVALを返す If IPV6_MULTICAST_HOPS がセットされなかったら、既定値は 1 (今の IPv4 と同様)。 引数の型: int IPV6_MULTICAST_LOOP マルチキャストデータグラムが、それを送ったホスト自身が加わって いるグループに送られた時、もしこのオプションが1にセットされて いれば、そのデータグラムのコピーはローカル配送のためにIP層によって ループバックされる。もし、このオプションが0にセットされれば、 コピーはループバックしない。他のオプション値はEINVALのエラーを 返す。 もし、IPV6_MULTICAST_LOOPがセットされてなければ、デフォルトは1 (ループバック; 現在のIPv4と同じ)である。 引数の型: unsigned int draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 17] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 マルチキャストパケットの受信は、以下で要約される二つの setsockopt() の オプションで制御される。getsockopt() でこれら二つのオプションが 使用されると EOPNOTSUPP のエラーが返される。 IPV6_JOIN_GROUP 指定したローカルインターフェイスでマルチキャストグループに参加する。 もしインターフェイス識別子に0が指定されると、カーネルはローカル インターフェイスを選ぶ。例えばいくつかのカーネルは、通常のIPv6 経路制御表の中からマルチキャストグループを探し、その結果のインタ フェースを使う。 引数の型: struct ipv6_mreq IPV6_LEAVE_GROUP 指定されたインターフェイスのマルチキャストグループから離脱する。 Argument type: struct ipv6_mreq これらのオプションの両方の引数型は ipv6_mreq 構造体であり、 ヘッダのインクルードの結果定義される: struct ipv6_mreq { struct in6_addr ipv6mr_multiaddr; /* IPv6 マルチキャストアドレス */ unsigned int ipv6mr_interface; /* インタフェース番号 */ }; プロセスは、マルチキャストデータグラムを受け取るために、マルチキャスト グループに加わり、データグラムが送られるであろう UDP ポートにバインド する必要がある。いくつかのプロセスはまた、ソケットの同じポートに届けら れた他のデータグラムを受け取るのを防ぐために、ポートに加えてマルチ キャストグループアドレスにもソケットをバインドする。 6. ライブラリ関数 IPv6 アドレスの各種操作をするために、新しいライブラリ関数が必要である。 関数は、ドメインネームシステム(DNS) で IPv6 アドレスを検索するのに必要で ある。正引き (ノード名からアドレスへの変換)と逆引き(アドレスからノード名 への変換) の両方がサポートされる必要がある。関数はまた、バイナリと テキスト形式との間で IPv6 アドレスを変換する必要がある。 我々は二つの関数 gethostbyname() と gethostbyaddr() がそのまま残る ことに注意しなければならない。IPv4 と IPv6 の両方のアドレスを扱うために 新しい関数が定義された。 6.1 ノード名からアドレス変換 注意: 現時点のこの関数は scope_id [5,6,7] をサポートしようとするいかなる アプリケーションからもつかわれてはならず(MUST)、そのようなアプリケーション には、本規格6.4節で示されているようにgetaddrinfo() が使われるべきである。 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 18] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 共通に使われてきた関数 gethostbyname() は、多くのアプリケーションに とって不十分である。一つ目の理由は、呼び出し側が要求するアドレスタイプ について指定する方法が用意されていないこと (IPv4 だけ、IPv6 だけ、IPv4 射影 IPv6 なら OK など)。そして二つ目は、この関数の多くの実装は、thread safeではない。RFC2133 は、gethostbyname2() という名前の関数を定義したが、 この関数も不十分である。その一つ目の理由は、IPv6 アドレスが要求された時、 グローバルオプション(RES_USE_INET6) の設定が要求されること。二つ目は、 必要とされるアドレスの型を越えた制御を呼出側で行なうためのフラグ引数が 必要とされていることである。 次の関数は新しい。そして、thread safe でなければならない。 #include #include struct hostent *getipnodebyname(const char *name, int af, int flags int *error_num); name 引き数は、ノード名か数字のアドレス文字(即ちドット表記の10進数 IPv4 アドレスや IPv6 の16進数アドレス) のどちらかを取ることができる。 af 引き数は、AF_INET か AF_INET6 かどちらかのアドレスファミリを指定する。 error_numの値は、thread safeなエラーコード返却をサポートするために、 適当なエラーコードがポインタを通じて呼び出し元に返される。error_numには 次の値のうちの一つがセットされるだろう。 HOST_NOT_FOUND そのようはホストは知らない。 NO_ADDRESS サーバは要求と名前を認識したが、アドレスがない。このドメインの サーバに対する他の型の要求は答が返ってくるかもしれない。 NO_RECOVERY 予期せぬ回復不可能な失敗が発生した。 TRY_AGAIN サーバの応答が失敗した等のたぶん一時的なエラーが起きた。 flags 引き数は、検索され、また、返されるるアドレスのタイプを示す。 我々は、(以下で定義される) AI_DEFAULT という特殊な flags の値が 多くのアプリケーションで操作されるべきであることに注意する。 即ち、IPv6 を使うための簡単なアプリケーションの移植は hptr = gethostbyname(name); という呼出を hptr = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num); draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 19] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 で置き換え、関連するエラー診断コードを、h_errno といった外部宣言変数の かわりに error_num に置換することである。 検索される、また返されるアドレス型を通じてよりよい制御を必要とする アプリケーションは、別の flags 引き数の組合せを指定することができる。 flags における 0 は、af 引き数の厳密な解釈を意味する。 - もし flags が 0 で af が AF_INET なら、呼び出し元は IPv4 アドレス だけを求めている。問い合わせは A レコードに対して行なわれる。もし 成功すれば、IPv4 アドレスが返され、hostent 構造体の h_length メンバは 4 になるだろう。そうでなければ、関数は NULL ポインタを返す。 - もし、flags が 0 で、af が AF_INET6 なら、呼び出し元は、IPv6 アドレスだけを求めている。問い合わせは AAAA/A6 レコードに対して 行なわれる。もし成功すれば、IPv6 アドレスが返され、hostent 構造体の h_length メンバは 16 になるだろう。そうでなければ、関数は NULL ポインタを返す。 他の定数は、関数の振る舞いを修正するために、flags 引き数に OR(論理和)を とることが出来る。 - もし、AF_INET6 の af に AI_V4MAPPED フラグが指定されたら、呼び出し 元は、IPv4 射影 IPv6 アドレスを受け入れるだろう。即ち、もし AAAA レコードも A6 レコードも見つからなければ、問い合わせは A レコードで 行なわれ、見つかれば IPv4 射影 IPv6 アドレスで返される(h_length は 16 になるだろう)。AI_V4MAPPED フラグは、af がAF_INET6 でない限り 無視される。 - AI_ALL フラグは AI_V4MAPPED フラグと連結して使われる。そしてそれは IPv6アドレスファミリでのみ使われる。AI_ALL が AI_V4MAPPED フラグとの 論理和をとられると、呼び出し元はIPv6とIPv4射影IPv6アドレスの全ての アドレスを要求している。問い合わせは最初AAAA/A6レコードで行なわれ、 成功すればIPv6アドレスが返される。それから他の問い合わせがAレコードで 行なわれ、見つかればIPv4射影IPv6アドレスで返される。h_length は 16 となる。この両方の問い合わせが失敗した時だけ関数はNULLポインタを 返す。このフラグはafが AF_INET6 でないかぎり無視される。 - AI_ADDRCONFIG フラグは、もしノードが少なくとも一つの設定されたIPv6 始点アドレスを持っていれば AAAA/A6 レコードで問い合わせるべきであり、 もしノードが少なくとも一つの設定された IPv4 始点アドレスを持って いれば A レコードで問い合わせるべきである、ということを指定する。 例えば、ノードが設定された IPv6 始点アドレスを持っていなくて、 af が AF_INET6 に等しく、そして、ノード名は AAAA と A レコードの 両方で探されるようになっているなら、 (a) もし AI_ADDRCONFIGだけが指定されれば、関数はNULLポインタを返し、 (b) もし AI_ADDRCONFIG | AI_V4MAPPED が指定されれば、Aレコードが IPv4射影IPv6アドレスとして返される 特別なフラグ値 AI_DEFAULT が次のように定義される #define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG) 我々は、getnodebyname() 関数が name 引き数にノード名かリテラルなアドレス draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 20] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 文字(即ちドット表記の10進数 IPv4 アドレスやIPv6 の16進数アドレス)を 許さなければならないことに注意している。これにより、アプリケーションは アドレス文字を処理するために inet_pton() を呼ぶ必要がなくなる。 アドレス文字のタイプと af 引き数の値によって4つのシナリオがある。 2つの簡単な場合は: name がドット表記のIPv4アドレスで af が AF_INET であるか、name が IPv6 16進数 アドレスで af が AF_INET6 である時である。返される hostent 構造体のメンバは 次の通りである。h_name は name 引き数のコピーを指し、h_aliases は NULL ポインタである。h_addrtype は af 引き数のコピーであり、h_length は 4 (AF_INET) か 16(AF_INET6) かのどちらかである。h_addr_list[0] は、4バイトか 16バイトのバイナリアドレスへのポインタで、h_addr_list[1] は NULL ポインタで ある。 name 引き数が、ドット表記の10進数 IPv4 アドレスで、af が AF_INET6 で flags が AI_V4MAPPEDであるなら、IPv4 射影 IPv6 アドレスが返される。h_name はIPv4射影 IPv6アドレスを含んだ IPv6 16進数アドレスを指し、h_aliases は NULL ポインタで ある。h_addrtype は AF_INET6 であり、h_length は 16、h_addr_list[0]は、 16バイトのバイナリアドレスへのポインタで、h_addr_list[1] は NULLポインタで ある。もし(AI_ALLに関係なく) AI_V4MAPPED がセットされていれば、IPv4射影IPv6 アドレスが、さもなくば NULL が返る。 name が IPv6 16進数アドレスで af が AF_INET であるならエラーになる。この 関数の戻り値は、NULL ポインタで、h_errno は HOST_NOT_FOUND になる。 6.2 アドレスからノード名変換 注意: スコープ識別子を使うアプリケーションは第6.5節に示されているように getnameinfo() を使うべきである。 次の関数は、今ある gethostbyaddr() 関数と同じ引数を持つが、エラー番号が 加わっている。 #include #include struct hostent *getipnodebyaddr(const void *src, size_t len, int af, int *error_num); getipnodebyname() と同様、getipnodebyaddr() は thread safe でなければ ならない。thread safeなエラーコード返却をサポートするために、error_num の 値は適当なエラーコードを持って呼出元に返される。error_num によって次の エラーの状況が返されるかも知れない: HOST_NOT_FOUND そのようはホストは知らない。 NO_ADDRESS draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 21] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 サーバは要求と名前を認識したが、アドレスがない。このドメインの サーバに対する他の型の要求は答が返ってくるかもしれない。 NO_RECOVERY 予期せぬ回復不可能な失敗が発生した。 TRY_AGAIN サーバの応答が失敗した等のたぶん一時的なエラーが起きた。 混乱の元になりそうなのが、IPv4射影IPv6アドレスとIPv4互換IPv6アドレスの扱い であるが、次の論理が適用されるべきである。 1. もし af が AF_INET6 で、len が 16 で、IPv6 アドレスが IPv4射影 IPv6 アドレスか IPv4互換IPv6 アドレスであるなら、IPv6 アドレスの最初の 12バイトをスキップし、af に AF_INET を、len に 4 をセットする。 2. もし af が AF_INET なら、与えられた IPv4 アドレスに対する名前を検索 する(例えば、in-addr.apra ドメインの PTR レコードに対する問い合わせ)。 3. もし af が AF_INET6 なら、与えられた IPv6 アドレスに対する名前を検索 する(例えば ip6.int と ip6.arpa ドメインの PTRレコードに対する問い 合わせ)。 4. もし関数が成功を返すときは、返される hostent 構造体に一つだけ 含まれるアドレスは、この関数への引数としてわたされたアドレスファミリ と同一のアドレスファミリを伴う、最初の引数としてとして渡された アドレスのコピーである。 リストした4つ全てのステップは、順番に実行される。IPv6の16進数アドレス "::" と "::1" はIPv4互換IPv6アドレスとして扱われてはならならず、もし、アドレスが "::" なら、HOST_NOT_FOUNDが返され、このアドレスの問い合わせは実行されない ことに注意せよ。 6.7節のマクロ IN6_IS_ADDR_V4COMPAT もまた "::" と "::1" に対して失敗を 返さなければならない。 6.3 getipnodebynameおよびgetipnodebyaddr用メモリ解放 hostent構造体は今ある定義から変更されていない。この構造体とこの構造体に よって示される情報は、getipnodebyname と getipnodebyaddr によって動的に 確保される。次の関数はこのメモリを解放する: #include void freehostent(struct hostent *ptr); draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 22] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 6.4 プロトコル非依存のノード名からサービス名変換 ノード名-アドレス変換は、電気電子技術者協会 (IEEE) POSIX 1003.1g (プロトコル非依存インターフェイス) ドラフト仕様書 [3] で選ばれた getaddrinfo() 関数を使ったプロトコル非依存の方法で行なわれる。 この関数についての公式の仕様が、次の付加的な要求を伴い、最新の POSIX 標準となるだろう: #include #include int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *ai); struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST, .. */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 または IPv4又はIPv6には IPPROTO_xxx */ size_t ai_addrlen; /* ai_addr の長さ */ char *ai_canonname; /* nodename の規準名 */ struct sockaddr *ai_addr; /* バイナリアドレス */ struct addrinfo *ai_next; /* リンクリスト中の次構造体 */ }; getaddrinfo() 関数はサービス位置(例えばホスト名)かつ/またサービス名を 変換し、ソケットアドレスと、与えられたサービスに位置付けられたソケットを 生成するために使われる関係する情報の組を返す。 nodename と servname 引き数は、ヌルで終端する文字列か NULL への ポインタである。これら二つの引き数のうち一つか両方かは、非 NULL ポインタでなければならない。 有効な名前の形式はプロトコルファミリ(群)依存である。もし特定の ファミリが与えられず、その名前が複数の対応済ファミリとして有効に 解釈できるかもしれない、実装はすべての対応済について解決を試み、 成功したすべての結果が返されるだろう。 もし nodename 引数が非ヌルなら、それは説明的名前かアドレス文字列かも しれない。もし示されたアドレスファミリが AF_INET または AF_UNSPEC なら、 許されうる nodename 引数は inet_pton() と同様に定義されるようになる。 もし示されたアドレスファミリが AF_INET6 または AF_UNSPEC なら、許され うる nodename 引数は [5] で定義されるように指定される。 nodename がヌルでなければ、要求されたサービス位置が nodename で 決まる; さもなくば、サービス位置は呼出し者近接である。 もし sercname がヌルなら、呼出は、与えられた nodename に対するネット ワークレベルアドレスを返す。servname がヌルでなければ、それは要求された draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 23] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 サービスを特定するユル終端文字列である。これはそのファミリやファミリ 群に適する説明的名前又は数的表現のどちらの可能性もある。もし与えられた アドレスファミリが AF_INET, AF_INET6 または AF_UNSPEC であれ service は 十進ポート番号を示す文字列として示されるかもしれない。 もし hints 引数がヌルでなければ、オプションを提供し、返却情報を特定の ソケットタイプ、アドレスファミリ、かつ/またプロトコルに制限するような 操作を命じることのできる入力値を含む構造体を指す。この hints 構造体の ai_flags, ai_family, ai_socktype そして ai_protocol 以外のメンバは、 ゼロもしくは NULL ポインタでなければならない。ai_family の AF_UNSPEC の 値は、呼び出し元がどのようなプロトコルファミリも受け入れることを意味する。 ai_socktype の値が 0 というのは、呼び出し元がどのようなソケットタイプも 受け入れることを意味する。ai_protocol の値が 0 というのは、呼び出し元が どのようなプロトコルも受け入れることを意味する。もし hints がヌル ポインタなら、その挙動は ai_flags, ai_soctype および ai_protocol フィールドに 0 値は含まれ、ai_family に AF_UNSPEC が含まれている構造を 指しているかのように動作しなければならない。 注意: 1. もし呼び出し元が TCP だけ処理して UDP を処理しないなら、 getaddrinfo() が呼ばれる時 hints 構造体の ai_socktype メンバは、 SOCK_STREAM に設定されるべきである。 2. 呼び出し元が IPv4 だけ処理してIPv6 を処理しないなら、hints 構造体の ai_family メンバは、getaddrinfo()が呼ばれる時、 PF_INET に設定されるべきである。 hintsパラメタの指すai_flagsフィールドは 0 値 またはひとつまたは それ以上の AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST, AI_NUMERICSERV, AI_V4MAPPED, AI_ALL, AI_ADDRCONFIG の値のビット論理和でなければ ならない。 hints 構造体の ai_flags メンバの AI_PASSIVE フラグはソケットアドレス 構造体の IP アドレス部をどのように埋めるかを規定する。もし AI_PASSIVE フラグが指定されていたら、返されるアドレス情報は特定のサービスに対する 入力コネクションを受け付けるようなソケットの結合(つまり、bind() の 呼出)に適するものでなくてはならない。この場合、もし nodename 引数が ヌルなら、ソケットアドレス構造体の IP アドレスの部分は、IPv4 アドレス なら INADDR_ANY、IPv6アドレスなら IN6ADDR_ANY_INIT がセットされるだろう。 もし AI_PASSIVE ビットが立っていなければ、返されるソケットアドレス 構造体は connect() (コネクション指向プロトコルむけ) か、connect()、 sendto()、sendmsg() のどれか (コネクションレスプロトコルむけ) に 適切なものでなければならない。この場合、 nodename 引数がヌルなら、 ソケットアドレス構造体の IP アドレスの部分は、ループバックアドレスと なるだろう。このフラグは nodename 引数がヌルでなければ無視される。 もし AI_CANONNAME フラグが指定され、nodename 引数がヌルでなければ、 この関数は(たとえば nodename が別名だったり短縮命名であったり する場合、その) nodename に関係する規準名を決定しようとする。 もし AI_NUMERICHOST フラグが指定されたら、非ヌル nodename 引数は 数的ホストアドレス文字列でなければならない。さもなくば、[EAI_NONAME] draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 24] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 というエラーが返される。このフラグにより、実行されようとするいかなる 名前解決サービス(例えば DNS)の実行を避けられる。 もし AI_NUMERICSERV フラグが指定されたら、非ヌル servname 文字列は 数的ポート番号でなければならない。そうれなければ、[EAI_NONAME] エラーが 返される。このフラグで(例えば NIS+といった)あらゆる名前解決サービスが 実行されることを防げる。 もし AF_INET6 の ai_family とともに AI_V4MAPPED フラグが指定されたら、 読み出し側はIPv4射影IPv6アドレスを受け付けるだろう。これは、 もし AAAA も A6 レコードも見つからなかったら、A レコードに対する 問い合わせが行われ、いかなる答えも IPv4射影IPv6アドレスとして返される (そして ai_addrlen は 16 になるだろう)。AI_V4MAPPED フラグは ai_family が AF_INET6 に一致しなければ無視される。 AI_ALL フラグは AI_V4MAPPED とともに使われ、AF_INET6 の ai_family で のみ使われる。もし AI_ALL が AI_V4MAPPED フラグと論理和されると、 呼び出し側は、IPv6アドレスおよびIPv4写像IPv6アドレスの全てを受け 付けるだろう。AAAA/A6 レコードに対する問い合わせが最初に行われ、 もし成功すれば IPv6 アドレスが返される。次にAレコードに対する問い 合わせが行われ、見つかれば、IPv4射影IPv6アドレスが返される(ai_addrlen は16だろう)。このフラグは ai_family が AF_INET6 に一致しなければ 無視される。 注意: もし ai_family が与えられなければ (AF_UNSPEC), AI_V4MAPPED と AI_ALL は AF_INET6 がサポートされている場合にのみ用いられる。 もし AI_ADDRCONFIG フラグが指定されたら、AAAA または A6 レコードに 対する問い合わせはそのノードが最低1つの IPv6 ソースアドレスを持っている 場合にのみ行われるべきであり、A レコードに対する問い合わせは、最低 1つの IPv4 ソースアドレスが設定されている場合にのみ行われるべきである。 この場合、ループバックアドレスは有効な設定済みソースアドレスとは みなされない。 hints 引数の指す ai_socktype フィールドはサービスのためのソケット型を 指定する。もし、ソケット型が指定されず(例えばゼロ値)、サービス名が 複数の対応したソケット型として有効に解釈できそうなら、実装は全ての 対応したソケット型に対するサービス名を解決しようとし、すべての 成功した結果が返されるだろう。非ゼロソケット型は、返却される情報を、 特定のソケット型の値に限るだろう。 freeaddrinfo() は getaddrinfo() から返された1つまたはそれ以上の addrinfo 構造体を、それらの構造体に関連したいかなる記憶域を含んで、 開放する。もし構造体の ai_next フィールドが非ヌルであれば、リストの 全ての構造が開放される。getaddrinfo() から返されたもとの addrinfo リストの任意の部分リストを開放に対応しなければならない。 getaddrinfo() および freeaddrinfo() は thread-safe でなければならない。 getaddrfinfo() における戻り値ゼロは、成功裏に完了したことを示し、 戻り値の非ゼロは失敗を示す。 getaddrinfo() が成功すると、res は addrinfo 構造体の接続リスト draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 25] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 を参照し、それぞれがソケットアドレスとそのソケットアドレスでソケット 作るのに使われる情報を特定する。リストは少なくとも1つの addrinfo 構造体を含まなければならない。それぞれの ai_next はリスト中の次 構造体へのポインタか、あるいは、リストの最後の構造体ではヌルポインタで ある。リスト中のそれぞれの構造体には、socket() 関数に使うう値、および connect() 関数の呼び出し、または、もし AI_PASSIVE フラグが指定されて いたらbind() 関数の呼び出しに使われるソケットアドレス構造体を含む。 ai_family, ai_socktype, ai_protocol フィールドは返されたソケット アドレスに適切なソケットを生成するための socket() 関数への引数として 使える。ai_addr と ai_addrlen は、そのようなソケットに対して、 AI_PASSIVE フラグに従って connect() や bind() への引数として使える。 もし nodename が非ヌルで、AI_CANONNAME フラグで要求されたら、最初の 構造体の ai_canonname は、入力 nodename に関係する規準名を含むヌル 終端文字列を指す; もし規準名がわからないときは、引数の nodename または同様の内容の文字列を含む。返却された構造体の ai_flags の 内容は未定義である。 引数により明示的に埋められない getaddrinfo() から返される全ての ソケットアドレス構造体のフィールド(例えば sin6_flow_info) は 0 に セットされなければならない。 注意: これは、ソケットアドレス構造体の比較を容易にする。 エラー戻り値は: [EAI_AGAIN] 現在 name を解決することができなかった。将来の試行は 成功するかもしれない。 [EAI_BADFLAGS] フラグパラメタが不正な値だった [EAI_FAIL] name を解決中に回復不可能なエラーが発生した。 [EAI_FAMILY] アドレスファミリが不明でだった。 [EAI_MEMORY] 返り値のための格納場所を確保しようとした時にメモリ確保に 失敗した。 [EAI_NONAME] 与えられたパラメタに対して、name が解決できなかった。 nodename も servname も渡されなかった。少なくともこれらの 一つが渡されなければならない。 [EAI_SERVICE] 渡された service は示されたソケットタイプに対して認識 できなかった。 [EAI_SOCKTYPE] The intended socket type was not recognized. [EAI_SYSTEM] システムエラーが発生した。エラーコードは errno でみつけ られる。 #include draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 26] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 #include char *gai_strerror(int ecode); 引数は、前に定義された EAI_xxx のうちの一つで、戻り値は、エラーが記述 されている文字列を指し示している。もし、引数が EAI_xxx のうちの一つで ないなら、関数は未知のエラーを示す文字列を指すポインタを返す。 6.5 ソケットアドレス構造体からノード名とサービス名 この関数の公式な仕様が getaddrinfo() の最終POSIX標準の更新になり、 それはこの関数を含むだろう。 #include #include int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); getnameinfo() はソケットアドレスとノード名とサービス位置に変換し、 それらのすべては getaddrinfo() に従って定義されている。 sa 引数は転換されるソケットアドレス構造体を指すポインタである。 もし node が非ヌルで nodelen が非ゼロであれば、node 引数はノード名を 受け取る nodelen 文字までを格納できるバッファを指す。もし、node 引数が NULL または nodelen がゼロなら、ノード名は返されない。ノード名が わからなければ、その名前の代わりにノードアドレスの数的形式が返される。 もし sa 引数が IPv6 アドレスなら、返されるアドレスは [5] で定義される ような形式だろう。 もし service が非ヌルで servicelen が非ゼロであれば、service 引数は サービス名を受け取る servicelen 文字までを格納できるバッファを指す。 もし、service 引数がNULL または servicelen がゼロなら、サービス名は 返されない。サービス名がわからなければ、その名前の代わりにサービス アドレスの数的形式(例えばそのポート番号)が返される。 node, service 引数の両方が NULL であることはできない。 flags 引数はこの関数の既定の挙動を変更するフラグである。既定では、完全 修飾ドメイン名(FQDN)が返されるが、 - もしフラグビット NI_NOFQDN がセットされていたら、ローカルなホストに 対しては、FQDNのノード名部分だけが返される。 - もしフラグビット NI_NUMERICHOST がセットされていたら、いかなる環境に おいても、その名前のかわりにホストのアドレスの数的形式が返される。 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 27] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 - もしフラグビット NI_NAMEREQD がセットされていたら、ホストの名前が判明 しなかったら、エラーが返される。 - もしフラグビット NI_NUMERICSERV がセットされていたら、いかなる環境に おいても、サービスアドレスの名前の代わりに数的形式(例えば、そのポート 番号)が返される。 - もしフラグビット NU_NUMERICSCOPE がセットされていたら、スコープ識別子の 名前の代わりにその数的形式(例えばインタフェース番号)が返される。この フラグは sa 引数が IPv6 アドレスでないときは無視される。 - もしフラグビット NI_DGRAM がセットされていたら、それはサービスがデータ グラムサービス(SOCK_DGRAM)であることを示す。デフォルトの挙動はサービスは ストリーム(SOCK_STREAM)であるとみなすことである。 注意: 1. 3つのNI_NUMERICxxx フラグは、多くのコマンドで用意されている -n フラグを 支援するために必要とされる。 2. NI_DGRAM は、UDP と TCP で別のサービスを表現する新しい AF_INET/AF_INET6 ポート番号(例えば 512-514)で必要とされる。 関数 getnameinfo() はスレッド安全でなければならない。 getnameinfo() の戻り値ゼロは成功裏の終了、戻り値非ゼロは失敗を示す。 成功裏の終了では、関数 getnameinfo() はノードとサービス名前を、必要とされて いれば、与えられたバッファに返却する。返却される名前は常にヌル終端文字列 である。 エラー戻り値: [EAI_AGAIN] name が現時点では解決できなかった。将来の試行では 成功するかも入れない。 [EAI_BADFLAGS] flag が不正な値だった。 [EAI_FAIL] 回復不可能なエラーが発生した。 [EAI_FAMILY] アドレスファミリが不明であるか、アドレス長さが与えられた ファミリに対して無効であった。 [EAI_MEMORY] メモリ確保の失敗。 [EAI_NONAME] 与えられたパラメタに対して name が解決できなかった。 NI_NAMEREQD がセットされていて、ホストの名前が わからなかった、または、nodename も servname も ヌルだった。 [EAI_SYSTEM] システムエラーが発生した。エラーコードは errno でみつけ られる。 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 28] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 6.6 アドレス変換関数 2つの関数 inet_addr() と inet_ntoa() が IPv4 アドレスをバイナリと テキスト形式との間で変換する。IPv6 アプリケーションも同様の関数を 必要である。次の2つの関数は IPv6 と IPv4 アドレスを変換する: #include #include int inet_pton(int af, const char *src, void *dst); const char *inet_ntop(int af, const void *src, char *dst, size_t size); inet_pton() 関数は、アドレスを標準テキスト形式から、数値のバイナリ形式 に変換する。af 引数はアドレスファミリを指定する。現在では AF_INET と AF_INET6 アドレスファミリがサポートされている。src 引数は、通過させる 文字列を指し示している。dst 引数は、関数が数字のアドレスを格納するための バッファを指し示している。アドレスはネットワークバイトオーダで返される。 inet_pton() は変換に成功すれば 1 を返し、入力が正しい IPv4 ドット表記の 文字列か正しい IPv6 アドレス文字列でなかった場合は 0 を返す。また af 引数が未知のものなら EAFNOSUPPORT を errno にセットし -1 を返す。これを コールしたアプリケーションは、dst によって参照されるバッファが数字の アドレスを保持するのに十分な大きさ (AF_INET なら4バイト、AF_INET6 なら 16 バイト) であることを保証しなければならない。 もし af 引数が AF_INET なら、関数は、標準の IPv4 ドット表記の形式の 文字列を受け入れる: ddd.ddd.ddd.ddd ここで ddd は、一つの3桁の10進数で 0 から 255 までである。今ある多くの 実装の inet_addr() と inet_aton() 関数は、8進数や16進数、4つの数字より 少ないものといった標準でない入力を受け入れることに注意せよ。inet_pton() はこれらの形式を受け入れない。 もし af 引数が AF_INET6 なら、関数は アドレスアーキテクチャ仕様書[2] の 2.2 節で定義された IPv6 の標準テキスト形式のうちの一つの文字列を 受け入れる。 inet_ntop() 関数は、数値のアドレスをその状態にふさわしいテキスト文字列 に変換する。af 引数はアドレスファミリを指定する。これは AF_INET か AF_INET6 のどちらかを取ることができる。src 引数は、af 引数が AF_INET の時は IPv4 アドレスを、af 引数が AF_INET6 の時は IPv6 アドレスを保持 するアドレスを指し示し、あどれすネットワークバイトオーダでなければならない。 dst 引数は、関数が結果のテキスト文字列を格納するであろうバッファを指し 示す。size 引数は、このバッファのサイズを指定する。アプリケーションは、 NULL でない dst 引数を指定しなければならない。IPv6アドレスに対しては、 バッファは少なくとも 46 オクテットでなければならない。IPv4 アドレスに 対しては、バッファは少なくとも 16 オクテットでなければならない。文字列 形式の IPv4 や IPv6 アドレスを格納するのにふさわしいサイズのバッファを アプリケーションが簡単に宣言できるように、次の二つの定数が で定義された。 #define INET_ADDRSTRLEN 16 #define INET6_ADDRSTRLEN 46 draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 29] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 inet_ntop() 関数は、変換に成功すれば、テキスト文字列を含んだバッファへ のポインタを返し、それ以外では NULL を返す。失敗した場合は、af 引数が不正 なら errno に EAFNOSUPPORT が、結果のバッファサイズが不十分なら ENOSPEC がセットされる。 6.7 アドレス試験マクロ 以下のマクロが特殊な IPv6 アドレスの試験に使うことができる。 #include int IN6_IS_ADDR_UNSPECIFIED (const struct in6_addr *); int IN6_IS_ADDR_LOOPBACK (const struct in6_addr *); int IN6_IS_ADDR_MULTICAST (const struct in6_addr *); int IN6_IS_ADDR_LINKLOCAL (const struct in6_addr *); int IN6_IS_ADDR_SITELOCAL (const struct in6_addr *); int IN6_IS_ADDR_V4MAPPED (const struct in6_addr *); int IN6_IS_ADDR_V4COMPAT (const struct in6_addr *); int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr *); int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr *); int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr *); int IN6_IS_ADDR_MC_ORGLOCAL (const struct in6_addr *); int IN6_IS_ADDR_MC_GLOBAL (const struct in6_addr *); 最初の7つのマクロは、アドレスが指定されたタイプなら真を返し、そうで なければ偽を返す。最後の5つは、マルチキャストアドレスのスコープをテストし、 アドレスが指定されたスコープのマルチキャストアドレスなら真、アドレスが マルチキャストアドレスでないか指定されたスコープでないなら偽を返す。 IN6_IS_ADDR_LINKLOCAL と IN6_IS_ADDR_SITELOCAL は、二つのローカルで 使用される IPv6 ユニキャストアドレスである時のみ真を返すことに注意せよ。 これら二つのマクロは、リンクローカルスコープかサイトローカルスコープの どちらかの IPv6 マルチキャストアドレスには真を返さない。 7. 新しい定義の概要 次のリストは、この文書で議論された定数、構造体、外部定義をヘッダごとに ソートして要約したものである。 IF_NAMESIZE struct if_nameindex{}; AI_ADDRCONFIG AI_DEFAULT AI_ALL AI_CANONNAME AI_NUMERICHOST AI_PASSIVE AI_V4MAPPED EAI_ADDRFAMILY EAI_AGAIN EAI_BADFLAGS EAI_FAIL EAI_FAMILY draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 30] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 EAI_MEMORY EAI_NODATA EAI_NONAME EAI_SERVICE EAI_SOCKTYPE EAI_SYSTEM NI_DGRAM NI_MAXHOST NI_MAXSERV NI_NAMEREQD NI_NOFQDN NI_NUMERICHOST NI_NUMERICSERV struct addrinfo{}; IN6ADDR_ANY_INIT IN6ADDR_LOOPBACK_INIT INET6_ADDRSTRLEN INET_ADDRSTRLEN IPPROTO_IPV6 IPV6_JOIN_GROUP IPV6_LEAVE_GROUP IPV6_MULTICAST_HOPS IPV6_MULTICAST_IF IPV6_MULTICAST_LOOP IPV6_UNICAST_HOPS SIN6_LEN extern const struct in6_addr in6addr_any; extern const struct in6_addr in6addr_loopback; struct in6_addr{}; struct ipv6_mreq{}; struct sockaddr_in6{}; AF_INET6 PF_INET6 struct sockaddr_storage; 次のリストは、この文書で議論された関数やマクロのプロトタイプをヘッダ ごとにソートして要約したものである。 int inet_pton(int, const char *, void *); const char *inet_ntop(int, const void *, char *, size_t); char *if_indextoname(unsigned int, char *); unsigned int if_nametoindex(const char *); void if_freenameindex(struct if_nameindex *); struct if_nameindex *if_nameindex(void); int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); int getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int); void freeaddrinfo(struct addrinfo *); char *gai_strerror(int); struct hostent *getipnodebyname(const char *, int, int, int *); draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 31] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 struct hostent *getipnodebyaddr(const void *, size_t, int, int *); void freehostent(struct hostent *); int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *); int IN6_IS_ADDR_LOOPBACK(const struct in6_addr *); int IN6_IS_ADDR_MC_GLOBAL(const struct in6_addr *); int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr *); int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr *); int IN6_IS_ADDR_MC_ORGLOCAL(const struct in6_addr *); int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr *); int IN6_IS_ADDR_MULTICAST(const struct in6_addr *); int IN6_IS_ADDR_SITELOCAL(const struct in6_addr *); int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *); int IN6_IS_ADDR_V4COMPAT(const struct in6_addr *); int IN6_IS_ADDR_V4MAPPED(const struct in6_addr *); 8. セキュリティ考察 IPv6 はいくつかの新しいセキュリティ機構を用意していて、その多くは アプリケーションからアクセス出来る必要がある。IPv6 セキュリティを サポートするためのソケットインターフェイスの拡張について詳述している もう一方のメモが執筆中である。 9. 西暦2000年についての考察 日付の使用に関して、西暦2000年問題については、このドラフトに問題はない。 Changes made rfc2553 to rfc2553bis-00: 1. 移植性の節3.10をXNS 5.2に従って更新。 2. getaddrinfo(), getnameinfo() を XNS 5.2 に従って更新。 3. 進行中の Scope Architecture, Scope Routing, および Extension Format for Scoped Addresses への参照を追加。 4. NI_NUMERICSCOPE を getnameinfo() に追加。 5. Added qualification to getipnodebyname/addr() functions that they will not work as is with scope identifiers with IPv6, and getaddrinfo/getnameinfo should be used. 6. Added DNS A6 record notation to AAAA and added ip6.arpa as new PTR record domain. draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 32] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 謝辞 この文書に対すして提案とフィードバックを寄せてくれた、次の諸氏を含む 多くの人々に感謝する: Werner Almesberger, Ran Atkinson, Fred Baker, Dave Borman, Andrew Cherenson, Alex Conta, Alan Cox, Steve Deering, Richard Draves, Francis Dupont, Robert Elz, Brian Haberman, 萩野 itojun 純一郎, Marc Hasson, Tom Herbert, Bob Hinden, Wan-Yen Hsu, Christian Huitema, Koji Imada, Markus Jork, Ron Lee, Alan Lloyd, Charles Lynn, Dan McDonald, Dave Mitton, Thomas Narten, Josh Osborne, Craig Partridge, Jean-Luc Richier, Erik Scoredos, Keith Sklower, 神明 達也, Matt Thomas, Harvey Thompson, Dean D. Throop, Karen Tracey, Glenn Trewitt, Paul Vixie, David Waitzman, Carl Williams, 山本和彦, Vlad Yasevich, and Brian Zill getaddrinfo() と getnameinfo() 関数は、Keith Sklower による、先のインター ネットドラフトから採用された。ドラフトに記述されたように、William Durst, Steven Wise, Michael Karels, および Eric Allman が、プロトコル非依存な 名前関数について数多くの有益な議論を提供し、Keith Sklower のもとの 提案の初期の版について再考した。Eric Allman が getaddrinfo() の最初の プロタイプを実装した。 名前とサービスの組の指定がプロトコル独立なサービス接続に十分である、 という知見は、X/Open の "Uniform Network Interface" に対する Marshall Rose による提案によってなされた。 Craig Metz, Jack McCann, Erik Nordmark, Tim Hartrick, および Mukesh Kacker がこの文書に多大な貢献をした。Ramesh Govindan はこのメモの旧版について 数多くの貢献をし、共同執筆した。 参考文献 [1] S. Deering, R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460 Draft Standard. [2] R. Hinden, S. Deering, "IP Version 6 Addressing Architecture", RFC 2373, July 1998 Draft Standard. [3] IEEE, "Protocol Independent Interfaces", IEEE Std 1003.1g, DRAFT 6.6, March 1997. [4] W. Stevens, M. Thomas, "Advanced Sockets API for IPv6", RFC 2292, February 1998. [5] T. Jinmei, A. Onoe, "An Extension of Format for IPv6 Scoped Addresses", Work-in-Progress. [6] S. Deering, B. Haberman, B. Zill "IP Version 6 Scoped Address Architecture", Work-in-Progress. [7] B. Haberman " Routing of Scoped Addresses in the Internet Protocol Version 6 (IPv6)", Work-in-Progress. draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 33] INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-00.txt May 2000 Authors' Addresses Robert E. Gilligan FreeGate Corporation 1208 E. Arques Ave. Sunnyvale, CA 94086 Phone: +1 408 617 1004 Email: gilligan@freegate.net Susan Thomson Bell Communications Research MRE 2P-343, 445 South Street Morristown, NJ 07960 Telephone: +1 201 829 4514 Email: set@thumper.bellcore.com Jim Bound Compaq Computer Corporation 110 Spitbrook Road ZK3-3/U14 Nashua, NH 03062-2698 Phone: +1 603 884 0400 Email: bound@zk3.dec.com W. Richard Stevens 1202 E. Paseo del Zorro Tucson, AZ 85718-2826 Phone: +1 520 297 9416 Email: rstevens@kohala.com draft-ietf-ipngwg-2553bis-00.txt Expires November 2000 [Page 34] 原訳: 補訳: 吉藤英明