EN JA
IP(4)
IP(4) FreeBSD Kernel Interfaces Manual IP(4)

名称

ipインターネットプロトコル

書式

#include < sys/types.h>
#include < sys/socket.h>
#include < netinet/in.h>

int
socket( AF_INET, SOCK_RAW, proto);

解説

IP は、インターネットプロトコルファミリによって使用されるトランスポート層 (レイヤ) のプロトコルです。 (TCP と UDP などの) IP に基づいた高位のプロトコルを使用するとき、 IP レベルでオプションを設定できます。また、新しいプロトコルや特殊用途のアプリケーションを開発するとき、“生の (raw) ソケット”を通してアクセスすることもできます。

いくつかの IP レベルの setsockopt(2)getsockopt(2) オプションがあります。 IP_OPTIONS は、それぞれの発信パケットの IP ヘッダで送信されるか、または着信パケット上でヘッダオプションを調べるための IP オプションを提供するために使用されます。 IP オプションは、インターネットファミリのどんなソケットタイプでも使用されます。送信される IP オプションのフォーマットは、次の 1 つを例外として IP プロトコル仕様 (RFC-791) で明記されています: 指定経路制御 (ソースルート) オプションのためのアドレスのリストは、ゲートウェイのリストの先頭に最初の中継点 (ホップ) ゲートウェイを含まなければなりません。最初の中継点 (ホップ) ゲートウェイアドレスは、オプションリストから引き出され、サイズは、使用する前にそれに従って調整されます。以前に指定されたオプションを無効にするには、長さ 0 のバッファを使用してください:

setsockopt(s, IPPROTO_IP, IP_OPTIONS, NULL, 0);

IP_TOSIP_TTL は、 SOCK_STREAM, SOCK_DGRAM とあるタイプの SOCK_RAW ソケットのための IP ヘッダでのサービスタイプ (type-of-service) と生存時間 (time-to-live) フィールドを設定するために使用されます。例えば、次のようです。

int tos = IPTOS_LOWDELAY;       /* <netinet/ip.h>参照 */ 
setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); 
 
int ttl = 60;                   /* 最大 = 255 */ 
setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));

IP_MINTTL は、ソケット上で受信するとき、パケットが持たなければならない最小の受け付け可能な TTL を設定するために使用されます。 TTL より少ないすべてのパケットは、静かに落とされます。このオプションは、ソケットでローカルの listener (接続を受け付け者) に到達する直接接続されたネットワークの外側からパケットを防ぐ 255 に設定されるときのみ、本当に役に立ちます。

IP_DONTFRAG は、IP パケットで Don't Fragment フラグを設定するために使用されます。現在、このオプションは、 IP_HDRINCL オプションが設定されていない場合、 udp(4) と生の ip(4) ソケットだけで順守されます。 tcp(4) ソケットでは、 Don't Fragment フラグは、Path MTU Discovery オプションによって制御されます。宛先 (終点) アドレスによって決定される、 egress (出口) インタフェースの MTU サイズより大きい送信パケットは、 EMSGSIZE エラーが返されます。

IP_RECVDSTADDR オプションが SOCK_DGRAM ソケットで有効にされると、 recvmsg(2) 呼び出しは、 UDP データグラムのための宛先 (終点) IP アドレスを返します。 msghdr 構造体の msg_control フィールドは、 IP アドレスが続く cmsghdr 構造体を含むバッファを指します。 cmsghdr フィールドには、次の値があります:

cmsg_len = CMSG_LEN(sizeof(struct in_addr)) 
cmsg_level = IPPROTO_IP 
cmsg_type = IP_RECVDSTADDR

IP_SENDSRCADDR のタイプコードを持つ補助データとして、ソケットの発信 UDP データグラムのために使用される発信元 (始点) アドレスを指定することができます。 msghdr 構造体の msg_control フィールドは、 IP アドレスがあとに続く cmsghdr 構造体を含んでいるバッファを指すすべきです。 cmsghdr フィールドは、次の値を持つべきです:

cmsg_len = CMSG_LEN(sizeof(struct in_addr)) 
cmsg_level = IPPROTO_IP 
cmsg_type = IP_SENDSRCADDR

ソケットは、 INADDR_ANY とローカルポートのいずれかにバインドされるべきで、 IP_SENDSRCADDR で供給されたアドレスは、 INADDR_ANY であるべきでなく、またはソケットは、ローカルアドレスにバインドされるべきで、 IP_SENDSRCADDR で供給されたアドレスは、 INADDR_ANY であるべきです。後者の場合で、バインドされたアドレスは、宛先に近いインタフェースの IP アドレスを選択する、一般的なソースアドレスの選択ロジックを通して上書きされます。

便宜上、 IP_SENDSRCADDR は、 IP_RECVDSTADDR と同じ値を持つように定義されるので、 recvmsg(2) からの IP_RECVDSTADDR コントロールメッセージは、 sendmsg(2) のための制御メッセージとして直接使用することができます。

IP_ONESBCAST オプションが SOCK_DGRAMSOCK_RAW ソケットで有効にされると、そのソケット上の発信ブロードキャストデータグラムの宛先 (終点) アドレスは、送信の前に、方向づけのないブロードキャストアドレス、 INADDR_BROADCAST に強制されます。 IFF_BROADCAST フラグのセットとの最初のネットワークインタフェースを通して方向づけのないブロードキャストを送信するシステムのデフォルトの振る舞いと対照的です。

このオプションで、方向づけのないブロードキャストデータグラムを送信するためにどのインタフェースが使用されるかをアプリケーションは、選ぶことができます。例えば、次のコードは、方向づけのないブロードキャストがブロードキャストアドレス 192.168.2.255 に設定されたインタフェースを通して強制的に送信されます:

char msg[512]; 
struct sockaddr_in sin; 
int onesbcast = 1; /* 0 = 無効 (デフォルト), 1 = 有効 */ 
 
setsockopt(s, IPPROTO_IP, IP_ONESBCAST, &onesbcast, sizeof(onesbcast)); 
sin.sin_addr.s_addr = inet_addr("192.168.2.255"); 
sin.sin_port = htons(1234); 
sendto(s, msg, sizeof(msg), 0, &sin, sizeof(sin));

ブロードキャストの嵐を防ぐために適切な値に IP_TTL オプションを設定するのは、アプリケーションの責任です。アプリケーションには、 SO_BROADCAST ソケットレベルオプションを設定するための十分な証明書がなければなりません。そうでなければ IP_ONESBCAST オプションには、まったく効果がありません。

IP_BINDANY オプションが SOCK_STREAM, SOCK_DGRAM または SOCK_RAW ソケットで有効にされるなら、システムの任意の利用可能なネットワークインタフェースにもバインドされなかったものさえ、任意のアドレスに bind(2) (バインド) することができます。透明なプロキシを実装するために、(特別なファイアウォール規則に関連した) この機能を使用することができます。 PRIV_NETINET_BINDANY 特権は、このオプションを設定するために必要です。

IP_RECVTTL オプションが SOCK_DGRAM ソケットで有効にされるなら、 recvmsg(2) 呼び出しは、 UDP データグラムのために IP TTL (有効期間) フィールドを返します。 msghdr 構造体の msg_control フィールドは、 TTL が後に続く cmsghdr 構造体を含んでいるバッファを指します。 cmsghdr フィールドには、次の値があります:

cmsg_len = CMSG_LEN(sizeof(u_char)) 
cmsg_level = IPPROTO_IP 
cmsg_type = IP_RECVTTL

IP_RECVTOS オプションが SOCK_DGRAM ソケットで有効にされるなら、 recvmsg(2) 呼び出しは、 UDP データグラムのために IP TOS (type of service) フィールドを返します。 TOS が後続する cmsghdr 構造体を含むバッファを指す msghdr 構造体の msg_control フィールド。 cmsghdr フィールドには、次の値があります:

cmsg_len = CMSG_LEN(sizeof(u_char)) 
cmsg_level = IPPROTO_IP 
cmsg_type = IP_RECVTOS

IP_RECVIF オプションが SOCK_DGRAM ソケットで有効にされるなら、 recvmsg(2) 呼び出しは、パケットが受信されたインタフェースに対応する struct sockaddr_dl を返します。 msghdr 構造体の msg_control フィールドは、 struct sockaddr_dl が後に続く cmsghdr 構造体を含んでいるバッファを指します。 cmsghdr フィールドには、次の値があります:

cmsg_len = CMSG_LEN(sizeof(struct sockaddr_dl)) 
cmsg_level = IPPROTO_IP 
cmsg_type = IP_RECVIF

IP_PORTRANGE は、特定されていない (0) のポート番号のソケットでローカルポート番号を選択するために使用されるポート範囲を設定するために使用されます。それは、次の考えられる値があります:

IP_PORTRANGE_DEFAULT
通常 IPPORT_HIFIRSTAUTO から IPPORT_HILASTAUTO のデフォルト範囲の値を使用します。これは、次の sysctl 設定を通して調整できます: net.inet.ip.portrange.firstnet.inet.ip.portrange.last です。
IP_PORTRANGE_HIGH
通常 IPPORT_HIFIRSTAUTO から IPPORT_HILASTAUTO の高い範囲の値を使用します。これは、次の sysctl 設定を通して調整できます: net.inet.ip.portrange.hifirstnet.inet.ip.portrange.hilast です。
IP_PORTRANGE_LOW
通常 UNIX システム上の特権があるプロセスに制限される、低い範囲のポートを使用します。範囲は、通常、降順で IPPORT_RESERVED - 1 から IPPORT_RESERVEDSTART までです。これは、次の sysctl 設定を通して調整できます: net.inet.ip.portrange.lowfirstnet.inet.ip.portrange.lowlast です。

ルートで所有されているプロセスでオープンされるだけの特権ポートの範囲は、 net.inet.ip.portrange.reservedlownet.inet.ip.portrange.reservedhigh sysctl 設定によって変更されるかもしれません。伝統的な範囲のデフォルトの値は、それぞれ、0 から IPPORT_RESERVED - 1 (0 から 1023) です。これらの設定は、使用または上記の他の net.inet.ip.portrange 値の計算で影響しないて、説明されないことに注意してください。これらの値を変更することは、 UNIX 伝統から出発して、これらの設定を変更する前に管理者が慎重に評価するべきであるセキュリティ重要性があります。

ポートは、ランダムなりすまし攻撃の困難を増加させるために、指定されたポート範囲中でランダムに割り付けられます。ベンチマーキングのようなシナリオでは、この振る舞いは、望ましくないかもしれません。これらの場合、 net.inet.ip.portrange.randomized は、ランダム化をオフに切り換えるために使用することができます。最後の瞬間に net.inet.ip.portrange.randomcps ポート以上が割り付けられたなら、シリアルポート割り付けが返されます。少なくとも net.inet.ip.portrange.randomtime 秒のためにいったん net.inet.ip.portrange.randomcps を下まわる現在のポート割り付け率のみランダム割り付けを返します。 net.inet.ip.portrange.randomcpsnet.inet.ip.portrange.randomtime のデフォルト値は、秒あたり 10 ポート割り付けと対応する 45 秒です。

マルチキャストオプション

IP マルチキャストは、タイプ SOCK_DGRAMSOCK_RAWAF_INET ソケット上だけと、インタフェースドライバがマルチキャストをサポートするネットワーク上だけでサポートされます。

IP_MULTICAST_TTL オプションは、マルチキャストの有効範囲を制御するために、発信マルチキャストデータグラムの生存時間 (time-to-live) (TTL) を変更します:

u_char ttl; /* 範囲: 0 から 255, デフォルト = 1 */ 
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));

TTL が 1 のデータグラムは、ローカルネットワークを超えて転送されません。 TTL が 0 のマルチキャストデータグラムは、どんなネットワークでも送信されませんが、送信をおこなうホストが宛先 (終点) グループに属すなら、そしてマルチキャストループバックが送信をおこなうソケット上で無効にしていないなら (下記参照)、局所的 (ローカルネットワーク) には配信されます。 TTL が 1 以上のマルチキャストデータグラムは、マルチキャストルータがローカルネットワークにアタッチ (帰属) されていれば、他のネットワークに転送されます。

インタフェースがマルチキャストグループメンバシップに指定されていない複数のインタフェースでのホストに関して、それぞれのマルチキャスト送信は、プライマリネットワークインタフェースから送信されます。 IP_MULTICAST_IF オプションは、次の与えられたソケットからその後の送信のためのデフォルトを置き換えます:

struct in_addr addr; 
setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr));

ここで、"addr"は、希望のインタフェースかまたはデフォルトのインタフェースを指定する INADDR_ANY のローカル IP アドレスです。

インデックスによってインタフェースを指定するために、 ip_mreqn のインスタンスが、代わりに渡されます。 imr_ifindex メンバは、必要なインタフェースのインデックス、またはデフォルトインタフェースを指定するためには、0 を、設定するべきです。カーネルは、それらのサイズによってこれらの 2 つの構造体を区別します。

マルチキャストメンバシップが、それぞれのインタフェースで調べられるように、 IP_MULTICAST_IF の使用は、 推薦されません。各インタフェースのための個々のメンバシップを要求せずに、複数のインタフェースでリンクローカル IPv4 マルチキャストデータグラム (224.0.0.0/24) を送信することができることを期待する、ルーティングデーモンのような、古いアプリケーションによって使用されるためだけにサポートされています。

SIOCGIFCONFSIOCGIFFLAGS ioctl でインタフェースのローカル IP アドレスとマルチキャスト能力を取得することができます。通常のアプリケーションは、このオプションを使用する必要はないはずです。

マルチキャストデータグラムが送信をおこなうホスト自身が (発信インタフェースで) 属するグループに送信されなら、データグラムのコピーは、デフォルトでローカルに配信するための IP 層によってループバックされます。 IP_MULTICAST_LOOP オプションは、送信側に、その後のデータグラムがループバックするかどうかの明白な制御を与えます。

u_char loop; /* 0 = 無効, 1 = 有効 (デフォルト) */ 
setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));

このオプションは、それら自身の送信を受け付けるオーバヘッドを取り除くことによって、 (経路制御 (routing) デーモンのような) 単一のホストで 1 つ未満のインスタンスを持っていないアプリケーションの性能を向上させます。 (会議プログラムのような) 1 つのホスト上に 2 つ以上のインスタンスがあるアプリケーションか、または送信側が (時間の問い合わせプログラムのような) 宛先 (終点) グループに属さないアプリケーションで一般的に使用するべきではありません。

sysctl 設定 net.inet.ip.mcast.loop は、新しいソケットのために IP_MULTICAST_LOOP ソケットオプションのデフォルトの設定を制御します。

初期 TTL が 1 より大きい送信されたマルチキャストデータグラムは、ホストがその他のインタフェース上の宛先 (終点) グループに属すなら、送られたものとは異なったインタフェースで送信をおこなうホストに配信されます。ループバック制御オプションは、そのような配信では、効果は、ありません。

グループに送信されたデータグラムを受信する前に、ホストは、マルチキャストグループのメンバにならなければなりません。マルチキャストグループに加わるには、 IP_ADD_MEMBERSHIP オプションを使用してください:

struct ip_mreq mreq; 
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

ここで、 mreq は、次の構造体です:

struct ip_mreq { 
    struct in_addr imr_multiaddr; /* グループの IP 
                                     マルチキャストアドレス */ 
    struct in_addr imr_interface; /* インタフェースの 
                                     ローカル IP アドレス */ 
}

imr_interface は、ホストがマルチホームであるなら、特定のマルチキャスト可能なインタフェースの IP アドレスに設定されるべきです。デフォルトのインタフェースを選択するために INADDR_ANY に設定されますが、これは、推薦されません。これは、デフォルトルートに対応する最初のインタフェースであると見なされます。そうでなければ、システムで設定された最初のマルチキャスト可能なインタフェースが使用されます。

FreeBSD 7.0 より前に、 imr_interface メンバがネットワーク範囲 0.0.0.0/8 の中であるなら、それは、 RIP Version 2 MIB Extension (RFC-1724) に従って、システムインタフェース MIB のインタフェースインデックスとして取り扱われます。 7.0 以降の FreeBSD バージョンでは、この振る舞いは、もはやサポートされません。開発者は、代わりに RFC 3678 マルチキャストソースフィルタ API、特に MCAST_JOIN_GROUP を使用するべきです。

1 つのソケットに最大 IP_MAX_MEMBERSHIPS までのメンバシップを加えることができます。メンバシップ (会員資格) は、1 つのインタフェースに関連しています。マルチホームのホストで動作するプログラムは、 2 つ以上のインタフェースで同じグループに加わる必要があるかもしれません。

メンバシップを落とすためには、次を使用します:

struct ip_mreq mreq; 
setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));

ここで、 mreq は、メンバシップを追加するために使用されるのと同じ値を含みます。メンバシップは、ソケットがクローズされるか、またはプロセスが終了するとき、落とされます。

IGMP プロトコルは、グループメンバシップの識別子としてインタフェースのプライマリ IP アドレスを使用します。これは、インタフェースで設定された最初の IP アドレスです。このアドレスが削除されるか、または変更されるなら、その時、IGMP メンバシップの状態が矛盾するので、結果は、未定義です。複数の IP 別名は、同じインタフェースで設定されるなら、それらは、無視されます。

この短所は、IPv6 で解決されました。 MLDv2 は、インタフェースへのユニークなリンクローカルアドレスが MLDv2 リスナを識別するために使用されることを要求します。

ソース特有のマルチキャストオプション

FreeBSD 8.0 以降、ソース特有のマルチキャスト (Source-Specific Multicast (SSM)) の使用がサポートされています。これらの拡張は、それらをできるだけ有効に使用するために IGMPv3 マルチキャストルータを必要とします。古いマルチキャストルータがリンクに存在しているなら、 FreeBSD は、単にルータによってやりとりする IGMP のバージョンにダウングレードし、上流のリンクでのソースフィルタリングの利点は、存在しませんが、カーネルは、ブロックされたソースからの転送をスケルチ (squelch, 遮断) し続けます。

ソケットのそれぞれのグループのメンバシップには、現在、次のフィルタモードがあります:

MCAST_EXCLUDE
このグループに送られたデータグラムは、ソースがブロックされたソースアドレスのリストにないなら、受け付けられます。
MCAST_INCLUDE
このグループに送られたデータグラムは、ソースが受け付けられたソースアドレスのリストにある場合にだけ、受け付けられます。

古い IP_ADD_MEMBERSHIP オプションを使用して加えられたグループは、排他的モード (exclusive-mode) に置かれ、特定のソースがブロックされるか、または許可されるかを要求することができます。これは、 delta-based API (デルタベース API) として知られています。

既存のグループのメンバシップでマルチキャストソースをブロックするためには:

struct ip_mreq_source mreqs; 
setsockopt(s, IPPROTO_IP, IP_BLOCK_SOURCE, &mreqs, sizeof(mreqs));

ここで、 mreqs は、次の構造体です:

struct ip_mreq_source { 
    struct in_addr imr_multiaddr; /* グループの IP マルチキャストアドレス */ 
    struct in_addr imr_sourceaddr; /* ソースの IP アドレス */ 
    struct in_addr imr_interface; /* インタフェースのローカル IP アドレス */ 
}

imr_sourceaddr は、ブロックされるソースのアドレスに設定されるべきです。

既存のグループでマルチキャストソースのブロックを解除するためには:

struct ip_mreq_source mreqs; 
setsockopt(s, IPPROTO_IP, IP_UNBLOCK_SOURCE, &mreqs, sizeof(mreqs));

IP_BLOCK_SOURCEIP_UNBLOCK_SOURCE オプションは、包括的モード (inclusive-mode) グループのメンバシップのために 許可されません

単一のソースで MCAST_INCLUDE モードのマルチキャストグループに加えるか、または既存の包括的モード (inclusive-mode) のメンバシップに別のソースを追加するためには:

struct ip_mreq_source mreqs; 
setsockopt(s, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, &mreqs, sizeof(mreqs));

包括的モードの既存のグループから単独のソースを離れるためには:

struct ip_mreq_source mreqs; 
setsockopt(s, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, &mreqs, sizeof(mreqs));

これがグループのための最後に受け付けられたソースであるなら、メンバシップは、落されます。

IP_ADD_SOURCE_MEMBERSHIPIP_DROP_SOURCE_MEMBERSHIP オプションは、排他的モード (exclusive-mode) のグループメンバシップのために 受け付けられません。しかしながら、排他的と包括的モードのメンバシップは、 RFC 3678 に文書化された full-state API (完全な状態の API) の使用をサポートしています。この API を使用するソースフィルタリストの管理については、 sourcefilter(3) を参照してください。

sysctl 設定の net.inet.ip.mcast.maxsocksrcnet.inet.ip.mcast.maxgrpsrc は、カーネルが割り付けるソケット毎とグループ毎のソースフィルタエントリの数の上限を指定するために使用されます。

生の (raw) IP ソケット

生の (raw) IP ソケットは、コネクションレス (接続なし) であり、通常、 sendto(2)recvfrom(2) 呼び出しと共に使用されます、しかしながら、 connect(2) 呼び出しが将来のパケットのための宛先 (終点) を固定するためにも使用されます (その場合、 read(2)recv(2)write(2)send(2) システムコールが使用されます)。

proto が 0 であるなら、デフォルトプロトコル IPPROTO_RAW は、発信パケットに使用され、そのプロトコルに向かう着信パケットだけが受信されます。 proto が 0 でないなら、そのプロトコル番号は、発信パケットで使用され、そして、着信パケットをフィルタするために使用されます。

発信パケットは、 IP_HDRINCL オプションが設定されていない場合を除いて、自動的に IP ヘッダを (ソケットが作成される宛先 (終点) アドレスとプロトコル番号に基づいている) 先頭に追加します。着信パケットは、ホストのバイト順に変換された ip_lenip_off のフィールドを除いて、そのままの IP ヘッダとオプションで受信されます。

IP_HDRINCL は、完全な IP ヘッダがデータに含まれ、 SOCK_RAW タイプでのみ使用されることを示します。

#include <netinet/in_systm.h> 
#include <netinet/ip.h> 
 
int hincl = 1;                  /* 1 = オン, 0 = オフ */ 
setsockopt(s, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl));

以前の BSD リリースとは、違って、このプログラムは、次を含む、 IP ヘッダのすべてのフィールドを設定しなければなりません:

ip->ip_v = IPVERSION; 
ip->ip_hl = hlen >> 2; 
ip->ip_id = 0;  /* 0 は、カーネルが適切な値を設定したことを意味します */ 
ip->ip_off = offset;

ip_lenip_off フィールドは、ホストバイト順で提供 しなければなりません。 他のすべてのフィールドは、ネットワークバイト順で提供しなければなりません。ネットワークバイト順の詳しい情報については、 byteorder(3) を参照してださい。 ip_id フィールドが 0 に設定されると、カーネルは、適切な値を選びます。ヘッダの発信元 (始点) アドレスが INADDR_ANY に設定されると、カーネルは、適切なアドレスを選択します。

エラー

ソケット操作は、失敗すれば、次のエラーのうちの 1 つを返します:
[ EISCONN]
既に接続があるソケットに接続を確立しようとしたとき、または宛先 (終点) アドレスが指定されたデータグラムを送信しようとし、ソケットが既に接続されているとき。
[ ENOTCONN]
データグラムを送信しようと試みるが、宛先 (終点) アドレスが指定されていない、そしてソケットが接続されていないとき。
[ ENOBUFS]
システムが内部のデータ構造のためのメモリを使い果たすとき。
[ EADDRNOTAVAIL]
ネットワークインタフェースが存在しないネットワークアドレスでソケットを作成する試みをするとき。
[ EACCES]
特権のないプロセスによって生の (raw) IP ソケットを作成する試みをするとき。

次の IP 特有のエラーは、 IP オプションを設定するか、または取得するとき生じるかもしれません:

[ EINVAL]
未知のソケットオプション名が与えられました。
[ EINVAL]
IP オプションフィールドは、不適切に形成されています。オプションフィールドが最小値より短いか、または提供されたオプションバッファがより長いということです。

IP_HDRINCL オプションセットがある“生のソケット”を通して IP データグラムの送信を試みるとき、次のエラーが生じるかもしれません:

[ EINVAL]
ユーザによって供給された ip_len フィールドは、ソケットに書き込まれたデータグラムの長さと等しくありませんでした。

関連項目

getsockopt(2), recv(2), send(2), byteorder(3), icmp(4), igmp(4), inet(4), intro(4), multicast(4), sourcefilter(3) D. Thaler, B. Fenner, and B. Quinn, Socket Interface Extensions for Multicast Source Filters, RFC 3678, Jan 2004.

歴史

ip プロトコルは、 4.2BSD で登場しました。 ip_mreqn 構造体は、 Linux 2.4 で登場しました。

バグ

FreeBSD 10.0 の前は、生の IP ソケットで受信されるパケットは、 ip_len フィールドから ip_hl が引かれていました。
October 12, 2012 FreeBSD