IP
Section: Linux Programmer's Manual (7)
Updated: 2001-06-19
Index
JM Home Page
roff page
名前
ip - Linux IPv4 プロトコルの実装
書式
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* 上記のスーパーセット */
tcp_socket = socket(PF_INET, SOCK_STREAM, 0);
udp_socket = socket(PF_INET, SOCK_DGRAM, 0);
raw_socket = socket(PF_INET, SOCK_RAW, protocol);
説明
Linux は RFC 791 と RFC 1122 で記述されている
Internet Protocol, version 4 を実装している。
ip
には RFC 1112 に準拠した level 2 マルチキャストの実装が含まれている。
またパケットフィルタ機能を含む IP ルーターも実装されている。
プログラミング・インターフェースは BSD ソケットと互換である。
ソケットに関するより詳細な情報は
socket(7)
を参照のこと。
IP ソケットは、
socket(2)
関数を
socket(PF_INET, socket_type, protocol)
のように呼び出すことで生成される。
指定できるソケットタイプは 3 つあり、
tcp(7)
ソケットをオープンする場合
SOCK_STREAM、
udp(7)
ソケットをオープンする場合
SOCK_DGRAM、
IP プロトコルに直接アクセスするために
raw(7)
ソケットをオープンする場合には
SOCK_RAW
である。
protocol
は送受信される IP ヘッダに書かれる IP プロトコルである。
指定できる値は、
TCP ソケットには
0 または IPPROTO_TCP、
UDP ソケットには
0 または IPPROTO_UDP
に限られる。
SOCK_RAW
に対しては、 RFC 1700 で定義されている有効な IANA IP プロトコルを、
割り当てられている番号で指定することができる。
あるプロセスで、やってくるパケットを受信したり
接続要求を受けたりしたい場合には、
そのプロセスはローカルなインターフェースアドレスに、
bind(2)
を用いてソケットをバインドしなければならない。
あるローカルな「アドレスとポート」のペアに対してバインドできる
IP ソケットは一つに限られる。
bind(2)
の呼び出しで
INADDR_ANY
が指定されていた場合は、ソケットはローカルなインターフェースの
すべてにバインドされる。
listen(2)
または
connect(2)
がバインドされていないソケットでコールされると、
そのソケットは自動的にローカルなアドレスを
INADDR_ANY
にセットし、空いているポートをランダムに選んでバインドする。
SO_REUSEADDR
フラグがセットされていない場合には、
バインドされていた TCP ローカルソケットアドレスは
クローズされた後しばらくの間使えなくなる。
SO_REUSEADDR
フラグを使うと TCP の信頼性を低下させるので、
使うときには注意が必要である。
アドレスのフォーマット
IP ソケットアドレスは、 IP インターフェースアドレスと
16ビットのポート番号の組み合わせで定義される。
IP プロトコルそのものはポート番号を扱わない。
ポート番号は、
udp(7)
や
tcp(7)
といった、上位のプロトコルで実装される。
raw ソケットでは、
sin_port
が IP プロトコルにセットされる。
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
u_int16_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
u_int32_t s_addr; /* address in network byte order */
};
sin_familiy
には常に
AF_INET
をセットする。これは必須である。 Linux 2.2 では、このセットを忘れると
ほとんどのネットワーク関数は
EINVAL
を返すようになっている。
sin_port
にはポート番号をネットワークバイトオーダーで指定する。
1024 未満のポート番号は特権ポートとよばれる。
特権プロセス
(CAP_NET_BIND_SERVICE
ケーパビリティを持つプロセス) 以外のプロセスは、これらのポートには
bind(2)
できない。 IPv4 プロトコルそのものにはポートに関する概念がない。
ポートは、
tcp(7)
や
udp(7)
といった、上位のプロトコルにおいて実装される。
sin_addr
は IP ホストアドレスである。
struct in_addr
の
s_addr
メンバには、ホストのインターフェースアドレスを
ネットワークバイトオーダーで指定する。
in_addr
は、INADDR_* の一つ (例えば
INADDR_ANY)
を代入する、
ライブラリ関数
inet_aton(3),
inet_addr(3),
inet_makeaddr(3)
を用いる、あるいは名前解決機構 (name resolver)
を直接用いる、のどれかで設定すべきである。
(gethostbyname(3)
を見よ)。 IPv4 アドレスには、ユニキャストアドレス、
ブロードキャストアドレス、マルチキャストアドレスがある。
ユニキャストアドレスは、あるホストの一つのアドレスを指定する。
ブロードキャストアドレスは、あるネットワーク上の全てのホストを指定する。
マルチキャストアドレスは、マルチキャストグループに所属する
全てのホストを指定する。ブロードキャストアドレスへのデータグラムは、
SO_BROADCAST
ソケットフラグがセットされていないと送信・受信できない。
現在の実装では、接続指向のソケットにはユニキャストアドレスしか使えない。
アドレスとポートは常にネットワークバイトオーダーで格納されることに注意せよ。
具体的には、ポートを指定する数値には
htons(3)
を呼び出す必要がある。
標準ライブラリにあるアドレス/ポート操作関数は
すべてネットワークバイトオーダーで動作する。
特別なアドレスがいくつか存在する:
- INADDR_LOOPBACK(127.0.0.1)
-
loopback デバイスを通して常にローカルなホストを参照する。
- INADDR_ANY(0.0.0.0)
-
バインドに用いる任意のアドレス。
- INADDR_BROADCAST(255.255.255.255)
-
任意のホスト。歴史的理由から、バインドの際には
INADDR_ANY
と同じ効果になる。
ソケットオプション
IP にはプロトコル固有のソケットオプションがいくつか存在し、
setsockopt(2)
で設定が、
getsockopt(2)
で取得ができる。 IP のソケットオプションレベルは
IPPROTO_IP
である。
ブール整数値のフラグでは、 0 は偽、それ以外は真を意味する。
- IP_OPTIONS
-
このソケットから送られるパケット全てに付随する IP オプションを
設定・取得する。オプションを保存しているメモリバッファへのポインタと
オプションの長さとを引き数に取る。
setsockopt(2)
を呼び出すと、ソケットに関連づけられる IP オプションを設定できる。
IPv4 におけるオプションのサイズの最大値は 40 バイトである。
用いることのできるオプションについては RFC 791 を見よ。
SOCK_STREAM
ソケットに対する初期接続要求パケットに IP オプションが含まれていると、
ルーティングヘッダを付けて戻されてくる初期パケットの
IP オプションに同じオプションがセットされる。接続が確立された後、
やってきたパケットのオプションを変更することはできない。
デフォルトでは。外部から受信したパケットの全ての source routing オプション
の処理は無効となっており、
accept_source_route
sysctl を用いればこれを有効にできる。これを無効にしていても timestamps など
の他のオプションの処理は行われる。データグラムソケットでは、
IP オプションはローカルユーザーしか設定できない。
getsockopt(2)
を
IP_OPTIONS
をつけて呼ぶと、現在送信に用いられている IP オプションを
引き数に与えたバッファに取得できる。
- IP_PKTINFO
-
IP_PKTINFO
補助メッセージを渡す。これには到着パケットに関する情報を提供する
pktinfo
構造体が含まれている。
データグラム指向のソケットでしか動作しない。
引き数は IP_PKTINFO メッセージを通過させるかどうかをソケットに
知らせるフラグである。
メッセージ自身は
recvmsg(2)
または
sendmsg(2)
を用いたパケットの制御メッセージとしてのみ送受信できる。
-
struct in_pktinfo {
unsigned int ipi_ifindex; /* Interface index */
struct in_addr ipi_spec_dst; /* Local address */
struct in_addr ipi_addr; /* Header Destination
address */
};
-
ipi_ifindex
はパケットが受信されたインターフェースの、他と重ならないインデックスである。
ipi_spec_dst
はパケットのローカルアドレスである。
ipi_addr
はパケットヘッダにある宛先アドレスである。
IP_PKTINFO
が
sendmsg(2)
に渡されて、かつ
ipi_spec_dst
が 0 以外の場合、
ipi_spec_dst
はルーティングテーブルを検索する際にローカルな送信元アドレスとして使用され、
IP source route オプションを設定するのにも使用される。
ipi_ifindex
が 0 以外の場合、このインデックスによって指定されるインターフェースの
プライマリローカルアドレスで
ipi_spec_dst
を上書きし、ルーティングテーブルを検索する。
- IP_RECVTOS
-
有効になっていると、
IP_TOS
補助メッセージが到着パケットとともに渡される。
これにはパケットヘッダの Service/Precedence
フィールドのタイプを指定するバイトデータが含まれている。
ブール整数値のフラグをとる。
- IP_RECVTTL
-
このフラグがセットされていると、
IP_TTL
コントロールメッセージが受信パケットの
time-to-live フィールドのバイトデータとともに渡される。
SOCK_STREAM
ソケットではサポートされていない。
- IP_RECVOPTS
-
到着した全ての IP オプションを
IP_OPTION
コントロールメッセージに入れてユーザーに渡す。
ルーティングヘッダとその他のオプションとは、
ローカルホストに対してはあらかじめ記入されている。
SOCK_STREAM
ソケットではサポートされていない。
- IP_RETOPTS
-
IP_RECVOPTS
と等価だが、未処理の生のオプションを、
この hop では記入されない timestamp レコードと route レコードとともに返す。
- IP_TOS
-
このソケットから送信されるすべての IP パケットに適用される
Type-Of-Service (TOS) フィールドを設定・取得する。
これはネットワーク上でのパケットの優先度を決めるために用いられる。
TOS はバイトデータである。標準の TOS フラグがいくつか定義されている。
IPTOS_LOWDELAY
はインタラクティブなトラフィックの遅延を最小にする。
IPTOS_THROUGHPUT
はスループットを最大にする。
IPTOS_RELIABILITY
は信頼性を最高にする。
IPTOS_MINCOST
は転送速度が遅くてもかまわないとき、「データを詰め込む」のに用いられる。
これらのうち、 1 つまでだけを設定できる。
他のビットは無効で、クリアされる。
Linux はデフォルトでは
IPTOS_LOWDELAY
データグラムを最初に送信する。
しかし、正確な振る舞いはキュー処理の設定に依存する。
高い優先度にするにはスーパーユーザー権限
(CAP_NET_ADMIN
ケーパビリティ) が必要となるかもしれない。
優先度は
(SOL_SOCKET, SO_PRIORITY)
ソケットオプションを用いれば、
プロトコルに依存しない形でも設定できる
(socket(7)
を見よ)。
- IP_TTL
-
time-to-live フィールドの値を設定または取得する。
この値はこのソケットから送信されるすべてのパケットに用いられる。
- IP_HDRINCL
-
有効になっていると、ユーザは IP ヘッダをユーザーデータの前に与える。
SOCK_RAW
ソケットでのみ有効である。詳細は
raw(7)
を見よ。このフラグが有効になっていると、
IP_OPTIONS,
IP_TTL,
IP_TOS
は無視される。
- IP_RECVERR (<linux/errqueue.h> で定義されている)
-
エラーメッセージの受け渡しに、信頼性の高い拡張された方法を有効にする。
データグラムソケットに対して有効になっていると、
発生したエラーは全てソケットごとのエラーキューに保存される。
ユーザーはソケット操作からエラーを受け取ったとき、
recvmsg(2)
を
MSG_ERRQUEUE
フラグとともに呼べばそのエラーを取得できる。
そのエラーを記述する
sock_extended_err
構造体が、タイプ
IP_RECVERR・
レベル
IPPROTO_IP
の補助メッセージとして渡される。
これは接続志向でないソケットで信頼性の高いエラー処理を行いたい場合に
有用である。エラーキューの受信データフラグメントには
エラーパケットが含まれる。
-
IP_RECVERR
制御メッセージには
sock_extended_err
構造体が含まれる:
-
#define SO_EE_ORIGIN_NONE 0
#define SO_EE_ORIGIN_LOCAL 1
#define SO_EE_ORIGIN_ICMP 2
#define SO_EE_ORIGIN_ICMP6 3
struct sock_extended_err {
u_int32_t ee_errno; /* error number */
u_int8_t ee_origin; /* where the error originated */
u_int8_t ee_type; /* type */
u_int8_t ee_code; /* code */
u_int8_t ee_pad;
u_int32_t ee_info; /* additional information */
u_int32_t ee_data; /* other data */
/* More data may follow */
};
struct sockaddr *SO_EE_OFFENDER(struct sock_extended_err *);
-
ee_errno
にはキューに入っているエラーの
errno
番号が入る。
ee_origin
にはエラーが発生した場所を示すコードが入る。
その他のフィールドはプロトコル依存である。
SO_EE_OFFENDER
マクロは与えられた補助メッセージへのポインタから
エラーの発生したネットワークオブジェクトのアドレスへのポインタを返す。
アドレスが不明な場合、
sockaddr
構造体の
sa_family
フィールドは
AF_UNSPEC
となり、その他のフィールド値は不定である。
-
IP は以下のような
sock_extended_err
構造体を用いる:
ee_origin
は、
エラーが ICMP パケットとして受信された場合には
SO_EE_ORIGIN_ICMP
にセットされ、ローカルで起こった場合には
SO_EE_ORIGIN_LOCAL
にセットされる。
不明な値は無視される。
ee_type
と
ee_code
は ICMP ヘッダの type フィールドと code フィールドの値にセットされる。
ee_info
には
EMSGSIZE
エラーに対する discover された MTU が入る。
メッセージにはエラーを引き起こしたノードの
sockaddr_in
構造体も含まれる。
これには
SO_EE_OFFENDER
マクロを使ってアクセスできる。
ソースが不明の場合、
SO_EE_OFFENDER アドレスの
sin_family
フィールドは
AF_UNSPEC
となる。
エラーがネットワークで起きた場合には、
ソケットで有効になっていたすべての IP オプション
(IP_OPTIONS, IP_TTL
など) とエラーパケットに含まれていたすべての IP オプションとが、
制御メッセージとして渡される。
エラーを起こしたパケットのペイロード (payload) は
普通のペイロードとして返される。
TCP にはエラーキューがないことに注意してほしい。
MSG_ERRQUEUE
は
SOCK_STREAM
ソケットに対しては使えない。
TCP では
IP_RECVERR
だけが有効だが、ソケット関数から返されるエラーは
SO_ERROR
だけになる。
-
raw ソケットに対して
IP_RECVERR
を指定すると、受信したすべての ICMP エラーをアプリケーションに
渡すようになる。指定しないと、
接続済みのソケットに対するエラーだけを報告する。
-
このオプションはブール値のフラグを設定・取得する。
IP_RECVERR
はデフォルトではオフになっている。
- IP_MTU_DISCOVER
-
ソケットの Path MTU Discovery の設定をセット・取得する。
有効になっていると、 Linux はこのソケットに対して
RFC 1191 で定義されている Path MTU Discovery を行う。
発信データグラムには、全て「フラグメント不許可」フラグがセットされる。
システム全体に対するデフォルトは、
SOCK_STREAM
ソケットに対しては
ip_no_pmtu_disc
sysctl を行うことによって制御可能、
その他については無効となっている。
SOCK_STREAM
でないソケットに対しては、
ユーザーがデータを MTU のサイズの塊にパケット化したり、
必要な場合には再送したりしなければならない。
このフラグがセットされていると、
カーネルは既知の path MTU より大きなパケットを拒否する
(EMSGSIZE
となる)。
Path MTU discovery フラグ | 意味
|
IP_PMTUDISC_WANT | ルートごとの設定を用いる。
|
IP_PMTUDISC_DONT | Path MTU Discovery を行わない。
|
IP_PMTUDISC_DO | 常に Path MTU Discovery を行う。
|
IP_PMTUDISC_PROBE | DFビットをセットするが、Path MTU を無視する。
|
path MTU discovery が有効になっていると、カーネルは宛先ホストごとに
自動的に path MTU を処理する。特定の相手に
connect(2)
で接続した場合には、
IP_MTU
ソケットオプションを用いれば、既知の path MTU の取得に便利である
(たとえば
EMSGSIZE
エラーが起きた後など)。これは時間とともに変化するかもしれない。
宛先がたくさんあるコネクションレスなソケットでは、
与えられた宛先に対する新しい MTU にも、
エラーキューを用いてアクセスすることができる
(IP_RECVERR
を見よ)。
MTU 更新が到着するごとに、新たなエラーがキューイングされる。
MTU discovery の進行中には、データグラムソケットからの初期パケットは
到着しないかもしれない。 UDP を用いるアプリケーションでは、
このことを気にかけておき、
パケットの再送アルゴリズムにこの分を除外させるべきである。
接続していないソケットに対して
path MTU discovery プロセスを立ち上げるには、
大きなデータグラムサイズ (最大 64K ヘッダバイト長) からはじめて、
path MTU が更新されるまでサイズを縮めていくことも可能である。
path MTU の値をまず見積もってみるには、宛先アドレスに
connect(2)
を使ってデータグラムソケットを接続し、
getsockopt(2)
を
IP_MTU
オプションとともに呼び、 MTU を取得することである。
IP_PMTUDISC_PROBE
を設定することで、
SOCK_DGRAM
や
SOCK_RAW
のソケットで RFC 4821 の MTU 探索を実装することが可能である。
また、この機能は、
tracepath(8)
のような診断ツールで特に有用である。これらのツールでは、
観測された Path MTU よりも大きな探索パケットを意図的に
送信しようとする。
- IP_MTU
-
ソケットの、既知の path MTU を取得する。
ソケットが接続している場合のみ有効である。
getsockopt(2)
でのみ使える。
- IP_ROUTER_ALERT
-
フォワードすべきパケットを IP Router Alert オプションをつけて
このソケットに渡す。
raw ソケットに対してのみ有効である。これはたとえばユーザー空間の
RSVP デーモンに対して便利である。タップされたパケットは
カーネルによってはフォワードされないので、これらを再送するのは
ユーザーの責任となる。ソケットのバインドは無視され、
このようなパケットはプロトコルによってのみフィルタリングされる。
整数値のフラグを取る。
- IP_MULTICAST_TTL
-
このソケットから発信されるマルチキャストパケットの
time-to-live 値を設定・取得する。
マルチキャストパケットに対しては、できるだけ小さな
TTL に設定することがとても重要である。デフォルトは 1 で、
ユーザープログラムが明示的に要求しない限り
マルチキャストパケットはローカルなネットワークから出ないことになる。
引き数に整数を取る。
- IP_MULTICAST_LOOP
-
マルチキャストパケットをローカルなソケットにループバックするかどうかを
定めるブール値の整数引き数を設定・取得する。
- IP_ADD_MEMBERSHIP
-
マルチキャストグループに参加する。
引き数は
ip_mreqn
構造体である。
struct ip_mreqn {
struct in_addr imr_multiaddr; /* IP multicast group
address */
struct in_addr imr_address; /* IP address of local
interface */
int imr_ifindex; /* interface index */
};
imr_multiaddr
には、アプリケーションが参加または撤退したい
マルチキャストグループのアドレスが入る。
これは有効なマルチキャストアドレスでなければならない。
imr_address
はシステムがマルチキャストグループに参加する際に用いる
ローカルなインターフェースのアドレスである。
これが
INADDR_ANY
であった場合には、適切なインターフェースがシステムによって選択される。
imr_ifindex
は
imr_multiaddr
グループに参加/撤退するインターフェースの interface index である。
どのインターフェースでもよい場合は 0 にする。
-
互換性のため、古い
ip_mreq
構造体もまだサポートされている。
ip_mreqn
との違いは、
imr_ifindex
フィールドを含まないことだけである。
setsockopt(2)
でのみ使える。
- IP_DROP_MEMBERSHIP
-
マルチキャストグループから抜ける。引き数は
IP_ADD_MEMBERSHIP
と同様に
ip_mreqn
または
ip_mreq
構造体である。
- IP_MULTICAST_IF
-
ローカルデバイスをマルチキャストソケットとして設定する。引き数は
IP_ADD_MEMBERSHIP
と同様に
ip_mreqn
または
ip_mreq
構造体である。
-
不正なソケットオプションが渡されると、
ENOPROTOOPT
が返される。
sysctl
IP プロトコルでは、いくつかのグローバルオプションを
sysctl を通して設定することができる。
これらの sysctl にアクセスするには、
/proc/sys/net/ipv4/*
ファイルを読み書きする方法と、インターフェースに対して
sysctl(2)
を用いる方法がある。
Boolean
と書かれた変数は整数値をとり、
0 以外の値 ("true") は対応するオプションが有効、
0 値 ("false") は無効、であることを意味する。
- ip_always_defrag (Boolean)
-
[2.2.13 で新規登場。以前のバージョンのカーネルでは、この機能は
コンパイル時に
CONFIG_IP_ALWAYS_DEFRAG
オプションによって制御されていた;
このファイルは 2.4.x 以降では存在しない]
このブール値のフラグが有効になっている (0 以外になっている) と、
到着したフラグメント (IP パケットの一部で、
発信元と発信先の間のどこかのホストで、そのパケットが
大きすぎると判断され、分割された場合に生じる)
は、たとえフォワードされる場合であっても
処理前に再構築 (デフラグメント) される。
ファイアウォールがローカル側のネットワークに唯一のリンクを持っている
場合や、透過プロクシの場合に限って有効にすべきである。
通常のルーターやホストでは絶対に有効にしないように。
さもないとフラグメントが別のリンクを経由して伝わる場合に、
通信のフラグメント化ができなくなってしまう。
また再構築処理はメモリと CPU 時間のコストが非常に大きい。
これはマスカレードや透過プロクシが設定されると、
不思議な仕組みによって自動的に有効になる。
- ip_autoconfig
-
まだ記述していない。
- ip_default_ttl (integer; default: 64)
-
送出されるパケットの time-to-live 値のデフォルトをセットする。
これは
IP_TTL
オプションを用いれば、パケットごとに変えることもできる。
- ip_dynaddr (Boolean; default: disabled)
-
動的ソケットアドレスと、インターフェースアドレスが変更された際の
マスカレードエントリの再書き込みを有効にする。
ダイアルアップインターフェースで、
IP アドレスが変更される場合に便利である。
- ip_forward (Boolean; default: disabled)
-
IP forwarding を有効にするかどうかのブール値フラグ。
IP forwarding するかどうかはインターフェースごとにも設定できる。
- ip_local_port_range
-
ソケットに割り当てられているデフォルトのローカルポートの範囲を定める
二つの整数を与える。割り当ては 1 番目の番号から始まり、 2 番目の番号で終わる。
これらはマスカレードで用いられているポートと重なってはならない
(その場合も取り扱われるが)。
ファイアウォールのパケットフィルターが「利用中のローカルポート」
について何らかの仮定をしている場合には、
番号を勝手に決めてしまうと問題が起きるかもしれない。
1 番目の番号は少なくとも 1024 より大きくすべきである。
良く使われるポートとの衝突を避けたり、ファイアウォールの問題を
回避したければ、 4096 よりも大きくするほうが良いだろう。
- ip_no_pmtu_disc (Boolean; default: disabled)
-
有効になっていると、デフォルトで TCP ソケットに対する
Path MTU Discoverty を行わない。
Path MTU Discovery は、
正しく設定されていない (ICMP パケットを全てドロップする) ファイアウォールや、
(point-to-point リンクで双方の MTU が一致していない場合など)
正しく設定されていないインターフェースが経路上に存在すると失敗してしまう。
Path MTU Discovery をグローバルに無効にするよりは、
壊れているルータを直すほうが良い。
Path MTU Discovery を無効にするとネットワークのコストが
大きくなってしまうからである。
- ip_nonlocal_bind (Boolean; default: disabled)
-
セットされていれば、プロセスが自分以外の IP アドレスを
bind(2)
できるようになる。これはかなり便利だが、うまく動かないアプリケーションもある。
- ip6frag_time (integer; default 30)
-
IPv6 フラグメントをメモリに保持しておく時間 (秒単位)。
- ip6frag_secret_interval (integer; default 600)
-
IPv6 フラグメントの hash secret の生成間隔 (hash secret の寿命)
(秒単位)。
- ipfrag_high_thresh (integer), ipfrag_low_thresh (integer)
-
キューイングされている IP フラグメントの量が
ipfrag_high_thresh
に達すると、キューの内容は
ipfrag_low_thresh
にまで切り捨てられる。それぞれの大きさを
バイト単位で表す整数値が入っている。
- neigh/*
-
arp(7)
を見よ。
ioctl
socket(7)
に記述されている ioctl は、
すべて ip にも適用される。
ジェネリックデバイスのパラメータを設定する ioctl については
netdevice(7)
に記述されている。
エラー
- EACCES
-
必要な権限のないユーザーが操作を実行しようとした。
以下のような場合が考えられる:
SO_BROADCAST
フラグを設定していない状態でブロードキャストアドレスに
パケットを送ろうとした。
prohibit
なルートを通してパケットを送ろうとした。
スーパーユーザー権限
(CAP_NET_ADMIN
ケーパビリティ) なしでファイアウォールの設定を変更しようとした。
スーパーユーザー権限
(CAP_NET_BIND_SERVICE
ケーパビリティ) なしで特権ポートにバインドしようとした。
- EADDRINUSE
-
既に使われているアドレスにバインドしようとした。
- EADDRNOTAVAIL
-
存在しないソケットが要求された。または要求された
ソースアドレスがローカルでない。
- EAGAIN
-
非ブロッキングソケットに対してブロックする操作を行った。
- EALREADY
-
非ブロッキングソケットに対する接続操作が既に実行中である。
- ECONNABORTED
-
accept(2)
の最中に接続がクローズされた。
- EHOSTUNREACH
-
宛先アドレスにマッチする有効なエントリがルーティングテーブルに
存在しない。このエラーはリモートルータからの、
あるいはローカルルーティングテーブルへの
ICMP メッセージによって引き起こされることがある。
- EINVAL
-
不正な引き数が渡された。送信操作において、
blackhole
ルートに送信しようとするとこのエラーが起こることがある。
- EISCONN
-
connect(2)
が、既に接続済みのソケットに対して呼ばれた。
- EMSGSIZE
-
データグラムが path MTU よりも大きく、フラグメント化もできない。
- ENOBUFS, ENOMEM
-
空きメモリが足りない。
このエラーは、メモリアロケーションがソケットバッファの
大きさによって制限されていることを意味しているのが通常であるが、
100% そうだというわけではない。
- ENOENT
-
パケットが全く到着していないソケットに対して
SIOCGSTAMP
が呼ばれた。
- ENOPKG
-
カーネルサブシステムが設定されていない。
- ENOPROTOOPT と EOPNOTSUPP
-
不正なソケットオプションが渡された。
- ENOTCONN
-
接続されていないソケットに対して、
接続状態でしか定義されていない操作を行おうとした。
- EPERM
-
高い優先度を設定したり、設定を変更したり、要求されたプロセスや
プロセスグループにシグナルを送ったりするのに必要な権限を、
ユーザーが持っていない。
- EPIPE
-
接続が先方から期待していなかったやり方で
クローズあるいはシャットダウンされた。
- ESOCKTNOSUPPORT
-
ソケットが未設定であるか、知らないソケットタイプが要求された。
他のエラーが上層のプロトコルによって生じるかもしれない。
tcp(7),
raw(7),
udp(7),
socket(7)
などを参照のこと。
バージョン
IP_MTU,
IP_MTU_DISCOVER,
IP_PKTINFO,
IP_RECVERR,
IP_ROUTER_ALERT
は Linux 2.2 で新しく導入されたオプションである。
これは Linux 固有であり、移植性を考慮したプログラムでは
用いるべきではない。
IP_PMTUDISC_PROBE
は Linux 2.6.22 で登場した。
struct ip_mreqn
は Linux 2.2 で登場した。 Linux 2.0 は
ip_mreq
しかサポートしていない。
sysctl 群は Linux 2.2 で導入された。
注意
SO_BROADCAST
オプションの利用には、くれぐれも注意すること。
これは Linux では特権操作ではない。
不注意なブロードキャストを行うと、ネットワークは簡単に過負荷状態になる。
新しいアプリケーションプロトコルには、ブロードキャストではなく
マルチキャストグループを用いるほうがよい。
ブロードキャストは推奨されない。
他の BSD のソケット実装では、
IP_RCVDSTADDR
と
IP_RECVIF
といったソケットオプションがサポートされており、
宛先アドレスや受信データグラムのインターフェースが取得できるように
なっていることもある。
Linux で同じことをやらせるには、より一般的な
IP_PKTINFO
が使える。
いくつかの BSD のソケット実装では
IP_RECVTTL
オプションも提供されているが、タイプ
IP_RECVTTL
の補助メッセージは受信パケットとともに渡される。
これは Linux で使われている
IP_TTL
オプションとは異なる動作である。
SOL_IP
ソケットオプションレベルは移植性がない。
BSD ベースのプロトコルスタックでは
IPPROTO_IP
レベルが使用されている。
移植性
Linux 2.0 との互換性のために、 obsolete な
socket(PF_INET, SOCK_PACKET, protocol)
という書式でも
packet(7)
をオープンできるようになっているが、これはお勧めできない。今後は
socket(PF_PACKET, SOCK_RAW, protocol)
を代わりに用いるべきである。主な違いは、ジェネリックなリンク層用の
sockaddr_ll
アドレス構造体が、古い
sockaddr_pkt
に変わって用いられるようになったことである。
バグ
エラーの値が全く首尾一貫していない。
IP 固有のインターフェースオプションを指定するための ioctl と
ARP テーブルのことが記述されていない。
glibc のバージョンによっては
in_pktinfo
の定義を忘れているものがある。
現時点でのとりあえずの対策としては、この man ページにある定義をプログラム中に
コピーすることである。
recvmsg(2)
で
msg_name
に
MSG_ERRQUEUE
を指定して、受信パケットに入っていた宛先アドレスを取得する方法は
2.2 カーネルの一部でうまく動かない。
関連項目
recvmsg(2),
sendmsg(2),
byteorder(3),
ipfw(4),
capabilities(7),
netlink(7),
raw(7),
socket(7),
tcp(7),
udp(7)
RFC 791:
オリジナルの IP の仕様
RFC 1122:
IPv4 ホストの必要条件
RFC 1812:
IPv4 ルータの必要条件
Index
- 名前
-
- 書式
-
- 説明
-
- アドレスのフォーマット
-
- ソケットオプション
-
- sysctl
-
- ioctl
-
- エラー
-
- バージョン
-
- 注意
-
- 移植性
-
- バグ
-
- 関連項目
-
This document was created by
man2html,
using the manual pages.
Time: 04:31:48 GMT, November 19, 2007