IPv4 レイヤは、扱っているソケットで IP_HDRINCL ソケットオプションが有効になっていなければ、 パケットを送信するときに IP ヘッダーを生成する。 IP_HDRINCL オプションが有効になっているときは、パケットには IP ヘッダーが含まれていなければならない。 受信時には、 IP ヘッダーは常にパケットに含まれている。
In order to create a raw socket, a process must have the CAP_NET_RAW capability in the user namespace that governs its network namespace.
All packets or errors matching the protocol number specified for the raw socket are passed to this socket. For a list of the allowed protocols, see the IANA list of assigned protocol numbers at and getprotobyname(3).
IPPROTO_RAW のプロトコルは暗黙のうちに IP_HDRINCL を有効にするので、 渡されたヘッダーで指定された、あらゆる IP プロトコルを送信できる。 IPPROTO_RAW 経由でのあらゆる IP プロトコルの受信は、 raw ソケットを用いては行えない。
IP ヘッダーフィールド。 IP_HDRINCL によって送信時に変更される。 | |
IP チェックサム | 常に変更される |
ソースアドレス | 元の値が 0 の時に変更される |
パケット ID | 元の値が 0 の時に変更される |
全体の長さ | 常に変更される |
IP_HERINCL が指定されていて、 IP ヘッダーに 0 でない送信先アドレスが記入されていた場合は、 その送信先アドレスがパケットの経路を決めるのに用いられる。 MSG_DONTROUTE が指定されている時には、 送信先アドレスはローカルなインターフェースを参照するものでなければならない。 さもないと、ルーティングテーブルの参照はいずれにせよ行われるが、 ゲートウェイが必要な経路は無視される。
IP_HDRINCL がセットされていなければ、 raw ソケットの IP ヘッダーオプションを setsockopt(2) を用いて設定することができる。詳細な情報は ip(7) を見よ。
Linux 2.2 以降では、 IP ヘッダーの全てのフィールドとオプションとを IP ソケットオプションによって設定できる。したがって raw ソケットが必要になるのは、新しいプロトコルを設計する場合か、 ユーザーインターフェースを持たないプロトコル (ICMP など) を扱う場合に 限られる。
パケットは、受信されるとまずプロトコルにバインドしている raw ソケットに渡され、 その後で他のプロトコルハンドラー (カーネルのプロトコルモジュールなど) に渡される。
さらに、データグラムソケットに使える全ての ip(7) SOL_IP ソケットオプションがサポートされている。
Linux 2.0 では SO_BSDCOMPAT ソケットオプションをセットすると、 BSD の raw ソケットにあるバグに互換性を取ることができた --- Linux 2.2 以降では、このオプションはもはや効力を持たない。
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 を用いれば同様のことが実現できる。
IP_HDRINCL オプションがセットされているとデータグラムはフラグメント化されず、 インターフェースの MTU の大きさに制限される。
送信用の IP プロトコルの設定を sin_port にしておく機能は Linux 2.2 から使えなくなった。 ソケットにバインドされているプロトコルか、最初の socket(2) コールによって指定されたプロトコルが常に用いられる。
Path MTU discovery に関しては RFC 1191 を参照。 IP プロトコルに関しては RFC 791 とインクルードファイル <linux/ip.h> を参照。