netdevice - Linux
ネットワークデバイスへの低レベルアクセス
#include <sys/ioctl.h>
#include <net/if.h>
この man
ページでは、ネットワークデバイスを設定するために
用いるソケットインターフェースについて解説する。
Linux
はネットワークデバイスを設定するための標準的な
ioctl を
いくつか備えている。これらはどんなソケットのファイルディスクリプタにも
用いることができる。ファミリーやタイプは何でもよい。
これらの ioctl
のほとんどは
ifreq
構造体を渡す。
struct ifreq {
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char *ifr_data;
};
};
通常、ユーザーによる設定対象デバイスの指定は、
ifr_name
にインターフェースの名前をセットすることによって行う。
他の構造体の全てのメンバは、メモリを共有する。
ioctl¶
「特権が必要」と記述されている
ioctl を実行するには、
実効ユーザー ID が 0
か、
CAP_NET_ADMIN
権限が必要である。これが満たされていない場合は
EPERM が返される。
- SIOCGIFNAME
- ifr_ifindex
を受け取り、インターフェースの名前を
ifr_name
に入れて返す。これは結果を
ifr_name
として返す唯一の ioctl
である。
- SIOCGIFINDEX
- インターフェースの
interface index を取得し、
ifr_ifindex
に入れて返す。
- SIOCGIFFLAGS, SIOCSIFFLAGS
- デバイスの active
フラグワードを取得または設定する。
ifr_flags
には以下の値のビットマスクが入る。
| デバイスフラグ |
|
| IFF_UP |
インターフェースは動作中。 |
| IFF_BROADCAST |
有効なブロードキャストアドレスがセットされている。 |
| IFF_DEBUG |
内部のデバッグフラグ。 |
| IFF_LOOPBACK |
インターフェースはループバックである。 |
| IFF_POINTOPOINT |
インターフェースは
point-to-point
リンクである。 |
| IFF_RUNNING |
リソースが割り当て済み。 |
| IFF_NOARP |
arp
プロトコルがない。
L2
宛先アドレスが設定されていない。 |
| IFF_PROMISC |
インターフェースは
promiscuous
モードである。 |
| IFF_NOTRAILERS |
trailer
の利用を避ける。 |
| IFF_ALLMULTI |
全てのマルチキャストパケットを受信する。 |
| IFF_MASTER |
負荷分散グループのマスターである。 |
| IFF_SLAVE |
負荷分散グループのスレーブである。 |
| IFF_MULTICAST |
マルチキャストをサポートしている。 |
| IFF_PORTSEL |
ifmap
によってメディアタイプを選択できる。 |
| IFF_AUTOMEDIA |
自動メディア選択が有効になっている。 |
| IFF_DYNAMIC |
このインターフェースが閉じると、アドレスは失われる。 |
| IFF_LOWER_UP |
ドライバからの L1
アップの通知 (Linux 2.6.17
以降) |
| IFF_DORMANT |
ドライバからの休止状態の通知
(Linux 2.6.17 以降) |
| IFF_ECHO |
送られたパケットをエコーする
(Linux 2.6.25 以降) |
|
|
active
フラグワードの設定は特権が必要な操作である。
読み出しはどんなプロセスからも可能である。
- SIOCGIFPFLAGS, SIOCSIFPFLAGS
- デバイスの拡張
(プライベート)
フラグを取得または設定する。
ifr_flags
には以下の値のビットマスクが入る。
| プライベートフラグ |
|
| IFF_802_1Q_VLAN |
インターフェースは
802.1Q VLAN
デバイスである。 |
| IFF_EBRIDGE |
インターフェースは
Ethernet
ブリッジデバイスである。 |
| IFF_SLAVE_INACTIVE |
インターフェースは非アクティブな
bonding
のスレーブである。 |
| IFF_MASTER_8023AD |
インターフェースは
802.3ad bonding
のマスターである。 |
| IFF_MASTER_ALB |
インターフェースは
balanced-alb bonding
のマスターである。 |
| IFF_BONDING |
インターフェースは
bonding
のマスターかスレーブである。 |
| IFF_SLAVE_NEEDARP |
インターフェースは検証に
APR が必要である。 |
| IFF_ISATAP |
インターフェースは
RFC4214 ISATAP
インターフェースである。 |
拡張 (プライベート)
インターフェースフラグの設定には特権が必要である。
- SIOCGIFADDR, SIOCSIFADDR
- ifr_addr
を用いてデバイスのアドレスの設定/取得を行う。
インターフェースのアドレスの設定は特権が必要な操作である。
互換性確保のため、設定/取得ができるのは
AF_INET
アドレスだけである。
- SIOCGIFDSTADDR, SIOCSIFDSTADDR
- point-to-point
デバイスの宛先アドレスを
ifr_dstaddr を用いて
設定/取得する。互換性確保のため、
設定/取得ができるのは
AF_INET
アドレスだけである。
宛先アドレスの設定は特権が必要な操作である。
- SIOCGIFBRDADDR, SIOCSIFBRDADDR
- デバイスのブロードキャストアドレスを
ifr_brdaddr を用いて
設定/取得する。互換性確保のため、
設定/取得ができるのは
AF_INET
アドレスだけである。
ブロードキャストアドレスの設定は特権が必要な操作である。
- SIOCGIFNETMASK, SIOCSIFNETMASK
- デバイスのネットワークマスクを
ifr_netmask を用いて
設定/取得する。互換性確保のため、
設定/取得ができるのは
AF_INET
アドレスだけである。
ネットワークマスクの設定は特権が必要な操作である。
- SIOCGIFMETRIC, SIOCSIFMETRIC
- デバイスのメトリックを
ifr_metric
を用いて取得・設定する。
これはまだ実装されていない。読み出そうとすると
ifr_metric に 0
をセットして返り、設定しようとすると
EOPNOTSUPP が返る。
- SIOCGIFMTU, SIOCSIFMTU
- デバイスの MTU (Maximum Transfer Unit)
を ifr_mtu
を用いて取得・設定する。
MTU
の設定は特権が必要な操作である。
MTU
の値を小さくしすぎるとカーネルがクラッシュするかもしれない。
- SIOCGIFHWADDR, SIOCSIFHWADDR
- デバイスのハードウェアアドレスを
ifr_hwaddr
を用いて取得・設定する。
ハードウェアアドレスは
sockaddr
構造体に設定される。
sa_family には ARPHRD_*
デバイスタイプが入り、
sa_data にはバイト 0
から始まる L2
ハードウェアアドレスが入る。
ハードウェアアドレスの設定は特権が必要な操作である。
- SIOCSIFHWBROADCAST
- デバイスのハードウェアブロードキャストアドレスを
ifr_hwaddr
の値に設定する。この操作には特権が必要である。
- SIOCGIFMAP, SIOCSIFMAP
- インターフェースのハードウェアのパラメータを
ifr_map
を用いて取得・設定する。
パラメータの設定は特権が必要な操作である。
struct ifmap {
unsigned long mem_start;
unsigned long mem_end;
unsigned short base_addr;
unsigned char irq;
unsigned char dma;
unsigned char port;
};
ifmap
構造体の解釈はデバイスドライバとアーキテクチャに依存する。
- SIOCADDMULTI, SIOCDELMULTI
- デバイスのリンク層のマルチキャストフィルターから、
ifr_hwaddr
のアドレスを追加・削除する。これらの操作には特権が必要である。
別の方法が packet(7)
で解説されている。
- SIOCGIFTXQLEN, SIOCSIFTXQLEN
- デバイスの送信キューの長さを
ifr_qlen
に取得・設定する。送信キューの長さの設定には特権が必要である。
- SIOCSIFNAME
- ifr_name
で指定したインターフェースの名前を
ifr_newname
に変更する。この操作には特権が必要である。インターフェースが
up していない
時にのみ使用できる。
- SIOCGIFCONF
- インターフェースの
(トランスポート層の)
アドレスのリストを返す。
現在のところ、互換性のため返されるのは
AF_INET (IPv4)
系のアドレスだけである。
他の操作と違い、この
ioctl では ifconf
構造体を渡す。
struct ifconf {
int ifc_len; /* バッファサイズ */
union {
char *ifc_buf; /* バッファアドレス */
struct ifreq *ifc_req; /* 構造体の配列 */
};
};
ifc_req が NULL の場合、
SIOCGIFCONF
はすべての取得できるアドレスを受け取るのに必要なバッファサイズ
(バイト数) を ifc_len
に格納して返す。
それ以外の場合は、
ifc_req には ifreq
構造体の配列へのポインタを渡す。
この構造体の配列には現在アクティブな
L3
インターフェースアドレスがすべて格納される。
ifc_len
はバイト単位の配列のサイズを渡す。
ifreq 構造体内では、
ifr_name
にインターフェース名が、
ifr_addr
にそのアドレスが入る。
実際に格納されたバイト数は
ifc_len で返される。
ifc_len
で指定されたサイズがすべてのアドレスを格納するのに不十分な場合、
カーネルは超過分をスキップし、成功を返す。
この状況になった場合、それを検出する信頼できる方法はない。
したがって、
前もって ifc_req を NULL
に設定して SIOCGIFCONF
を呼び出して必要なバッファサイズを決定するか、
返された ifc_len
と元の値の差分が
sizeof(struct ifreq)
よりも小さい場合は必ずバッファを大きくして再度呼び出すか、
のいずれかを行うことが推奨される。
ifconf か ifreq
構造体へのアクセスでエラーが置こった場合には
EFAULT が返される。
ほとんどのプロトコルには、専用のインターフェースオプションを
設定するための独自の
ioctl が存在する。
説明は各プロトコルの
man ページを見よ。 IP
アドレスの設定に関しては
ip(7) を参照。
さらに、デバイスによってはプライベートな
ioctl がある。
これらはここでは説明しない。
厳密にいうと、
SIOCGIFCONF
や、
AF_INET
ソケットアドレスだけを
引き数に取ったり返したりする他の
ioctl は IP 固有であり、
ip(7) に属する。
アドレスがなかったり、
IFF_RUNNING
フラグがセットされていないインターフェースの名前は
/proc/net/dev
で知ることができる。
ローカル IPV6 IP
アドレスは
/proc/net か
rtnetlink(7)
で知ることができる。
glibc 2.1 では
<net/if.h> に
ifr_newname
マクロがない。
とりあえずの対応策として、以下のコードを追加しておくこと。
#ifndef ifr_newname
#define ifr_newname ifr_ifru.ifru_slave
#endif
関連項目¶
proc(5),
capabilities(7),
ip(7),
rtnetlink(7)
この文書について¶
この man ページは Linux
man-pages
プロジェクトのリリース
3.65 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。