other versions
other languages
other sections
RAW(7) | Linux Programmer's Manual | RAW(7) |
名前¶
raw - Linux の IPv4 raw ソケット書式¶
#include <sys/socket.h>説明¶
raw ソケットを使うと、新しい IPv4 プロトコルをユーザ空間で 実装できるようになる。 raw ソケットは、リンクレベルヘッダを 含まない raw データグラムの送受信ができる。 IPv4 レイヤは、扱っているソケットで IP_HDRINCL ソケットオプションが有効になっていなければ、 パケットを送信するときに IP ヘッダを生成する。 IP_HDRINCL オプションが有効になっているときは、パケットには IP ヘッダが含まれていなければならない。 受信時には、 IP ヘッダは常にパケットに含まれている。 実効ユーザー ID が 0 のプロセスか、 CAP_NET_RAW 権限を持つプロセスだけが raw ソケットをオープンすることができる。 この raw ソケットに指定された protocol 番号にマッチする全てのパケットとエラーとが、このソケットに渡される。 許可されているプロトコルのリストは RFC 1700 の割り当て番号と getprotobyname(3) を見よ。 IPPROTO_RAW のプロトコルは暗黙のうちに IP_HDRINCL を有効にするので、 渡されたヘッダで指定された、あらゆる IP プロトコルを送信できる。 IPPROTO_RAW 経由でのあらゆる IP プロトコルの受信は、 raw ソケットを用いては行えない。IP ヘッダフィールド。 IP_HDRINCL によって送信時に変更される。 | |
IP チェックサム | 常に変更される。 |
ソースアドレス | 元の値が 0 の時に変更される。 |
パケット ID | 元の値が 0 の時に変更される。 |
全体の長さ | 常に埋められる。 |
アドレスのフォーマット¶
raw ソケットは標準の sockaddr_in アドレス構造体を用いる。定義は ip(7) でなされている。 sin_port フィールドを IP プロトコル番号の指定に用いることができるが、 Linux 2.2 ではこれは送信時には無視され、常に 0 にされる (バグ の項を参照)。 受信パケットに対しては、 sin_port はそのパケットのプロトコルにセットされる。 用いることのできる IP プロトコルは、インクルードファイル <netinet/in.h> を見よ。ソケットオプション¶
raw ソケットのオプションは、 IPPROTO_RAW ファミリーフラグを与えて setsockopt(2) を呼べば設定でき、 getsockopt(2) を呼べば取得できる。- ICMP_FILTER
- IPPROTO_ICMP プロトコルにバインドされた raw ソケットのための特殊なフィルタを有効にする。 この値は ICMP メッセージのタイプそれぞれに対して、どれをフィルターアウト するかを表したビットセットである。デフォルトでは ICMP メッセージは全くフィルターしない。
エラー処理¶
ネットワークで生じたエラーがユーザに渡されるのは、 ソケットが接続済みの場合か IP_RECVERR フラグが有効になっている場合に限られる。 接続済みのソケットに対しては、 EMSGSIZE および EPROTO だけが渡される (互換性のため)。 IP_RECVERR を設定すると、全てのネットワークエラーがエラーキューに保存される。エラー¶
- EACCES
- ユーザーが broadcast フラグを設定していないソケットを用いて ブロードキャストアドレスに送信を行おうとした。
- EFAULT
- 不正なメモリアドレスが与えられた。
- EINVAL
- 引き数が不正。
- EMSGSIZE
- パケットが大きすぎる。 Path MTU Discoverry が有効になっている ( IP_MTU_DISCOVER ソケットフラグ) か、パケットのサイズが IPv4 で許されている パケットサイズの最大値 64KB を越えている。
- EOPNOTSUPP
- ソケット呼び出しに不正なフラグ ( MSG_OOB など) が渡された。
- EPERM
- ユーザーは raw ソケットをオープンする権限を持っていない。 実行ユーザー ID が 0 のプロセスか、 CAP_NET_RAW 属性を持つプロセスだけがこれを行うことができる。
- EPROTO
- パラメータの問題を報告する ICMP エラーを受け取った。
バージョン¶
IP_RECVERR と ICMP_FILTER は Linux 2.2 で登場した。これらは Linux での拡張であり、 移植性の必要なプログラムでは用いるべきでない。 Linux 2.0 では SO_BSDCOMPAT ソケットオプションをセットすると、 BSD の raw ソケットにあるバグに互換性を取ることができた — Linux 2.2 以降では、このオプションはもはや効力を持たない。注意¶
デフォルトでは、raw ソケットは Path MTU Discovery を行う。 つまり、カーネルは特定の宛先 IP アドレスの MTU (Maximum Transmission Unit; 最大転送単位) を記録し、raw パケットの書き込みが MTU を超えた場合 EMSGSIZE を返す。 EMSGSIZE を返された場合、アプリケーションはパケットサイズを小さくすべきである。 ソケットオプション IP_MTU_DISCOVER または /proc/sys/net/ipv4/ip_no_pmtu_disc ファイルを使って Path MTU Discovery を無効にすることもできる (詳細は ip(7) を参照)。 Path MTU Discovery を無効にした場合は、パケットサイズが インタフェースの MTU よりも大きいと raw ソケットはそのパケットを フラグメント化して送出する。 しかしながら、性能と信頼性の理由から Path MTU Discovery を 無効にするのは推奨できない。 bind(2) システムコールを用いると、 raw ソケットを 特定のローカルアドレスにバインドさせることができる。 このバインドがされていない場合は、指定した IP プロトコルの すべてのパケットが受信される。 さらに、 SO_BINDTODEVICE を用いれば raw ソケットを特定のネットワークデバイスに バインドさせることもできる。 socket(7) を見よ。 IPPROTO_RAW ソケットは送信専用である。もしどうしてもすべての IP パケットを 受信したい場合は、 packet(7) ソケットを ETH_P_IP プロトコルで用いること。 packet ソケットは raw ソケットのように IP フラグメントを再構成しないことに注意。 datagram ソケットに対するすべての ICMP パケットを受信したい場合は、 特定のソケットに対して IP_RECVERR を用いるほうが良い場合が多い。 ip(7) を見よ。 raw ソケットは、 Linux のすべての IP プロトコルを受信することができる。 ICMP や TCP のように、カーネル内部にプロトコルモジュールを持つような ものも可能である。この場合には、パケットはカーネルモジュールと raw ソケットの両方に渡される (raw ソケットが複数あればそれぞれに渡される)。 移植性の必要なプログラムではこの機能に依存するべきではない。 他の多くの BSD におけるソケットの実装ではこの点において制限がある。 Linux はユーザーから渡されたヘッダを決して変更しない (ただし IP_HDRINCL の説明にあるように、 0 をいくつか埋める場合を除く)。 これは他の多くの raw ソケットの実装では異なる。 一般に raw ソケットは移植性がないことが多いので、 移植性が必要なプログラムでは避けるべきである。 raw ソケットへの送信では、 IP プロトコルを sin_port から取得できなければならない。この機能は Linux 2.2 では使えなくなった。 IP_HDRINCL を用いれば同様のことが実現できる。バグ¶
透過プロクシ (transparent proxy) 拡張については記述していない。 IP_HDRINCL オプションがセットされているとデータグラムはフラグメント化されず、 インターフェースの MTU の大きさに制限される。 送信用の IP プロトコルの設定を sin_port にしておく機能は Linux 2.2 から使えなくなった。 ソケットにバインドされているプロトコルか、最初の socket(2) コールによって指定されたプロトコルが常に用いられる。関連項目¶
recvmsg(2), sendmsg(2), capabilities(7), ip(7), socket(7) Path MTU discovery に関しては RFC 1191 を参照。 IP プロトコルに関しては RFC 791 とインクルードファイル <linux/ip.h> を参照。この文書について¶
この man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2012-05-10 | Linux |