IPV6(7) | Linux Programmer's Manual | IPV6(7) |
ipv6 - Linux IPv6 プロトコルの実装
#include <sys/socket.h>
#include <netinet/in.h>
tcp6_socket = socket(AF_INET6, SOCK_STREAM, 0);
raw6_socket = socket(AF_INET6, SOCK_RAW,
protocol);
udp6_socket = socket(AF_INET6, SOCK_DGRAM,
protocol);
Linux 2.2 では、Internet Protocol, version 6 を オプションとして実装している。 この man ページでは、Linux カーネルと glibc 2.1 での実装に基づいて、 IPv6 の基本的な API を解説する。 インターフェースは BSD ソケットインターフェースをもとにしている。 socket(7) を参照。
IPv6 API は、 IPv4 API (ip(7) 参照) とほぼ互換になることを目指している。 この man ページでは相違点のみを解説する。
AF_INET6 ソケットを何らかのプロセスにバインドするには、 ローカルアドレスを in6_addr 型の変数 in6addr_any からコピーしてくる必要がある。 static な初期値 IN6ADDR_ANY_INIT も用いることができ、これは定数式に展開される。 これらの両者はネットワークバイトオーダーである。
IPv6 のループバックアドレス (::1) は global 変数 in6addr_loopback から取得できる。初期化には IN6ADDR_LOOPBACK_INIT を用いるべきである。
v4-mapped-on-v6 アドレス型を用いることで、 IPv4 接続も v6 API で扱うことができる。 こうすれば、プログラムは v6 の API をサポートするだけで、 両方のプロトコルをサポートできる。 v4-mapped-on-v6 アドレス型は C ライブラリ内部のアドレスを 扱う関数によって透過的に処理される。
IPv4 と IPv6 はローカルポート空間を共有する。 IPv4 の接続 (またはパケット) を IPv6 ソケットが取得すると、 発信元アドレスが v6 にマップされ、その接続 (パケット) も v6 にマップされる。
struct sockaddr_in6 { sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* port number */ uint32_t sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr; /* IPv6 address */ uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */ }; struct in6_addr { unsigned char s6_addr[16]; /* IPv6 address */ };
sin6_family は常に AF_INET6 に設定される。 sin6_port はプロトコルポートである (ip(7) の sin_port を参照)。 sin6_flowinfo は IPv6 のフロー指定子 (flow identifier) である。 sin6_addr は 128 ビットの IPv6 アドレスである。 sin6_scope_id は アドレスのスコープに依存した ID である (これは Linux 2.4 で導入された)。 Linux の場合は、これはリンクローカルアドレスでのみサポートされている。 この場合 sin6_scope_id にはインターフェースのインデックスが含まれる ことになる (netdevice(7) を参照)。
IPv6 は何種類かのアドレスタイプをサポートしている。 単一のホストをアドレスするための unicast、 ホストのグループをアドレスするための multicast、 ホストのグループ中で最も近くにいるものをアドレスするための anycast (これは Linux では実装されていない)、 IPv4 ホストをアドレスするための IPv4-on-IPv6。 他にも予約済みのアドレスタイプがある。
IPv6 でのアドレス表記は 4 桁の 16 進数 8 個からなり、 ':' は区切り文字はで、"::" は 0 ビットの文字列を表す。 特殊なアドレスとして、ループバックを表す ::1、 IPv4-mapped-on-IPv6 を表す ::FFFF::<IPv4 アドレス> がある。
IPv6 のポート空間は IPv4 と共有されている。
IPv6 はプロトコル固有のソケットオプションをいくつかサポートしている。 これらは setsockopt(2) で設定でき、 getsockopt(2) で取得できる。 IPv6 のソケットオプションレベルは IPPROTO_IPV6 である。 ブール整数のフラグは、0 が偽であり、それ以外は真である。
Linux 2.4 では 64 ビットのホストに対して sockaddr_in6 のバイナリ互換性が保たれていない。 in6_addr のアラインメントが変更され、また sin6_scope_id フィールドが新たに追加されたからである。 カーネルインターフェースの互換性は保たれているが、 sockaddr_in6 や in6_addr を他の構造体に含んでいるようなプログラムでは 保たれないかもしれない。 これは i386 のような 32 ビットのホストでは問題にならない。
sin6_flowinfo フィールドは Linux 2.4 で登場した。 これが渡されたアドレス長に含まれていると、 カーネルに透過的に渡され、読まれる。 より長いアドレスバッファーを渡し、 そして送信アドレスの長さをチェックするようなプログラムは うまく動かないかもしれない。
sockaddr_in6 構造体はジェネリックな sockaddr よりも大きい。 すべてのアドレスタイプが struct sockaddr の中に安全に納められると仮定しているプログラムは、代わりに struct sockaddr_storage を用いるように変更する必要がある。
SOL_IP, SOL_IPV6, SOL_ICMPV6, and other SOL_* socket options are nonportable variants of IPPROTO_*. See also ip(7).
IPv6 拡張 API は、現在まだ RFC 2292 を完全には実装していない。 2.2 カーネルは受信オプションをほぼ完全にサポートサポートしているが、 glibc2.1 には IPv6 オプションを生成するマクロが存在していない。
EH および AH ヘッダー での IPSec のサポートは存在しない。
フローラベル管理はまだ完全でなく、ここにも記述されていない。
この man ページはまだ完成していない。
cmsg(3), ip(7)
RFC 2553: IPv6 BASIC API; Linux はこの RFC に準拠するようにしている。 RFC 2460: IPv6 specification.
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。
2020-12-21 | Linux |