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;
};
};
struct ifconf {
int ifc_len; /* size of buffer */
union {
char *ifc_buf; /* buffer address */
struct ifreq *ifc_req; /* array of structures */
};
};
通常、ユーザーによる設定対象デバイスの指定は、
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
プロトコルがない。 |
| 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)
ファミリーのアドレスのみである。
ユーザーは ifconf
構造体を ioctl
の引数として渡す。
ifconf 構造体には、
ifreq
構造体の配列へのポインタである
ifc_req
と、バイト単位の配列の長さを指定する
ifc_len が含まれる。
カーネルは ifreqs
を現在動作している全ての
L3
インターフェースアドレスで埋める。
ifr_name
にはインターフェース名
(eth0:1 など) が入り、 ifr_addr
にはアドレスが入る。
カーネルは実際の長さを
ifc_len に返す。 ifc_len
が元のバッファの長さと同じだった場合、
オーバーフローを起こしている可能性があるので、
全てのアドレスを取得するためにより大きなバッファで再試行するべきである。
エラーがなかった場合は
ioctl は 0 を返す。
エラーがあった場合は
-1 を返す。
オーバーフローはエラーとは見なされない。
ほとんどのプロトコルには、専用のインターフェースオプションを
設定するための独自の
ioctl が存在する。
説明は各プロトコルの
man ページを見よ。
さらに、デバイスによってはプライベートな
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.41 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。